Do TZ conversion in GPA conversion, keep timestamps in UTC. This makes ZIP conversion inconsistent across TZs, but less hacky everywhere else. Pending addition of a tool to just dump a combined timestamp.

This commit is contained in:
elasota
2020-01-23 03:45:36 -05:00
parent 38d172aa49
commit b20e1876e3
2 changed files with 29 additions and 27 deletions

View File

@@ -7,7 +7,7 @@ int main(int argc, const char **argv)
if (argc != 2) if (argc != 2)
{ {
fprintf(stderr, "Usage: MakeTimestamp <output.ts>\n"); fprintf(stderr, "Usage: MakeTimestamp <output.ts>\n");
fprintf(stderr, "Outputs the current timestamp in 1904 epoch format"); fprintf(stderr, "Outputs the current timestamp in 1904 UTC epoch format");
return -1; return -1;
} }
@@ -25,14 +25,11 @@ int main(int argc, const char **argv)
if (!SystemTimeToFileTime(&epochStart, &epochStartFT)) if (!SystemTimeToFileTime(&epochStart, &epochStartFT))
return 0; return 0;
SYSTEMTIME localTime; FILETIME timestampFT;
GetLocalTime(&localTime); GetSystemTimeAsFileTime(&timestampFT);
FILETIME localTimeFT;
SystemTimeToFileTime(&localTime, &localTimeFT);
int64_t epochStart64 = (static_cast<int64_t>(epochStartFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(epochStartFT.dwHighDateTime) << 32); int64_t epochStart64 = (static_cast<int64_t>(epochStartFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(epochStartFT.dwHighDateTime) << 32);
int64_t currentTime64 = (static_cast<int64_t>(localTimeFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(localTimeFT.dwHighDateTime) << 32); int64_t currentTime64 = (static_cast<int64_t>(timestampFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(timestampFT.dwHighDateTime) << 32);
int64_t timeDelta = (currentTime64 - epochStart64) / 10000000; int64_t timeDelta = (currentTime64 - epochStart64) / 10000000;
FILE *f = nullptr; FILE *f = nullptr;

View File

@@ -112,38 +112,43 @@ void ConvertToMSDOSTimestamp(int64_t timestamp, uint16_t &msdosDate, uint16_t &m
int64_t epochStart64 = (static_cast<int64_t>(epochStartFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(epochStartFT.dwHighDateTime) << 32); int64_t epochStart64 = (static_cast<int64_t>(epochStartFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(epochStartFT.dwHighDateTime) << 32);
int64_t offsetDate64 = (epochStart64 + timestamp * 10000000); int64_t offsetDate64 = (epochStart64 + timestamp * 10000000);
FILETIME timestampFT; FILETIME utcTimestampFT;
timestampFT.dwLowDateTime = static_cast<DWORD>(offsetDate64 & 0xffffffff); utcTimestampFT.dwLowDateTime = static_cast<DWORD>(offsetDate64 & 0xffffffff);
timestampFT.dwHighDateTime = static_cast<DWORD>((offsetDate64 >> 32) & 0xffffffff); utcTimestampFT.dwHighDateTime = static_cast<DWORD>((offsetDate64 >> 32) & 0xffffffff);
// We could use FileTimeToDosDateTime but we want to clamp TIME_ZONE_INFORMATION tzInfo;
SYSTEMTIME timestampST; GetTimeZoneInformation(&tzInfo);
FileTimeToSystemTime(&timestampFT, &timestampST);
DWORD yearsSince1980 = timestampST.wYear - 1980; SYSTEMTIME utcTimestampST;
FileTimeToSystemTime(&utcTimestampFT, &utcTimestampST);
SYSTEMTIME localTimestampST;
SystemTimeToTzSpecificLocalTime(&tzInfo, &utcTimestampST, &localTimestampST);
DWORD yearsSince1980 = localTimestampST.wYear - 1980;
if (yearsSince1980 < 0) if (yearsSince1980 < 0)
{ {
// Time machine // Time machine
yearsSince1980 = 0; yearsSince1980 = 0;
timestampST.wSecond = 0; localTimestampST.wSecond = 0;
timestampST.wMinute = 0; localTimestampST.wMinute = 0;
timestampST.wHour = 0; localTimestampST.wHour = 0;
timestampST.wDay = 1; localTimestampST.wDay = 1;
timestampST.wMonth = 1; localTimestampST.wMonth = 1;
} }
else if (yearsSince1980 > 127) else if (yearsSince1980 > 127)
{ {
// I was promised flying cars, but it's 2107 and you're still flying paper airplanes... // I was promised flying cars, but it's 2107 and you're still flying paper airplanes...
yearsSince1980 = 127; yearsSince1980 = 127;
timestampST.wSecond = 59; localTimestampST.wSecond = 59;
timestampST.wMinute = 59; localTimestampST.wMinute = 59;
timestampST.wHour = 23; localTimestampST.wHour = 23;
timestampST.wDay = 31; localTimestampST.wDay = 31;
timestampST.wMonth = 12; localTimestampST.wMonth = 12;
} }
msdosTime = (timestampST.wSecond / 2) | (timestampST.wMinute << 5) | (timestampST.wHour << 11); msdosTime = (localTimestampST.wSecond / 2) | (localTimestampST.wMinute << 5) | (localTimestampST.wHour << 11);
msdosDate = timestampST.wDay | (timestampST.wMonth << 5) | (yearsSince1980 << 9); msdosDate = localTimestampST.wDay | (localTimestampST.wMonth << 5) | (yearsSince1980 << 9);
} }
void ExportZipFile(const char *path, const std::vector<PlannedEntry> &entries, const PortabilityLayer::MacFileProperties &mfp) void ExportZipFile(const char *path, const std::vector<PlannedEntry> &entries, const PortabilityLayer::MacFileProperties &mfp)