1 year ago
#374946
PKallback
Conversion of Local Time to GMT/UTC, and back GMT/UTC to Local Time in C++
The problem of conversion from GMT/UTC to local time in C++ is tricky because of daylight saving. To solve the daylight saving problem there must be a table for every country and zone, since daylight saving is not universal. This problem/solution is maybe not universal since I'm still using MFC when coding C++ in Windows.
What I have tried so far is the following... Going from local time to GMT/UTC is quite easy with this example:
void GetGMTTime(int year, int month, int day, int hour, int min, int sec, tm& gmt) {
CTime date_time(year, month, day, hour, min, sec);
tm local;
// This is only for comparison and should be equal to the input variables
date_time.GetLocalTm(&local);
// Conversion to GMT/UTC
date_time.GetGmtTm(&gmt);
}
To go the other way arround is more tricky and CTime has no implementation for it. One method is to have a new CTime variable with the GMT/UTC time as the initial value. When running the function CTime::GetGmtTm() will now generate a time that is less than or greater than the GMT/UTC time (well, if you live in UK you don't have this problem). The CTime can than be incremented or decremented by 1 hour until CTime::GetGmtTm() will return the same value as the original GMT/UTC time. To get the local time, run CTime::GetLocalTm() again.
The algorithm above is exemplified with the code below:
void CDateTimeDlg::ConvertTimeFromGMTtoLocal(const tm gmt, tm& local) {
// Initialization
CTime test(gmt.tm_year + 1900, gmt.tm_mon + 1, gmt.tm_mday, gmt.tm_hour, gmt.tm_min, gmt.tm_sec);
tm gmtcmp; // As in GMT compare
test.GetGmtTm(&gmtcmp);
while (ConvertTmToUINT(gmt) != ConvertTmToUINT(gmtcmp)) {
if (ConvertTmToUINT(gmtcmp) < ConvertTmToUINT(gmt)) {
test += CTimeSpan(0, 1, 0, 0);
}
else if (ConvertTmToUINT(gmtcmp) > ConvertTmToUINT(gmt)) {
test -= CTimeSpan(0, 1, 0, 0);
}
test.GetGmtTm(&gmtcmp);
}
test.GetLocalTm(&local);
}
// UINT as 32 bit
UINT CDateTimeDlg::ConvertTmToUINT(const tm t) {
UINT year = t.tm_year + 1900;
UINT month = t.tm_mon + 1;
UINT day = t.tm_mday;
UINT hour = t.tm_hour;
UINT min = t.tm_min;
UINT sec = t.tm_sec;
UINT days = t.tm_yday;
UINT uintdate{ 0 };
uintdate = (year - 1980) << 26;
uintdate |= days << 17;
uintdate |= hour << 12;
uintdate |= min << 6;
uintdate |= sec;
return uintdate;
}
My question is if this can be done more easily without using an iteration?
c++
mfc
ctime
0 Answers
Your Answer