Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mtime incorrect in fatfs during daylight saving time (IDFGH-7467) #9039

Closed
lbernstone opened this issue May 27, 2022 · 2 comments
Closed

mtime incorrect in fatfs during daylight saving time (IDFGH-7467) #9039

lbernstone opened this issue May 27, 2022 · 2 comments
Assignees
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally

Comments

@lbernstone
Copy link

lbernstone commented May 27, 2022

Environment

  • Development Kit: Custom, but N/A
  • Module or chip used: ESP32-C3, likely all
  • IDF version (run git describe --tags to find it): v4.4.1
  • Build System: Arduino
  • Compiler version (run xtensa-esp32-elf-gcc --version to find it): riscv32-esp-elf-gcc8_4_0-esp-2021r2-patch3-linux-amd64
  • Operating System: Linux
  • Using an IDE?: Yes , arduino just for convenience. No Arduino code included in example
  • Power Supply: USB

Problem Description

When a timezone is set with DST, and time is set inside DST, file modified time (mtime) is 3599 seconds off. Weird number, maybe something is supposed to be one hour diff, but isn't multiplied?

Expected Behavior

System time and file written time should be identical

Actual Behavior

22:29:11.888 -> systime: 1653638041
22:29:12.154 -> filetime: 1653641640

Steps to reproduce

#include <vfs_fat_internal.h>
static wl_handle_t hndWl = WL_INVALID_HANDLE;

void setup() {
  Serial.begin(115200);
  delay(2000);
  struct timeval tv = {1653638041, 0};
  settimeofday(&tv, NULL);
  setenv("TZ", "MST7MDT,M3.2.0,M11.1.0", 1);
  tzset();
  Serial.printf("systime: %d\n", time(NULL));
  const esp_vfs_fat_mount_config_t conf = {
      .format_if_mount_failed = true,
      .max_files = 4,
      .allocation_unit_size = CONFIG_WL_SECTOR_SIZE
  };
  esp_vfs_fat_spiflash_mount("/fatfs", "ffat", &conf, &hndWl);
  FILE *tfile = fopen("/fatfs/test", "w");
  fprintf(tfile, "hello");
  fclose(tfile);
  struct stat info;
  stat("/fatfs/test", &info);
  Serial.printf("filetime: %d\n", info.st_mtime);
}
void loop() {delay(-1);}
@espressif-bot espressif-bot added the Status: Opened Issue is new label May 27, 2022
@github-actions github-actions bot changed the title mtime incorrect in fatfs during daylight saving time mtime incorrect in fatfs during daylight saving time (IDFGH-7467) May 27, 2022
@igrr
Copy link
Member

igrr commented May 27, 2022

Thanks for reporting this @lbernstone. I vaguely remember there being some discussion on this before, and some reason why the filesystem works the way it does, but I can't find it right now. We'll investigate this.

The difference is probably indeed one hour (3600 seconds), but FATFS keeps time at 2-second precision, so instead of mtime=1653641641 (exactly 3600 seconds difference) you got 1653641640.

@lbernstone
Copy link
Author

Only thing I see in the history is this #1369

@espressif-bot espressif-bot added Status: In Progress Work is in progress and removed Status: Opened Issue is new labels May 31, 2022
@espressif-bot espressif-bot added Resolution: NA Issue resolution is unavailable Status: Done Issue is done internally Resolution: Done Issue is done internally and removed Status: In Progress Work is in progress Resolution: NA Issue resolution is unavailable labels Jun 10, 2022
espressif-bot pushed a commit that referenced this issue Jun 22, 2022
mktime function uses tm_isdst member as an indicator whether the time
stamp is expected to be in daylight saving time (1) or not (0).
FAT filesystem uses local time as mtime, so no information about DST
is available from the filesystem.

According to mktime documentation, tm_isdst can be set to -1, in which
case the C library will try to determine if DST was or wasn't in
effect at that time, and will set UTC time accordingly.

Note that the conversion from UTC to local time and then back to UTC
(time_t -> localtime_r -> FAT timestamp -> mktime -> time_t) does not
always recover the same UTC time. In particular, the local time in the
hour before DST comes into effect can be interpreted as "before DST"
or "after DST", which would correspond to different UTC values. In
this case which option the C library chooses is undefined.

Closes #9039
Originally reported in espressif/arduino-esp32#6786
espressif-bot pushed a commit that referenced this issue Feb 11, 2023
mktime function uses tm_isdst member as an indicator whether the time
stamp is expected to be in daylight saving time (1) or not (0).
FAT filesystem uses local time as mtime, so no information about DST
is available from the filesystem.

According to mktime documentation, tm_isdst can be set to -1, in which
case the C library will try to determine if DST was or wasn't in
effect at that time, and will set UTC time accordingly.

Note that the conversion from UTC to local time and then back to UTC
(time_t -> localtime_r -> FAT timestamp -> mktime -> time_t) does not
always recover the same UTC time. In particular, the local time in the
hour before DST comes into effect can be interpreted as "before DST"
or "after DST", which would correspond to different UTC values. In
this case which option the C library chooses is undefined.

Closes #9039
Originally reported in espressif/arduino-esp32#6786
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally
Projects
None yet
Development

No branches or pull requests

3 participants