SunshinePHP Developer Conference 2015

mktime

(PHP 4, PHP 5)

mktimeObține timestamp-ul Unix pentru o dată și oră

Descrierea

int mktime ([ int $hour = date("H") [, int $minute = date("i") [, int $second = date("s") [, int $month = date("n") [, int $day = date("j") [, int $year = date("Y") [, int $is_dst = -1 ]]]]]]] )

Întoarce timestamp-ul Unix ce corespunde argumentelor furnizate. Acest timestamp este un integer lung conținând numărul de secunde între Epoca Unix (1 Ianuarie 1970 00:00:00 GMT) și timpul specificat.

Argumentele pot fi omise unul după altul de la dreapta spre atânga; orice argument omis va fi stabilit la valoarea curentă în corespundere cu data și ora locale.

Note

Notă:

Începând cu PHP 5.1, când este apelat fără argumente, mktime() aruncă o notificare E_STRICT: utilizați funcția time() în loc.

Parametri

hour

Numărul orei relativ cu începutul zilei determinat de month, day și year. Valorile negative se referă la ora înainte de miezul nopții a zilei în cauză. Valorile mai mari decât 23 se referă la ora corespunzătoare a zilei (zilelor) următoare.

minute

Numărul minutului relativ cu începutul orei determinat de hour. Valorile negative se referă la minutul orei precedente. Valorile mai mari decât 59 se referă la minutul corespunzător a orei (orelor) următoare.

second

Numărul de secunde relativ cu începutul minutului determinat de minute. Valorile negative se referă la secunda minutului precedent. Valorile mai mari decât 59 se referă la secunda corespunzătoare ale minutului (minutelor) următoare.

month

Numărul lunii relativ cu sfârșitul anului precedent. Valorile de la 1 până la 12 se referă la lunile normale ale anului în cauză. Valorile mai mici decât 1 (inclusiv valorile negative) se referă la lunile anului precedent în ordine inversă, deci 0 este Decembrie, -1 este Noiembrie, etc. Valorile mai mari decât 12 se referă la luna corespunzătoare a anului (anilor) următor.

day

Numărul zilei relativ cu sfârșitul lunii precedente. Valorile de la 1 până la 28, 29, 30 sau 31 (în dependență de lună) se referă la zilele normale ale lunii în cauză. Valorile mai mici decât 1 (inclusiv valorile negative) se referă la zilele lunii precedente, deci 0 este ultima zi a lunii precedente, -1 este penultima zi, etc. Valorile mai mari decât numărul de zile din luna respectivă se referă la ziua corespunzătoare din luna (lunile) următoare.

year

Numărul anului. Poate fi format din două sau din patru cifre. Valorile 0-69 corespund anilor 2000-2069, iar 70-100 corespund 1970-2000. Pe sistemele unde time_t este un întreg pe 32 biți cu semn, cum este pe majoritatea sistemelor contemporane, domeniul valid pentru year este între 1901 și 2038. Însă înainte de PHP 5.1.0 acest domeniu era limitat între 1970 și 2038 pe unele sisteme (de ex. Windows).

is_dst

Acest parametru poate fi stabilit în 1 dacă este în efect timpul de vară (daylight savings time (DST)), 0 dacă nu, sau -1 (valoarea implicită) dacă nu se cunoaște dacă este în efect timpul de vară. Dacă nu se cunoaște, PHP încearcă singur să determine acest lucru. Aceasta poate cauza rezultate neașteptate (dar nu neapărat incorecte). Unele ore nu sunt valide dacă DST este activat pe sistemul unde rulează PHP, sau dacă parametrul is_dst este stabilit în 1. Dacă DST este activat de ex. la 2:00, toate orele între 2:00 și 3:00 sunt invalide și mktime() întoarce o valoare nedefinită (de obicei negativă). Unele sisteme (de ex. Solaris 8) activează DST la miezul nopții, de aceea ora 0:30 în ziua când DST este activat este evaluată ca 23:30 a zilei precedente.

Notă:

