【问题标题】:GetDateFormat() fails on dates before 1/1/1601GetDateFormat() 在 1601 年 1 月 1 日之前的日期失败
【发布时间】:2012-09-11 19:01:01
【问题描述】:

我正在尝试使用 Windows GetDateFormat API 函数格式化日期:

nResult = GetDateFormat(
      localeId,   //0x409 for en-US, or LOCALE_USER_DEFAULT if you're not testing
      0,          //flags
      dt,         //a SYSTEMTIME structure
      "M/d/yyyy", //the format we require
      null,       //the output buffer to contain string (null for now while we get the length)
      0);         //the length of the output buffer (zero while we get the length)

现在我们传递一个日期/时间:

SYSTEMTIME dt;
dt.wYear = 1600;
dt.wMonth = 12;
dt.wDay = 31;

在这种情况下,nResult 返回零:

如果不成功,该函数返回 0。要获取扩展的错误信息,应用程序可以调用 GetLastError,它可以返回以下错误代码之一:

  • ERROR_INSUFFICIENT_BUFFER。提供的缓冲区大小不够大,或者被错误地设置为 NULL。
  • ERROR_INVALID_FLAGS。为标志提供的值无效。
  • ERROR_INVALID_PARAMETER。任何参数值无效。

但是,如果我在一天后返回日期:

SYSTEMTIME dt;
dt.wYear = 1601;
dt.wMonth = 1;
dt.wDay = 1;

然后就可以了。

我做错了什么?如何格式化日期?

例如the birth of Christ的日期:

12/25/0000

the date when the universe started:

-10/22/4004 6:00 PM

或凯撒去世的日期:

-3/15/44

阅读奖励

【问题讨论】:

  • 没有零年。耶稣名义上出生于 0001 年 12 月 25 日。
  • 1867 年阿拉斯加没有 10 月 7 日。(当年也没有 10 月 8 日、9 日、10 日、11 日、12 日、13 日、14 日、15 日、16 日或 17 日)

标签: winapi localization internationalization


【解决方案1】:

这其实是对SystemTime的限制。

...year/month/day/hour/minute/second/milliseconds value since 1 January 1601 00:00:00 UT... to 31 December 30827 23:59:59.999

我花了一些时间寻找如何绕过这个限制,但由于 GetDateFormat() 采用 SystemTime,您可能不得不硬着头皮编写自己的 format() 方法。

【讨论】:

  • 严格来说,您指的是FILETIME 结构,它自1601 年1 月1 日以来100 ns 间隔的数量。另一方面,我现在确实看到了记录在案的最小值和最大值 TIMESTAMP。现在我看到这是TIMESTAMP 的限制(而不是使用公历的GetDateFormat),我别无选择,只能到别处寻找。我希望 Windows 的其他地方有一个在特定语言环境中格式化日期的功能。
  • 糟糕,FILETIME100 ns 的计数是正确的。读的时候我的眼睛一定跳了一下。当然,这个想法仍然存在,只是 SYSTEMTIME 显示为年/月/日/小时/分钟/秒/毫秒值。
【解决方案2】:

SYSTEMTIME 结构仅从 1601 年到 30827 年有效,因为在 Windows 机器中,系统时间是从 1.1.1601 00:00 开始的经过时间间隔计算的。看 Wikipedia文章。

【讨论】:

    猜你喜欢
    • 2017-07-06
    • 1970-01-01
    • 2012-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    • 1970-01-01
    • 2013-02-03
    相关资源
    最近更新 更多