如何将纪元之前的日期表示为UNIX时间戳

45

我发现我不知道如何以Unix时间戳的形式储存1970年1月1日之前的日期。因为这个日期是Unix“时代”,所以这并不奇怪。

但是,即使它并不是为此而设计的,我仍然希望以Unix格式存储过去很久以前的日期。
我有我的原因。

那么我的问题是:如何使Unix时间戳包含“无效”但仍有效的日期?储存负数秒是否可行?我们甚至可以在Unix时间戳中存储负数秒吗?我的意思是它不是无符号的吗?

另外,如果我没错的话,我只能储存到1901.12.13 20:45:52,通过任何方式能将其推广到更早的历史时期吗?


1
Unix的time_t是一个带符号的32位整数,因此它可以回溯到你所指出的1901年。你应该检查你的操作系统,许多操作系统已经扩展了time_t到64位,这给了你几百亿年的余地。 - Dan Lowe
1个回答

58

Unix Time通常是从1970年1月1日UTC时间的第一刻起的32位整数秒数,纪元1970年1月1日00:00:00 UTC。这意味着大约136年的范围,纪元的两侧各占一半。负数表示更早的时间,零表示纪元,正数表示更晚的时间。对于有符号的32位整数,值的范围从1901-12-132038-01-19 03:14:07 UTC

这并非铁板一块。嗯,它确实是写在一堆不同的石头上,旧的石头上写着32位,新的石头上写着64位。一些规范说这个意义是“实现定义的”。一些Unix系统使用无符号整数仅扩展到未来的时间,但通常的做法是使用有符号数。有些使用浮点数而不是整数。有关详细信息,请参阅维基百科上的Unix Time文章和这个问题
所以,基本上,你的问题没有意义。你必须了解你的编程语言的上下文(标准C,其他C,Java等),环境(POSIX兼容),特定的软件库,或者数据库存储,或者应用程序。

避免从纪元开始计数

除了缺乏具体性之外,还有其他几十个时代被各种软件系统使用,其中一些非常受欢迎和常见。例如,NTFS文件系统和COBOL使用1601年1月1日,各种FAT文件系统使用1980年1月1日,Apple Cocoa使用2001年1月1日,Excel和Lotus 1-2-3电子表格使用1900年1月0日。

此外,还有不同粒度的计数方式。除了整秒,一些系统使用毫秒、微秒或纳秒。

我建议不要将日期时间作为从时代开始的计数。相反,应在编程语言或数据库中使用特定的数据类型。

ISO 8601

当没有可用的数据类型或者在交换数据时,应使用标准的ISO 8601格式的文本。该标准定义了各种日期时间值的合理字符串格式。

  • 日期
    • 2015-07-29
  • 带有与UTC的偏移的日期时间(Z代表零/Zulu代表UTC)(注意偏移量前的零填充)
    • 2015-07-29T14:59:08Z
    • 2001-02-13T12:34:56.123+05:30
  • 周(带或不带星期几)
    • 2015-W31
    • 2015-W31-3
  • 序数日期(年中的第几天)
    • 2015-210
  • 时间间隔
    • "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z"
  • 持续时间(格式为PnYnMnDTnHnMnS
    • P3Y6M4DT12H30M5S = "三年六个月四天十二小时三十分钟五秒的时间段"
在StackOverflow.com上搜索更多关于这些主题的问题和答案。

太棒了,虽然我担心它可能会变成“实现定义”。 - Wolfer
Perl的localtime函数也是从1900年1月0日开始计算的,尽管它是以数字数组的形式表示,而不是自纪元以来的秒数。 - Electric Coffee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接