Time zones [modified]
-
I've a weird problem making me crazy !!! I've to read a sequence of dates from a text file and convert these dates into time_t. I DON't want to take into account timezones and daylight savings, so the input date must be converted into the exact output date. So, i've avoided mktime() to convert from tm (filled up with string dates from source) to time_t. The next solution i've used was to convert a SYSTEMTIME to a time_t with these functions (based on similar functions, UnixTimeToSystemTime(), described in MSDN): void FileTimeToUnixTime(LPFILETIME pft, time_t *t) { LONGLONG ll; ll = pft->dwHighDateTime; ll <<= 32; ll |= pft->dwLowDateTime; ll = ll - 116444736000000000; *t = ll / 10000000; } void SystemTimeToUnixTime(LPSYSTEMTIME pst, time_t *t) { FILETIME ft; SystemTimeToFileTime(pst, &ft); FileTimeToUnixTime(&ft, t); } because I was sure that SystemTimeToFileTime() only converts to SYSTEMTIME format to FILETIME format without any other considerations like timezone or daylight saving. In my PC these work well. When I've run the code in another PC, the resulting date is 1 hour back. (it's very strange too, because that PC has the same date settings of mine). I can't achive the result to obatin a time_t that reflect the same source date, without variations caused by currently timezone and daylight saving settings. -- modified at 9:12 Thursday 3rd August, 2006
-
I've a weird problem making me crazy !!! I've to read a sequence of dates from a text file and convert these dates into time_t. I DON't want to take into account timezones and daylight savings, so the input date must be converted into the exact output date. So, i've avoided mktime() to convert from tm (filled up with string dates from source) to time_t. The next solution i've used was to convert a SYSTEMTIME to a time_t with these functions (based on similar functions, UnixTimeToSystemTime(), described in MSDN): void FileTimeToUnixTime(LPFILETIME pft, time_t *t) { LONGLONG ll; ll = pft->dwHighDateTime; ll <<= 32; ll |= pft->dwLowDateTime; ll = ll - 116444736000000000; *t = ll / 10000000; } void SystemTimeToUnixTime(LPSYSTEMTIME pst, time_t *t) { FILETIME ft; SystemTimeToFileTime(pst, &ft); FileTimeToUnixTime(&ft, t); } because I was sure that SystemTimeToFileTime() only converts to SYSTEMTIME format to FILETIME format without any other considerations like timezone or daylight saving. In my PC these work well. When I've run the code in another PC, the resulting date is 1 hour back. (it's very strange too, because that PC has the same date settings of mine). I can't achive the result to obatin a time_t that reflect the same source date, without variations caused by currently timezone and daylight saving settings. -- modified at 9:12 Thursday 3rd August, 2006
Nyarlatotep wrote:
I've to read a sequence of dates from a text file...
What do these dates look like?
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb
-
Nyarlatotep wrote:
I've to read a sequence of dates from a text file...
What do these dates look like?
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb
Input file is a CSV file. Dates are in dd/mm/yyyy format and I've to convert those dates into time_t without time zone o daylight saving affection ...
-
Input file is a CSV file. Dates are in dd/mm/yyyy format and I've to convert those dates into time_t without time zone o daylight saving affection ...
If you are reading the dates in as dd/mm/yyyy, then you can separate the three components like:
char dateToday[] = "04/08/2006";
char *pDay = strtok(dateToday, "/"),
*pMonth = strtok(NULL, "/"),
*pYear = strtok(NULL, "/");Now you can convert those to numeric values using
atoi()
.
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb
-
If you are reading the dates in as dd/mm/yyyy, then you can separate the three components like:
char dateToday[] = "04/08/2006";
char *pDay = strtok(dateToday, "/"),
*pMonth = strtok(NULL, "/"),
*pYear = strtok(NULL, "/");Now you can convert those to numeric values using
atoi()
.
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb
My problem is not to parse the input string date. I parse the input date and input time and put each value into a tm struct (day, month, year, hour, minutes, seconds) and I'have used mktime() function to convert from the tm struct to time_t value. BUT mktime() takes into account time zone and daylight saving so, for example, if input date into the tm struct is 01/06/2006 15:00:00 (first June), the time_t date obtained from mktime() is 01/06/2006 17:00:00 (I am in GMT +1 and day light saving is in effect adding an extra hour). Instead I want to convert the parsed date into time_t without take into account time zones and day light saving, obtaining the the same date as the input, in every time zone the program runs. To avoid this 'problem' I've tried to use a function (see inital post) that use SystemTimeToFileTime internally, because I thought that SystemTimeToFileTime only converts from SYSTEMTIME struct to FILETIME struct without taking into account time zones and day light saving. But I was wrong, I suppose. -- modified at 10:23 Friday 4th August, 2006
-
My problem is not to parse the input string date. I parse the input date and input time and put each value into a tm struct (day, month, year, hour, minutes, seconds) and I'have used mktime() function to convert from the tm struct to time_t value. BUT mktime() takes into account time zone and daylight saving so, for example, if input date into the tm struct is 01/06/2006 15:00:00 (first June), the time_t date obtained from mktime() is 01/06/2006 17:00:00 (I am in GMT +1 and day light saving is in effect adding an extra hour). Instead I want to convert the parsed date into time_t without take into account time zones and day light saving, obtaining the the same date as the input, in every time zone the program runs. To avoid this 'problem' I've tried to use a function (see inital post) that use SystemTimeToFileTime internally, because I thought that SystemTimeToFileTime only converts from SYSTEMTIME struct to FILETIME struct without taking into account time zones and day light saving. But I was wrong, I suppose. -- modified at 10:23 Friday 4th August, 2006
Nyarlatotep wrote:
My problem is not to parse the input string date.
My bad. I just assumed you had the math worked out, but was having difficulty with the parsing.
Nyarlatotep wrote:
...mktime() takes into account time zone and daylight saving so...
So what is the value of
tm_isdst
prior to callingmktime()
?Nyarlatotep wrote:
...the time_t date obtained from mktime() is 01/06/2006 17:00:00
What are you using to convert the
time_t
value to a string?
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb
-
Nyarlatotep wrote:
My problem is not to parse the input string date.
My bad. I just assumed you had the math worked out, but was having difficulty with the parsing.
Nyarlatotep wrote:
...mktime() takes into account time zone and daylight saving so...
So what is the value of
tm_isdst
prior to callingmktime()
?Nyarlatotep wrote:
...the time_t date obtained from mktime() is 01/06/2006 17:00:00
What are you using to convert the
time_t
value to a string?
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb
I've set tm_isdst to 0. However to convert the string into time_t I've used these functions (insted of mktime): void FileTimeToUnixTime(LPFILETIME pft, time_t *t) { // Note that LONGLONG is a 64-bit value LONGLONG ll; ll = pft->dwHighDateTime; ll <<= 32; ll |= pft->dwLowDateTime; ll = ll - 116444736000000000; *t = ll / 10000000; } void SystemTimeToUnixTime(LPSYSTEMTIME pst, time_t *t) { FILETIME ft; SystemTimeToFileTime(pst, &ft); FileTimeToUnixTime(&ft, t); } the datetime string is parsed and a SYSTEMTIME struct is filled. Then SystemTimeToUnixTime() is used to convert from SYSTEMTIME to time_t. --------------------------------------------------- To revert time_t to a string I've used these functions : void UnixTimeToFileTime(time_t t, LPFILETIME pft) { // Note that LONGLONG is a 64-bit value LONGLONG ll; ll = Int32x32To64(t, 10000000) + 116444736000000000; pft->dwLowDateTime = (DWORD)ll; pft->dwHighDateTime = ll >> 32; } void UnixTimeToSystemTime(time_t t, LPSYSTEMTIME pst) { FILETIME ft; UnixTimeToFileTime(t, &ft); FileTimeToSystemTime(&ft, pst); } time_t is converted to a SYSTEMTIME by UnixTimeToSystemTime(). Then I've build a datetime string using SYSTEMTIME members. These functions use internally FileTimeToSystemTime() and SystemTimeToFileTime() and no other OS functions. I've thought that these two functions only convert SYSTEMTIME to FILETIME and vice versa without taking into account time zone and day light saving ...
-
I've set tm_isdst to 0. However to convert the string into time_t I've used these functions (insted of mktime): void FileTimeToUnixTime(LPFILETIME pft, time_t *t) { // Note that LONGLONG is a 64-bit value LONGLONG ll; ll = pft->dwHighDateTime; ll <<= 32; ll |= pft->dwLowDateTime; ll = ll - 116444736000000000; *t = ll / 10000000; } void SystemTimeToUnixTime(LPSYSTEMTIME pst, time_t *t) { FILETIME ft; SystemTimeToFileTime(pst, &ft); FileTimeToUnixTime(&ft, t); } the datetime string is parsed and a SYSTEMTIME struct is filled. Then SystemTimeToUnixTime() is used to convert from SYSTEMTIME to time_t. --------------------------------------------------- To revert time_t to a string I've used these functions : void UnixTimeToFileTime(time_t t, LPFILETIME pft) { // Note that LONGLONG is a 64-bit value LONGLONG ll; ll = Int32x32To64(t, 10000000) + 116444736000000000; pft->dwLowDateTime = (DWORD)ll; pft->dwHighDateTime = ll >> 32; } void UnixTimeToSystemTime(time_t t, LPSYSTEMTIME pst) { FILETIME ft; UnixTimeToFileTime(t, &ft); FileTimeToSystemTime(&ft, pst); } time_t is converted to a SYSTEMTIME by UnixTimeToSystemTime(). Then I've build a datetime string using SYSTEMTIME members. These functions use internally FileTimeToSystemTime() and SystemTimeToFileTime() and no other OS functions. I've thought that these two functions only convert SYSTEMTIME to FILETIME and vice versa without taking into account time zone and day light saving ...
I'm not sure what effect all of those other functions have on the date value, but I tried the following and got the correct output both times regardless of the value of
tm_isdst
:struct tm now;
now.tm_sec = 0; /* seconds after the minute - [0,59] */
now.tm_min = 0; /* minutes after the hour - [0,59] */
now.tm_hour = 15; /* hours since midnight - [0,23] */
now.tm_mday = 1; /* day of the month - [1,31] */
now.tm_mon = 5; /* months since January - [0,11] */
now.tm_year = 106; /* years since 1900 */
now.tm_wday = 5; /* days since Sunday - [0,6] */
now.tm_isdst = 1;printf("%s", asctime(&now));
time_t t2 = mktime(&now);
printf("%s", ctime(&t2));I guess I'm just not understanding your problem well enough.
"Money talks. When my money starts to talk, I get a bill to shut it up." - Frank
"Judge not by the eye but by the heart." - Native American Proverb