gmmktime

(PHP 3, PHP 4, PHP 5)

gmmktime -- 取得 GMT 日期的 UNIX 时间戳

说明

int gmmktime ( [int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]] )

mktime() 完全一样,只除了返回值是格林威治标准时的时间戳。

参数总是表示 GMT 日期,因此 is_dst 对结果没有影响。

mktime() 一样,参数可以从右到左依次空着,空着的参数会被设为相应的当前 GMT 值。

注: 自 5.1.0 起,is_dst 参数被废弃。因此应该用新的时区处理特性。

注: gmmktime() 内部使用了 mktime(),因此只有转换成本地时间也合法的时间才能用在其中。 so only times valid in derived local time can be used.

例子 1. gmmktime() 在 Windows 中的边界

<?php
gmmktime
(0, 0, 0, 1, 1, 1970); // 在 GMT 和西方合法,在东方不合法
?>

参见 mktime()date()time()


add a note add a note User Contributed Notes
francois at bonzon dot com
22-Dec-2005 04:34
In response to mirko at example dot com is_est function, to be exact, the two lines defining $begin_time and $end_time should read:

<?php

$begin_time
= gmmktime(1, 0, 0, 3, $begin_date, $Y);
$end_time = gmmktime(1, 0, 0, 10, $end_date, $Y);

?>

Because the clocks go forward, resp. back at 01.00 UTC, not at midnight.
mirko at example dot com
31-Oct-2005 08:33
<?php

/**
 * Check if given time is during Europen Summer Time
 *
 * @link http://en.wikipedia.org/wiki/European_Summer_Time
 * @param int $time UTC timestamp (GMT)
 * @return boolean true if it is EST else false
 */
function is_est($time)
{
  
// get year
  
$Y = gmdate("Y", $time);
  
  
// calc start / end dates and time for that year
  
$begin_date = (31 - (5*$Y/4 + 4) % 7);
  
$end_date = (31 - (5*$Y/4 + 1) % 7);
  
$begin_time = gmmktime(0,0,03,$begin_date,$Y);
  
$end_time = gmmktime(0,0,010,$end_date,$Y);
  
  
// if it's in that period
  
$is_dst = $time >= $begin_time && $time < $end_time;
   return
$is_dst;
}

?>
ranjeet at magnet-i dot com
16-Sep-2005 08:52
<?php
function getTimeRemaining($timeZonePass,
$dateTimeUser,$ID,$table,$coloumnName)
{
global
$configVars;

$timeZoneDefault=explode("_",$timeZonePass);

$timeZone=(substr($timeZoneDefault[0],1))*(60) ;

if((
substr($timeZoneDefault[0],0,1)) =="+")
  
$defaultSeconds=gmdate("Y-m-d-H-i-s",time()+
  
$timeZone);
elseif((
substr($timeZoneDefault[0],0,1)) =="-")
  
$defaultSeconds=gmdate("Y-m-d-H-i-s",time()-
  
$timeZone);
else
  
$defaultSeconds=gmdate("Y-m-d-H-i-s",time());

$defaultSecondsExp=explode("-",$defaultSeconds);

$defaultGmktime=gmmktime($defaultSecondsExp[3],
          
$defaultSecondsExp[4],
$defaultSecondsExp[5], $defaultSecondsExp[1],
          
$defaultSecondsExp[2],
$defaultSecondsExp[0]);

$dateArray=explode("-",$dateTimeUser);

$slectedGmktime=gmmktime(23,59,59,$dateArray[1],
          
$dateArray[2],$dateArray[0]);

if((
substr($timeZoneDefault[0],0,1)) =="+")
  
$slectedGmktimeAdded=($slectedGmktime)+
                       (
$timeZone);
elseif((
substr($timeZoneDefault[0],0,1)) =="-")
  
$slectedGmktimeAdded=($slectedGmktime)+
                       (
$timeZone);
else
  
$slectedGmktimeAdded=($slectedGmktime);

//$slectedGmDate=gmdate("Y-m-d-H-i-s",
          
$slectedGmktimeAdded);

$timeMinus=$slectedGmktimeAdded -
      
$defaultGmktime;

$secondsInDay= 60*60*24;

