2011-09-17 91 views
3

首先,我知道這個問題在某種程度上是這樣回答的:Calculate day number from an unix-timestamp in a math way?什麼是unix時間戳公式?

我需要一個自定義函數/公式爲此。所以它只會返回ISO格式的日期。 「YYYY-MM-DD」。

eg. 1316278442 = 2011-09-17 

編輯通過分機! 這是錯誤的!請不要讀這個。

我一直在這一整天!我設法擺脫的唯一事情就是一週中的某一天。

$ dayOfWeek =($ timestamp/86400)%7; //這裏1是星期六,7日

速度是問題,這就是爲什麼我不希望使用date('Y-m-d',$timestamp);

如果你不能幫我絲毫自定義函數或公式,至少給我更好的解釋如何做到這一點。它用很多種語言完成,必須有人知道如何做到這一點。

非常感謝您的幫助。

+0

當地時間?格林威治標準時間? –

+3

是什麼讓你認爲'date('Y-m-d',$ timestamp)'會比自己計算日期要慢? – arnaud576875

+6

如果'日期'不夠快,因爲你考慮使用另一種語言 – Gordon

回答

6

這裏是date()DateTime::setTimestamp()使用從Unix時間戳計算日期的功能:

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

正如你所看到的,這是一個有點閏年複雜等

-

這就是說,如果你只需要一週中的某一天,看起來你可以安全地忽略閏年,而只是使用你在問題中給出的公式:$dayOfWeek=($timestamp/86400)%7

+1

至少沒有閏秒! –

+0

THANK你回答(儘管它是一個參考),而不是像其他人一樣在問題中散佈錯誤! – arijeet

+0

10x我將繼續閱讀... – Ext

0

您可以先使用unixtojd()將其轉換爲julian,然後使用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

好的。該功能已完成。它需要一個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); 
?>