PHP
downloads | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

strftime> <microtime
Last updated: Fri, 02 May 2008

view this page in

mktime

(PHP 4, PHP 5)

mktime — Citeşte valoarea UNIX timestamp pentru o dată

Descriere

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

Atenţie: Observaţi ordinea ciudată a argumentelor, care diferă de ordinea argumentelor într-un apel normal al funcţiei UNIX mktime(); în cazul în care această ordine nu este respectată vor fi furnizate rezultate aleatoare (vezi mai jos). Acest tip de eroare este una comună.

Returează valoarea UNIX timestamp corespunzătoare argumentelor. Acest timestamp este un întreg lung (long integer) care conţine numărul de secunde între începutul Epocii UNIX (1 ianuarie 1970) şi timpul specificat.

Se poate renunţa la argumente începând de la dreapta la stânga; orice argument astfel omis va fi setat la valoarea curentă în conformitate cu data şi timpul locale.

Is_dst poate fi setat la 1 dacă timpul este în perioada în care este activă ora de iarnă, 0 în caz contrar, sau -1 (implicit) în caz că nu se ştie.

Notă: Is_dst a fost adăugat în 3.0.10.

Funcţia mktime() este folositoare pentru efectuarea de calcule şi validări ale datei, şi va produce rezultate corecte chiar în cazul unor invalide. De exemplu, fiecare dintre următoarele linii va produce şirul de caractere "Jan-01-1998".

Example #1 mktime() example

echo date ("M-d-Y", mktime (0,0,0,12,32,1997));
echo date ("M-d-Y", mktime (0,0,0,13,1,1997));
echo date ("M-d-Y", mktime (0,0,0,1,1,1998));
echo date ("M-d-Y", mktime (0,0,0,1,1,98));
Parametrul year poate fi format din două sau patru cifre, cu valori între 0-69 pentru anii 2000-2069 şi 70-99 pentru anii 1970-1999 (pentru sistemele pe care time_t este reprezentat ca un întreg cu semn pe 32 de biţi, cum sunt cele de acum, intervalul valid pentru year este undeva între 1902 şi 2037).

Ultima zi a unei luni va fi exprimată ca ziua "0" a lunii următoare nu ca ziua -1. Ambele exemple de mai jos vor produce acelaşi rezultat: şirul de caractere "The last day in Feb 2000 is: 29".

Example #2 Ultima zi din lună

$lastday = mktime (0,0,0,3,0,2000);
echo strftime ("Last day in Feb 2000 is: %d", $lastday);
     
$lastday = mktime (0,0,0,4,-31,2000);
echo strftime ("Last day in Feb 2000 is: %d", $lastday);

Datele cu anul, luna şi ziua egale cu zero sunt considerate ilegale (dealtfel vor produce rezultatul 30.11.1999, ceea ce reprezintă un comportament ciudat).

Vezi, de asemenea, date() şi time().



strftime> <microtime
Last updated: Fri, 02 May 2008
 
add a note add a note User Contributed Notes
mktime
thomas_corthals at hotmail dot com
13-May-2008 07:34
It seems mktime() doesn't return negative timestamps on Linux systems with a version of glibc <= 2.3.3.
egi at gmx dot ch
15-Apr-2008 06:18
> You said :
> mktime() seems to produce an incorrect result when you have months and dates prefixed with 0.

> eg. mktime(0, 0, 0, 04, 08, 2008);
> will produce an incorrect result where as

> mktime(0, 0, 0, 4, 8, 2008);
> produces the correct result.

This has nothing to do with mktime! It's the normal behaviour of PHP that a ANY number prefixed with '0' is treated as Octal!

Try: print 015;  // prints 13 which is the decimal representation of 018 Octal

It's not a BUG it's a FEATURE ;-)
LP
11-Apr-2008 08:59
In response to : zhenya dot t at livelynk dot com

You said :
mktime() seems to produce an incorrect result when you have months and dates prefixed with 0.

eg. mktime(0, 0, 0, 04, 08, 2008);
will produce an incorrect result where as

mktime(0, 0, 0, 4, 8, 2008);
produces the correct result.

---------------------------------------------------

Resolution:
You can simply call the function intval(<your parameter>) inside the function:
eg. mktime(0, 0, 0, intval('04'), intval('08'), 2008);
will produce a correct result
elnur dot home at gmail dot com
05-Apr-2008 09:05
Reply to post:

> Anonymous
> 04-Apr-2008 04:30
>
> While you might expect mktime() to give you the time of midnight  if the hours parameter is set to zero, it may not.  Instead it returns  noon in this example. PHP 5.2.4.

