4

I have a date (no time, assuming time 00:00:00) that I convert between a time_t and a struct tm.

I get a date in the simple YYYYMMDD format and convert that to a struct tm:

struct tm my_tm;
memset(&my_tm, 0, sizeof(my_tm));
my_tm.tm_year = str.mid(0, 4).toInt() - 1900;
my_tm.tm_mon = str.mid(4, 2).toInt() - 1;
my_tm.tm_mday = str.mid(6, 2).toInt();
  • P.S.: for those wondering I have a QString (Qt) hence the mid() and toInt() members used.

Then I convert that date to a time_t using mktime():

time_t my_time(mktime(&my_tm));

At that point the date changes to the day before (more precisely, -1h) if the date is March 6, 2016 ("20160306" becomes 2016/03/05 in the struct tm). This is because of DST (the tm_isdst is set accordingly).

I have another version of mktime() called mkgmtime() and that works as expected: I get the same date since DST is ignored by that function:

time_t my_time(mkgmtime(&my_tm));

I can then convert the date back to a struct tm using the gmtime_r() function. This way, again, I get the same date:

struct tm other_tm;
gmtime_r(&my_time, &other_tm);

However, at some point I want to display the date in a standard format as defined by the end user's locale. For that I use the ICU library. In the following, I force f_current_timezone variable to UTC before calling format_date(), then the date comes out as Mar 6, 2016 (if I keep the user timezone, I may instead get Mar 5, 2016.)

QString locale::format_date(time_t d)
{
    QUnicodeString const timezone_id(f_current_timezone);
    LocalPointer<TimeZone> tz(TimeZone::createTimeZone(timezone_id));
    Locale const l(f_current_locale.toUtf8().data());
    LocalPointer<DateFormat> dt(DateFormat::createDateInstance(DateFormat::kDefault, l));
    dt->setTimeZone(*tz);
    UDate const udate(d * 1000LL);
    QUnicodeString u;
    dt->format(udate, u);
    return u;
}

Is it safe (Does it make sense to you) to use "UTC" as the timezone to get the correct result from format_date()?

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156

1 Answers1

0

Before using mktime(), set tm_hour to 12 (12pm). If all you care about is formatting the date portion using the application's locate, using noon for mktime() will be sufficient, for that purpose.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148