Începând cu PHP 5.1.0, acest parametru a devenit dezaprobat. În rezultat noile facilități de gestiune a fusului orar trebuie utilizate în loc.

Valorile întoarse

mktime() întoarce timestamp-ul Unix al argumentelor furnizate. Dacă argumentele nu sunt valide, funcția întoarce FALSE (înainte de PHP 5.1 întorcea -1).

Erori/Excepții

Fiecare apel al unei funcții de dată/oră va genera o E_NOTICE dacă zona orară nu este validă și/sau un mesaj E_STRICT sau E_WARNING dacă se utilizează setările sistemului sau variabila de mediu TZ. Vedeți de asemenea date_default_timezone_set()

Istoria schimbărilor

Versiunea Descriere
5.3.0 mktime() acum emite o notificare E_DEPRECATED dacă este utilizat parametrul is_dst.
5.1.0 Parametrul is_dst a devenit dezapreciat. Funcția a fost modificată să întoarcă FALSE în caz de eroare, în loc de -1. Funcția a fost modificată să accepte anul, luna și ziua cu valorile zero.
5.1.0 Când este apelată fără argumente, mktime() aruncă o notificare E_STRICT. Utilizați funcția time() în loc.
5.1.0

Acum generează erori ale zonei orare de tip E_STRICT și E_NOTICE.

Exemple

Example #1 Exemplu simplu mktime()

<?php
// Stabilește fusul orar implicit pentru a fi utilizat. Disponibil începând cu PHP 5.1
date_default_timezone_set('UTC');

// Afișează: July 1, 2000 is on a Saturday
echo "July 1, 2000 is on a " date("l"mktime(000712000));

// Afișează ceva de felul: 2006-04-05T01:02:03+00:00
echo date('c'mktime(123452006));
?>

Example #2 Exemple mktime()

mktime() este utilă pentru a face operații aritmetice și de validare a datelor, deoarece ea va calcula automat valoarea corectă pentru vlorile introduse din afara domeniului. De exemplu, fiecare rând ce urmează produce string-ul "Jan-01-1998".

<?php
echo date("M-d-Y"mktime(00012321997));
echo 
date("M-d-Y"mktime(0001311997));
echo 
date("M-d-Y"mktime(000111998));
echo 
date("M-d-Y"mktime(0001198));
?>

Example #3 Ultima zi a lunii

Ultima zi a oricărei luni poate fi exprimată ca ziua "0" a lunii următoare, dar nu ziua -1. Ambele exemple ce urmează vor produce string-ul "Ultima zi din Februarie 2000 este: 29".

<?php
$lastday 
mktime(000302000);
echo 
strftime("Ultima zi din Februarie 2000 este: %d"$lastday);
$lastday mktime(0004, -312000);
echo 
strftime("Ultima zi din Februarie 2000 este: %d"$lastday);
?>

Note

Precauţie

Înainte de PHP 5.1.0, timestamp-urile negative nu erau susținute în unele sisteme, inclusiv nici într-o versiune cunoscută Windows. De aceea domeniul valid al anilor era limitat între 1970 și 2038.

Vedeți de asemenea

  • checkdate() - Validează o dată Gregoriană
  • gmmktime() - Obține momentul de timp Unix pentru o dată GMT
  • date() - Formatează o oră/dată
  • time() - Întoarce timpul curent Unix

add a note add a note

User Contributed Notes 21 notes

up
13
Alan
5 years ago
Do remember that, counter-intuitively enough, the arguments for month and day are inversed (or middle-endian). A common mistake for Europeans seems to be to feed the date arguments in the expected order (big endian or little endian).

It's clear to see where this weird order comes from (even with the date being big endian the order for all arguments would still be mixed - it's obviously based on the American date format with the time "prefixed" to allow an easier shorthand) and why this wasn't changed (passing the values in the wrong order produces a valid, though unexpected, result in most cases), but it continues to be a source of confusion for me whenever I come back to PHP from other languages or libraries.
up
8
joseph dot andrew dot hughes at gmail dot com
6 years ago
Just a small thing to think about if you are only trying to pull the month out using mktime and date.  Make sure you place a 1 into day field.  Otherwise you will get incorrect dates when a month is followed by a month with less days when the day of the current month is higher then the max day of the month you are trying to find.. (Such as today being Jan 30th and trying to find the month Feb.)
up
4
info at microweb dot lt
3 years ago
Function to generate array of dates between two dates (date range array)