> Example:   
> $ts_now  = date('Y-m-d h:i:s'); // 2008-04-04 07:30:00
> $ts_then = date('Y-m-d h:i:s', mktime(0, 0, 0, date("m"),   date("d"),   date("Y")+1)); // 2009-04-04 12:00:00

You mistakenly used "h" which stands for hours in 12-hours format.
Use "H" instead and you'll see that the function gives you the time of midnight correctly.
Anonymous
04-Apr-2008 04:30
While you might expect mktime() to give you the time of midnight if the hours parameter is set to zero, it may not.  Instead it returns noon in this example. PHP 5.2.4.

Example:    
$ts_now  = date('Y-m-d h:i:s'); // 2008-04-04 07:30:00
$ts_then = date('Y-m-d h:i:s', mktime(0, 0, 0, date("m"),   date("d"),   date("Y")+1)); // 2009-04-04 12:00:00
Stefan Bechtold
21-Mar-2008 07:05
Another useful function that I have created years ago. Useful for all calendar applications, if you have to switch to a date given by a week number and a specific day (e.g. tuesday in week 12: mktimefromcw(2008, 12, 2)).

/**
 * @return timestamp
 * @param integer year
 * @param integer woy
 * @param integer dow
 * @desc This function retrieves the time for the given year, week of year and day of the week and returns it.
 */
function mktimefromcw($year, $woy=1, $dow=1) {
  # $year = year (four digits)
  # $woy  = week of the year (1..53)
  # $dow  = day of the week (1..7)

  $dow = ($dow) % 7;
  $woy = ($woy) - 1;

  # Get reference value (this is the first monday of the first week of the year, not easy to calculate)
  $fdoy_timestamp = mktime(0,0,0,1,1,$year);
  $fdoy = ((date("w", $fdoy_timestamp) + 6) % 7) + 1;

  if($fdoy == 1) {
    # This first day of the year is a monday
    $fcwstart = $fdoy_timestamp;
  }
  elseif($fdoy < 5) {
    # The first day if before Friday, therefor the first Monday can be found in the previos year (this is no fun, believe in it!).
    $fcwstart = strtotime("last Monday", $fdoy_timestamp);
  }
  else {
    # The first day is a friday or later, so the first days belong to calender week 53 (yes, this is possible!) of the previous year, do not count them for this year.
    $fcwstart = strtotime("next Monday", $fdoy_timestamp);
  }

  # Create timestamp
  $timestr = date("d F Y", $fcwstart)." +$woy week +$dow day";
  $time = strtotime($timestr);

  # Return timestamp
  return $time;
}
Saidur Rahman (Rana)
16-Mar-2008 11:13
Here some example i have implemented. I think it will be helpful someone

    function fullDateFormat( $value ){
        $d = explode("-", $value);
        $cdate = date ("F j, Y", mktime (0,0,0,$d[1],$d[2],$d[0]));
        echo $cdate;
    }
//-----Enter date format like mysql date (e.g. 2000-01-30)------//
fullDateFormat("2008-03-17");
//Output like: March 17, 2008

    function detailsDateFormat( $value ){
        $d = explode("-", $value);
        $cdate = date ("l F j, Y", mktime (0,0,0,$d[1],$d[2],$d[0]));
        echo $cdate;
    }
//-----Enter date format like mysql date (e.g. 2000-01-30)------//
detailsDateFormat("2008-03-17");
//Output like: Monday March 17, 2008
blackdog
05-Mar-2008 01:45
Converting date() style strings to unix epoch time was giving me an "A non well formed numeric value encountered in" error. Simply resolved with an (int) call on the string:

<?php
$ue_time
= time();
$old_date = date('Y-m-d');
$old_time = date('h:i');
$new_date = str_replace('-', ', ', $old_date);
$new_time = str_replace(':', ', ', $old_time);
$convert_date = $new_time.', '.$new_date;
$convert_date = (int)$convert_date;
$converted = mktime ($convert_date);
echo
$ue_time.' vs '.$old_date.' '.$old_time.' converted = '.$converted;
?>
JSantilln elquenovotoporfox at hotmail
20-Feb-2008 01:21
<?php
//Beware of this when comparing dates:

