Что такое формула метки времени Unix? - PullRequest
4 голосов
/ 17 сентября 2011

Прежде всего, я знаю, что этот вопрос был вроде задан / вроде как здесь ответил: Рассчитать номер дня из метки времени unix математическим способом? .

Мне нужна пользовательская функция / формула для этого. поэтому он возвращает только дату в формате ISO. "YYYY-MM-DD".

eg. 1316278442 = 2011-09-17

РЕДАКТИРОВАТЬ Ext! ЭТО НЕ ВЕРНО ! Пожалуйста, не читайте это.

Я был на этом весь день! Единственное, что мне удалось выбраться, это день недели.

$ = день недели ($ временная метка / 86400) 7%; // А здесь 1 суббота, 7 пятница

Скорость - это проблема, поэтому я не хочу использовать date('Y-m-d',$timestamp);

Если вы не можете помочь мне с пользовательской функцией или формулой, по крайней мере, дайте мне лучшее объяснение того, как это сделать. Это было сделано на многих языках, должен быть кто-то, кто знает, как это сделать.

Заранее благодарю за помощь.

Ответы [ 3 ]

6 голосов
/ 17 сентября 2011

Вот функция, которую date() и DateTime::setTimestamp() используют для вычисления даты из метки времени Unix:

https://github.com/php/php-src/blob/d57eefe6227081001978c3a63224065af8b5728e/ext/date/lib/unixtime2tm.c#L39

Как видите, это немного усложняется високосными годами и т. Д.

-

Тем не менее, если вам нужен только день недели, кажется, что вы можете спокойно игнорировать високосные годы и просто использовать формулу, которую вы задали в вопросе: $dayOfWeek=($timestamp/86400)%7

1 голос
/ 19 сентября 2011

Хорошо.Функция завершена.Он принимает метку времени Unix и возвращает YYYY-MM-DD.Это было все, что мне было нужно.Надеюсь, это кому-нибудь поможет ...

<?php
$t=1325522004;//return 2011-09-19
/*
 * Transform a Unix Timestamp to ISO 8601 Date format YYYY-MM-DD 
 * @param unix timestamp
 * @return Returns a formated date (YYYY-MM-DD) or false
 */
function unixToIso8601($timestamp){
    if($timestamp<0){return false;}//Do not accept negative values
    /* Too many constants, add this to a class to speed things up. */
    $year=1970;//Unix Epoc begins 1970-01-01
    $dayInSeconds=86400;//60secs*60mins*24hours
    $daysInYear=365;//Non Leap Year
    $daysInLYear=$daysInYear+1;//Leap year
    $days=(int)($timestamp/$dayInSeconds);//Days passed since UNIX Epoc
    $tmpDays=$days+1;//If passed (timestamp < $dayInSeconds), it will return 0, so add 1
    $monthsInDays=array();//Months will be in here ***Taken from the PHP source code***
    $month=11;//This will be the returned MONTH NUMBER.
    $day;//This will be the returned day number. 

    while($tmpDays>=$daysInYear){//Start adding years to 1970
        $year++;
        if(isLeap($year)){
            $tmpDays-=$daysInLYear;
        }
        else{
            $tmpDays-=$daysInYear;
        }
    }

    if(isLeap($year)){//The year is a leap year
        $tmpDays--;//Remove the extra day
        $monthsInDays=array(-1,30,59,90,120,151,181,212,243,273,304,334);
    }
    else{
        $monthsInDays=array(0,31,59,90,120,151,181,212,243,273,304,334);
    }

    while($month>0){
        if($tmpDays>$monthsInDays[$month]){
            break;//$month+1 is now the month number.
        }
        $month--;
    }
    $day=$tmpDays-$monthsInDays[$month];//Setup the date
    $month++;//Increment by one to give the accurate month

    return $year.'-'.(($month<10)?'0'.$month:$month).'-'.(($day<10)?'0'.$day:$day);
}
function isLeap($y){
    return (($y)%4==0&&(($y)%100!=0||($y)%400==0));
}
echo unixToIso8601($t);
?>
0 голосов
/ 17 сентября 2011

Вы можете сначала преобразовать в julian с помощью unixtojd (), а затем использовать cal_from_jd, чтобы разделить на год, месяц, день. Это немного быстрее. Код ниже дает мне этот результат:

2009-02-13 0.13018703460693 seconds  using date()
2009-02-13 0.037487983703613 seconds using unixtojd(),cal_from_jd(),and sprintf()



function microtime_float(){
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}
$time_start = microtime_float();
$unix_timestamp = 1234567890;
for($i=0;$i<10000;$i++) {
    $d = date('Y-m-d',$unix_timestamp);
}
$time_stop = microtime_float();
echo $d . " " . ($time_stop - $time_start) . " seconds using date()<br>\n";

//////////////////////////


$time_start = microtime_float();

$unix_timestamp = 1234567890;
for($i=0;$i<10000;$i++) {
    $julian_date = unixtojd($unix_timestamp);
    $date_array = cal_from_jd($julian_date, CAL_GREGORIAN);
    $d = sprintf('%d-%02d-%02d',$date_array['year'],$date_array['month'],$date_array['day']);
}

$time_stop = microtime_float();
echo $d . " " . ($time_stop - $time_start) . " seconds using unixtojd(),cal_from_jd(),and sprintf()<br>\n";
...