arduino-esp32
arduino-esp32 copied to clipboard
Unnecessary timezone offset on file timestamp when working with SD.h
Board
ESP32 DevKit V1
Device Description
n/a
Hardware Configuration
ESP32 VSPI is connected to a microSD module: GPIO05 - SS GPIO23 - MOSI GPIO19 - MISO GPIO18 - SCLK
Version
v2.0.11
IDE Name
Platform IO
Operating System
Windows 11
Flash frequency
80 MHz
PSRAM enabled
no
Upload speed
115200
Description
When writing onto my SD card, the file timestamp seems to be affected by my timezone settings.
For testing, I have set the time to a constant value 1704067200 which corresponds to 2024-01-01 00:00:00 GMT.
Using
const char* tz_posix = "CST-8";
I get the following:
Timezone: CST-8
Now is : 2024-01-01 08:00:00
Writing file: /hello.txt
File written
Appending to file: /hello.txt
Message appended
Listing directory: /
FILE: hello.txt SIZE: 13 LAST WRITE: 2024-01-01 08:00:00
08:00:00 is correct since CST-8 is 8 hours ahead of GMT, but when I read the SD card from my laptop the timestamp is actually 08:00:00 GMT instead of CST-8.
This is consistent when I tested with other timezones as well. The only one which seems unaffected is when I use
const char* tz_posix = "GMT";
Is this a known issue, or am I going about this problem the wrong way?
Sketch
#include <Arduino.h>
#include "FS.h"
#include "SD.h"
#include "SPI.h"
#include <time.h>
void writeFile(fs::FS &fs, const char * path, const char * message);
void appendFile(fs::FS &fs, const char * path, const char * message);
void listDir(fs::FS &fs, const char * dirname, uint8_t levels);
// const char* tz_posix = "EST+10EDT+11,M10.1.0/02:00:00,M4.1.0/03:00:00";
// const char* tz_posix = "CST+8"; // test
// const char* tz_posix = "CST-8"; // test
// const char* tz_posix = "MSK-3"; // test
// const char* tz_posix = "BST-6"; // test
const char* tz_posix = "JST-9"; // test
// const char* tz_posix = "GMT";
void setup(){
Serial.begin(115200);
timeval tv{1704067200,0}; // test date Monday, January 1, 2024 12:00:00 AM GMT
timezone tz;
settimeofday(&tv,NULL);
setenv("TZ", tz_posix, 1);
tzset();
Serial.printf("Timezone: %s\r\n", tz_posix);
struct tm tmstruct ;
getLocalTime(&tmstruct, 5000);
Serial.printf("\nNow is : %d-%02d-%02d %02d:%02d:%02d\n",(tmstruct.tm_year)+1900,( tmstruct.tm_mon)+1, tmstruct.tm_mday,tmstruct.tm_hour , tmstruct.tm_min, tmstruct.tm_sec);
if(!SD.begin()){
Serial.println("Card Mount Failed");
return;
}
writeFile(SD, "/hello.txt", "Hello ");
appendFile(SD, "/hello.txt", "World!\n");
listDir(SD, "/", 0);
}
void loop(){}
// ==================================
// Utility functions
void writeFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE);
if(!file){
Serial.println("Failed to open file for writing");
return;
}
if(file.print(message)){
Serial.println("File written");
} else {
Serial.println("Write failed");
}
file.close();
}
void appendFile(fs::FS &fs, const char * path, const char * message){
Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if(!file){
Serial.println("Failed to open file for appending");
return;
}
if(file.print(message)){
Serial.println("Message appended");
} else {
Serial.println("Append failed");
}
file.close();
}
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
Serial.printf("Listing directory: %s\n", dirname);
File root = fs.open(dirname);
if(!root){
Serial.println("Failed to open directory");
return;
}
if(!root.isDirectory()){
Serial.println("Not a directory");
return;
}
File file = root.openNextFile();
while(file){
if(file.isDirectory()){
// ignore
}
else {
Serial.print(" FILE: ");
Serial.print(file.name());
Serial.print(" SIZE: ");
Serial.print(file.size());
time_t t= file.getLastWrite();
struct tm * utmstruct = gmtime(&t);
struct tm * tmstruct = localtime(&t);
Serial.printf(" LAST WRITE: %d-%02d-%02d %02d:%02d:%02d",(tmstruct->tm_year)+1900,( tmstruct->tm_mon)+1, tmstruct->tm_mday,tmstruct->tm_hour , tmstruct->tm_min, tmstruct->tm_sec);
}
file = root.openNextFile();
}
}
Debug Message
// another test log
Timezone: JST-9
Now is : 2024-01-01 09:00:00
Writing file: /hello.txt
File written
Appending to file: /hello.txt
Message appended
Listing directory: /
FILE: hello.txt SIZE: 13 LAST WRITE: 2024-01-01 09:00:00
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
- [X] I confirm I have checked existing issues, online documentation and Troubleshooting guide.
Just to clarify about the behavior: When you run this on the esp32, it all seems to work just fine, but if you take that SD card and put it in another machine, it seems like the times are wrong.
If you have WSL, can you open a terminal and run TZ="UTC" ls -l in the SD directory? Does it show the time as 0:00 or 8:00?
Thanks for responding. I have verified on both my Windows and Linux machines.
No issues when timezone is set to GMT:
-rwxrwxrwx 1 user test 13 Jan 1 00:00 hello_gmt.txt
-rwxrwxrwx 1 user test 13 Jan 1 09:00 hello_jst.txt
I wonder if anyone else has encountered the same behaviour...
Hi @lbernstone, is this something you can reproduce on your end?
I am on vacation, so I don't have a sd card handy
Thanks for replying. Have a good vacation!
Is there something I can test in the mean time?