function daysBetween($date1, $date2)
{
   
$d1 = explode("-", $date1);
   
$d2 = explode("-", $date2);
  
   
$year1 = $d1[0];
   
$month1 = $d1[1];
   
$day1 = $d1[2];

   
$year2 $d2[0];
   
$month2 = $d2[1];
   
$day2 = $d2[2];
   
   
$deadline1 = mktime(0, 0, 0, $month1, $day1, $year1, 0);
   
$deadline2 = mktime(0, 0, 0, $month2, $day2, $year2, 0);

   
/* If you dont put 0 at last parameter both mktime calls, and
       a Daylight Saving Time is not specified,
       a float days number can be returned. Is better to pass 0
       in both mktimes and round the result: */
   
   
$res = round( ($deadline2 - $deadline1) / (60 * 60 * 24) );
    return
$res;
}
/* My Test dates: */
echo daysBetween('2008-3-5','2008-3-11');

?>
Nate from nooberouno dot com
02-Feb-2008 07:45
// How to get the UNIX Time for Sunday of any week of the year. I need it for consistant weekly features regardless of the year.

// Current Week Number
$weeknumber = date("W");
// UNIX Time for Jan 1, (current year)
$firstweek = mktime(0,0,0,1,1,date("Y"));
// UNIX Time for the start of the current week (Usually not a Sunday)
$currentweek = $firstweek+($weeknumber*604800)-604800;
// Checks what day of the week it is, then adds a day until its Sunday
$sundaycheck = date("w",$currentweek);
do{
    if($sundaycheck!=0){
        $currentweek += 86400;
        $sundaycheck = date("w",$currentweek);
    }
}while($sundaycheck!=0);
echo date("l jS F, Y @ H:i:s a", $currentweek)."<br>";

// Will display the Sunday of the current week.
admin at aflog dot org
01-Feb-2008 08:01
Heres a way to get the UNIX timestamp for the first day of this week:

<?php
$week
= mktime(0, 0, 0, date("n"), date("j"), date("Y")) - (date("N")*3600*24);

echo
date("l jS F, Y @ H:i:s a", $week);
?>

In my case this outputted:
Sunday 27th January, 2008 @ 00:00:00 am
(and today is Saturday 2nd February, 2008 @ 16:59:41 pm)

This is useful for (what i am doing which is) site stats pages. Can be used to give your mysql query a cut off date for example, for all the visitors this week, or how many posts this week or whatever it may be

xjden
joseph dot andrew dot hughes at gmail dot com
30-Jan-2008 12:58
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.)
Tiago Valdo
17-Jan-2008 10:42
Taking a sample from a fellow poster a bit up, I've made this quite simple MYSQL date to timestamp which will convert both date or date/time fields.

function MySQLtoTimestamp($mysqlDate) {
    if (strlen($mysqlDate) > 10) {
        list($year, $month, $day_time) = explode('-', $mysqlDate);
        list($day, $time) = explode(" ", $day_time);
        list($hour, $minute, $second) = explode(":", $time);
        $ts = mktime($hour, $minute, $second, $month, $day, $year);
    } else {
        list($year, $month, $day) = explode('-', $mysqlDate);
        $ts = mktime(0, 0, 0, $month, $day, $year);
    }
    return $ts;
}
hiten dot barchha at gmail dot com
27-Dec-2007 12:39
There was one requirement of finding recurring date for daily, monthly, quarterly and yearly subscription.
Following is the example to find out next recurring dates.

Logic : Code is taking care of following things.

1. Date is valid date
2. If next recurring date is not valid than it will take last date of month.
3. This code will useful to those who are interested to keep track of recurring payments on his own database
rather than payment gateway.
4. Code will allow you to find dates for daily, monthly, quarterly and yearly.

