Skip to content

Commit 569a050

Browse files
authored
Merge pull request #1143 from notro/stat_epoch_fix
Fix os.stat() epoch and use RTC for file timestamp
2 parents 9a10849 + b61cf8d commit 569a050

File tree

6 files changed

+37
-16
lines changed

6 files changed

+37
-16
lines changed

extmod/vfs_fat.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
320320
} else {
321321
mode |= MP_S_IFREG;
322322
}
323-
mp_int_t seconds = timeutils_seconds_since_2000(
323+
mp_uint_t seconds = timeutils_seconds_since_epoch(
324324
1980 + ((fno.fdate >> 9) & 0x7f),
325325
(fno.fdate >> 5) & 0x0f,
326326
fno.fdate & 0x1f,
@@ -335,9 +335,9 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
335335
t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid
336336
t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid
337337
t->items[6] = mp_obj_new_int_from_uint(fno.fsize); // st_size
338-
t->items[7] = MP_OBJ_NEW_SMALL_INT(seconds); // st_atime
339-
t->items[8] = MP_OBJ_NEW_SMALL_INT(seconds); // st_mtime
340-
t->items[9] = MP_OBJ_NEW_SMALL_INT(seconds); // st_ctime
338+
t->items[7] = mp_obj_new_int_from_uint(seconds); // st_atime
339+
t->items[8] = mp_obj_new_int_from_uint(seconds); // st_mtime
340+
t->items[9] = mp_obj_new_int_from_uint(seconds); // st_ctime
341341

342342
return MP_OBJ_FROM_PTR(t);
343343
}

lib/timeutils/timeutils.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,17 @@ mp_uint_t timeutils_seconds_since_2000(mp_uint_t year, mp_uint_t month,
158158
+ (year - 2000) * 31536000;
159159
}
160160

161+
void timeutils_seconds_since_epoch_to_struct_time(mp_uint_t t, timeutils_struct_time_t *tm) {
162+
t -= EPOCH1970_EPOCH2000_DIFF_SECS;
163+
timeutils_seconds_since_2000_to_struct_time(t, tm);
164+
}
165+
166+
mp_uint_t timeutils_seconds_since_epoch(mp_uint_t year, mp_uint_t month, mp_uint_t date,
167+
mp_uint_t hour, mp_uint_t minute, mp_uint_t second) {
168+
mp_uint_t t = timeutils_seconds_since_2000(year, month, date, hour, minute, second);
169+
return t + EPOCH1970_EPOCH2000_DIFF_SECS;
170+
}
171+
161172
mp_uint_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t mday,
162173
mp_int_t hours, mp_int_t minutes, mp_int_t seconds) {
163174

@@ -211,5 +222,5 @@ mp_uint_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t mday,
211222
year++;
212223
}
213224
}
214-
return timeutils_seconds_since_2000(year, month, mday, hours, minutes, seconds);
225+
return timeutils_seconds_since_epoch(year, month, mday, hours, minutes, seconds);
215226
}

lib/timeutils/timeutils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#ifndef MICROPY_INCLUDED_LIB_TIMEUTILS_TIMEUTILS_H
2828
#define MICROPY_INCLUDED_LIB_TIMEUTILS_TIMEUTILS_H
2929

