【问题标题】:What is the maximum time.Time in Go?Go 中的最长时间是多少?
【发布时间】:2014-07-31 17:11:35
【问题描述】:

我正在寻找有关 Max time.Time 的文档。

其他语言使其明确,例如在 C# 中:http://msdn.microsoft.com/en-us/library/system.datetime.maxvalue(v=vs.110).aspx

public static readonly DateTime MaxValue

这个常量的值相当于 23:59:59.9999999, December 9999 年 31 月 31 日,正好是 1 月 1 日 00:00:00 之前的一个 100 纳秒滴答声, 10000。

Go 中的最大 time.Time 是多少?它是否记录在某处?

【问题讨论】:

标签: date time go


【解决方案1】:

time.Time 在 go 中存储为 int64 加上 32 位纳秒值,但如果您使用 @JimB 的答案,您将触发 sec 组件上的整数溢出,并且像 time.Before() 这样的比较将不起作用。

这是因为 time.Unix(sec, nsec) 将 62135596800 秒的偏移量添加到 sec,它表示第 1 年(Go 中的零时间)和 1970 年(Unix 中的零时间)之间的秒数。

@twotwotwo 的游乐场示例在 http://play.golang.org/p/i6S_T4-X3v 中说明了这一点,但这里是一个精炼版本。

// number of seconds between Year 1 and 1970 (62135596800 seconds)
unixToInternal := int64((1969*365 + 1969/4 - 1969/100 + 1969/400) * 24 * 60 * 60)

// max1 gets time.Time struct: {-9223371974719179009 999999999}
max1 := time.Unix(1<<63-1, 999999999)
// max2 gets time.Time struct: {9223372036854775807 999999999}
max2 := time.Unix(1<<63-1-unixToInternal, 999999999)

// t0 is definitely before the year 292277026596
t0 := time.Date(2015, 9, 16, 19, 17, 23, 0, time.UTC)

// t0 < max1 doesn't work: prints false
fmt.Println(t0.Before(max1))
// max1 < t0 doesn't work: prints true
fmt.Println(t0.After(max1))
fmt.Println(max1.Before(t0))

// t0 < max2 works: prints true
fmt.Println(t0.Before(max2))
// max2 < t0 works: prints false
fmt.Println(t0.After(max2))
fmt.Println(max2.Before(t0))

因此,虽然这有点痛苦,但如果您想要一个最大值 time.Time,您可以使用 time.Unix(1&lt;&lt;63-62135596801, 999999999),这对于查找某个时间范围内的最小值等比较有用。

【讨论】:

    【解决方案2】:

    运行时间存储为一个 int64 加上一个 32 位 Nanosec 值(由于技术原因目前是一个 uintptr),所以不用担心会用完。

    t := time.Unix(1<<63-1, 0)
    fmt.Println(t.UTC())
    

    打印219250468-12-04 15:30:07 +0000 UTC

    如果出于某种原因您想要一个有用的最大时间(有关详细信息,请参阅@cce's answer),您可以使用:

    maxTime := time.Unix(1<<63-62135596801, 999999999)
    

    【讨论】:

    • 哈哈,知道这真是太棒了。 Y292277026596 问题!
    • @twotwotwo 实际上,它发生在292277026596-12-04 15:30:07.999999999 +0000 UTC 之前-查看play.golang.org/p/O8A2QhQLka
    • @Momer 啊,令人兴奋!与您的示例相比,看起来我需要在我的日历上预约219248499-12-06 15:30:07.999999999(我通过从秒中减去 unixToInternal 以使与 1970 的比较正确:play.golang.org/p/i6S_T4-X3v)。每天学习新东西!
    • 如果要进行 .Before / .After 比较,请务必查看 cce 的答案。
    • @KyleBrandt:哦,谢谢,我很久以前忘记解决这个问题了。
    【解决方案3】:

    请注意,虽然@cce 的回答确保AfterBefore 可以工作,但其他API 不会。 UnixNano 仅在 1970 年左右的 ±292 年内有效(1678 年到 2262 年之间)。此外,由于最长持续时间约为 292 年,即使是这两个也会在Sub 上给出一个固定的结果。

    因此,另一种方法是选择一个最小值[1] 并执行以下操作:

    var MinTime = time.Unix(-2208988800, 0) // Jan 1, 1900
    var MaxTime = MinTime.Add(1<<63 - 1)
    

    在这些范围内,一切都应该工作。

    [1]:如果您不关心 1970 年之前的日期,另一个明显的选择是 time.Unix(0, 0)

    【讨论】:

      猜你喜欢
      • 2019-04-27
      • 1970-01-01
      • 2010-11-27
      • 1970-01-01
      • 2019-05-29
      • 2014-07-10
      • 1970-01-01
      • 2016-01-05
      • 2014-07-31
      相关资源
      最近更新 更多