10000 unix/modtime: Add utime.mktime function, to complement utime.localtime. · micropython/micropython@1b844e9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1b84 10000 4e9

Browse files
pi-anldpgeorge
authored andcommitted
unix/modtime: Add utime.mktime function, to complement utime.localtime.
This also adds it to the windows port.
1 parent b23bd64 commit 1b844e9

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

ports/unix/modtime.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,37 @@ STATIC mp_obj_t mod_time_localtime(size_t n_args, const mp_obj_t *args) {
161161
}
162162
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_time_localtime_obj, 0, 1, mod_time_localtime);
163163

164+
STATIC mp_obj_t mod_time_mktime(mp_obj_t tuple) {
165+
size_t len;
166+
mp_obj_t *elem;
167+
mp_obj_get_array(tuple, &len, &elem);
168+
169+
// localtime generates a tuple of len 8. CPython uses 9, so we accept both.
170+
if (len < 8 || len > 9) {
171+
mp_raise_TypeError("mktime needs a tuple of length 8 or 9");
172+
}
173+
174+
struct tm time = {
175+
.tm_year = mp_obj_get_int(elem[0]) - 1900,
176+
.tm_mon = mp_obj_get_int(elem[1]) - 1,
177+
.tm_mday = mp_obj_get_int(elem[2]),
178+
.tm_hour = mp_obj_get_int(elem[3]),
179+
.tm_min = mp_obj_get_int(elem[4]),
180+
.tm_sec = mp_obj_get_int(elem[5]),
181+
};
182+
if (len == 9) {
183+
time.tm_isdst = mp_obj_get_int(elem[8]);
184+
} else {
185+
time.tm_isdst = -1; // auto-detect
186+
}
187+
time_t ret = mktime(&time);
188+
if (ret == -1) {
189+
mp_raise_msg(&mp_type_OverflowError, "invalid mktime usage");
190+
}
191+
return mp_obj_new_int(ret);
192+
}
193+
MP_DEFINE_CONST_FUN_OBJ_1(mod_time_mktime_obj, mod_time_mktime);
194+
164195
STATIC const mp_rom_map_elem_t mp_module_time_globals_table[] = {
165196
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utime) },
166197
{ MP_ROM_QSTR(MP_QSTR_clock), MP_ROM_PTR(&mod_time_clock_obj) },
@@ -174,6 +205,7 @@ STATIC const mp_rom_map_elem_t mp_module_time_globals_table[] = {
174205
{ MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) },
175206
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) },
176207
{ MP_ROM_QSTR(MP_QSTR_localtime), MP_ROM_PTR(&mod_time_localtime_obj) },
208+
{ MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&mod_time_mktime_obj) },
177209
};
178210

179211
STATIC MP_DEFINE_CONST_DICT(mp_module_time_globals, mp_module_time_globals_table);

tests/unix/time.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
try:
2+
import utime as time
3+
except ImportError:
4+
import time
5+
6+
DAYS_PER_MONTH = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
7+
8+
tzseconds = -time.mktime((1970, 1, 1, 0, 0, 0, 0, 0, 0))
9+
10+
def is_leap(year):
11+
return (year % 4) == 0
12+
13+
def test():
14+
seconds = 0
15+
wday = 3 # Jan 1, 1970 was a Thursday
16+
for year in range(1970, 2038):
17+
print("Testing %d" % year)
18+
yday = 1
19+
for month in range(1, 13):
20+
if month == 2 and is_leap(year):
21+
DAYS_PER_MONTH[2] = 29
22+
else:
23+
DAYS_PER_MONTH[2] = 28
24+
for day in range(1, DAYS_PER_MONTH[month] + 1):
25+
secs = time.mktime((year, month, day, 0, 0, 0, 0, 0, 0)) + tzseconds
26+
if secs != seconds:
27+
print("mktime failed for %d-%02d-%02d got %d expected %d" % (year, month, day, secs, seconds))
28+
return
29+
tuple = time.localtime(seconds)
30+
secs = time.mktime(tuple)
31+
if secs != seconds:
32+
print("localtime failed for %d-%02d-%02d got %d expected %d" % (year, month, day, secs, seconds))
33+
return
34+
seconds += 86400
35+
if yday != tuple[7]:
36+
print("locatime for %d-%02d-%02d got yday %d, expecting %d" % (year, month, day, tuple[7], yday))
37+
return
38+
if wday != tuple[6]:
39+
print("locatime for %d-%02d-%02d got wday %d, expecting %d" % (year, month, day, tuple[6], wday))
40+
return
41+
yday += 1
42+
wday = (wday + 1) % 7
43+
44+
test()

0 commit comments

Comments
 (0)
0