<?PHP
function getDates($bdate,$duration) {
   
$aDate = explode("-",$bdate);
   
$datetime = mktime(0, 0, 0, $aDate[1], $aDate[2], $aDate[0]);

    switch(
$duration) {
        case
0:
            for(
$i=0;$i<12;$i++) {
               
$nextmonth = date("Y-m-d",mktime(0, 0, 0, date("m",$datetime),
                            
date("d",$datetime)+1+$i,   date("Y",$datetime)));
                echo
$nextmonth."<br><br>";
            }
            break;
        case
1:
            for(
$i=0;$i<12;$i++) {
               
$tempnextmonth = ($aDate[1]+1+$i)%12;
                if(
$tempnextmonth == 0) {
                   
$tempnextmonth = 12;
                }
               
$nextyear = date("Y",mktime(0, 0, 0, date("m",$datetime)+1+$i,
                           
date("d",$datetime),   date("Y",$datetime)));
                if (
checkdate(str_pad($tempnextmonth,2,0,STR_PAD_LEFT),
                   
$aDate[2],$nextyear) == false) {
                   
                    echo
$nextyear."-".str_pad($tempnextmonth,2,0,STR_PAD_LEFT)."-".
                   
date('d', mktime(0, 0, 0, ($tempnextmonth + 1), 0, $nextyear))
                    .
"<br><br>";
                }
                else {
                    echo
$nextyear."-".str_pad($tempnextmonth,2,0,STR_PAD_LEFT)."-".
                   
$aDate[2]."<br><br>";
                }
            }
            break;   
        case
2:
            for(
$i=0;$i<12;$i++) {
               
$tempnextmonth = ($aDate[1]+4+(4*$i))%12;
                if(
$tempnextmonth == 0) {
                   
$tempnextmonth = 12;
                }
               
$nextyear = date("Y",mktime(0, 0, 0, date("m",$datetime)+4+(4*$i),
                           
date("d",$datetime),   date("Y",$datetime)));
                if (
checkdate(str_pad($tempnextmonth,2,0,STR_PAD_LEFT),
                   
$aDate[2],$nextyear) == false) {
                   
                    echo
$nextyear."-".str_pad($tempnextmonth,2,0,STR_PAD_LEFT)."-".
                        
date('d', mktime(0, 0, 0, ($tempnextmonth + 1), 0, $nextyear)).
                        
"<br><br>";
                }
                else {
                    echo
$nextyear."-".str_pad($tempnextmonth,2,0,STR_PAD_LEFT)."-".
                   
$aDate[2]."<br><br>";
                }
            }
            break;
        case
3:
            for(
$i=0;$i<12;$i++) {
               
$nextmonth = date("Y-m-d",mktime(0, 0, 0, date("m",$datetime),
                            
date("d",$datetime),   date("Y",$datetime)+1+$i));
                echo
$nextmonth."<br><br>";
            }
            break;
    }
}
?>

How to use this function?

<?PHP getDates(date("Y-m-d"),$period); ?>

You can set $period as your recurring period time.

0 - Daily Dates
1 - Monthly Dates
2 - Quarterly Dates
3 - Yearly Dates
topsys at gmail dot com
17-Nov-2007 06:54
I made this simple class to add/remove time to my subscription service. It makes it easy to make new time without having to write the whole mktime line everytime. I'm posting it here, as it might help somebody.

<?php
class mkTime {
    var
$day = 0;
    var
$month = 0;
    var
$year = 0;
    var
$hour = 0;
    var
$minute = 0;
    var
$sec = 0;
    var
$iniTime;
    var
$returnFormat = "Y-m-d H:i:s";
   
    function
addTime() {
       
$newTime = mktime(
       
date("H",$this->iniTime)+$this->hour,
       
date("i",$this->iniTime)+$this->minute,
       
date("s",$this->iniTime)+$this->sec,
       
date("m",$this->iniTime)+$this->month,
       
date("d",$this->iniTime)+$this->day,
       
date("Y",$this->iniTime)+$this->year
       
);
       
$rtnTime = date($this->returnFormat,$newTime);
        return
$rtnTime;
    }
   
    function
removeTime() {
       
$newTime = mktime(
       
date("H",$this->iniTime)-$this->hour,
       
date("i",$this->iniTime)-$this->minute,
       
date("s",$this->iniTime)-$this->sec,
       
date("m",$this->iniTime)-$this->month,
       
date("d",$this->iniTime)-$this->day,
       
date("Y",$this->iniTime)-$this->year
       
);
       
$rtnTime = date($this->returnFormat,$newTime);
        return
$rtnTime;
    }

}

$t = new mkTime; // call the class
$t->iniTime = time(); // set initial time
$t->year = 1; // add/remove a year
$newTime = $t->addTime(); // call the add time function
echo "$newTime<br/><br/>"; // write result to browser

$t = new mkTime; // call the class
$t->iniTime = time(); // set initial time
$t->year = 1; // add/remove a year
$t->returnFormat = "d/m-Y @ H:i:s"; // time return format
$newTime = $t->removeTime(); // call the remove time function
echo "$newTime<br/><br/>"; // write result to browser
?>
PHPcoder at freemail dot ig3 dot net
06-Sep-2007 10:58
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().
Jonathan Woodard
31-Aug-2007 07:31
NB: one 'gotcha' with the implementation of mktime()'s parameters:

<?php
for( $i = 1 $i <= 12 ; $i++ )
{
    echo
"Month '$i' is: " . date( "F" , mktime( 0 , 0 , 0 , $i ) ) . "\n";
}
?>
Will output:
Month '1' is: January
Month '2' is: March
Month '3' is: March
Month '4' is: May
Month '5' is: May
Month '6' is: July
Month '7' is: July
Month '8' is: August
Month '9' is: October
Month '10' is: October
Month '11' is: December
Month '12' is: December
on the 31st day of every month.