if (
$secondsInDay <= $timeMinus)
{
  
$daysRemaining = floor($timeMinus/
                  
$secondsInDay);
   if(
$daysRemaining >1 )
       return
$daysRemaining ."&nbsp;Days&nbsp;";
   else
       return
$daysRemaining ."&nbsp;Day&nbsp;";
}

if(empty(
$daysRemaining))

  
$secondsInHour= 60*60;
   if (
$secondsInHour <= $timeMinus)
   {
      
$hoursRemaining =floor ($timeMinus/
                      
$secondsInHour);
       if(
$hoursRemaining > 1 )
           return
$hoursRemaining ."&nbsp;Hours&nbsp;";
       else
           return
$hoursRemaining ."&nbsp;Hour&nbsp;";
   }
}

if(empty(
$hoursRemaining))
{
  
//$secondsRemaining = $timeMinus. "&nbsp;Seconds";
  
$secondsInMinute = 60;
   if (
$secondsInMinute <= $timeMinus)
   {
      
$mintuesRemaining =floor ($timeMinus/
              
$secondsInMinute);
       if(
$mintuesRemaining > 1 )
           return
$mintuesRemaining ."&nbsp;Minutes&nbsp;";
       else
           return
$mintuesRemaining ."&nbsp;Minute&nbsp;";
   }
}

if(empty(
$mintuesRemaining))
{
  
$secondsRemaining = $timeMinus;
   if(
$secondsRemaining < 0)
   { 
      
timedOutSale($ID,$table,$coloumnName);
       return
"Time out";
   }
   elseif(
$secondsRemaining > 1 )
       return
$secondsRemaining . "&nbsp;Seconds";
   else
       return
$secondsRemaining . "&nbsp;Second";
}
}

function
timedOutSale($ID,$table)
{
   GLOBAL
$configVars, $db,$tableNames;
  
$query "UPDATE " . $table
                  
. " SET status = 'T'
                   WHERE $coloumnName = '"
. $ID ."'";

          
$result = $db->query($query);
   return;
}

?>
16-Sep-2005 12:02
function getTimeRemaining($timeZonePass,
$dateTimeUser,$ID,$table,$coloumnName)
{
global $configVars;

$timeZoneDefault=explode("_",$timeZonePass);

$timeZone=(substr($timeZoneDefault[0],1))*(60) ;

if((substr($timeZoneDefault[0],0,1)) =="+")
   $defaultSeconds=gmdate("Y-m-d-H-i-s",time()+
   $timeZone);
elseif((substr($timeZoneDefault[0],0,1)) =="-")
   $defaultSeconds=gmdate("Y-m-d-H-i-s",time()-
   $timeZone);
else
   $defaultSeconds=gmdate("Y-m-d-H-i-s",time());

$defaultSecondsExp=explode("-",$defaultSeconds);

$defaultGmktime=gmmktime($defaultSecondsExp[3],
           $defaultSecondsExp[4],
$defaultSecondsExp[5], $defaultSecondsExp[1],
           $defaultSecondsExp[2],
$defaultSecondsExp[0]);

$dateArray=explode("-",$dateTimeUser);

$slectedGmktime=gmmktime(23,59,59,$dateArray[1],
           $dateArray[2],$dateArray[0]);

if((substr($timeZoneDefault[0],0,1)) =="+")
   $slectedGmktimeAdded=($slectedGmktime)+
                       ($timeZone);
elseif((substr($timeZoneDefault[0],0,1)) =="-")
   $slectedGmktimeAdded=($slectedGmktime)+
                       ($timeZone);
else
   $slectedGmktimeAdded=($slectedGmktime);

//$slectedGmDate=gmdate("Y-m-d-H-i-s",
           $slectedGmktimeAdded);

$timeMinus=$slectedGmktimeAdded -
       $defaultGmktime;

$secondsInDay= 60*60*24;

if ($secondsInDay <= $timeMinus)
{
   $daysRemaining = floor($timeMinus/
                   $secondsInDay);
   if($daysRemaining >1 )
       return $daysRemaining ."&nbsp;Days&nbsp;";
   else
       return $daysRemaining ."&nbsp;Day&nbsp;";
}

if(empty($daysRemaining))
{   
   $secondsInHour= 60*60;
   if ($secondsInHour <= $timeMinus)
   {
       $hoursRemaining =floor ($timeMinus/
                       $secondsInHour);
       if($hoursRemaining > 1 )
           return $hoursRemaining ."&nbsp;Hours&nbsp;";
       else
           return $hoursRemaining ."&nbsp;Hour&nbsp;";
   }
}

if(empty($hoursRemaining))
{
   //$secondsRemaining = $timeMinus. "&nbsp;Seconds";
   $secondsInMinute = 60;
   if ($secondsInMinute <= $timeMinus)
   {
       $mintuesRemaining =floor ($timeMinus/
               $secondsInMinute);
       if($mintuesRemaining > 1 )
           return $mintuesRemaining ."&nbsp;Minutes&nbsp;";
       else
           return $mintuesRemaining ."&nbsp;Minute&nbsp;";
   }
}

if(empty($mintuesRemaining))
{
   $secondsRemaining = $timeMinus;
   if($secondsRemaining < 0)
   {   
       timedOutSale($ID,$table,$coloumnName);
       return "Time out";
   }
   elseif($secondsRemaining > 1 )
       return $secondsRemaining . "&nbsp;Seconds";
   else
       return $secondsRemaining . "&nbsp;Second";
}
}

function timedOutSale($ID,$table)
{
   GLOBAL $configVars, $db,$tableNames;
   $query =  "UPDATE " . $table
                   . " SET status = 'T'
                   WHERE $coloumnName = '" . $ID ."'";

           $result = $db->query($query);
   return;
}
jbr (AT) ya-right.com
14-Feb-2005 02:04
I have seen many different hacked versions of this function for people using Windows that want to support dates before Jan 1, 1970. Here is yet another one that is different than others you may have seen! It does not use loops like all the others I have seen!

<?

// usage...

echo win_gmmktime ( 12, 43, 16, 07, 23, 1946 );

