In addition to GLEN's post on DEC 5th 2007
(Just a note for others)
The results for the three time types Glen listed under "returns" all returned the exact same timestamp
- 1196812966
Using those three functions will only make the exact same timestamp if the server the code is executed on IS in GMT timezone.
'mktime()' and 'time()' will both return the timestamp for your server time, and will both be the same as eachother.
gmmktime will return a GMT timestamp.
So if run on a server that is NOT in the GMT timezone then gmmktime will return a different timestamp to the other two.
gmmktime
(PHP 4, PHP 5)
gmmktime — Obtiene la marca de tiempo Unix para una fecha GMT
Descripción
Idéntica a mktime(), excepto que los parámetros pasados representan una fecha GMT. gmmktime() usa mktime() internamente de modo que sólo pueden usarse horas válidas en el tiempo local derivado.
Al igual que mktime(), los argumentos pueden dejarse vacíos de derecha a izquierda, en cuyo caso los argumentos omitidos serán definidos de acuerdo con el valor GMT actual.
Lista de parámetros
- hora
-
La hora
- minuto
-
El minuto
- segundo
-
El segundo
- mes
-
El mes
- dia
-
El día
- anyo
-
El año
- es_dst
-
Los parámetros siempre representan una fecha GMT así que es_dst no influencia el resultado.
Valores retornados
Devuelve una marca de tiempo Unix tipo integer.
Registro de cambios
| Versión | Descripción |
|---|---|
| 5.1.0 | A partir de PHP 5.1.0, el parámetro es_dst se ha hecho obsoleto. Como resultado, las nuevas características de manejo de zona horaria deberían usarse en su lugar. |
Ejemplos
Example #1 Límite de gmmktime() en Windows
<?php
gmmktime(0, 0, 0, 1, 1, 1970); // válido en GMT y el oeste, inválido en el este
?>
gmmktime
17-Apr-2008 11:19
05-Dec-2007 01:27
I need a multi-timezone system, and the best way is to store and do calculations on all times in GM/UTC. When outputting times, do the conversion to a local time then.
So my challenge was to figure out how to get a UTC timestamp in the first place. That's the equivalent of time() .. but returning in UTC. I innocently thought such a routine must exist in PHP to do likewise. It doesn't.
This routine just converts UTC time to local time (adds/subtracts your timezone) from the parameters you pass. Without parameters, it is the same as other routines (pretty useless then):
<?php
$mt = mktime(); // gives you local time
$gt = gmmktime(); // gives you local time
$t = time(); // gives you local time
echo "mktime = " . mktime() . "<br />";
echo "gmmktime = " . gmmktime() . "<br />";
echo "time = " . time() . "<br />";
?>
returns:
mktime = 1196812966
gmmktime = 1196812966
time = 1196812966
How do you get a UTC timestamp then ?
<?php
$utc_str = gmdate("M d Y H:i:s", time());
$utc = strtotime($utc_str);
?>
you have to get the current timestamp, convert it to a GM/UTC formatted string, then convert it back to a timestamp. You have to make sure you sure 24hr format.
Another way is to manually adjust the current time by your computer's timezone offset, but figuring out the offset isn't exactly a brain-dead operation either.
Why is this so hard?
06-Sep-2007 08:26
gmmktime() should ONLY be used to create a timestamp when specifying a specific GMT date and time.
If you want to make a valid time stamp for the current date & time, use mktime() instead.
UNIX timestamps, by definition, store the GMT time relative to the UNIX epoch.
gmmktime() (without any parameters specified) will effectively use the computer's LOCAL time values just the same as if they were explicit parameters, and the resulting time stamp will be incorrect. (The resulting timestamp will actually be offset in the OPPOSITE direction of the local timezone offset from GMT!)
15-Aug-2007 04:48
@ Robert Chapin
You have the same problem as I did, gmmktime requires the hours to be in the 24 hour format.
See my post below.
21-Jul-2007 01:24
This information is _NOT_ correct:
is_dst
Parameters always represent a GMT date so is_dst doesn't influence the result.
echo gmmktime(1,0,0,3,31,2004); // 1080694800
echo gmmktime(1,0,0,3,31,2004,false); // WRONG: 1080698400
This behaviour is tested on PHP 4.4.4-9, locale sl_SI.
08-Jul-2007 12:02
dim dot zol:
Check your clocks sir ;) time() returns the local clock under PHP 4, so the mistake is addition. If gmmktime() is adding the offset to local time then it is officially broken.
Example:
Program run at 09:52 zulu
echo date('Y-m-d H:i:s', time() - intval(date('Z'))).'<br />';
echo date('Y-m-d H:i:s', gmmktime());
echo date('Y-m-d H:i:s', time() + intval(date('Z'))).'<br />';
echo date('Y-m-d H:i:s', gmmktime());
Results:
2007-07-08 09:52:22
2007-07-07 21:52:22
2007-07-07 21:52:57
2007-07-07 21:52:57
Robert Chapin
Chapin Information Services
04-Jul-2007 05:17
Robert,
Your mismatch is due to the subtraction of date('Y'). You must do an addition instead.
<?php
echo date('Y-m-d H:i:s', time() + intval(date('Z')))."\n";
echo date('Y-m-d H:i:s', gmmktime());
?>
Returns:
2007-07-04 08:03:01
2007-07-04 08:03:01
Take a closer look at the value returned by date('Y') and you will see that anything West of the UTC is negative; hence, it should not be added, not subtracted.
03-Jul-2007 02:49
Behavior seen in PHP 4:
<?php
echo date('Y-m-d H:i:s', time() - intval(date('Z'))).'<br />';
echo date('Y-m-d H:i:s', gmmktime());
?>
Output:
2007-07-03 00:25:51
2007-07-02 12:25:51
The first result is correct. I do not yet know the cause of this problem.
13-Jun-2007 09:57
Beware that despite the documentation which states is_dst is ignored, with PHP 5.2 at least, it is not actually ignored and will cause a 1 hour offset on the UTC time returned.
This caused some interesting bugs, especially with the tzdelta function shown from previous posts below - you need to make the final parameter a 0 instead of $ar[8] otherwise you get an off-by-1-hour as a result.
As a result, I now use :
function tzdelta ( $iTime = 0 ) {
if ( 0 == $iTime ) { $iTime = time(); }
$ar = localtime ( $iTime );
$ar[5] += 1900; $ar[4]++;
$iTztime = gmmktime ( $ar[2], $ar[1], $ar[0], $ar[4], $ar[3], $ar[5], 0);
return ( $iTztime - $iTime );
}
19-Jan-2007 11:05
I was getting odd results using gmmktime...
I was converting a date/time to a timestamp to get a date/time in the future. Date/time to convert: Friday 19th of January 2007 10:06:00 PM.
<?php
gmmktime(9, 46, 0, 1 19, 2007);
?>
Returns this timestamp: 1169201160.
When formatted into a GMT date/time it comes out as Friday 19th of January 2007 10:06:00 AM. Notice it's 12 hours out from the original date/time.
I finally found the reason to be that gmmktime needs a 24 time not 12, should of noticed this since it doesn't have an am/pm input.
So the correct call would be something like...
<?php
if($date_time_ampm == "PM") $time_hours += 12;
gmmktime($time_hours, 46, 0, 1 19, 2007);
?>
21-Dec-2005 09: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.
31-Oct-2005 01: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,0, 3,$begin_date,$Y);
$end_time = gmmktime(0,0,0, 10,$end_date,$Y);
// if it's in that period
$is_dst = $time >= $begin_time && $time < $end_time;
return $is_dst;
}
?>
16-Sep-2005 02: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 ." Days ";
else
return $daysRemaining ." Day ";
}
if(empty($daysRemaining))
{
$secondsInHour= 60*60;
if ($secondsInHour <= $timeMinus)
{
$hoursRemaining =floor ($timeMinus/
$secondsInHour);
if($hoursRemaining > 1 )
return $hoursRemaining ." Hours ";
else
return $hoursRemaining ." Hour ";
}
}
if(empty($hoursRemaining))
{
//$secondsRemaining = $timeMinus. " Seconds";
$secondsInMinute = 60;
if ($secondsInMinute <= $timeMinus)
{
$mintuesRemaining =floor ($timeMinus/
$secondsInMinute);
if($mintuesRemaining > 1 )
return $mintuesRemaining ." Minutes ";
else
return $mintuesRemaining ." Minute ";
}
}
if(empty($mintuesRemaining))
{
$secondsRemaining = $timeMinus;
if($secondsRemaining < 0)
{
timedOutSale($ID,$table,$coloumnName);
return "Time out";
}
elseif($secondsRemaining > 1 )
return $secondsRemaining . " Seconds";
else
return $secondsRemaining . " Second";
}
}
function timedOutSale($ID,$table)
{
GLOBAL $configVars, $db,$tableNames;
$query = "UPDATE " . $table
. " SET status = 'T'
WHERE $coloumnName = '" . $ID ."'";
$result = $db->query($query);
return;
}
?>
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 ." Days ";
else
return $daysRemaining ." Day ";
}
if(empty($daysRemaining))
{
$secondsInHour= 60*60;
if ($secondsInHour <= $timeMinus)
{
$hoursRemaining =floor ($timeMinus/
$secondsInHour);
if($hoursRemaining > 1 )
return $hoursRemaining ." Hours ";
else
return $hoursRemaining ." Hour ";
}
}
if(empty($hoursRemaining))
{
//$secondsRemaining = $timeMinus. " Seconds";
$secondsInMinute = 60;
if ($secondsInMinute <= $timeMinus)
{
$mintuesRemaining =floor ($timeMinus/
$secondsInMinute);
if($mintuesRemaining > 1 )
return $mintuesRemaining ." Minutes ";
else
return $mintuesRemaining ." Minute ";
}
}
if(empty($mintuesRemaining))
{
$secondsRemaining = $timeMinus;
if($secondsRemaining < 0)
{
timedOutSale($ID,$table,$coloumnName);
return "Time out";
}
elseif($secondsRemaining > 1 )
return $secondsRemaining . " Seconds";
else
return $secondsRemaining . " Second";
}
}
function timedOutSale($ID,$table)
{
GLOBAL $configVars, $db,$tableNames;
$query = "UPDATE " . $table
. " SET status = 'T'
WHERE $coloumnName = '" . $ID ."'";
$result = $db->query($query);
return;
}
13-Feb-2005 07: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 );
}
?>
02-Feb-2005 09: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;
15-Jan-2005 10:16
Why not just do:
<?php
// assuming $start and $end are timestamps
$day_diff = floor(abs($start - $end) / 86400);
?>
05-Jan-2005 09: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;
}
07-Dec-2004 05: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
22-Nov-2004 06: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)
19-Oct-2004 04: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!
13-Sep-2004 12: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;
}
?>
17-Jun-2004 07: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);
?>
29-Mar-2004 07: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.
14-Feb-2004 12: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
