Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Date and Time Functions : mktime

mktime

Get Unix timestamp for a date (PHP 4, PHP 5)
int mktime ( [int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]] )

Returns the Unix timestamp corresponding to the arguments given. This timestamp is a long integer containing the number of seconds between the Unix Epoch (January 1 1970 00:00:00 GMT) and the time specified.

Arguments may be left out in order from right to left; any arguments thus omitted will be set to the current value according to the local date and time.

Parameters

hour

The number of the hour.

minute

The number of the minute.

second

The number of seconds past the minute.

month

The number of the month.

day

The number of the day.

year

The number of the year, may be a two or four digit value, with values between 0-69 mapping to 2000-2069 and 70-100 to 1970-2000. On systems where time_t is a 32bit signed integer, as most common today, the valid range for year is somewhere between 1901 and 2038. However, before PHP 5.1.0 this range was limited from 1970 to 2038 on some systems (e.g. Windows).

is_dst

This parameter can be set to 1 if the time is during daylight savings time (DST), 0 if it is not, or -1 (the default) if it is unknown whether the time is within daylight savings time or not. If it's unknown, PHP tries to figure it out itself. This can cause unexpected (but not incorrect) results. Some times are invalid if DST is enabled on the system PHP is running on or is_dst is set to 1. If DST is enabled in e.g. 2:00, all times between 2:00 and 3:00 are invalid and mktime() returns an undefined (usually negative) value. Some systems (e.g. Solaris 8) enable DST at midnight so time 0:30 of the day when DST is enabled is evaluated as 23:30 of the previous day.

Note:

As of PHP 5.1.0, this parameter became deprecated. As a result, the new timezone handling features should be used instead.

Return Values

mktime() returns the Unix timestamp of the arguments given. If the arguments are invalid, the function returns FALSE (before PHP 5.1 it returned -1).

Errors/Exceptions

Every call to a date/time function will generate a E_NOTICE if the time zone is not valid, and/or a E_STRICT message if using the system settings or the TZ environment variable. See also date_default_timezone_set()

ChangeLog

Version Description
3.0.10 Added is_dst parameter
5.1.0 The is_dst parameter became deprecated. Made the function return FALSE on error, instead of -1. Fixed the function to accept the year, month and day to be all passed as zero.
5.1.0

Now issues the E_STRICT and E_NOTICE time zone errors.

Examples

Example 458. mktime() example

mktime() is useful for doing date arithmetic and validation, as it will automatically calculate the correct value for out-of-range input. For example, each of the following lines produces the string "Jan-01-1998".

<?php
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));
?>


Example 459. Last day of next month

The last day of any given month can be expressed as the "0" day of the next month, not the -1 day. Both of the following examples will produce the string "The last day in Feb 2000 is: 29".

<?php
$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);
?>


Notes

Caution:

Before PHP 5.1.0, negative timestamps were not supported under any known version of Windows and some other systems as well. Therefore the range of valid years was limited to 1970 through 2038.

Related Examples ( Source code ) » mktime


Code Examples / Notes » mktime

venimus777

You may consider easier to calculate dates using strtotime() instead of mktime():
<?
   date('Y-m-d',strtotime('now +'.$f.' months'));
?>
will produce the date $f($f>=0) months after today.


rga

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), 31,  2007 );
$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
?>


laurie

With regard to Example 1 and using mktime to correct out-of-range input.
It should be noted that mktime will implement day light saving amends. Consider the following:
<?
print(date("d/m/Y H:i:s",mktime(0,0,0,3,(27 + 1),2004)));
?>
OUTPUT "28/03/2004 02:00:00"
<?
print(date("d/m/Y H:i:s",(mktime(0,0,0,3,27,2004) + (((1 * 24) * 60) * 60))));
?>
OUTPUT "28/03/2004 00:00:00"
Dependent on your requirements this may or may be desirable


sun4php

