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

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy