2017-03-14 335 views
0

我試着用自己最大的64位有符號整數來計算日期,但總是以幾百萬年不同的另一日期結束。我試過使用恆星年和閏年,但我總是得到至少幾百萬年的結果。爲什麼計算64位簽名的unix時間戳溢出時的292,277,026,596年12月4日的日期?

以下是我迄今爲止嘗試:

dateA = 1970 + (9223372036854775807/31556926.08)

dateB = 1970 + (9223372036854775807/31536000) + (((9223372036854775807/31536000)/4)/365)

都返回錯誤的答案。任何人都可以引導我在正確的方向嗎?

+0

確定的符號值作爲限制?一些實現使用無符號的。 –

+2

你甚至谷歌如何計算閏年? - 你缺少可能影響事情的多個部分。 – stdunbar

+0

但即使閏年錯了,恆星年不正確嗎? –

回答

2

你需要考慮閏年的年份。一年是閏年,如果:

  • 它被4整除;
  • 除非它可以被100整除;
  • 如果它是整除由400

作一個粗略的估計年度計算1970 + 0x7fffffffffffffff // 86400 // (365 + 1/4 - 1/100 + 1/400)給出292277026596.的答案,我會離開的確切日期的推導作爲一個練習讀者。

我用Python 3進行了這種計算,它給出了整數除法的實際結果。針對Python 2進行相應的調整。

+0

謝謝!我沒有從'__future__'導入分部,所以我搞砸了所有的結果,現在這個結果是準確的。 –

2

讓我們用datetime來做一些繁重的工作。

>>> import datetime 

首先,公曆每400年重複一次。這是400年週期中的天數:

>>> 365 * 400 + 100 - 4 + 1 
146097 

清除?每年至少有365天。閏年會有100次(+100),除非100可以被閏年(-4)除盡,除了400被閏年(+1)整除的年份除外。

然後用它來找出塊多少400年適合在一些等於最大的63位整數秒:

>>> divmod((1 << 63) - 1, 146097 * 24 * 3600) 
(730692561, 7161147007) 

因此,我們必須730692561 400年的塊,用7161147007秒遺留下來。 datetime可以直接計算該秒數超越時代:

>>> datetime.datetime(1970, 1, 1) + datetime.timedelta(seconds=7161147007) 
datetime.datetime(2196, 12, 4, 15, 30, 7) 

所以,除了一年,最後表示的第二,12月4日十五點30分07秒UTC。

爲了拿到年終,只需添加730692561 400年的塊:

>>> 2196 + 730692561 * 400 
292277026596 
+0

減去400年的確切倍數是非常好的,我希望我能想到它。 –

+1

heh - 我寫了'datetime'模塊,它在內部做了一些非常類似的事情,以防萬一我們有一天允許無限期整數;-) –

+1

我再次看到了這個答案,而且在我看來,在400年後你可能會結束了一週的不同日子,所以我檢查了:146097%7 == 0.那些格里高利人想到了一切! –