Very often we are faced with the problem of adjusting ourself to local time where application is running rather than running our application at server time.
Now we have a way to do that by setting TZ variable using putenv() method. But due to the non-availability of standard time zone codes, developers are often faced with the ambiguity of how to implement a non standard time zone(those which are not too popular)
I figured a way out myself for this. It uses the information that a particular time zone is n hours ahead or n hours behind standard GMT time zone.
here is what i did.
<?php
$day=15;
 $month=12;
 $year=2003;
 //convert it to unix timestamp
 
 $deadline=mktime('','','',$month,$day,$year);
//caluculate our time from GMT time
 $hour=gmdate('H');
 $min=gmdate('i');
 $sec=gmdate('s');
 $month=gmdate('n');
 $day=gmdate('d');
 $year=gmdate('Y');
 $stamp=mktime ($hour,$min,$sec,$month,$day,$year);
// technique is to convert the GMT date & time to unix stamp, then convert time zone
 //specific information like add 5 hours or subtract 5 hours to seconds,(consider day
 //light saving here), and add/subtract it to the unix time stamp and then convert
 //it back to date using date function if needed or perform operations needed on the
 // time stamp
 
 //subtract 6/n hours from GMT time (Central standard time/CST)
    //vary this part to whatever time zone you are at
 $do=6*60*60;
 $lstamp=$stamp-$do;
 echo("Today(local date/Central):".date('h:i:s d/n/Y',$lstamp)."
");
 
 $left=$deadline-$lstamp;

 $days_left=floor($left/(24 * 60 * 60));
 $hours_left=floor($left/(60 * 60 ));
 echo "
Days Left: $days_left
";
 echo "
Hours Left(approx): $hours_left
";
 ?>
Change the $do variable to whatever seconds you are different from GMT and add or subtract accordingly to generate $lstamp.
This would solve your time zone problems.
Happy Coding,
Suneel Kanuri


romain sam

Under Windows, mktime goes until 2038-01-19 (03:14:07 ...)

duane

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).


php it haveajoint dut com

To Peter W [Below] - day3-day2 IS 9000,
This is because day 2 [28th Oct] is the last day of daylight saving - the clocks go back so day 2 is 25 hours long]
that is to say that
28.10.2007 00:00:00 -> 28.10.2007 02:00:00 - 2hr
clock goes back to 1.00 am
28.10.2007 01:00:00 -> 29.10.2007 00:00:00 - 23hr
Total 25hrs


m dot hoppe

This function returns no negative results inside of XEN guests.

carloseduardopauluk

There is many solutions to get the difference between two dates by using the mktime function. But, like posted by PHPCoder, due to the 32-bits nature of timestamps values, there is no mean to use mktime to dates bigger than 2038-01-19T03:14:08+0000Z.
One other solution to get the difference between two dates is to use this function:
function date_dif($iniDate, $endDate) {
  $iniDate = explode("-",$iniDate);
  $endDate = explode("-",$endDate);
  $start_date = gregoriantojd($iniDate[1], $iniDate[2], $iniDate[0]);
  $end_date = gregoriantojd($endDate[1], $endDate[2], $endDate[0]);
  $dif = $end_date - $start_date;
  return $dif;
}
The result is given in days.


stephen

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

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
?>


phpcoder

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().


slerena

