Skip to content

Commit 8f20cdc

Browse files
committed
all: Rename absolute time-based functions to include "epoch".
For time-based functions that work with absolute time there is the need for an Epoch, to set the zero-point at which the absolute time starts counting. Such functions include time.time() and filesystem stat return values. And different ports may use a different Epoch. To make it clearer what functions use the Epoch (whatever it may be), and make the ports more consistent with their use of the Epoch, this commit renames all Epoch related functions to include the word "epoch" in their name (and remove references to "2000"). Along with this rename, the following things have changed: - mp_hal_time_ns() is now specified to return the number of nanoseconds since the Epoch, rather than since 1970 (but since this is an internal function it doesn't change anything for the user). - littlefs timestamps on the esp8266 have been fixed (they were previously off by 30 years in nanoseconds). Otherwise, there is no functional change made by this commit. Signed-off-by: Damien George <[email protected]>
1 parent bd7af61 commit 8f20cdc

17 files changed

+67
-50
lines changed

extmod/vfs_fat.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -311,17 +311,14 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
311311
} else {
312312
mode |= MP_S_IFREG;
313313
}
314-
mp_int_t seconds = timeutils_seconds_since_2000(
314+
mp_int_t seconds = timeutils_seconds_since_epoch(
315315
1980 + ((fno.fdate >> 9) & 0x7f),
316316
(fno.fdate >> 5) & 0x0f,
317317
fno.fdate & 0x1f,
318318
(fno.ftime >> 11) & 0x1f,
319319
(fno.ftime >> 5) & 0x3f,
320320
2 * (fno.ftime & 0x1f)
321321
);
322-
#if MICROPY_EPOCH_IS_1970
323-
seconds += TIMEUTILS_SECONDS_1970_TO_2000;
324-
#endif
325322
t->items[0] = MP_OBJ_NEW_SMALL_INT(mode); // st_mode
326323
t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino
327324
t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev

extmod/vfs_lfs.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include "py/runtime.h"
2828
#include "py/mphal.h"
29+
#include "lib/timeutils/timeutils.h"
2930
#include "extmod/vfs.h"
3031
#include "extmod/vfs_lfs.h"
3132

@@ -126,7 +127,8 @@ const char *mp_vfs_lfs2_make_path(mp_obj_vfs_lfs2_t *self, mp_obj_t path_in);
126127
mp_obj_t mp_vfs_lfs2_file_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode_in);
127128