Why? Because the 5th parameter "day" defaults to "right now," which will not work reliably for days after the 28th.

To make sure this doesn't happen, specify the first day of the month:
<?php
mktime
( 0 , 0 , 0 , $i , 1 )
?>
lb at bostontech dot net
01-Aug-2007 08:46
As per derrick miller's contribution for MySQL date stamps (which equally applies to pgSQL)...  I find this processes a little faster than exploding the string:

(All done in one statement)

function unix_date($input_date)
    { // take date string such as "1985-07-25" and return the Unix timestamp
    return mktime(0, 0, 0, substr($input_date, 5, 2), substr($input_date, 8, 2), substr($input_date, 0,4));
    }
rlz
16-Jul-2007 09:52
Finding out the number of days in a given month and year, accounting for leap years when February has more than 28 days.

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

Hope it helps a soul out there.
mike at mike-griffiths dot co dot uk
11-Jul-2007 06:04
It may be useful to note that no E_WARNINGS or E_NOTICES are give if you specify a date <1901 or >2038 on systems where time_t is a 32bit signed integer.

If a date is specified outside of the allowed range you may get some unexpected results as no timestamp will be returned.
Julian
08-Apr-2007 02:29
Simple date compare:

mktime(0, 0, 0) >= mktime(0, 0, 0, $_POST['MonthVld'], $_POST['DayVld'], $_POST['YrVld'])

mktime(0, 0, 0)  creates a unix time of the current date.

mktime(0, 0, 0, $_POST['MonthVld'], $_POST['DayVld'], $_POST['YrVld']) creates a unix time of the date that your user enters.
rga at merchantpal dot com
31-Mar-2007 09:46
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
?>
m dot hoppe at hyperspeed dot de
11-Mar-2007 01:31
This function returns no negative results inside of XEN guests.
derrick dot miller dot DONTSENDMEJUNK at axis80 dot com
23-Feb-2007 11:17
Here's a handy function which will convert dates in MySQL format (yyyy-mm-dd) to a Unix timestamp.  While this can also be done within MySQL queries via the UNIX_TIMESTAMP() function, it is not always convenient to do so.

// Returns the Unix timestamp of a MySQL date (YYYY-MM-DD)
function mysqldate_to_unix_timestamp($date) {

    list($year, $month, $day) = explode('-', $date);
    return mktime(0, 0, 0, $month, $day, $year);
}
Duane
29-Jan-2007 10:35
To Stephen:

You left out one other important difference between human time and timestamps, leap seconds, these get added and removed as needed up to twice a year depending on the earths rotational speed (if the earth spins faster or slower over a period of time).
Stephen
08-Jan-2007 02:43
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.

Here is a good discussion of this issue:

http://forums.devshed.com/php-development-5/
need-to-get-the-age-between-dob-
and-today-29925.html?&highlight=age+leap

[the above link was too long; combine the three lines to get the URL]

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
jsebfranck
07-Nov-2006 04:42
There are several notes for mktime which use the number 86400 to differentiate two days. However this technique may pose a problem in case there is a day where the hour change between the two dates to compare.

Consequently, if you want the timestamp difference between the day where the hour change and the next day, it will not be equals to 86400 but either 82800 in case its the winter change of hour day or 90000 for the summer change of hour day.

For example in 2006 :

<?php
echo mktime(0,0,0,10,29,2006) - mktime(0,0,0,10,30,2006); // -90 000
?>
php at jaggard dot org dot uk
31-Oct-2006 01:28
As I see it, this function should default to zero for the first 3 arguments but one for the next two.

It makes sense to talk about the 0th hour of the day (midnight) or the 0th minute of the hour or the 0th second of the minute, but it makes no sense to talk about the 0th day of the month or the 0th month of the year.

The example of why this change should happen is below:
<select id="month" name="month">
  <?php
   
for ($i = 1; $i <= 12; $i++)
      echo
'<option value="'.$i.'">'.date('F',mktime(0,0,0,$i)).'</option>';
 
?>
</select>

Produces a list of meaningless months. To make it useful, you have to add an extra argument to mktime.
<?php
  mktime
(0,0,0,$i,1)
?>
scratch_fury at yahoo dot com
24-Aug-2006 10:07
In response to the post by "nicky" on July 9, 2006:

