diff --git a/time/example_time_tuple.py b/time/example_time_tuple.py new file mode 100644 index 00000000..2c73ed27 --- /dev/null +++ b/time/example_time_tuple.py @@ -0,0 +1,10 @@ +import time + +ts = 0 +for i in range(0, 31): + ts += 1 << i + ltt = time.localtime(ts) + gtt = time.gmtime(ts) + print("ts: ", ts, " local: ", tuple(ltt), " utc: ", tuple(gtt)) + lts = time.mktime(ltt) + assert ts == lts diff --git a/time/time.py b/time/time.py index 11b5ef4c..9223d6f7 100644 --- a/time/time.py +++ b/time/time.py @@ -1,4 +1,6 @@ from utime import * +import ustruct +import uctypes import ffi import ffilib import array @@ -12,6 +14,16 @@ libc = ffilib.libc() gmtime_ = libc.func("P", "gmtime", "P") localtime_ = libc.func("P", "localtime", "P") strftime_ = libc.func("i", "strftime", "sisP") +mktime_ = libc.func("i", "mktime", "P") + + +def _tuple_to_c_tm(t): + return ustruct.pack("@iiiiiiiii", t[5], t[4], t[3], t[2], t[1] - 1, t[0] - 1900, (t[6] + 1) % 7, t[7] - 1, t[8]) + + +def _c_tm_to_tuple(tm): + t = ustruct.unpack("@iiiiiiiii", tm) + return tuple([t[5] + 1900, t[4] + 1, t[3], t[2], t[1], t[0], (t[6] - 1) % 7, t[7] + 1, t[8]]) def strftime(format, t=None): @@ -25,6 +37,31 @@ def strftime(format, t=None): l = strftime_(buf, 32, format, tm_p) return str(buf[:l], "utf-8") + +def localtime(t=None): + if t is None: + t = time() + + t = int(t) + a = ustruct.pack('i', t) + tm_p = localtime_(a) + return _c_tm_to_tuple(uctypes.bytearray_at(tm_p, 36)) + + +def gmtime(t=None): + if t is None: + t = time() + + t = int(t) + a = ustruct.pack('i', t) + tm_p = gmtime_(a) + return _c_tm_to_tuple(uctypes.bytearray_at(tm_p, 36)) + + +def mktime(tt): + return mktime_(_tuple_to_c_tm(tt)) + + def perf_counter(): return time()