c++ - 使用 UTC 来回转换日期以忽略 DST 但仍对当前用户使用有效的语言环境是否安全?

标签 c++ date utc date-conversion

我有一个日期(没有时间,假设时间为 00:00:00),我在 time_tstruct tm 之间转换。

我得到一个简单的 YYYYMMDD 格式的日期,并将其转换为 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.:对于那些想知道我有一个 QString (Qt) 因此使用了 mid()toInt() 成员的人.

然后我使用 mktime() 将该日期转换为 time_t:

time_t my_time(mktime(&my_tm));

此时,如果日期是 2016 年 3 月 6 日(“20160306”在 struct tm 中变为 2016/03/05),则日期更改为前一天(更准确地说,-1h) .这是因为 DST(相应地设置了 tm_isdst)。

我有另一个版本的 mktime() 叫做 mkgmtime()并且按预期工作:我得到相同的日期,因为 DST 被该函数忽略:

time_t my_time(mkgmtime(&my_tm));

然后我可以使用 gmtime_r() 函数将日期转换回 struct tm。这样,我又得到了相同的日期:

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

但是,有时我想以最终用户区域设置定义的标准格式显示日期。为此,我使用了 ICU 库。在下文中,我在调用 format_date() 之前强制将 f_current_timezone 变量设置为 UTC,然后日期显示为 2016 年 3 月 6 日(如果我保留用户时区,我可能会得到 2016 年 3 月 5 日。)

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;
}

使用“UTC”作为时区从 format_date() 获得正确结果是否安全(对您来说有意义吗)?

最佳答案

在使用 mktime() 之前,将 tm_hour 设置为 12(中午 12 点)。如果您所关心的只是使用应用程序的定位来格式化日期部分,那么对于 mktime() 使用 noon 就足够了。

关于c++ - 使用 UTC 来回转换日期以忽略 DST 但仍对当前用户使用有效的语言环境是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36380575/

相关文章:

c++ - 按类型获取元组元素(C++0x 之前)

java - SQLite:从日期获取周数

java.sql.timestamp 与日期

javascript - 使用 Javascript 和 PHP 加载第一页/单页时客户端的 UTC 偏移量

c# - 获取并格式化与 NodaTime ZonedDateTime 值对应的 UTC 时间?

html - C++ 更改输出文件名(如果存在)

c++ - 在同一项目中包含 <termios.h> 和 <asm/termios.h>

javascript - Date.UTC() 返回上个月的最后一天,而 getUTCFullYear()、getUTCMonth() 正确返回正确月份的第一天

c++ - 在 vector 上找到第一对元素 (int) 并获得第二对 (struct)

php - 将 ISO 8601 转换为 unix 时间戳