Thanks to all people that post it's code I've made two useful functions to check working days on each month, and render week times in a combo.
function working_days (){
       $date = date('Y-m-d');
       $year = substr($date, 0,4);
       $month = substr($date, 5, 2);
       $day = substr($date, 8, 2);
       $d_daysinmonth = date('t', mktime(0,0,0,$month,1,$year));  // how many days in month
       $full_weeks = ceil ($d_daysinmonth / 7);
       $festive_days = floor(($d_daysinmonth / 7) * 2);
       $total_working_days = $d_daysinmonth - $festive_days;
       $total_working_hours = $total_working_days * 8;
       return $total_working_days;
}
function working_weeks_combo () {
       $date = date('Y-m-d');
       $year = substr($date, 0,4);
       $month = substr($date, 5, 2);
       $day = substr($date, 8, 2);
       $d_daysinmonth = date('t', mktime(0,0,0,$month,1,$year));  // how many days in month
      $full_weeks = ceil ($d_daysinmonth / 7);
       $d_firstdow = date('w', mktime(0,0,0,$month,'1',$year));     // FIRST falls on what day of week (0-6)
       $ajuste = $d_firstdow -1;
       $new_date = date('Y-m-d', strtotime("$year-$month-01 - $ajuste days"));
       echo '<select name="working_week">';
       for ($ax=0; $ax < $full_weeks; $ax++){
               echo "<option>".date('Y-m-d', strtotime($new_date. "+ $ax week"));
       }
       echo "</select>";
}


hayley watson

soulreeper's code to add a fortnight to a given date can be improved:
<?php
$date = "2007-04-30";
$new_date = date('Y-m-d', strtotime($date.' +2 weeks');
?>


julian

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.


nigel gilbert

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 daylight savings time starts.  For example, on several OSs, there is no such time as 00:00:00 30-03-2003 (and mktime returns a negative value), because the clock changed from 23:59:59 29-03-2003 straight to 01:00:00 30-03-2003 as a result of Daylight Saving. At better choice is to use, for example, 12,0,0,30,3,2003 as the argument to mktime, that is, use noon, not midnight as the default time.

carlo dot tafuro

Negative timestamps give problem also using linux as guest operating system inside WMvare with Windows host operating system.

jonathan woodard

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 )
?>


webmaste

My little code for make a code to get the difference between dates
<?
$data1 = mktime (0,0,0,5,5,2005); //specify a date1
$data2 = mktime (0,0,0,5,15,2005); //specify a date2
$differenza = ($data2 - $data1 ) / 86400;
echo " The Different $data2 - data1 = $differenza";
?>


evorg

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 :)


mike

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.


iain

In the above example it should ne boted that if you try to calculate the command at midnight on the 28/04/2004 you will get an erroneous response. This has been driving me to distraction.
$myTime = mktime( 0, 0, 0, 3, 28, 2004);
Solution I found was to create the time at 3am well after the 2am daylight savings problem, viz:
$myTime = mktime( 3, 0, 0, 3, 28, 2004);
Not sure if this is documented anywhere.


scratch_fury

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.


luke

In response to phpprince at phpprince dot com:
The same thing can be done with
<?php
echo date('Y-m-d H:i:s', strtotime('+7 days'));
?>


kepex

In response to Jonathan Woodard,
Is better to explicit all the parameters, because in your example, you are asuming the "right now"-year, and that could affect in a leap year...


funkisyourfriend

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.


andreas dot schmeiler

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);
}


colin dot horne

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));
?>


trahma

I think it is important to note that the timestamp returned is based upon the number of seconds from the epoch GMT, and then modified by the time zone settings on the server.
Thus...
mktime(0,0,0,1,1,1970) will not always return 0.  For example with the US eastern time zone (GMT-5) will return 18000 (5 hours past the epoch) and the same function with the time zone set to the US pacific time zone (GMT-8) will return 28800 (8 hours past the epoch).
In an instance where you want time zone independence, you should use the function gmmktime()


manhon824

I read the above note and think up a simple way(just 10 lines) to find time difference in days, hrs, mins, secs!
In my way, we do not need to fix the format of time!
$starttime=time();
// the start time can change to =strtotime($endtime);
$endtime=strtotime($endtime);
//$endtime can be any format as well as it can be converted to secs
$timediff = $endtime-$starttime;
  $days=intval($timediff/86400);
  $remain=$timediff%86400;
  $hours=intval($remain/3600);
  $remain=$remain%3600;
  $mins=intval($remain/60);
  $secs=$remain%60;