Just so everyone's clear, if you have a date string formatted in a standard way, you'll probably want to go ahead and use PHP's built-in strtotime() function.  The advantage to using nicky's str2time() function seems to be that you can specify how the date string you're passing in is formatted, so you can deal with non-standard date strings.
nicky
09-Jul-2006 04:08
here's a function to generate a timestamp from a certain date by using patterns:
<?php
function str2time($strStr, $strPattern = null)
{
   
// an array of the valide date characters, see: http://php.net/date#AEN21898
   
$arrCharacters = array(
       
'd', // day
       
'm', // month
       
'y', // year, 2 digits
       
'Y', // year, 4 digits
       
'H', // hours
       
'i', // minutes
       
's'  // seconds
   
);
   
// transform the characters array to a string
   
$strCharacters = implode('', $arrCharacters);

   
// splits up the pattern by the date characters to get an array of the delimiters between the date characters
   
$arrDelimiters = preg_split('~['.$strCharacters.']~', $strPattern);
   
// transform the delimiters array to a string
   
$strDelimiters = quotemeta(implode('', array_unique($arrDelimiters)));

   
// splits up the date by the delimiters to get an array of the declaration
   
$arrStr     = preg_split('~['.$strDelimiters.']~', $strStr);
   
// splits up the pattern by the delimiters to get an array of the used characters
   
$arrPattern = preg_split('~['.$strDelimiters.']~', $strPattern);

   
// if the numbers of the two array are not the same, return false, because the cannot belong together
   
if (count($arrStr) !== count($arrPattern)) {
        return
false;
    }

   
// creates a new array which has the keys from the $arrPattern array and the values from the $arrStr array
   
$arrTime = array();
    for (
$i = 0;$i < count($arrStr);$i++) {
       
$arrTime[$arrPattern[$i]] = $arrStr[$i];
    }

   
// gernerates a 4 digit year declaration of a 2 digit one by using the current year
   
if (isset($arrTime['y']) && !isset($arrTime['Y'])) {
       
$arrTime['Y'] = substr(date('Y'), 0, 2) . $arrTime['y'];
    }

   
// if a declaration is empty, it will be filled with the current date declaration
   
foreach ($arrCharacters as $strCharacter) {
        if (empty(
$arrTime[$strCharacter])) {
           
$arrTime[$strCharacter] = date($strCharacter);
        }
    }

   
// checks if the date is a valide date
   
if (!checkdate($arrTime['m'], $arrTime['d'], $arrTime['Y'])) {
        return
false;
    }

   
// generates the timestamp
   
$intTime = mktime($arrTime['H'], $arrTime['i'], $arrTime['s'], $arrTime['m'], $arrTime['d'], $arrTime['Y']);
   
// returns the timestamp
   
return $intTime;
}
// example
$time = str2time('06-07-08 07:58:02', 'd-m-y H:i:s');
var_dump($time);
var_dump(date('d.m.Y H:i:s', $time));
?>
carlo dot tafuro at poste dot it
08-May-2006 04:40
Negative timestamps give problem also using linux as guest operating system inside WMvare with Windows host operating system.
ian at opensystems dot net dot au
14-Nov-2005 12:21
A trivial way to avoid having to remember the quirky order of variables.

It's also more convenient to use because you can ignore the last three (time) variables if all you want to do is manupulate the date components.

Just include the following function at the top of your script and call ansi_mktime instead of mktime.

function ansi_mktime($y=0, $month=0, $d=0, $h=0, $min=0, $s=0){
    return mktime($h, $min, $s, $month, $d, $y);
}

// eg:
$day = 14;
echo date("dS \d\a\y of M Y", ansi_mktime(2005, 11, $day + 7))

// output: 21st day of Nov 2005
funkisyourfriend at gmail dot com
06-Aug-2005 03:25
In response to Hayden...

I hate to inform you of this after you've worked out your own function for date validation, but PHP has a function called checkdate(). It does the exact same thing as your isvaliddate() function.
Hayden
06-Jun-2005 05:33
Here is a quick way to check the a date is valid. I use this when I get users to enter dates via drop downs, which leave open the possibility for impossible dates like 30-Feb-2005 and 31-Jun-2005 etc. This is only necessary as mktime() will accept these invalid dates, which is, in my case, sometimes not the desired handling.

<?php
function isvaliddate($day, $month, $year) {
   
$day = intval($day);
   
$month = intval($month);
   
$year = intval($year);
   
$time = mktime(0,0,0,$month,$day,$year);
    if (
$day != date("j",$time)) return false;
    if (
$month != date("n",$time)) return false;
    if (
$year != date("Y",$time)) return false;
    return
true;
}
?>