128129
STATIC void lfs_get_mtime(uint8_t buf[8]) {
129-
uint64_t ns = mp_hal_time_ns();
130+
// On-disk storage of timestamps uses 1970 as the Epoch, so convert from host's Epoch.
131+
uint64_t ns = timeutils_nanoseconds_since_epoch_to_nanoseconds_since_1970(mp_hal_time_ns());
130132
// Store "ns" to "buf" in little-endian format (essentially htole64).
131133
for (size_t i = 0; i < 8; ++i) {
132134
buf[i] = ns;

extmod/vfs_lfsx.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -365,10 +365,8 @@ STATIC mp_obj_t MP_VFS_LFSx(stat)(mp_obj_t self_in, mp_obj_t path_in) {
365365
for (size_t i = sizeof(mtime_buf); i > 0; --i) {
366366
ns = ns << 8 | mtime_buf[i - 1];
367367
}
368-
mtime = timeutils_seconds_since_2000_from_nanoseconds_since_1970(ns);
369-
#if MICROPY_EPOCH_IS_1970
370-
mtime += TIMEUTILS_SECONDS_1970_TO_2000;
371-
#endif
368+
// On-disk storage of timestamps uses 1970 as the Epoch, so convert to host's Epoch.
369+
mtime = timeutils_seconds_since_epoch_from_nanoseconds_since_1970(ns);
372370
}
373371
#endif
374372

lib/timeutils/timeutils.h

+32-11
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,6 @@ typedef struct _timeutils_struct_time_t {
4242
uint16_t tm_yday; // 1..366
4343
} timeutils_struct_time_t;
4444

45-
static inline uint64_t timeutils_seconds_since_2000_to_nanoseconds_since_1970(mp_uint_t s) {
46-
return ((uint64_t)s + TIMEUTILS_SECONDS_1970_TO_2000) * 1000000000ULL;
47-
}
48-
49-
static inline mp_uint_t timeutils_seconds_since_2000_from_nanoseconds_since_1970(uint64_t ns) {
50-
return ns / 1000000000ULL - TIMEUTILS_SECONDS_1970_TO_2000;
51-
}
52-
5345
bool timeutils_is_leap_year(mp_uint_t year);
5446
mp_uint_t timeutils_days_in_month(mp_uint_t year, mp_uint_t month);
5547
mp_uint_t timeutils_year_day(mp_uint_t year, mp_uint_t month, mp_uint_t date);
@@ -63,10 +55,39 @@ mp_uint_t timeutils_seconds_since_2000(mp_uint_t year, mp_uint_t month,
6355
mp_uint_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t mday,
6456
mp_int_t hours, mp_int_t minutes, mp_int_t seconds);
6557

66-
static inline uint64_t timeutils_nanoseconds_since_1970(mp_uint_t year, mp_uint_t month,
58+
// Select the Epoch used by the port.
59+
#if MICROPY_EPOCH_IS_1970
60+
61+
static inline uint64_t timeutils_seconds_since_epoch(mp_uint_t year, mp_uint_t month,
6762
mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second) {
68-
return timeutils_seconds_since_2000_to_nanoseconds_since_1970(
69-
timeutils_seconds_since_2000(year, month, date, hour, minute, second));
63+
return timeutils_seconds_since_2000(year, month, date, hour, minute, second) + TIMEUTILS_SECONDS_1970_TO_2000;
64+
}
65+
66+
static inline mp_uint_t timeutils_seconds_since_epoch_from_nanoseconds_since_1970(uint64_t ns) {
67+
return ns / 1000000000ULL;
68+
}
69+
70+
static inline uint64_t timeutils_nanoseconds_since_epoch_to_nanoseconds_since_1970(uint64_t ns) {
71+
return ns;
7072
}
7173

74+
#else // Epoch is 2000
75+
76+
#define timeutils_seconds_since_epoch_to_struct_time timeutils_seconds_since_2000_to_struct_time
77+
#define timeutils_seconds_since_epoch timeutils_seconds_since_2000
78+
79+
static inline uint64_t timeutils_seconds_since_epoch_to_nanoseconds_since_1970(mp_uint_t s) {
80+
return ((uint64_t)s + TIMEUTILS_SECONDS_1970_TO_2000) * 1000000000ULL;
81+
}
82+
83+
static inline mp_uint_t timeutils_seconds_since_epoch_from_nanoseconds_since_1970(uint64_t ns) {
84+
return ns / 1000000000ULL - TIMEUTILS_SECONDS_1970_TO_2000;
85+
}
86+
87+
static inline int64_t timeutils_nanoseconds_since_epoch_to_nanoseconds_since_1970(int64_t ns) {
88+
return ns + TIMEUTILS_SECONDS_1970_TO_2000 * 1000000000ULL;
89+
}
90+
91+
#endif
92+
7293
#endif // MICROPY_INCLUDED_LIB_TIMEUTILS_TIMEUTILS_H

ports/esp32/fatfs_port.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ DWORD get_fattime(void) {
3434
struct timeval tv;
3535
gettimeofday(&tv, NULL);
3636
timeutils_struct_time_t tm;
37-
timeutils_seconds_since_2000_to_struct_time(tv.tv_sec, &tm);
37+
timeutils_seconds_since_epoch_to_struct_time(tv.tv_sec, &tm);
3838

3939
return ((DWORD)(tm.tm_year - 1980) << 25) | ((DWORD)tm.tm_mon << 21) | ((DWORD)tm.tm_mday << 16) |
4040
((DWORD)tm.tm_hour << 11) | ((DWORD)tm.tm_min << 5) | ((DWORD)tm.tm_sec >> 1);

ports/esp32/machine_rtc.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ STATIC mp_obj_t machine_rtc_datetime_helper(mp_uint_t n_args, const mp_obj_t *ar
9393
gettimeofday(&tv, NULL);
9494
timeutils_struct_time_t tm;
9595

96-
timeutils_seconds_since_2000_to_struct_time(tv.tv_sec, &tm);
96+
timeutils_seconds_since_epoch_to_struct_time(tv.tv_sec, &tm);
9797

9898
mp_obj_t tuple[8] = {
9999
mp_obj_new_int(tm.tm_year),
@@ -114,7 +114,7 @@ STATIC mp_obj_t machine_rtc_datetime_helper(mp_uint_t n_args, const mp_obj_t *ar
114114
mp_obj_get_array_fixed_n(args[1], 8, &items);
115115

116116
struct timeval tv = {0};
117-
tv.tv_sec = timeutils_seconds_since_2000(mp_obj_get_int(items[0]), mp_obj_get_int(items[1]), mp_obj_get_int(items[2]), mp_obj_get_int(items[4]), mp_obj_get_int(items[5]), mp_obj_get_int(items[6]));
117+
tv.tv_sec = timeutils_seconds_since_epoch(mp_obj_get_int(items[0]), mp_obj_get_int(items[1]), mp_obj_get_int(items[2]), mp_obj_get_int(items[4]), mp_obj_get_int(items[5]), mp_obj_get_int(items[6]));
118118
tv.tv_usec = mp_obj_get_int(items[7]);
119119
settimeofday(&tv, NULL);
120120

ports/esp32/modutime.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) {
4444
} else {
4545
seconds = mp_obj_get_int(args[0]);
4646
}
47-
timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
47+
timeutils_seconds_since_epoch_to_struct_time(seconds, &tm);
4848
mp_obj_t tuple[8] = {
4949
tuple[0] = mp_obj_new_int(tm.tm_year),
5050
tuple[1] = mp_obj_new_int(tm.tm_mon),

ports/esp32/mphalport.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,7 @@ void mp_hal_delay_us(uint32_t us) {
200200
uint64_t mp_hal_time_ns(void) {
201201
struct timeval tv;
202202
gettimeofday(&tv, NULL);
203-
// gettimeofday returns seconds since 2000/1/1
204-
uint64_t ns = timeutils_seconds_since_2000_to_nanoseconds_since_1970(tv.tv_sec);
203+
uint64_t ns = tv.tv_sec * 1000000000ULL;
205204
ns += (uint64_t)tv.tv_usec * 1000ULL;
206205
return ns;
207206
}

ports/esp8266/esp_mphal.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void MP_FASTCODE(mp_hal_delay_ms)(uint32_t delay) {
139139
}
140140

141141
uint64_t mp_hal_time_ns(void) {
142-
return pyb_rtc_get_us_since_2000() * 1000ULL;
142+
return pyb_rtc_get_us_since_epoch() * 1000ULL;
143143
}
144144

145145
void ets_event_poll(void) {

ports/esp8266/fatfs_port.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ DWORD get_fattime(void) {
3333

3434
// TODO: Optimize division (there's no HW division support on ESP8266,
3535
// so it's expensive).
36-
uint32_t secs = (uint32_t)(pyb_rtc_get_us_since_2000() / 1000000);
36+
uint32_t secs = (uint32_t)(pyb_rtc_get_us_since_epoch() / 1000000);
3737

3838
timeutils_struct_time_t tm;
39-
timeutils_seconds_since_2000_to_struct_time(secs, &tm);
39+
timeutils_seconds_since_epoch_to_struct_time(secs, &tm);
4040

4141
return ((DWORD)(tm.tm_year - 1980) << 25) | ((DWORD)tm.tm_mon << 21) | ((DWORD)tm.tm_mday << 16) |
4242
((DWORD)tm.tm_hour << 11) | ((DWORD)tm.tm_min << 5) | ((DWORD)tm.tm_sec >> 1);

ports/esp8266/machine_rtc.c

+9-9
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ STATIC mp_obj_t pyb_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_
8484
return (mp_obj_t)&pyb_rtc_obj;
8585
}
8686

87-
void pyb_rtc_set_us_since_2000(uint64_t nowus) {
87+
void pyb_rtc_set_us_since_epoch(uint64_t nowus) {
8888
uint32_t cal = system_rtc_clock_cali_proc();
8989
// Save RTC ticks for overflow detection.
9090
rtc_last_ticks = system_get_rtc_time();
@@ -96,7 +96,7 @@ void pyb_rtc_set_us_since_2000(uint64_t nowus) {
9696
system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta));
9797
};
9898

99-
uint64_t pyb_rtc_get_us_since_2000() {
99+
uint64_t pyb_rtc_get_us_since_epoch() {
100100
uint32_t cal;
101101
int64_t delta;
102102
uint32_t rtc_ticks;
@@ -120,17 +120,17 @@ uint64_t pyb_rtc_get_us_since_2000() {
120120

121121
void rtc_prepare_deepsleep(uint64_t sleep_us) {
122122
// RTC time will reset at wake up. Let's be preared for this.
123-
int64_t delta = pyb_rtc_get_us_since_2000() + sleep_us;
123+
int64_t delta = pyb_rtc_get_us_since_epoch() + sleep_us;
124124
system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta));
125125
}
126126

127127
STATIC mp_obj_t pyb_rtc_datetime(size_t n_args, const mp_obj_t *args) {
128128
if (n_args == 1) {
129129
// Get time
130-
uint64_t msecs = pyb_rtc_get_us_since_2000() / 1000;
130+
uint64_t msecs = pyb_rtc_get_us_since_epoch() / 1000;
131131

132132
timeutils_struct_time_t tm;
133-
timeutils_seconds_since_2000_to_struct_time(msecs / 1000, &tm);
133+
timeutils_seconds_since_epoch_to_struct_time(msecs / 1000, &tm);
134134

135135
mp_obj_t tuple[8] = {
136136
mp_obj_new_int(tm.tm_year),
@@ -149,8 +149,8 @@ STATIC mp_obj_t pyb_rtc_datetime(size_t n_args, const mp_obj_t *args) {
149149
mp_obj_t *items;
150150
mp_obj_get_array_fixed_n(args[1], 8, &items);
151151

152-
pyb_rtc_set_us_since_2000(
153-
((uint64_t)timeutils_seconds_since_2000(
152+
pyb_rtc_set_us_since_epoch(
153+
((uint64_t)timeutils_seconds_since_epoch(
154154
mp_obj_get_int(items[0]),
155155
mp_obj_get_int(items[1]),
156156
mp_obj_get_int(items[2]),
@@ -209,7 +209,7 @@ STATIC mp_obj_t pyb_rtc_alarm(mp_obj_t self_in, mp_obj_t alarm_id, mp_obj_t time
209209
}
210210

211211
// set expiry time (in microseconds)
212-
pyb_rtc_alarm0_expiry = pyb_rtc_get_us_since_2000() + (uint64_t)mp_obj_get_int(time_in) * 1000;
212+
pyb_rtc_alarm0_expiry = pyb_rtc_get_us_since_epoch() + (uint64_t)mp_obj_get_int(time_in) * 1000;
213213

214214
return mp_const_none;
215215

@@ -222,7 +222,7 @@ STATIC mp_obj_t pyb_rtc_alarm_left(size_t n_args, const mp_obj_t *args) {
222222
mp_raise_ValueError(MP_ERROR_TEXT("invalid alarm"));
223223
}
224224

225-
uint64_t now = pyb_rtc_get_us_since_2000();
225+
uint64_t now = pyb_rtc_get_us_since_epoch();
226226
if (pyb_rtc_alarm0_expiry <= now) {
227227
return MP_OBJ_NEW_SMALL_INT(0);
228228
} else {

ports/esp8266/modmachine.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ STATIC mp_obj_t machine_deepsleep(size_t n_args, const mp_obj_t *args) {
132132

133133
// see if RTC.ALARM0 should wake the device
134134
if (pyb_rtc_alarm0_wake & MACHINE_WAKE_DEEPSLEEP) {
135-
uint64_t t = pyb_rtc_get_us_since_2000();
135+
uint64_t t = pyb_rtc_get_us_since_epoch();
136136
if (pyb_rtc_alarm0_expiry <= t) {
137137
sleep_us = 1; // alarm already expired so wake immediately
138138
} else {

ports/esp8266/modmachine.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ void pin_set(uint pin, int value);
3232
extern uint32_t pyb_rtc_alarm0_wake;
3333
extern uint64_t pyb_rtc_alarm0_expiry;
3434

35-
void pyb_rtc_set_us_since_2000(uint64_t nowus);
36-
uint64_t pyb_rtc_get_us_since_2000();
35+
void pyb_rtc_set_us_since_epoch(uint64_t nowus);
36+
uint64_t pyb_rtc_get_us_since_epoch();
3737
void rtc_prepare_deepsleep(uint64_t sleep_us);
3838

3939
#endif // MICROPY_INCLUDED_ESP8266_MODMACHINE_H

ports/esp8266/modutime.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) {
5858
timeutils_struct_time_t tm;
5959
mp_int_t seconds;
6060
if (n_args == 0 || args[0] == mp_const_none) {
61-
seconds = pyb_rtc_get_us_since_2000() / 1000 / 1000;
61+
seconds = pyb_rtc_get_us_since_epoch() / 1000 / 1000;
6262
} else {
6363
seconds = mp_obj_get_int(args[0]);
6464
}
65-
timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
65+
timeutils_seconds_since_epoch_to_struct_time(seconds, &tm);
6666
mp_obj_t tuple[8] = {
6767
tuple[0] = mp_obj_new_int(tm.tm_year),
6868
tuple[1] = mp_obj_new_int(tm.tm_mon),
@@ -98,10 +98,10 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
9898
MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime);
9999

100100
/// \function time()
101-
/// Returns the number of seconds, as an integer, since 1/1/2000.
101+
/// Returns the number of seconds, as an integer, since the Epoch.
102102
STATIC mp_obj_t time_time(void) {
103103
// get date and time
104-
return mp_obj_new_int(pyb_rtc_get_us_since_2000() / 1000 / 1000);
104+
return mp_obj_new_int(pyb_rtc_get_us_since_epoch() / 1000 / 1000);
105105
}
106106
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
107107

ports/stm32/modutime.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) {
7676
} else {
7777
mp_int_t seconds = mp_obj_get_int(args[0]);
7878
timeutils_struct_time_t tm;
79-
timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
79+
timeutils_seconds_since_epoch_to_struct_time(seconds, &tm);
8080
mp_obj_t tuple[8] = {
8181
tuple[0] = mp_obj_new_int(tm.tm_year),
8282
tuple[1] = mp_obj_new_int(tm.tm_mon),
@@ -125,7 +125,7 @@ STATIC mp_obj_t time_time(void) {
125125
RTC_TimeTypeDef time;
126126
HAL_RTC_GetTime(&RTCHandle, &time, RTC_FORMAT_BIN);
127127
HAL_RTC_GetDate(&RTCHandle, &date, RTC_FORMAT_BIN);
128-
return mp_obj_new_int(timeutils_seconds_since_2000(2000 + date.Year, date.Month, date.Date, time.Hours, time.Minutes, time.Seconds));
128+
return mp_obj_new_int(timeutils_seconds_since_epoch(2000 + date.Year, date.Month, date.Date, time.Hours, time.Minutes, time.Seconds));
129129
}
130130
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
131131

ports/stm32/rtc.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,8 @@ uint64_t mp_hal_time_ns(void) {
452452
RTC_DateTypeDef date;
453453
HAL_RTC_GetTime(&RTCHandle, &time, RTC_FORMAT_BIN);
454454
HAL_RTC_GetDate(&RTCHandle, &date, RTC_FORMAT_BIN);
455-
ns = timeutils_nanoseconds_since_1970(
456-
2000 + date.Year, date.Month, date.Date, time.Hours, time.Minutes, time.Seconds);
455+
ns = timeutils_seconds_since_epoch(2000 + date.Year, date.Month, date.Date, time.Hours, time.Minutes, time.Seconds);
456+
ns *= 1000000000ULL;
457457
uint32_t usec = ((RTC_SYNCH_PREDIV - time.SubSeconds) * (1000000 / 64)) / ((RTC_SYNCH_PREDIV + 1) / 64);
458458
ns += usec * 1000;
459459
#endif

py/mphal.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ mp_uint_t mp_hal_ticks_cpu(void);
7676
#endif
7777

7878
#ifndef mp_hal_time_ns
79-
// Nanoseconds since 1970/1/1.
79+
// Nanoseconds since the Epoch.
8080
uint64_t mp_hal_time_ns(void);
8181
#endif
8282

0 commit comments

Comments
 (0)