Need to address inconsistencies between mktime and localtime.
Currently, if I do:
>>> time.localtime(-1072915200)
(1966, 1, 1, 0, 0, 0, 5, 1)
>>> time.mktime((1966, 1, 1, 0, 0, 0, 5, 1))
3222052096
>>> time.localtime(3222052096)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: overflow converting long int to machine word
>>> hex(3222052096)
'0xc00c9d00'
>>> hex(0x80000000 - 1072915200)
'0x400c9d00'
I think that time.mktime((1966, 1, 1, 0, 0, 0, 5, 1)) should return the negative representation. However, I noticed that timeutils_seconds_since_2000 returns an mp_uint_t rather than an mp_int_t
So a couple of questions came to mind:
1 - Do we want to support times from 1966 to 2000 (which is the -ve small int range)?
2 - Should we support mpz ints?
3 - Adding full support for mpz ints seems like overkill, but we could get 1 extra bit by allowing mpz ints in the full 32-bit range to be supported. Then we'd be able to support dates from 2000 +/- 68 years. This would only require a slightly different conversion into and out of the timeutils functions. The actual code itself wouldn't need to change.
Thoughts?
Add time.mktime and enhance time.localtime (for stmhal)
Now you can use time.localtime on the timestamps presented by os.stat
I tested the implementation using the following script on my stmhal board:
import time
DAYS_PER_MONTH = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def is_leap(year):
return (year % 4) == 0
def test():
seconds = 0
wday = 5 # Jan 1, 2000 was a Saturday
for year in range(2000, 2034):
print("Testing %d" % year)
yday = 1
for month in range(1, 13):
if month == 2 and is_leap(year):
DAYS_PER_MONTH[2] = 29
else:
DAYS_PER_MONTH[2] = 28
for day in range(1, DAYS_PER_MONTH[month] + 1):
secs = time.mktime((year, month, day, 0, 0, 0, 0, 0))
if secs != seconds:
print("mktime failed for %d-%02d-%02d got %d expected %d" % (year, month, day, secs, seconds))
tuple = time.localtime(seconds)
secs = time.mktime(tuple)
if secs != seconds:
print("localtime failed for %d-%02d-%02d got %d expected %d" % (year, month, day, secs, seconds))
return
seconds += 86400
if yday != tuple[7]:
print("locatime for %d-%02d-%02d got yday %d, expecting %d" % (year, month, day, tuple[7], yday))
return
if wday != tuple[6]:
print("locatime for %d-%02d-%02d got wday %d, expecting %d" % (year, month, day, tuple[6], wday))
return
yday += 1
wday = (wday + 1) % 7
test()