<?php
function dates_range($date1, $date2)
{
   if (
$date1<$date2)
   {
      
$dates_range[]=$date1;
      
$date1=strtotime($date1);
      
$date2=strtotime($date2);
       while (
$date1!=$date2)
       {
          
$date1=mktime(0, 0, 0, date("m", $date1), date("d", $date1)+1, date("Y", $date1));
          
$dates_range[]=date('Y-m-d', $date1);
       }
   }
   return
$dates_range;
}

echo
'<pre>';
print_r(dates_range('2009-12-25', '2010-01-05'));
echo
'</pre>';
?>

[EDIT BY danbrown AT php DOT net: Contains a bugfix submitted by (carlosbuz2 AT gmail DOT com) on 04-MAR-2011, with the following note: The first date in array is incorrect.]
up
4
tom at chegg dot com
4 years ago
I was using the following to get a list of month names.

for ($i=1; $i<13; $i++) {
  echo date('F', mktime(0,0,0,$i) . ",";
}

Normally this outputs -
January,February,March,April,May,June,July,August,
September,October,November,December

However if today's date is the 31st you get instead:
January,March,March,May,May,July,July,August,October,
October,December,December

Why? Because Feb,Apr,June,Sept, and Nov don't have 31 days!

The fix, add the 5th parameter, don't let the day of month default to today's date:

  echo date('F', mktime(0,0,0,$i,1) . ",";
up
3
thomas_corthals at hotmail dot com
6 years ago
It seems mktime() doesn't return negative timestamps on Linux systems with a version of glibc <= 2.3.3.
up
1
Rad
6 months ago
Be careful passing zeros into mktime, in most cases a zero will count as the previous unit of time. The documentation explains this yet most of the comments here still use zeroes.

For example, if you pass the year 2013 into mktime, with zeroes for everything else, the outcome is probably not what you are looking for.

<?php
echo date('F jS, Y g:i:s a', mktime(0, 0, 0, 0, 0, 2013));
// November 30th, 2012 12:00:00 am
?>

Instead of using 0's, try 1's. This makes more sense (except for minutes/seconds). Maybe not as obvious of a purpose as zeroes to other programmers, though.

<?php
echo date('F jS, Y g:i:s a', mktime(1, 1, 1, 1, 1, 2013));
// January 1st, 2013 1:01:01 am
?>
up
2
ronnie dot kurniawan at gmail dot com
5 years ago
Add (and subtract) unixtime:

<?php
function utime_add($unixtime, $hr=0, $min=0, $sec=0, $mon=0, $day=0, $yr=0) {
 
$dt = localtime($unixtime, true);
 
$unixnewtime = mktime(
     
$dt['tm_hour']+$hr, $dt['tm_min']+$min, $dt['tm_sec']+$sec,
     
$dt['tm_mon']+1+$mon, $dt['tm_mday']+$day, $dt['tm_year']+1900+$yr);
  return
$unixnewtime;
}
?>
up
0
zfowler at unomaha dot edu
4 years ago
Proper way to convert Excel dates into PHP-friendly timestamps using mktime():

<?php
// The date 6/30/2009 is stored as 39994 in Excel
$days = 39994;

// But you must subtract 1 to get the correct timestamp
$ts = mktime(0,0,0,1,$days-1,1900);

// So, this would then match Excel's representation:
echo date("m/d/Y",$ts);
?>

Excel uses "number of days since Jan. 1, 1900" to store its dates.  It also treats 1900 as a leap year when it wasn't, thus there is an extra day which must be accounted for in PHP (and the rest of the world).  Subtracting 1 from Excel's number will fix this problem.
up
0
PHPcoder at freemail dot ig3 dot net
7 years ago
The maximum possible date accepted by mktime() and gmmktime() is dependent on the current location time zone.

For example, the 32-bit timestamp overflow occurs at 2038-01-19T03:14:08+0000Z.  But if you're in a UTC -0500 time zone (such as EST in North America), the maximum accepted time before overflow (for older PHP versions on Windows) is 2038-01-18T22:14:07-0500Z, regardless of whether you're passing it to mktime() or gmmktime().
up
0
rga at merchantpal dot com
7 years ago
You cannot simply subtract or add month VARs using mktime to obtain previous or next months as suggested in previous user comments (at least not with a DD > 28 anyway).

If the date is 03-31-2007, the following yeilds March as a previous month. Not what you wanted.

<?php
$dateMinusOneMonth
= mktime(0, 0, 0, (3-1), 312007 );
$lastmonth = date("n | F", $dateMinusOneMonth);
echo
$lastmonth;    //---> 3 | March
?>

mktime correctly gives you back the 3rd of March if you subtract 1 month from March 31 (there are only 28 days in Feb 07).

If you are just looking to do month and year arithmetic using mktime, you can use general days like 1 or 28 to do stuff like this:

<?php
$d_daysinmonth
= date('t', mktime(0,0,0,$myMonth,1,$myYear));     // how many days in month
$d_year = date('Y', mktime(0,0,0,$myMonth,1,$myYear));        // year
$d_isleapyear = date('L', mktime(0,0,0,$myMonth,1,$myYear));    // is YYYY a leapyear?

$d_firstdow = date('w', mktime(0,0,0,$myMonth,'1',$myYear));     // FIRST falls on what day of week (0-6)
$d_firstname = date('l', mktime(0,0,0,$myMonth,'1',$myYear));     // FIRST falls on what day of week Full Name

$d_month = date('n', mktime(0,0,0,$myMonth,28,$myYear));         // month of year (1-12)
$d_monthname = date('F', mktime(0,0,0,$myMonth,28,$myYear));         // Month Long name (July)
$d_month_previous = date('n', mktime(0,0,0,($myMonth-1),28,$myYear));         // PREVIOUS month of year (1-12)
$d_monthname_previous = date('F', mktime(0,0,0,($myMonth-1),28,$myYear));     // PREVIOUS Month Long name (July)
$d_month_next = date('n', mktime(0,0,0,($myMonth+1),28,$myYear));         // NEXT month of year (1-12)
$d_monthname_next = date('F', mktime(0,0,0,($myMonth+1),28,$myYear));         // NEXT Month Long name (July)
$d_year_previous = date('Y', mktime(0,0,0,$myMonth,28,($myYear-1)));        // PREVIOUS year
$d_year_next = date('Y', mktime(0,0,0,$myMonth,28,($myYear+1)));        // NEXT year

$d_weeksleft = (52 - $d_weekofyear);                     // how many weeks left in year
$d_daysinyear = $d_isleapyear ? 366 : 365;                // set correct days in year for leap years
$d_daysleft = ($d_daysinyear - $d_dayofyear);                // how many days left in year
?>
up
-1
ooogla at hotmail dot com
6 years ago
If you want to increment the day based on a variable when using a loop you can use this when you submit a form

1. Establish a start date and end date in two different variables

2. Get the number of days between a date

$ndays = (strtotime($_POST['edate']) - strtotime($_POST['sdate'])) / (60 * 60 * 24);

Then here is the string you slip in your loop

$nextday  = date('Y-m-d', mktime(0, 0, 0, date("m", strtotime($_POST['sdate']))  , date("d", strtotime($_POST['sdate']))+ $count, date("Y", strtotime($_POST['sdate']))));

$count is incremented by the loop.
up
-2
ionut dot bodea at eydos dot ro
6 years ago
Here is what I use to calculate age. It took me 30 minutes to write and it's quite accurate. What it has special is that it's calculating the number of days a year has (float number), by testing if a year is a leap one or not. This number is used to compute the age.

<?php
function get_age($date_start, $date_end) {
   
$t_lived = get_timestamp($date_end) - get_timestamp($date_start);
   
$seconds_one_year = get_days_per_year($date_start, $date_end) * 24 * 60 * 60;
   
$age = array();
   
$age['years_exact'] = $t_lived / $seconds_one_year;
   
$age['years'] = floor($t_lived / $seconds_one_year);
   
$seconds_remaining = $t_lived % $seconds_one_year;
   
$age['days'] = round($seconds_remaining / (24 * 60 * 60));
    return
$age;
}
function
get_timestamp($date) {
    list(
$y, $m, $d) = explode('-', $date);
    return
mktime(0, 0, 0, $m, $d, $y);
}
function
get_days_per_year($date_start, $date_end) {
    list(
$y1) = explode('-', $date_start);
    list(
$y2) = explode('-', $date_end);
   
$years_days = array();
    for(
$y = $y1; $y <= $y2; $y++) {
       
$years_days[] = date('L', mktime(0, 0, 0, 1, 1, $y)) ? 366 : 365;
    }
    return
round(array_sum($years_days) / count($years_days), 2);
}

$date_birth = '1979-10-12';
$date_now = date('Y-m-d');

$age = get_age($date_birth, $date_now);
echo
'<pre>';
print_r($age);
echo
'</pre>';
?>


It will display something like this:
Array
(
    [years_exact] => 28.972974329491
    [years] => 28
    [days] => 355
)
up
-2
yan
5 years ago
caculate days between two date

<?php
 
// end date is 2008 Oct. 11 00:00:00
 
$_endDate = mktime(0,0,0,11,10,2008);
 
// begin date is 2007 May 31 13:26:26
 
$_beginDate = mktime(13,26,26,05,31,2007);

 
$timestamp_diff= $_endDate-$_beginDate +1 ;
 
// how many days between those two date
 
$days_diff = $timestamp_diff/86400;

?>
up
-3
cebleo at n-trance dot net
5 years ago
to ADD or SUBSTRACT times NOTE that if you dont specify the UTC zone your result is the difference +- your server UTC delay.

if you are ina utc/GMT +1

<?php
$hours_diff
= strtotime("20:00:00")-strtotime("19:00:00");
echo 
date('h:i', $hours_diff)." Hours";
?>

it shows: 02:00 Hours

but if you use a default UTC time:

<?php
date_default_timezone_set
('UTC');
$hours_diff = strtotime("20:00:00")-strtotime("19:00:00");
echo
"<br>". date('h:i', $hours_diff);
?>

it shows: 01:00 Hours.
up
-2
info at djdb dot be
1 year ago
raw date to clean timestamp
private function dateToTimestamp($date){
        $datefrom = explode(" ", $date);
        $value = array();
        if(strpos($datefrom[0], '-')){
            //print "issplit -";
            $value = explode("-", $datefrom[0]);
        }
        if(strpos($datefrom[0], '/')){
            //print "issplit /";
            $value = explode("/", $datefrom[0]);
        }
        /*if(){
           
        }*/
        if(strlen($value[2])==4){//13/12/2012
            //int mktime([hour[minute[second[month[day[year
            return mktime(0, 0, 0,$value[1],$value[0],$value[2]);
        }else{                  //2012/12/13
            //int mktime([hour[minute[second[month[day[year
            return mktime(0, 0, 0,$value[1],$value[2],$value[0]);
        }
    }
up
-3
Stephen
7 years ago
There are several warnings here about using mktime() to determine a date difference because of daylight savings time. However, nobody seems to have mentioned the other obvious problem, which is leap years.

Leap years mean that any effort to use mktime() and time() to determine the age (positive or negative) of some timestamp in years will be flawed. There are some years that are 366 days long, therefore you cannot say that there is a set number of seconds per year.

Timestamps are good for determining *real* time, which is not the same thing as *human calendar* time. The Gregorian calendar is only an approximation of real time, which is tweaked with daylight savings time and leap years to make it conform more to humans' expectations of how time should or ought to work. Timestamps are not tweaked and therefore are the only authoritative way of recording in computers a proper order of succession of events, but they cannot be integrated with a Gregorian system unless you take both leap years and DST into account. Otherwise, you may get the wrong number of years when you are approaching a value of exactly X years.

As for PHP, you could still use timestamps as a way of determining age if you took into account not only DST but also whether or not each year is a leap year and adjusted your calculations accordingly. However, this could become messy and inefficient.

There is an alternative approach to calculating days given the day, month and year of the dates to be compared. Compare the years first, and then compare the month and day - if the month and day have already passed (or, if you like, if they match the current month and day), then add 1 to the total for the years.

This solution works because it stays within the Gregorian system and doesn't venture into the world of timestamps.

There is also the issue of leap seconds, but this will only arise if you literally need to get the *exact* age in seconds. In that case, of course, you would also need to verify that your timestamps are exactly correct and are not delayed by script processing time, plus you would need to determine whether your system conforms to UTC, etc. I expect this will hardly be an issue for anybody using PHP, however if you are interested there is an article on this issue on Wikipedia:

http://en.wikipedia.org/wiki/Leap_second
up
-4
rlz
7 years ago
Finding out the number of days in a given month and year, accounting for leap years when February has more than 28 days.

<?php
function days_in_month($year, $month) {
    return(
date( "t", mktime( 0, 0, 0, $month, 1, $year) ) );
}
?>

Hope it helps a soul out there.
up
-4
Jacob Santos
1 year ago
Please note that incrementing a date using mktime in a loop is not proper. You could do it, except that there is a far better method found in the DateTime PHP class. Look at the documentation for DateTime::modify, DateTime::add (when supported) and DateTime::sub (when supported).

Also, adding seconds to a time is, well it isn't as easy as it seems, "Hey I'll just add 3600 seconds or 86400 seconds or x seconds!". The phrase once bitten, twice shy is quite applicable with the usage of adding seconds. If you ever had to 'fix' a time by calculating midnight to add the correct number of seconds, then you are doing it wrong.

Luckily, knowing is not a requirement, because DateTime and friends exists, removing the complexity for you.

So if given a choice of

mktime($seconds, $minutes, $hours+1);

and

$datetime->modify('+1 hour');

or

$datetime->add('P1H');

I'll go with the second choice, but probably not the third, unless I was using DateInterval::createFromDateString, so that other developers knew my intent.
up
-3
delfino dot salinas at gmail dot com
7 months ago
this function returns the number of days of a provided month and year, it consider the actual rules for leap years

(if the year is multiple of 4 which is not a multiple of 100 unless multiple of thousand then is a leap)
Regards, hope this function solves any issue :)

function daysinmonth($month,$year) {
$dim = 0;
switch ($month) {
    case 1:
    case 3:
    case 5:
    case 7:
    case 8:
    case 10:
    case 12:
        $dim=31;
        break;
    case 4:
    case 6:
    case 9:
    case 11:
        $dim=30;
        break;
    case 2:
        if($year%4==0) {
            if($year%100==0) {
                if($year%1000==0) { $dim=29; } else { $dim=28; }
            } else {
                $dim=29;
            }
        } else {$dim=28;}
        break;
    }
    return($dim);
}
up
-4
mogster at redesign dot no
7 months ago
Just a simple function to return mktime from a db (mysql) datetime (Y-m-d H:i:s):

function retMktimest($dbdate) {
  return mktime(substr($dbdate, 11, 2), substr($dbdate, 14, 2), substr($dbdate, 17, 2), substr($dbdate, 5, 2), substr($dbdate, 8, 2), substr($dbdate, 0, 4));
}
up
-9
contact at phpmember dot com
4 years ago
How many days have  passed since the beginning of the year.... regardless of what year it is...

<?php
//Carlos Galindo
//phpmember.com

$days = floor((time()-mktime(null,null,null,1,0,date("Y")))/86400);
           
echo
"$days days have passed";

//Good Luck
?>
To Top