Что такое формула временных меток unix?


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

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

eg. 1316278442 = 2011-09-17

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

Я занимаюсь этим весь день! Единственное, что мне удалось вытащить, - это день неделя.

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

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

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

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

Author: Community, 2011-09-17

3 answers

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

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

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

--

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

 6
Author: arnaud576875, 2011-09-17 16:26:07

Вы можете сначала преобразовать в юлиан с помощью 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";
 0
Author: Charlie, 2011-09-17 16:25:13

Хорошо. Функция завершена. Он принимает временную метку unix и возвращает ГГГГ-ММ-ДД. Это было все, что мне было нужно. Я надеюсь, что это кому-нибудь поможет...

<?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
Author: Ext, 2011-09-19 11:17:10