Note that date("Y",$time) checks the year as a 4 digit year. That line could be replaced as shown below to allow for the 2 digit notation as well.
Also the order the arguments need to be specified is day, month, year, because I come from NZ and that is the format we use here. If you prefer another format, for example month, day, year, just change the order of the arguments on the first line.

<?php
function isvaliddate($day, $month, $year) {
   
$day = intval($day);
   
$month = intval($month);
   
$year = intval($year);
   
$time = mktime(0,0,0,$month,$day,$year);
    if (
$day != date("j",$time)) return false;
    if (
$month != date("n",$time)) return false;
    if ((
$year != date("Y",$time)) AND ($year != date("y",$time))) return false;
    return
true;
}
?>

Hope this helps someone!
Cheers,
Hayden.
caliban at darklock dot com
27-May-2005 06:40
cdblog at gmail dot com didn't clarify exactly what his function does: it returns the week number WITHIN THE CURRENT MONTH, i.e. the first day of the month is in week 1, the eighth day is in week 2, the fifteenth is in week 3, the 22nd is in week 4, and the 29th is in week 5. A useful function, if you need such things.
cdblog at gmail dot com
26-May-2005 02:06
<?php
   
/**
    * @return int
    * @desc get the week's No. by day.
    * @link http://php.clickz.cn/articles/date/getWeekNoByDay,html
    * @update at my php blog, http://php.clickz.cn/
    */
   
function getWeekNoByDay($year = 2005,$month = 5,$day = 5) {
        return
ceil(($day + date("w",mktime(0,0,0,$month,1,$year)))/7);   
    }
?>
colin dot horne at gmail dot com
30-Mar-2005 10:48
If the month is greater than 12, it goes into the next year. If it is less than 1, it goes into the previous year. Generally, it behaves as you'd expect it to :-)

Examples:

<?php

// January 1, 2005
print date ("F j, Y", mktime (0,0,0,13,1,2004));

// December 1, 2003
print date ("F j, Y", mktime (0,0,0,0,1,2004));

// February 1, 2005
print date ("F j, Y", mktime (0,0,0,14,1,2004));

// November 1, 2003
print date ("F j, Y", mktime (0,0,0,-1,1,2004));

?>
Romain Sam
25-Mar-2005 07:50
Under Windows, mktime goes until 2038-01-19 (03:14:07 ...)
andreas dot schmeiler at rtlnewmedia dot de
11-Feb-2005 04:41
if you ever wondered how to convert a windows (ASP) Timestamp to an unix Timestamp, try this:

(windowsTime to unixTime):

function wT2uT($win_timestamp) {
 
   $WIN_DATE_CONST=2209165200;
   $WIN_TIME_CONST=115740.74074074;
 
   list($win_date, $win_time)=explode(",",$win_timestamp);
 
   $win_time=substr($win_time."0000000000",0,10);
 
   $ux_date = $win_date*24*60*60;
   $ux_date-= (date("I")*60*60);
   $ux_date-= $WIN_DATE_CONST;
  
   $ux_time = round($win_time/$WIN_TIME_CONST);
  
   return($ux_date+$ux_time);
}
fontajos at phpeppershop dot com
01-Dec-2004 02:19
<?php
// Calculates UNIX timestamps from datestamps counting
// days from 01/01/0000. Used in some DataFlex databases.
// Tested only with Timestamps > 01/01/1970 and
// < 31/12/2025.
// Arguments: $days (Integer, days-from-0000,
//                   e.g. 731168 = 30/10/2001)
function date_diff_value($days) {
  
// 1/1/1970 = 719543 days counting from 01/01/0000
  
$day_1_1_1970 = 719543;
  
$diff = $days - $day_1_1_1970;
  
$unix_ts = $diff * 86400;
   return
$unix_ts;
}
?>
phpmanual at localpin dot com
02-Nov-2004 01:03
Daylight saving time!  Grrrrrrrrrr!  (And a minor "Grrr!" for PHP making this less intuitive than it should be).

In brief, NEVER add number of seconds, like 60*60*24, but use strtotime("+1 day", $myDate)).

Some of the 'simple' functions above for calculating dates will NOT work correctly when a date includes daylight saving time.  Shown below is the problem illustrated and a simple solution.

EXAMPLE 1: WRONG!
I had the following loop, which worked fine all year, until this weekend, when the clocks changed, and it broke!  The problem is daylight saving time:

