基本上,我正在尝试重新创建PHP日期的年份功能。使用自1970年1月1日以来的秒数,我试图使用内置函数获得一年。我有一个想法,但由于闰年它没有用。任何人都可以给我一个工作公式,自1970年以来需要几秒钟,并从中得到一年?
答案 0 :(得分:4)
找到你需要处理跳跃的年份。
从1开始的年份被命令为4年的块,其中最后一个是一天,对吧?所以你有块:
seconds_block = 365*3 + 366 days = 126230400 seconds
seconds_year = 365 days = 31536000 seconds
1970年是其封闭的第二年,所以:
<?php
//test_year.php
$given_seconds = $argv[1];
$seconds_year = 31536000;
$seconds_block = 126230400;
$total_blocks_to_1968 = 492;
$actual_block = floor((($given_seconds + $seconds_year) / $seconds_block)) + $total_blocks_to_1968;
$actual_offset_from_last_block = ($given_seconds + $seconds_year) % $seconds_block;
$actual_year_of_the_block = min(floor($actual_offset_from_last_block / $seconds_year) + 1, 4);
$actual_year = $actual_block * 4 + $actual_year_of_the_block;
echo $actual_year;
测试它......
$ php test_year.php 0
1970
$ php test_year.php 1
1970
$ php test_year.php -1
1969
$ php test_year.php 31536000
1971
$ php test_year.php 31535999
1970
$ php test_year.php 126230400
1974
$ php test_year.php 126230399
1973
更多: 如果除以可被100整除的那些(但不是400),则可以整除一年。
function isLeap(year){
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)
}
编辑:伪代码公式
x = input // number of seconds since 1970
sy = 31536000 // seconds a non leap year
sb = 126230400 // seconds a block of 3 non leap years and one that is
actual_year = (floor(((x + sy) / sb)) + 492) * 4 +
(min(floor(((x + sy) % sb) / sy) + 1, 4));
干杯
答案 1 :(得分:1)
你不能忽视闰年。
你找出代码:)
是的,这没有太多优化:)
P.S。显然,当逐月前进时,请记住,如果年度飞跃,2月份有29天:)
答案 2 :(得分:1)
这实际上是错误的,但如果您不需要在新的一年时间完全改变年份,那么就足够了。这个想法是,为了每4年实现一次闰年,一年中的天数为365.25天。
$a = time();
$y = 1970 + floor($a / 60 / 60 / 24 / 365.25);
答案 3 :(得分:1)
1970 - 2038年,你可以使用这些等价物(+/-几个月和几年的几分钟):
Human readable time Seconds
1 minute 60 seconds
1 hour 3600 seconds
1 day 86400 seconds
1 week 604800 seconds
1 month (30.44 days) 2629743 seconds
1 year (365.24 days) 31556926 seconds
你可以测试你的公式here这些等价物可以在关键日(即12月31日/ 1月1日)足够的时间内关闭,并且仅适用于远离边界的纪元时代。
如果你想完全,你需要处理每一个闰年;通过公式或通过迭代。
此Perl代码计算从1970年(Unix纪元)+/- 130或更多年的任何年份的纪元秒的年份。您需要在平台上了解时钟号的大小(32位或64位)才能知道跨度:
sub days_in_year {
my $year=shift;
my $leap =
($year % 400 == 0) ? 1
: ($year % 100 == 0) ? 0
: ($year % 4 == 0) ? 1
: 0
;
return (365+$leap);
}
sub epoch_to_year {
use integer;
my $t=shift;
my $ey=1970;
my $secs=$t;
if($t<0) {
while($secs<0) {
$secs+=days_in_year(--$ey)*24*60*60;
}
return $ey;
}
else {
while($secs>0) {
$secs-=days_in_year($ey++)*24*60*60;
}
return $ey if ($secs==0);
return $ey-1;
}
}
它是慢的你应该使用一个库,但你没有它可以工作。将它转换为PHP是微不足道的。 (sub
=&gt; function
,删除my
等)
答案 4 :(得分:1)
如果您使用的是类UNIX系统,则可以使用系统的date
功能格式化时间,而不是重新实现PHP函数:
date +%Y
给出了当前年份。然后,您可以使用-d开关格式化自定义日期,而不是当前日期:
date -d "UTC 1970-01-01 1287946333 secs +%Y"
给出“2010”。