30+
#define EPOCH1970_EPOCH2000_DIFF_SECS 946684800
31+
3032
typedef struct _timeutils_struct_time_t {
3133
uint16_t tm_year; // i.e. 2014
3234
uint8_t tm_mon; // 1..12
@@ -48,6 +50,11 @@ void timeutils_seconds_since_2000_to_struct_time(mp_uint_t t,
4850
mp_uint_t timeutils_seconds_since_2000(mp_uint_t year, mp_uint_t month,
4951
mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second);
5052

53+
void timeutils_seconds_since_epoch_to_struct_time(mp_uint_t t, timeutils_struct_time_t *tm);
54+
55+
mp_uint_t timeutils_seconds_since_epoch(mp_uint_t year, mp_uint_t month, mp_uint_t date,
56+
mp_uint_t hour, mp_uint_t minute, mp_uint_t second);
57+
5158
mp_uint_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t mday,
5259
mp_int_t hours, mp_int_t minutes, mp_int_t seconds);
5360

ports/atmel-samd/fatfs_port.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,13 @@
2828
#include "py/runtime.h"
2929
#include "lib/oofatfs/ff.h" /* FatFs lower layer API */
3030
#include "lib/oofatfs/diskio.h" /* FatFs lower layer API */
31+
#include "lib/timeutils/timeutils.h"
32+
#include "shared-bindings/rtc/RTC.h"
3133

3234
DWORD get_fattime(void) {
33-
// TODO(tannewt): Support the RTC.
34-
return ((2016 - 1980) << 25) | ((9) << 21) | ((1) << 16) | ((16) << 11) | ((43) << 5) | (35 / 2);
35+
timeutils_struct_time_t tm;
36+
common_hal_rtc_get_time(&tm);
37+
38+
return ((tm.tm_year - 1980) << 25) | (tm.tm_mon << 21) | (tm.tm_mday << 16) |
39+
(tm.tm_hour << 11) | (tm.tm_min << 5) | (tm.tm_sec >> 1);
3540
}

shared-bindings/time/__init__.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636
#include "shared-bindings/time/__init__.h"
3737
#include "supervisor/shared/translate.h"
3838

39-
#define EPOCH1970_EPOCH2000_DIFF_SECS 946684800
40-
4139
//| :mod:`time` --- time and timing related functions
4240
//| ========================================================
4341
//|
@@ -142,9 +140,9 @@ const mp_obj_namedtuple_type_t struct_time_type_obj = {
142140

143141
mp_obj_t struct_time_from_tm(timeutils_struct_time_t *tm) {
144142
timeutils_struct_time_t tmp;
145-
mp_uint_t secs = timeutils_seconds_since_2000(tm->tm_year, tm->tm_mon, tm->tm_mday,
143+
mp_uint_t secs = timeutils_seconds_since_epoch(tm->tm_year, tm->tm_mon, tm->tm_mday,
146144
tm->tm_hour, tm->tm_min, tm->tm_sec);
147-
timeutils_seconds_since_2000_to_struct_time(secs, &tmp);
145+
timeutils_seconds_since_epoch_to_struct_time(secs, &tmp);
148146
tm->tm_wday = tmp.tm_wday;
149147
tm->tm_yday = tmp.tm_yday;
150148

@@ -202,9 +200,9 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) {
202200
STATIC mp_obj_t time_time(void) {
203201
timeutils_struct_time_t tm;
204202
struct_time_to_tm(rtc_get_time_source_time(), &tm);
205-
mp_uint_t secs = timeutils_seconds_since_2000(tm.tm_year, tm.tm_mon, tm.tm_mday,
203+
mp_uint_t secs = timeutils_seconds_since_epoch(tm.tm_year, tm.tm_mon, tm.tm_mday,
206204
tm.tm_hour, tm.tm_min, tm.tm_sec);
207-
return mp_obj_new_int_from_uint(secs + EPOCH1970_EPOCH2000_DIFF_SECS);
205+
return mp_obj_new_int_from_uint(secs);
208206
}
209207
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
210208

@@ -228,7 +226,7 @@ STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) {
228226
mp_raise_msg(&mp_type_OverflowError, translate("timestamp out of range for platform time_t"));
229227

230228
timeutils_struct_time_t tm;
231-
timeutils_seconds_since_2000_to_struct_time(secs - EPOCH1970_EPOCH2000_DIFF_SECS, &tm);
229+
timeutils_seconds_since_epoch_to_struct_time(secs, &tm);
232230

233231
return struct_time_from_tm(&tm);
234232
}
@@ -262,7 +260,7 @@ STATIC mp_obj_t time_mktime(mp_obj_t t) {
262260

263261
mp_uint_t secs = timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]),
264262
mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5]));
265-
return mp_obj_new_int_from_uint(secs + EPOCH1970_EPOCH2000_DIFF_SECS);
263+
return mp_obj_new_int_from_uint(secs);
266264
}
267265
MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime);
268266
#endif // MICROPY_LONGINT_IMPL

tests/extmod/vfs_fat_ramdisk.py.exp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ statvfs: (512, 512, 16, 16, 16, 0, 0, 0, 0, 255)
55
getcwd: /
66
True
77
[('foo_file.txt', 32768, 0, 6)]
8-
stat root: (16384, 0, 0, 0, 0, 0, 0, 0, 0, 0)
8+
stat root: (16384, 0, 0, 0, 0, 0, 0, 946684800, 946684800, 946684800)
99
stat file: (32768, 0, 0, 0, 0, 0, 6)
1010
True
1111
True

0 commit comments

Comments
 (0)