summaryrefslogtreecommitdiffstatshomepage
path: root/ports
diff options
context:
space:
mode:
authorYoctopuce dev <dev@yoctopuce.com>2025-07-01 13:16:20 +0200
committerDamien George <damien@micropython.org>2025-07-09 11:54:21 +1000
commitdf05caea6c6437a8b4756ec502a5e6210f4b6256 (patch)
tree4ffab6a3b85bb8a287e661d55a7ddc59f80357d9 /ports
parentc4a88f2ce7da87d5f635ec25edba481917020fd8 (diff)
downloadmicropython-master.tar.gz
micropython-master.zip
shared/timeutils: Standardize supported date range on all platforms.HEADmaster
This is code makes sure that time functions work properly on a reasonable date range, on all platforms, regardless of the epoch. The suggested minimum range is 1970 to 2099. In order to reduce code footprint, code to support far away dates is only enabled specified by the port. New types are defined to identify timestamps. The implementation with the smallest code footprint is when support timerange is limited to 1970-2099 and Epoch is 1970. This makes it possible to use 32 bit unsigned integers for all timestamps. On ARM4F, adding support for dates up to year 3000 adds 460 bytes of code. Supporting dates back to 1600 adds another 44 bytes of code. Signed-off-by: Yoctopuce dev <dev@yoctopuce.com>
Diffstat (limited to 'ports')
-rw-r--r--ports/cc3200/mods/modtime.c2
-rw-r--r--ports/esp32/modtime.c2
-rw-r--r--ports/esp8266/modtime.c4
-rw-r--r--ports/mimxrt/modtime.c9
-rw-r--r--ports/renesas-ra/modtime.c2
-rw-r--r--ports/stm32/modtime.c2
-rw-r--r--ports/stm32/mpconfigport.h1
-rw-r--r--ports/unix/Makefile4
-rw-r--r--ports/unix/modtime.c10
-rw-r--r--ports/unix/mpconfigport.h3
-rw-r--r--ports/windows/Makefile4
11 files changed, 22 insertions, 21 deletions
diff --git a/ports/cc3200/mods/modtime.c b/ports/cc3200/mods/modtime.c
index 21388568ab..254678fb2d 100644
--- a/ports/cc3200/mods/modtime.c
+++ b/ports/cc3200/mods/modtime.c
@@ -50,5 +50,5 @@ static mp_obj_t mp_time_localtime_get(void) {
// Returns the number of seconds, as an integer, since the Epoch.
static mp_obj_t mp_time_time_get(void) {
- return mp_obj_new_int(pyb_rtc_get_seconds());
+ return timeutils_obj_from_timestamp(pyb_rtc_get_seconds());
}
diff --git a/ports/esp32/modtime.c b/ports/esp32/modtime.c
index 4695dd23e7..991f2cf578 100644
--- a/ports/esp32/modtime.c
+++ b/ports/esp32/modtime.c
@@ -54,5 +54,5 @@ static mp_obj_t mp_time_localtime_get(void) {
static mp_obj_t mp_time_time_get(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
- return mp_obj_new_int(tv.tv_sec);
+ return timeutils_obj_from_timestamp(tv.tv_sec);
}
diff --git a/ports/esp8266/modtime.c b/ports/esp8266/modtime.c
index 0903005597..e99d920fde 100644
--- a/ports/esp8266/modtime.c
+++ b/ports/esp8266/modtime.c
@@ -31,7 +31,7 @@
// Return the localtime as an 8-tuple.
static mp_obj_t mp_time_localtime_get(void) {
- mp_int_t seconds = pyb_rtc_get_us_since_epoch() / 1000 / 1000;
+ mp_uint_t seconds = pyb_rtc_get_us_since_epoch() / 1000u / 1000u;
timeutils_struct_time_t tm;
timeutils_seconds_since_epoch_to_struct_time(seconds, &tm);
mp_obj_t tuple[8] = {
@@ -50,5 +50,5 @@ static mp_obj_t mp_time_localtime_get(void) {
// Returns the number of seconds, as an integer, since the Epoch.
static mp_obj_t mp_time_time_get(void) {
// get date and time
- return mp_obj_new_int(pyb_rtc_get_us_since_epoch() / 1000 / 1000);
+ return timeutils_obj_from_timestamp(pyb_rtc_get_us_since_epoch() / 1000 / 1000);
}
diff --git a/ports/mimxrt/modtime.c b/ports/mimxrt/modtime.c
index a2ccf1b273..3bcfac411c 100644
--- a/ports/mimxrt/modtime.c
+++ b/ports/mimxrt/modtime.c
@@ -51,14 +51,7 @@ static mp_obj_t mp_time_localtime_get(void) {
static mp_obj_t mp_time_time_get(void) {
snvs_lp_srtc_datetime_t t;
SNVS_LP_SRTC_GetDatetime(SNVS, &t);
- // EPOCH is 1970 for this port, which leads to the following trouble:
- // timeutils_seconds_since_epoch() calls timeutils_seconds_since_2000(), and
- // timeutils_seconds_since_2000() subtracts 2000 from year, but uses
- // an unsigned number for seconds, That causes an underrun, which is not
- // fixed by adding the TIMEUTILS_SECONDS_1970_TO_2000.
- // Masking it to 32 bit for year < 2000 fixes it.
- return mp_obj_new_int_from_ull(
+ return timeutils_obj_from_timestamp(
timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.minute, t.second)
- & (t.year < 2000 ? 0xffffffff : 0xffffffffffff)
);
}
diff --git a/ports/renesas-ra/modtime.c b/ports/renesas-ra/modtime.c
index cbd639721f..e1358f82bc 100644
--- a/ports/renesas-ra/modtime.c
+++ b/ports/renesas-ra/modtime.c
@@ -53,5 +53,5 @@ static mp_obj_t mp_time_time_get(void) {
rtc_init_finalise();
ra_rtc_t time;
ra_rtc_get_time(&time);
- return mp_obj_new_int(timeutils_seconds_since_epoch(time.year, time.month, time.date, time.hour, time.minute, time.second));
+ return timeutils_obj_from_timestamp(timeutils_seconds_since_epoch(time.year, time.month, time.date, time.hour, time.minute, time.second));
}
diff --git a/ports/stm32/modtime.c b/ports/stm32/modtime.c
index ff1495a5d9..87a4536b04 100644
--- a/ports/stm32/modtime.c
+++ b/ports/stm32/modtime.c
@@ -59,5 +59,5 @@ static mp_obj_t mp_time_time_get(void) {
RTC_TimeTypeDef time;
HAL_RTC_GetTime(&RTCHandle, &time, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&RTCHandle, &date, RTC_FORMAT_BIN);
- return mp_obj_new_int(timeutils_seconds_since_epoch(2000 + date.Year, date.Month, date.Date, time.Hours, time.Minutes, time.Seconds));
+ return timeutils_obj_from_timestamp(timeutils_seconds_since_epoch(2000 + date.Year, date.Month, date.Date, time.Hours, time.Minutes, time.Seconds));
}
diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h
index 41ed3d08b7..b910188c5a 100644
--- a/ports/stm32/mpconfigport.h
+++ b/ports/stm32/mpconfigport.h
@@ -76,6 +76,7 @@
#ifndef MICROPY_FLOAT_IMPL // can be configured by each board via mpconfigboard.mk
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
#endif
+#define MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE (1)
#define MICROPY_USE_INTERNAL_ERRNO (1)
#define MICROPY_SCHEDULER_STATIC_NODES (1)
#define MICROPY_SCHEDULER_DEPTH (8)
diff --git a/ports/unix/Makefile b/ports/unix/Makefile
index 3c54d156c3..8bd58a2542 100644
--- a/ports/unix/Makefile
+++ b/ports/unix/Makefile
@@ -52,6 +52,10 @@ CFLAGS += $(INC) $(CWARN) -std=gnu99 -DUNIX $(COPT) -I$(VARIANT_DIR) $(CFLAGS_EX
# This option has no effect on 64-bit builds.
CFLAGS += -D_FILE_OFFSET_BITS=64
+# Force the use of 64-bits for time_t in C library functions on 32-bit platforms.
+# This option has no effect on 64-bit builds.
+CFLAGS += -D_TIME_BITS=64
+
# Debugging/Optimization
ifdef DEBUG
COPT ?= -Og
diff --git a/ports/unix/modtime.c b/ports/unix/modtime.c
index fbd94b5ecd..41b7c89df4 100644
--- a/ports/unix/modtime.c
+++ b/ports/unix/modtime.c
@@ -34,6 +34,7 @@
#include "py/mphal.h"
#include "py/runtime.h"
+#include "shared/timeutils/timeutils.h"
#ifdef _WIN32
static inline int msec_sleep_tv(struct timeval *tv) {
@@ -130,12 +131,7 @@ static mp_obj_t mod_time_gm_local_time(size_t n_args, const mp_obj_t *args, stru
if (n_args == 0) {
t = time(NULL);
} else {
- #if MICROPY_PY_BUILTINS_FLOAT && MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
- mp_float_t val = mp_obj_get_float(args[0]);
- t = (time_t)MICROPY_FLOAT_C_FUN(trunc)(val);
- #else
- t = mp_obj_get_int(args[0]);
- #endif
+ t = (time_t)timeutils_obj_get_timestamp(args[0]);
}
struct tm *tm = time_func(&t);
@@ -196,7 +192,7 @@ static mp_obj_t mod_time_mktime(mp_obj_t tuple) {
if (ret == -1) {
mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("invalid mktime usage"));
}
- return mp_obj_new_int(ret);
+ return timeutils_obj_from_timestamp(ret);
}
MP_DEFINE_CONST_FUN_OBJ_1(mod_time_mktime_obj, mod_time_mktime);
diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h
index 21ce75a351..973b5e74ce 100644
--- a/ports/unix/mpconfigport.h
+++ b/ports/unix/mpconfigport.h
@@ -124,6 +124,9 @@ typedef long mp_off_t;
// VFS stat functions should return time values relative to 1970/1/1
#define MICROPY_EPOCH_IS_1970 (1)
+// port modtime functions use time_t
+#define MICROPY_TIMESTAMP_IMPL (MICROPY_TIMESTAMP_IMPL_TIME_T)
+
// Assume that select() call, interrupted with a signal, and erroring
// with EINTR, updates remaining timeout value.
#define MICROPY_SELECT_REMAINING_TIME (1)
diff --git a/ports/windows/Makefile b/ports/windows/Makefile
index 115d1a61ef..9eee98cdd4 100644
--- a/ports/windows/Makefile
+++ b/ports/windows/Makefile
@@ -46,6 +46,10 @@ LDFLAGS += -lm -lbcrypt $(LDFLAGS_EXTRA)
# This option has no effect on 64-bit builds.
CFLAGS += -D_FILE_OFFSET_BITS=64
+# Force the use of 64-bits for time_t in C library functions on 32-bit platforms.
+# This option has no effect on 64-bit builds.
+CFLAGS += -D_TIME_BITS=64
+
# Debugging/Optimization
ifdef DEBUG
CFLAGS += -g