PHP strtotime 不带闰年

发布于 2024-10-09 01:07:05 字数 1420 浏览 9 评论 0原文

关于这个线程,我开发了部分解决方案:

function strtosecs($time,$now=null){
    static $LEAPDIFF=86400;
    $time=strtotime($time,$now);
    return $time-(round((date('Y',$time)-1968)/4)*$LEAPDIFF);
}

该函数应该获取给定字符串的秒数而不检查闰年。

它计算 1970 年的闰年数 [(year-1986)/4],将其乘以闰年与平年之间的秒数差(最终,它只是 1970 年的秒数)一天)。

最后,我简单地从计算的时间中删除所有多余的闰年秒。以下是输入/输出的一些示例:

// test code
echo strtosecs('+20 years',0).'=>'.(strtosecs('+20 years',0)/31536000);
echo strtosecs('+1 years',0).'=>'.(strtosecs('+1 years',0)/31536000);

// test output
630676800 => 19.998630136986
31471200  => 0.99794520547945

您可能会问为什么我要对输出进行除法?是为了测试一下; 31536000 是一年中的秒数,因此 19.99... 应该是 20,0.99... 应该是 1。 当然,我可以将其全部舍入并得到“正确”答案,但我担心不准确。

编辑1:因为它看起来并不明显,所以我的问题在于顽固性;你只要 20 年不问 PHP,它就会给你 19.99...,对吗?

编辑2:这一切似乎都可以归结为1968年的部分;

  • 1970;在我尝试过的所有测试中发现它都是准确的。
  • 1969;发现它这里使用...例如:(2008- 1969)/4 = 9.75...) 以及此处提到< /a>.第 2 年(+3 年)以后准确。
  • 1968;如下所述,这是 UNIX 时间(1970 年)闰年的“零年”。 (对我来说)这听起来“正确”,但根本不准确。

With regards to this thread, I've developed a partial solution:

function strtosecs($time,$now=null){
    static $LEAPDIFF=86400;
    $time=strtotime($time,$now);
    return $time-(round((date('Y',$time)-1968)/4)*$LEAPDIFF);
}

The function is supposed to get the number of seconds given a string without checking leap-years.

It does this calculating the number of leap-years 1970 [(year-1986)/4], multiplying it by the difference in seconds between a leap-year and a normal year (which in the end, it's just the number of seconds in a day).

Finally, I simply remove all those excess leap-year seconds from the calculated time. Here's some examples of the inputs/outputs:

// test code
echo strtosecs('+20 years',0).'=>'.(strtosecs('+20 years',0)/31536000);
echo strtosecs('+1 years',0).'=>'.(strtosecs('+1 years',0)/31536000);

// test output
630676800 => 19.998630136986
31471200  => 0.99794520547945

You will probably ask why am I doing a division on the output? It's to test it out; 31536000 is the number of seconds in a year, so that 19.99... should be 20 and 0.99... should be a 1.
Sure, I could round it all and get "correct" answer, but I'm worried about the inaccuracies.

Edit1: Since it doesn't seem obvious, my problem is with inveteracies; you just don't ask PHP for 20 years and it gives you 19.99..., right?

Edit2: It all seems to boil down to the part about 1968;

  • 1970; found it accurate in all tests I've tried.
  • 1969; Found it used here (...ex: (2008-1969)/4 = 9.75...) as well as mentioned here. Accurate after the 2nd year (+3 years) onwards.
  • 1968; as detailed below, this is "year zero" of leap years from unix time (1970). It sounds "right" (to me) but it isn't accurate, at all.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ゝ杯具 2024-10-16 01:07:05

这是否与使用 PHP 管理浮点数时固有的不准确性有关?

http://php.net/manual/en/language.types.float.php

Could this be related to the inherent inaccuracy experienced when using PHP to manage floating point numbers?

http://php.net/manual/en/language.types.float.php

你又不是我 2024-10-16 01:07:05

您应该将计算中的1968(它从哪里来?)替换为unix时间的原点:1970,这样您将得到更准确的结果。

编辑

您必须执行 intval 来计算闰年的数量,它必须是整数:

return $time - (intval( (date('Y', $time) - 1969) / 4) * $LEAPDIFF);

这将为您提供 +0 - 范围内的正确结果> +68 ,32位机器上unix时间结束

You should replace 1968 in your calculation (where does it come from ?) by the origine of unix time : 1970 and you will get more accurate results.

Edit

You have to do an intval to count the number of leapyears which must be an integer :

return $time - (intval( (date('Y', $time) - 1969) / 4) * $LEAPDIFF);

This will give you correct results within the range +0 -> +68 , end of unix time on 32bit machine

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文