Skip to content

Commit 95e70cd

Browse files
committed
time: Use 1970 epoch
Use UNIX epoch to match CPython. This overflows small int so time.{time,localtime,mktime} is only supported with long int. Also remove some comment cruft in time_time().
1 parent cf33ad9 commit 95e70cd

1 file changed

Lines changed: 26 additions & 9 deletions

File tree

shared-bindings/time/__init__.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include "shared-bindings/rtc/__init__.h"
3535
#include "shared-bindings/time/__init__.h"
3636

37+
#define EPOCH1970_EPOCH2000_DIFF_SECS 946684800
38+
3739
//| :mod:`time` --- time and timing related functions
3840
//| ========================================================
3941
//|
@@ -183,31 +185,33 @@ void struct_time_to_tm(mp_obj_t t, timeutils_struct_time_t *tm) {
183185
// elems[8] tm_isdst is not supported
184186
}
185187

188+
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
186189
mp_obj_t MP_WEAK rtc_get_time_source_time(void) {
187190
mp_raise_RuntimeError("RTC is not supported on this board");
188191
}
189192

190193
//| .. method:: time()
191194
//|
192-
//| Return the current time in seconds since since Jan 1, 2000.
195+
//| Return the current time in seconds since since Jan 1, 1970.
193196
//|
194197
//| :return: the current time
195198
//| :rtype: int
196199
//|
197200
STATIC mp_obj_t time_time(void) {
198201
timeutils_struct_time_t tm;
199202
struct_time_to_tm(rtc_get_time_source_time(), &tm);
200-
mp_uint_t secs = timeutils_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday, // mp_uint_t date
203+
mp_uint_t secs = timeutils_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday,
201204
tm.tm_hour, tm.tm_min, tm.tm_sec);
202-
return mp_obj_new_int_from_uint(secs);
205+
return mp_obj_new_int_from_uint(secs + EPOCH1970_EPOCH2000_DIFF_SECS);
203206
}
204207
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
205208

206209
//| .. method:: localtime([secs])
207210
//|
208-
//| Convert a time expressed in seconds since Jan 1, 2000 to a struct_time in
211+
//| Convert a time expressed in seconds since Jan 1, 1970 to a struct_time in
209212
//| local time. If secs is not provided or None, the current time as returned
210213
//| by time() is used.
214+
//| The earliest date for which it can generate a time is Jan 1, 2000.
211215
//|
212216
//| :return: the current time
213217
//| :rtype: time.struct_time
@@ -217,8 +221,12 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) {
217221
return rtc_get_time_source_time();
218222
}
219223

224+
mp_int_t secs = mp_obj_int_get_checked(args[0]);
225+
if (secs < EPOCH1970_EPOCH2000_DIFF_SECS)
226+
mp_raise_msg(&mp_type_OverflowError, "timestamp out of range for platform time_t");
227+
220228
timeutils_struct_time_t tm;
221-
timeutils_seconds_since_2000_to_struct_time(mp_obj_get_int(args[0]), &tm);
229+
timeutils_seconds_since_2000_to_struct_time(secs - EPOCH1970_EPOCH2000_DIFF_SECS, &tm);
222230

223231
return struct_time_from_tm(&tm);
224232
}
@@ -247,11 +255,16 @@ STATIC mp_obj_t time_mktime(mp_obj_t t) {
247255
mp_raise_TypeError("function takes exactly 9 arguments");
248256
}
249257

250-
return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]),
251-
mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])));
258+
if (mp_obj_get_int(elem[0]) < 2000)
259+
mp_raise_msg(&mp_type_OverflowError, "timestamp out of range for platform time_t");
260+
261+
mp_uint_t secs = timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]),
262+
mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5]));
263+
return mp_obj_new_int_from_uint(secs + EPOCH1970_EPOCH2000_DIFF_SECS);
252264
}
253265
MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime);
254-
#endif
266+
#endif // MICROPY_LONGINT_IMPL
267+
#endif // MICROPY_PY_COLLECTIONS
255268

256269
STATIC const mp_rom_map_elem_t time_module_globals_table[] = {
257270
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_time) },
@@ -260,10 +273,14 @@ STATIC const mp_rom_map_elem_t time_module_globals_table[] = {
260273
{ MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&time_sleep_obj) },
261274
#if MICROPY_PY_COLLECTIONS
262275
{ MP_ROM_QSTR(MP_QSTR_struct_time), MP_ROM_PTR(&struct_time_type_obj) },
276+
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
263277
{ MP_ROM_QSTR(MP_QSTR_localtime), MP_ROM_PTR(&time_localtime_obj) },
264278
{ MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&time_mktime_obj) },
265-
#endif
279+
#endif // MICROPY_LONGINT_IMPL
280+
#endif // MICROPY_PY_COLLECTIONS
281+
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
266282
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&time_time_obj) },
283+
#endif
267284
};
268285

269286
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);

0 commit comments

Comments
 (0)