// Loop through dates adding 1 days worth of seconds each time
$myDate = 1098914400  // October 28th
for ($myDate = $fromDate; $myDate <= $toDate;   $myDate = $myDate + 60 * 60 * 24) {
  $printable = strftime("%d-%m-%Y %H:%M:%S", $myDate);
  echo $printable
}

"28-10-2004 00:00:00"
"29-10-2004 00:00:00"
"30-10-2004 00:00:00"
"31-10-2004 00:00:00"
"31-10-2004 23:00:00"  (oops!  31st October repeats and time now 23:00!!)
"01-11-2004 23:00:00"
"02-11-2004 23:00:00"

EXAMPLE 2: CORRECT!
$myDate = 1098914400  // October 28th
for ($myDate = $fromDate; $myDate <= $toDate; $myDate = strtotime("+1 day", $myDate)) {
  $printable = strftime("%d-%m-%Y %H:%M:%S", $myDate);
  echo $printable
}

"28-10-2004 00:00:00"
"29-10-2004 00:00:00"
"30-10-2004 00:00:00"
"31-10-2004 00:00:00"
"01-11-2004 00:00:00"
"02-11-2004 00:00:00"
Evorg
28-Sep-2004 07:24
mktime should be used when removing cookies. Normally people tend to use: time()-3600 to set the expiration date in "the past". The problem with this is that some computers is set at a wrong date and therfore differs from the server-time. That will render the time()-3600 unusable.

Instead use mktime(12,0,0,1, 1, 1990) as you expiration criteria. I'm convinced that only a very few users has set their time back more than 1990 :)
jlim at natsoft dot com dot my
25-Jun-2004 05:36
Hi,

For those looking for a solution to the 1970-2038 limitation, the adodb time library does the trick nicely. The website has changed, to

http://phplens.com/phpeverywhere/adodb_date_library

"This library replaces native functions as follows:

   getdate()  with  adodb_getdate()
   date()    with  adodb_date()
   gmdate()  with  adodb_gmdate()
   mktime()  with  adodb_mktime()
   gmmktime() with  adodb_gmmktime()"

Download the inc file:
http://phplens.com/lens/dl/adodb-time.zip

Enjoy, John Lim
matt at killermookie dot org
22-Apr-2004 05:27
I noticed that while it is legal to do this:

$date=date("Y-m-d", mktime(0,0,0,4,20,2004);

It doesn't quite work the same when you do this:

$time=date("H:i:s", mktime(10,30,15,0,0,0);

No matter what variables you put in for time, it'll always spit out 15:59:59. You need to include the month, day and year if you want it to convert the time.

I spent nearly an hour trying to figure out what I was doing wrong til I stuck in a random date.
y4yh00 at yahoo dot com
07-Apr-2004 04:58
For those looking for a solution to the 1970-2038 limitation, the adodb time library does the trick nicely.

http://php.weblogs.com/adodb_date_time_library
"This library replaces native functions as follows:

    getdate()  with  adodb_getdate()
    date()     with  adodb_date()
    gmdate()   with  adodb_gmdate()
    mktime()   with  adodb_mktime()
    gmmktime() with  adodb_gmmktime()"

Download the inc file:
http://phplens.com/lens/dl/adodb-time.zip

Enjoy,
rob
joakim stai
28-Mar-2004 10:48
As Nigel pointed out, you should be aware of DST (Daylight Savings Time) when using mktime(). Some systems will return a negative value if you use 0 as the hour, as it will simply skip from (for example) 23:59:59 to 01:00:00. Instead use 12 (noon) as the hour and you won't get a negative timestamp or a date in the 1960's.

This code will work with DST:
$today = mktime(12, 0, 0, date("m"), date("d"), date("Y"));
pb at _remove_ pedal dot dk
28-Feb-2004 07:30
I find it easiest, if I want to find you how many days there are between two dates to use the following method:

$init_day = 1;
$init_mth = 1;
$init_yr = 2004;

$dst_day = 5;
$dst_mth = 8;
$dst_yr = 2004;

//first convert to unix timestamp
$init_date = mktime(12,0,0,$init_mth,$init_day,$init_yr);
$dst_date = mktime(12,0,0,$init_mth,$init_day,$init_yr);

$offset = $dst_date-$init_date; //Depending on which offset type you want, switch order

$days = floor($offset/60/60/24);
Nigel Gilbert
15-Feb-2004 12:15
Several posts here offer procedures to compute the number of days between two dates based on using mktime, using the given date and 00:00:00 as the time.  It turns out that this is bad choice for the default time for such calculations when the date in question happens to be the date when dayl