Секунды в год

В основном, я пытаюсь воссоздать функциональность года в формате PHP. Используя количество секунд с 1 января 1970 года, я пытаюсь получить год с помощью встроенной функции. У меня была идея, но она не работала из-за високосных лет. Может ли кто-нибудь дать мне рабочую формулу, которая занимает секунды с 1970 года и получает год от нее?

Related of "Секунды в год"

Чтобы найти год, вам нужно справиться с прыжками.

Годы от 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 

Подробнее: Один год – прыжок, если он делится на 4, за исключением тех, которые делятся на 100 (но не на 400).

 function isLeap(year){ return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0) } 

EDIT: псевдокодная формула

 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)); 

ура

Вы не можете игнорировать високосные годы.

    • У вас год = 1970
    • Добавьте numSecsInYear к этому, увеличьте год
    • если год скачок, то «съесть» еще одну секунду.
    • … пока не будет меньше 1 года секунд
  • затем идут месяц за месяцем, день за днем, час за часом, мин-мин

Кроме того, год прыгает, если – если заканчивается 00, если он не дает покоя после деления на 400 – иначе, если он не дает покоя после деления на 4

Вы определяете код 🙂

И да, это не очень оптимизировано 🙂

ps, очевидно, когда месяц за месяцем, имейте в виду, что февраль имеет 29 дней, если год скачок 🙂

Это на самом деле неправильно, но достаточно хорошее приближение, если вам не нужен год, чтобы точно измениться в момент нового года. Идея состоит в том, что количество дней в году, чтобы быть високосным годами каждые 4 года, составляет 365,25 дня.

 $a = time(); $y = 1970 + floor($a / 60 / 60 / 24 / 365.25); 

Если вы используете UNIX-подобную систему, вы можете использовать функциональность date системы для форматирования времени вместо переопределения функции PHP:

 date +%Y 

дает текущий год. Затем вы можете использовать ключ -d для форматирования пользовательской даты, а не текущей даты:

 date -d "UTC 1970-01-01 1287946333 secs +%Y" 

дает «2010».

В течение 1970-1920 годов вы можете использовать эти эквиваленты (+/- несколько минут для месяцев и лет):

 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 

Вы можете проверить свои формулы здесь. Эти эквиваленты могут быть отключены на достаточное количество минут в ключевые дни (например, 31 декабря / 1 января) и хороши только в эпоху от границ.

Если вы хотите быть точным, вам нужно иметь дело с каждым високосным годом; либо через формулу, либо через итерацию.

Этот код Perl вычисляет год с периодов эпохи за любой год +/- 130 или более лет с 1970 года (эпоха Unix). Вы должны знать на своей платформе, как большой (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 => function , delete my и т. д.)