//this code is copied from the other note!thx to that guy!
$timediff=$days.'days'.$hours.'hr'.$mins.'min'.$secs.'s';
Hope that it is usefull!


matt

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.


larry

I needed a script to display a dropdown menu with a list of week ending dates. I wrote this as a result. I hope it helps somebody. The selname variable is the name of the select field and the day of week of the begining date designates the end of the week.
<?php
$selname="we_date";
//Build Begin date
$month=10;
$day=04;
$year=2003;
$hour=date('H');
$min=date('i');
$sec=date('s');
//convert it to unix timestamp
$bdate=mktime($hour,$min,$sec,$month,$day,$year);
//Build Today    
$thour=date('H');
$tmin=date('i');
$tsec=date('s');
$tmonth=date('n');
$tday=date('d');
$tyear=date('Y');
//convert it to unix timestamp
$today=mktime($thour,$tmin,$tsec,$tmonth,$tday,$tyear);
   
//just the weeks
$nbdate=floor($bdate/(7 * 24 * 60 * 60));
$ntoday=floor($today/(7 * 24 * 60 * 60));
//difference between today and the beginning date
$diff=$today-$bdate;
echo "<select size='1' name='$selname'>\n";
while ($bdate <= $today+(7 * 24 * 60 * 60)){
echo ("<option value='".date('n/d/Y',$bdate)."'>
".date('n/d/Y',$bdate)."</option>\n");
$bdate=$bdate+(7 * 24 * 60 * 60);
}
echo "</select>";
?>


dasprid

I have to correct, what Evorg (28-Sep-2004 04:24) wrote. If you want to delete a cookie, simply take the value 0 (zero) as timestamp. It's the same as the timestamp, which Evorg's example generates.

pb

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);


jlim

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


derrick dot miller dot dontsendmejunk

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);
}


nicky

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));
?>


hayden

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.


peter w

Hello, im found some strange behaviour. Someone knows whats is going on or it is a bug?:
lets do like this:
three dates in timestamp:
27.10.2007: 1193436000
28.10.2007: 1193522400
29.10.2007: 1193612400
convert back:
1193436000: 27.10.2007 00:00:00
1193522400: 28.10.2007 00:00:00
1193612400: 29.10.2007 00:00:00
And one day is always 24 hours * 60 minutes * 60 secondes = 86400. So the difference between these three dates in timestamp should also be the same.But:
day2-day1 = 86400
day3-day2 = 90000
Here is my code, im using PHP Version 5.1.6:
echo ' three dates in timestamp:
';
$day1 = mktime(0, 0, 0, 10, 27, 2007);
$day2 = mktime(0, 0, 0, 10, 28, 2007);
$day3 = mktime(0, 0, 0, 10, 29, 2007);

echo '27.10.2007: '.$day1.'
';
echo '28.10.2007: '.$day2.'
';
echo '29.10.2007: '.$day3.'
';

echo 'convert back:
';
echo $day1.': '.date('d.m.Y H:i:s',$day1).'
';
echo $day2.': '.date('d.m.Y H:i:s',$day2).'
';
echo $day3.': '.date('d.m.Y H:i:s',$day3).'
';

echo 'And one day is always 24 hours * 60 minutes * 60 secondes = 86400. So the difference between these three dates in timestamp should also be the same.But:
';

echo 'day2-day1 = '.($day2-$day1).'
';
echo 'day3-day2 = '.($day3-$day2).'
';


kontakt

function uniks_date($data) {
$part = explode( '-', $data );
$dzien = $part[count($part)-1];
$mc = $part[count($part)-2];
$rok = $part[count($part)-3];
$data1 = mktime(0, 0, 0, $mc, $dzien, $rok);
return $data1;
}
Easy way to covert date from YYYY-MM-DD (hidden in $data) to UNIKS type.


y4yh00

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


rlz

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.


phpmanual

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"