function
win_gmmktime ( $hour, $minute, $second, $month, $day, $year )
{
   if (
$year > 1969 )
   {
       return (
gmmktime ( $hour, $minute, $second, $month, $day, $year ) );
   }

  
$t = 0;
  
$ds = 86400;
  
$hs = 3600;
  
$dy = 365;
  
$ms = 60;

  
$months = array ( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
  
$leap_year = $year % 4 == 0 && ( $year % 100 > 0 || $year % 400 == 0 ) ? true : false;

   if (
$year < 1969 )
   {
      
$y = 1969 - $year;
      
$t -= ( $y * $dy ) * $ds;
      
$x = ceil ( $y / 4 );

       if (
$leap_year && $month > 2 )
       {
          
$x -= 1;
       }

      
$t -= $x * $ds;
   }

   if (
$month != 12 )
   {
      
$tm = $months;
      
$tm = array_slice ( $tm, $month );
      
$t -= array_sum ( $tm ) * $ds;
       unset (
$tm );
   }

  
$nh = ( ( $month == 2 && $leap_year ? 29 : $months[$month-1] ) - $day );
  
$t -= $nh != 0 ? $nh * $ds : 0;
  
$nh = 23 - $hour;
  
$t -= $nh != 0 ? $nh * $hs : 0;
  
$nh = 59 - $minute;
  
$t -= $nh != 0 ? $nh * $ms : 0;
  
$nh = 59 - $second;
  
$t -= $nh != 0 ? $nh + 1 : 0;

   return (
$t );
}

?>
welch at advomatic dot com
03-Feb-2005 04:48
Here is a handy routine for counting down to the minute, hour, and day to a timestamp

     $minutesleft = floor(($timestamp - gmtime()) / 60);

     if ($minutesleft < 0) {
       $timeleft = 'NOW';
     }
     else if ($minutesleft < 60) {
       $timeleft = ($minutesleft==1 ? '1 minute' : $minutesleft.' minutes');
     }
     else if ($minutesleft >= 60 && $minutesleft < (24*60)) {
       $timeleft = (floor($minutesleft/60) == 1 ? '1 hour' : floor($minutesleft/60).' hours');
     }
     else if ($minutesleft >= (24*60)) {
       $days = floor($minutesleft / (24*60));
       // hours remainder
       $hours = ($minutesleft % (24*60)) / 60;
       // hours left in the day
       $hours_left = ((time() / 60) % (24*60)) / 60;
       // see if the remainder of hours is greater than the hours left in today, if so increase the days by one so that the days remaining mimics the date rather than how many 24 hour periods there are between now and then.
       if($hours > $hours_left) {
         $days++;
       }
       $timeleft = ($days == 1 ? '1 day' : $days.' days');
     }

     echo $timeleft;
imoore76 at yahoo dot com
16-Jan-2005 05:16
Why not just do:

<?php

// assuming $start and $end are timestamps

$day_diff = floor(abs($start - $end) / 86400);

?>
justin at booleangate dot org
05-Jan-2005 04:10
Here's a play on turgut85's countDays function.  I've found it to be more efficient and it accepts unix timestamps rather than arrays.  Thanks for the ideas.

function count_days($start, $end) {
  // Count the days between $start and $end where both $start and $end
  //  are UNIX timestamps
 
  // Swap the two values if end is greater than start (to avoid the
  //  loop of death).
  if ($start < $end) {
   $t = $start;
   $start = $end;
   $end = $t;
  }
 
  // Increment the start time by one day until it is equal to the
  //  end time
 
  $days = 0;
  while ( $start < $end ) {
   $start = strtotime("+1 days", $start);
   $days++;
  }
 
  return $days;
}
turgut85 at hotmail dot com
07-Dec-2004 12:53
<?php

// THIS ROUTINE COUNT DAYS BEETWEEN TWO DATE //
// BEGIN DATE COULD BE IN THE PAST OR IN THE FUTURE //

$beg['YEAR']=2004;
$beg['MONTH']=10;
$beg['DAY']=1;

$end['YEAR']=2004;
$end['MONTH']=10;
$end['DAY']=3;

function
countDays ($beg,$end) {
  
$start = gmmktime(0,0,0,$beg['MONTH'],$beg['DAY'],$beg['YEAR']);
$endin = gmmktime(0,0,0,$end['MONTH'],$end['DAY'],$end['YEAR']);

// echo $start."\n";
// echo $endin."\n";

$day = 0;

if (
$start < $endin) {
$toward = 1;
} else  {
$toward = 0;
}

$mover = $start;

if (
$start != $endin) {
  
do {
  
$day++;
  
   if (
$toward)  {
  
$mover = gmmktime(0,0,0,$beg['MONTH'],($beg['DAY']+$day),$beg['YEAR']);
   } else {
  
$mover = gmmktime(0,0,0,$beg['MONTH'],($beg['DAY']-$day),$beg['YEAR']);
   }

  
} while (
$mover != $endin);

}

echo
$day;

return
$day;
}

echo
countDays ($beg,$end). " days. ";

?>

Turgut Z. YESILYURT
turgut85@hotmail.com
System and Application Developer
New Jersey, USA
mwwaygoo AT hotmail DOT com
23-Nov-2004 01:36
REF: http://www.dti.gov.uk/er/sumtimetb.htm

Since 1981 EC Directives have prescribed the start and end dates of summer time in all Member States.  There have to date been eight Directives which have set summer-time arrangements for fixed periods. The Summer Time Act 1972 sets the appropriate dates in the UK and summer-time orders have been made as necessary to implement the European Directives. The 9th EC Directive prescribes the start and end dates of summer time as the last Sundays in March and October respectively. These dates are in line with those already operating in the United Kingdom. The 9th Directive provides that these start and end dates should apply indefinitely.
---
9th EC Directive - 19 January 2001

Article 1
For the purposes of this Directive "summer-time period" shall mean the period of the year during which clocks are put forward by 60 minutes compared with the rest of the year.

Article 2
From 2002 onwards, the summer-time period shall begin, in every Member State, at 1.00 a.m., Greenwich Mean Time, on the last Sunday in March.

Article 3
From 2002 onwards, the summer-time period shall end, in every Member State, at 1.00 a.m., Greenwich Mean Time, on the last Sunday in October.

You stand corrected ;-)  (well up until 2007 anyway)
Andy
19-Oct-2004 10:00
mwwaygoo's code isn't quite right. My understanding is that the relevant dates for changing between daylight saving time in the UK is the third sunday of march and october - not the last sunday!
mwwaygoo AT hotmail DOT com
13-Sep-2004 06:51
I had a problem with hosting a UK site on a US server, the times didnt match (obviously) and also didnt account for daylight savings time. The daylight savings dates and times of change differ worldwide, so detecting if the server was in dst wouldnt work (see http://webexhibits.org/daylightsaving/).

Here is a function for creating a timestamp which can be used by date() to create all the parameters required to display the local time (site not server). I have used GMT time to create the timestamp as there is no offset for UK time (+00).

<?php
function UKdst_time()
{
  
// created by Matthew Waygood (www.waygoodstuff.co.uk)
  
$timestamp = mktime(gmdate("H, i, s, m, d, Y")); // UTC time
  
$this_year=gmdate("Y", $timestamp);

  
// last sunday in march at 1am UTC
  
$last_day_of_march=gmmktime(1,0,0,3,31,$this_year);
  
$last_sunday_of_march=strtotime("-".gmdate("w", $last_day_of_march)." day", $last_day_of_march);
  
  
// last sunday in october at 1am UTC
  
$last_day_of_october=gmmktime(1,0,0,10,31,$this_year);
  
$last_sunday_of_october=strtotime("-".gmdate("w", $last_day_of_october)." day", $last_day_of_october);

   if( (
$timestamp > $last_sunday_of_march) && ($timestamp < $last_sunday_of_october) )
   {
      
$timestamp=$timestamp+3600; // foward one hour
  
}
   return
$timestamp;
}
?>
francois at bonzon dot com
18-Jun-2004 01:02
A simpler way to get a GMT date into a UNIX timestamp is to use the strtotime() function.

<?php

// Prints: 1076705142
$gmstr = 'Fri, 13 Feb 2004 20:45:42 GMT';
echo
strtotime($gmstr);

?>
Dave
30-Mar-2004 01:35
There appears to be a discrepency between PHP and C timestamps.  The C time() and gettimeofday() functions are documented to return based on UTC time, but the value obtained doesn't match the PHP gmmktime() function.  Instead, it matches the PHP mktime() function, which is supposed to be local time.
  
It seems that C always uses a UTC timestamp and adjusts to local time through different handling functions (gmtime() vs localtime()).  PHP appears to use differing UTC/local timestamps, but single handling functions.

The exception to this rule is the PHP time() function, which appears to behave in the same was as the C version.

In short, if your PHP is working with timestamps created in C (or vice versa) make sure you are comparing apples to apples.
zhong311 at collegeclub dot com
14-Feb-2004 07:40
When attempting to use HTTP's If-Modified-Since features for caching I ran into the problem of being able to compare the GMT date the browser was sending to my own Last-Modified date (stored in a database field). I saw many examples of how to create a GMT date from a unix timestamp, but little on how to actually get a GMT date into a unix timestamp. Perhaps someone has a better way, here's my solution:

<?php

function gmstrtotime($sgm) {
  
$months = array(
    
'Jan'=>1,
    
'Feb'=>2,
    
'Mar'=>3,
    
'Apr'=>4,
    
'May'=>5,
    
'Jun'=>6,
    
'Jul'=>7,
    
'Aug'=>8,
    
'Sep'=>9,
    
'Oct'=>10,
    
'Nov'=>11,
    
'Dec'=>12
  
);
   list(
$D, $d, $M, $Y, $H, $i, $s) = sscanf($sgm, "%3s, %2d %3s %4d %2d:%2d:%2d GMT");
   return
gmmktime($H, $i, $s, $months[$M], $d, $Y);
}

// test: after all is said and done
// $time should be the same as $gmtime

$time = time();
$us = date("m/d/Y H:i:s",$time);
$sgm = gmdate("D, d M Y H:i:s",$time) . " GMT";

$gmtime = gmstrtotime($sgm);

echo
$us . "<BR>";
echo
$sgm . "<BR>";
echo
$time . "<BR>";
echo
$gmtime . "<BR>";

?>

My results:

02/13/2004 10:45:42
Fri, 13 Feb 2004 20:45:42 GMT
1076705142
1076705142

Credit to kyle at frozenonline dot com for his strtotime example