praas

Consider skipping months with mktime().
$nextmonth = date("M",mktime(0,0,0,date("n")+1,date("j"),date("Y")));
On any day in Januari you expect to get Feb, right?
But on January 30th you'll get Mar. It will try Feb 30th, which doesn't exist, and skips another month. Therefore in this case present a day value that will certainly be legal in any month, like day "1".
This will give you next month on any day of the year:
$nextmonth = date("M",mktime(0,0,0,date("n")+1,1,date("Y")));


caliban

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.

dave j.

bichinhoverde's my_gmmktime function uses an incomplete definition of leap year.  It's not leap year if the year is divisible by 100 and NOT divisible by 400. E.G. 2000 was a leap year, but 2100 will not be. Trivial, but it should be said.
Thus,
  if ( $i % 4 == 0 ) {
    $output += 24*60*60;
  }
should be:
  if ( (($i % 4 == 0) && ($i % 100 != 0))
      || ($i % 400 == 0) ) {
    $output += 24*60*60;
  }


lb

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));
}


joakim stai

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"));


php

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)
?>


ian

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


alex

A simple statement to calculate days between two dates
$dayselepsed = round((strtotime($dateone) - strtotime($datetwo))/(60*60*24)-1);
Regards Alex Curvers


radu

A more complete MySQL to Unix timestamp function:
function mysql_to_ts($mysql_time) {
 if (!preg_match('/^(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})$/', $mysql_time, $matches)) {
   return NULL;
 }
 return mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
}


php

a conversion from the ISO date format 'yyyy-mm-dd' can simply be done by
<?php
$timestamp = strtotime('2007-03-29');
$timestamp = strtotime('2007-03-29 11:27:33');
?>


jakethecake

@ Peter W (16-Aug-2007 12:08)
The reason the difference between 28th & 29th Oct is 3600 seconds more than 27th & 28th is because the clocks go back on the 28th October 2007, hence the extra hour...
I was just caught out with the same thing :)


alexixalex

// a simple way to calculate the age of someone
function age($format,$birthday,$today)
 {
   $birthday_ex = explode("$format",$birthday);
   $actdate_ex = explode("$format",$today);
   $tempage = ($actdate_ex[2] - $birthday_ex[2]);
   $birth = mktime(0,0,0,$actdate_ex[0],$actdate_ex[1]);
   $now = mktime(0,0,0,$birthday_ex[0],$birthday_ex[1]);
   if ( $now < $birth)
     {
       $age = $tempage ;
       echo $age;
     }
   else
     {
       $age = $tempage - 1 ;
       echo $age;
     }
 }


seoulreeper

<?php
//the date of the variable holding the original date value
$date = "2007-04-30";
//format the date for mktime() function -- you need day, month, year
$year = substr($date, 0,4);
$month = substr($date, 5, 2);
$day = substr($date, 8, 2);
//check the results
echo $year;
echo "
";
echo $month;
echo "
";
echo $day;
//the variable to hold the new date plus 14 days
$new_date = date("Y-m-d", mktime(0, 0, 0, $month, $day +14, $year));
//check the results of new date
echo "
";
echo $new_date;
?>


fontajos

<?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;
}
?>


cdblog

<?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);
   }
?>


Change Language


Follow Navioo On Twitter
checkdate
date_create
date_date_set
date_default_timezone_get
date_default_timezone_set
date_format
date_isodate_set
date_modify
date_offset_get
date_parse
date_sun_info
date_sunrise
date_sunset
date_time_set
date_timezone_get
date_timezone_set
date
getdate
gettimeofday
gmdate
gmmktime
gmstrftime
idate
localtime
microtime
mktime
strftime
strptime
strtotime
time
timezone_abbreviations_list
timezone_identifiers_list
timezone_name_from_abbr
timezone_name_get
timezone_offset_get
timezone_open
timezone_transitions_get
eXTReMe Tracker