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

search for in the

checkdate> <cyrus_unbind
Last updated: Sat, 24 Mar 2007

view this page in

XXII. Funkce pro datum a čas

Úvod

Tyto funkce vám umožňují získat datum a čas ze serveru, na kterém běží PHP skripty. Lze je použít k formátování zápisu času a data mnoha různými způsoby.

Poznámka: Uvědomte si prosím, že tyto funkce závisí na národním nastavení vašeho serveru. Zvláštní pozornost věnujte letnímu času a přestupným rokům!

Požadavky

Tyto funkce jsou k dispozici jako součást standardního modulu, který je vždy dostupný.

Instalace

K používání těchto funkcí není třeba žádná instalace, jsou součástí jádra PHP.

Konfigurace běhu

Toto rozšíření nemá definováno žádné konfigurační direktivy.

Typy prostředků

Toto rozšíření nemá definován žádný typ prostředku (resource).

Předdefinované konstanty

Toto rozšíření nemá definovány žádné konstanty.

Obsah

checkdate — Zkontroluje gregoriánské datum
date_create — Returns new DateTime object
date_date_set — Sets the date
date_default_timezone_get — Gets the default timezone used by all date/time functions in a script
date_default_timezone_set — Sets the default timezone used by all date/time functions in a script
date_format — Returns date formatted according to given format
date_isodate_set — Sets the ISO date
date_modify — Alters the timestamp
date_offset_get — Returns the daylight saving time offset
date_parse — Returns associative array with detailed info about given date
date_sun_info — Returns an array with information about sunset/sunrise and twilight begin/end
date_sunrise — Returns time of sunrise for a given day and location
date_sunset — Returns time of sunset for a given day and location
date_time_set — Sets the time
date_timezone_get — Return time zone relative to given DateTime
date_timezone_set — Sets the time zone for the DateTime object
date — Formátuje místní datum/čas
getdate — Vrací informaci o datu/čase
gettimeofday — Vrací aktuální čas
gmdate — Formátuje datum/čas GMT/UTC
gmmktime — Vrací UNIXové časové razítko pro datum/čas v GMT
gmstrftime — Formátuje datum/čas v GMT/UTC vzhledem k národnímu nastavení
idate — Format a local time/date as integer
localtime — Vrací místní čas
microtime — Vrací aktuální UNIXové časové razítko s mikrosekundami
mktime — Vrací UNIXové časové razítko pro datum/čas
strftime — Formátuje místní čas/datum s ohledem na nastavení národních specifik
strptime — Parse a time/date generated with strftime()
strtotime — Parse about any English textual datetime description into a Unix timestamp
time — Return current Unix timestamp
timezone_abbreviations_list — Returns associative array containing dst, offset and the timezone name
timezone_identifiers_list — Returns numerically index array with all timezone identifiers
timezone_name_from_abbr — Returns the timezone name from abbrevation
timezone_name_get — Returns the name of the timezone
timezone_offset_get — Returns the timezone offset from GMT
timezone_open — Returns new DateTimeZone object
timezone_transitions_get — Returns all transitions for the timezone


checkdate> <cyrus_unbind
Last updated: Sat, 24 Mar 2007
 
add a note add a note User Contributed Notes
Funkce pro datum a čas
Robb_Bean at gmx dot nospam dot net
19-Mar-2008 12:47
With PHP 5.1 and 5.2 the languages datetime support has changed. Although these functions should guess your local timezone settings, they may fail if using a default configuration in a "pre-5.1 way", which means setting no timezone for PHP. In the case PHP could not get a timezone it emits a E_STRICT warning. Note that this affects _all_ datetime functions and keep it in mind when porting software from previous versions to 5.1 or later! It may also confuse your error handling (this is the way I noticed that things have changed, since these changes are not documentated _here_).

References:

http://www.php.net/manual/de/migration51.datetime.php
http://www.php.net/manual/de/migration52.datetime.php
sagar
28-Feb-2008 05:53
####################################
Provide week number and get start_timestamp and end_timestamp
#####################################

// this week number will come from the timeshare form
 $week = 51;

$times = get_start_and_end_date_from_week($week);
$start_time = $times['start_timestamp'];
$end_time = $times['end_timestamp'];

function get_start_and_end_date_from_week ($w)
{
    $y = date("Y", time());
    $o = 6; // week starts from sunday by default

    $days = ($w - 1) * 7 + $o;

    $firstdayofyear = getdate(mktime(0,0,0,1,1,$y));
    if ($firstdayofyear["wday"] == 0) $firstdayofyear["wday"] += 7;
    # in getdate, Sunday is 0 instead of 7
    $firstmonday = getdate(mktime(0,0,0,1,1-$firstdayofyear["wday"]+1,$y));
    $calcdate = getdate(mktime(0,0,0,$firstmonday["mon"], $firstmonday["mday"]+$days,$firstmonday["year"]));

    $sday = $calcdate["mday"];
    $smonth = $calcdate["mon"];
    $syear = $calcdate["year"];
   
       
    $timestamp['start_timestamp'] =  mktime(0, 0, 0, $smonth, $sday, $syear);
    $timestamp['end_timestamp'] =  $timestamp['start_timestamp'] + (60*60*24*7);

    return $timestamp;

}    # function datefromweek
nate at example dot com
05-Feb-2008 01:56
Here's my version of date diff that handles leap years, DST, and deals with the diff in terms of "human calculations". For example, this code does not assume that a year = 365.25 days, or that a month = 30/31 days. The results are exactly what a human being would determine as a good result.

<?

/**
 * this code assumes php >= 5.1.0. if using < 5.1, read
 * php.net/strtotime and change the condition for checking
 * for failure from strtotime()
 */

// $t1, $t2: unix times, or strtotime parseable
// $precision: max number of units to output
// $abbr: if true, use "hr" instead of "hour", etc.
function date_diff ($t1, $t2, $precision = 6, $abbr = false) {
    if (
preg_match('/\D/', $t1) && ($t1 = strtotime($t1)) === false)
        return
false;

    if (
preg_match('/\D/', $t2) && ($t2 = strtotime($t2)) === false)
        return
false;

    if (
$t1 > $t2)
        list(
$t1, $t2) = array($t2, $t1);

   
$diffs = array(
       
'year' => 0, 'month' => 0, 'day' => 0,
       
'hour' => 0, 'minute' => 0, 'second' => 0,
    );

   
$abbrs = array(
       
'year' => 'yr', 'month' => 'mth', 'day' => 'day',
       
'hour' => 'hr', 'minute' => 'min', 'second' => 'sec'
   
);

    foreach (
array_keys($diffs) as $interval) {
        while (
$t2 >= ($t3 = strtotime("+1 ${interval}", $t1))) {
           
$t1 = $t3;
            ++
$diffs[$interval];
        }
    }

   
$stack = array();
    foreach (
$diffs as $interval => $num)
       
$stack[] = array($num, ($abbr ? $abbrs[$interval] : $interval) . ($num != 1 ? 's' : ''));

   
$ret = array();
    while (
count($ret) < $precision && ($item = array_shift($stack)) !== null) {
        if (
$item[0] > 0)
           
$ret[] = "{$item[0]} {$item[1]}";
    }

    return
implode(', ', $ret);
}

$t1 = 'Feb 4, 2008 12:16:00';
$t2 = 'Jul 3, 2006 16:15:30';

echo
date_diff($t1, $t2), "\n",
   
date_diff($t1, $t2, 3), "\n",
   
date_diff($t1, $t2, 2, true), "\n";

?>
Dave Laurier
11-Jan-2008 09:20
Hi baroto,

You are right, I see what you mean. I do not know how to explain what I was expecting but I figure the results do make sense. I am sorry for any confusion that I may have caused.

Actually, I can give it a try. What I expected is that all of the ..._total variables would return the total amounts so (months = 12 * years + number of single months) and the variables like years, months and days would return the amounts of full years, full months and full days (within this month not taking into account any days between last months date and this date). But looking at the code that expectation does not make sense and indeed the code and the results are fine.

Thanks and once more stoicnluv thanks for your code!

Dave
baroto at gmail dot com
08-Jan-2008 06:32
to Dave Laurier:

Isn't the difference between 2006-10-28 and 2007-12-01 is 1 year 1 month and 3 days rather than 1 year 2 months and 1 day?
Dave Laurier
06-Jan-2008 03:42
I really like the date_diff function from stoicnluv because of its capabilities to handle leap years and daylight saving time but I found out is is not working correctly when there is more than 1 year and 2 months between the two dates. For example:

d1 = 2006-10-28
d2 = 2007-11-30

The result for months and days is correct (one year, one month and two days):

Array
(
    [years] => 1
    [months] => 1
    [days] => 2
    [hours] => 1
    [minutes] => 0
    [seconds] => 0
    [months_total] => 12
    [days_total] => 398
    [hours_total] => 9553
    [minutes_total] => 573180
    [seconds_total] => 34390800
)

However when using a date which is +1 year +2 months:

d1 = 2006-10-28
d2 = 2007-12-01

The result is incorrect (expected: one year, two months and 1 day, returns one year, one month and 3 days):

Array
(
    [years] => 1
    [months] => 1
    [days] => 3
    [hours] => 1
    [minutes] => 0
    [seconds] => 0
    [months_total] => 12
    [days_total] => 399
    [hours_total] => 9577
    [minutes_total] => 574620
    [seconds_total] => 34477200
)
stoicnluv at gmail dot com
06-Nov-2007 12:14
A better and accurate function to calculate the difference between 2 dates. Takes leap years and DST into consideration. Accepts string date or timestamp as arguments.

<?php
function date_diff($d1, $d2){
   
$d1 = (is_string($d1) ? strtotime($d1) : $d1);
   
$d2 = (is_string($d2) ? strtotime($d2) : $d2);

   
$diff_secs = abs($d1 - $d2);
   
$base_year = min(date("Y", $d1), date("Y", $d2));

   
$diff = mktime(0, 0, $diff_secs, 1, 1, $base_year);
    return array(
       
"years" => date("Y", $diff) - $base_year,
       
"months_total" => (date("Y", $diff) - $base_year) * 12 + date("n", $diff) - 1,
       
"months" => date("n", $diff) - 1,
       
"days_total" => floor($diff_secs / (3600 * 24)),
       
"days" => date("j", $diff) - 1,
       
"hours_total" => floor($diff_secs / 3600),
       
"hours" => date("G", $diff),
       
"minutes_total" => floor($diff_secs / 60),
       
"minutes" => (int) date("i", $diff),
       
"seconds_total" => $diff_secs,
       
"seconds" => (int) date("s", $diff)
    );
}

$a = date_diff("2006-11-01", "2007-11-01");

echo
"<pre>";
print_r($a);
echo
"</pre>";
?>

This example will output (if your timezone uses US DST):

Array
(
    [years] => 0
    [months_total] => 11
    [months] => 11
    [days_total] => 364
    [days] => 30
    [hours_total] => 8759
    [hours] => 23
    [minutes_total] => 525540
    [minutes] => 0
    [seconds_total] => 31532400
    [seconds] => 0
)

As you can see, the result is not exactly 1 year (less 1 hour) since Nov 1, 2006 is not DST while Nov 1, 2007 is DST.
venoel at rin dot ru
26-Oct-2007 12:33
May be useful for somebody. This function takes on daylight saving time

Function DateDiff($date1,$date2) {
  $timedifference=$date2-$date1;
  $corr=date("I",$date2)-date("I",$date1);
  $timedifference+=$corr;
  return $timedifference;
}

Example:

$d1=mktime(2,0,0,10,28,2007);
$d2=mktime(4,0,0,10,28,2007);
$period=DateDiff($d1,$d2);
printf("<br>%s",date("I d.m.Y H:i",$d1));
printf("<br>%u hour",$period/3600);
printf("<br>%s",date("I d.m.Y H:i",$d2));

Getting 2 hour instead 3.
koch.ro
17-Oct-2007 09:42
Not really elegant, but tells you, if your installed timezonedb is the most recent:

class TestDateTimeTimezonedbVersion extends PHPUnit_Framework_TestCase
{
    public function testTimezonedbIsMostRecent()
    {
        ini_set( 'date.timezone', 'Europe/Berlin' );
        ob_start();                                                                                                       
        phpinfo(INFO_MODULES);
        $info = ob_get_contents();                                                                                        
        ob_end_clean();
        $start = strpos( $info, 'Timezone Database Version' ) + 29;

        $this->assertTrue( FALSE !== $start, 'Seems there is no timezone DB installed' );

        $end   = strpos( $info, "\n", $start );
        $installedVersion = substr( $info, $start, $end - $start );

        exec( 'pecl remote-info timezonedb', &$output );
        $availableVersion = substr( $output[2], 12 );

        $this->assertEquals( $availableVersion, $installedVersion,
        'The installed timezonedb is not actual. Installed: '.$installedVersion
        .' available: '.$availableVersion
        );
    }
}
herbert DOT fischer ATT gEE mail DOT com
11-Oct-2007 10:44
Updating internal's PHP timezone database (5.1.x and 5.2.x)

http://fischer.tecnologia.ws/en/node/1

[editor: Although this does work, it's often easier just to install the pecl timezonedb extension - they should be up-to-date with the latest possible information]
aquatakat at telus dot net
24-Sep-2007 10:25
I wrote a simple script to format a duration in seconds. Give the function some value in seconds and it will return an array.

<?php

function format_duration($seconds) {

   
$periods = array(
       
'centuries' => 3155692600,
       
'decades' => 315569260,
       
'years' => 31556926,
       
'months' => 2629743,
       
'weeks' => 604800,
       
'days' => 86400,
       
'hours' => 3600,
       
'minutes' => 60,
       
'seconds' => 1
   
);

   
$durations = array();

    foreach (
$periods as $period => $seconds_in_period) {
        if (
$seconds >= $seconds_in_period) {
           
$durations[$period] = floor($seconds / $seconds_in_period);
           
$seconds -= $durations[$period] * $seconds_in_period;
        }
    }
   
    return
$durations;

}

echo
format_duration(864);

/*
[minutes] => 14
[seconds] => 24
*/

echo format_duration(3600);

/*
[hours] => 1
*/

echo format_duration(11111111);

/*
[months] => 4
[days] => 6
[hours] => 20
[minutes] => 28
[seconds] => 59
*/

?>
Darren Edwards
06-Sep-2007 05:54
I was looking for a solution where I could return the number of days, hours, Minutes and seconds between two entries in a table.
DATE_DIFF is not running on my mysql server as my provider uses mysql version 4.0.25
Solution was to use to days and std time functions to calculate the difference in one call.
The fields stored in the table(report_table) are
time(00:00:00),
date(0000-00-00) and record(enum) which tells the app the type of log stored. EG start or end of a report.

SELECT
(TO_DAYS( `end`.`date` ) - TO_DAYS( `start`.`date` ))
-
( second( `end`.`time` ) + (minute( `end`.`time` )*60) + (hour( `end`.`time` )*3600)
<
 second( `start`.`time` ) + (minute( `start`.`time` )*60) + (hour( `start`.`time` )*3600))
AS `days` ,
SEC_TO_TIME(
(second( `end`.`time` ) + (minute( `end`.`time` )*60) + (hour( `end`.`time` )*3600) )
-
(second( `start`.`time` ) + (minute( `start`.`time` )*60) + (hour( `start`.`time` )*3600) )
 ) AS `hms`,
`start`.`time` as `start`,
`end`.`time`  as `end`

FROM `report_table` AS `start` , `report_table` AS `end`
AND `start`.`record` = 'Report Begin'
AND `end`.`record` = 'Report End'
LIMIT 1

If there is no end of report then it will not return a result, as you would expect.
Leopoldo A dot Oducado (poducado at comfsm dot fm)
16-Feb-2007 04:50
Here is my function to count the number days, weeks, months, and year. I tried it below 1970 and it works.

<?php
function datecal($date,$return_value)
{
$date = explode("/", $date);
$month_begin = $date[0];
$month_begin_date = $date[1];
$year1 = $date[2];
$month_end = date("n");
$month_end_date = date("j");
$year2 = date("Y");
$days_old = 0;
$years_old = 0;
$months_old = 0;
if(
$month_begin==12)
{
 
$month = 1;
 
$year = $year1+1;
}
else
{
 
$month = $month_begin+1;
 
$year = $year1;
}
$begin_plus_days = cal_days_in_month(CAL_GREGORIAN, $month_begin, $year1) - $month_begin_date;
$end_minus_days = cal_days_in_month(CAL_GREGORIAN, $month_end, $year2) - $month_end_date;
while (
$year <= $year2)
{   
     if(
$year == $year2)
    {
     
$days_old = $days_old + cal_days_in_month(CAL_GREGORIAN, $month, $year);    
      if(
$month < $month_end)
        {
        
$months_old = $months_old + 1;   
        
$month = $month + 1;
        }
          elseif (
$month==$month_end and $month_end_date >= $month_begin_date)
            {
        
$year = $year2+1;   
        }
      else
        {   
        
$year = $year2+1;   
        }
    }
    else
    {
    
$days_old = $days_old + cal_days_in_month(CAL_GREGORIAN, $month, $year);
         if (
$month <= 11)
            {
        
$month = $month + 1;
        
$months_old = $months_old + 1;   
            }
         else
            {
        
$month = 1;
        
$year = $year + 1;
        
$months_old = $months_old + 1;       
            }    
    }
}
$days_old = ($days_old + $begin_plus_days) - $end_minus_days;
if(
$return_value == "d")
  { return
$days_old; }
elseif (
$return_value == "w")
  { return
intval($days_old/7); }
elseif (
$return_value == "m")
  { return
$months_old; }
elseif (
$return_value == "y")
  { return
intval($months_old/12); }
}

echo
datecal("08/13/1975","m");
?>
bgold at matrix-consultants dot com
17-Jan-2007 02:08
When debugging code that stores date/time values in a database, you may find yourself wanting to know the date/time that corresponds to a given unix timestamp, or the timestamp for a given date & time.

The following script will do the conversion either way.  If you give it a numeric timestamp, it will display the corresponding date and time.  If you give it a date and time (in almost any standard format), it will display the timestamp.

All conversions are done for your locale/time zone.

<?
       
while (true)
        {
               
// Read a line from standard in.
               
echo "enter time to convert: ";
               
$inline = fgets(STDIN);
               
$inline = trim($inline);
                if (
$inline == "" || $inline == ".")
                        break;

               
// See if the line is a date.
               
$pos = strpos($inline, "/");
                if (
$pos === false) {
                       
// not a date, should be an integer.
                       
$date = date("m/d/Y G:i:s", $inline);
                        echo
"int2date: $inline -> $date\n";
                } else {
                       
$itime = strtotime($inline);
                        echo
"date2int: $inline -> $itime\n";
                }
        }
?>
slash at mauricien dot org
22-Dec-2006 10:06
The post below has been edited saying there is a bug line 12 and 13 and proposition a solution. I think there was no
bug in the original post.

 menaurus at gmx dot de
16-Jul-2003 01:37
The argument has to be in the standard mysql format (y-m-d)...

function age($date) {

if (!$date) return false;
$year=0+substr($date,0,4);
$month=0+substr($date,5,2);
$day=0+substr($date,8,2);
$t=0;
$d=date("d");
$m=date("m");
$y=date("Y");
$age=$y-$year;

if ($m<$month) $t=-1;
else if ($m==$month) if ($d<$day) $t=-1;

return ($age+$t);
}

this funktion has got a little bug:
On Line 12 and 13...
Bugfix:
12 if ($month<$m) $t=-1;
13 else if ($m==$month AND $day<$d) $t=-1;
mikeb at tracersinfo dot com
06-Nov-2006 08:27
Another month late on this, but I would amend alex's post to recommend using gmdate() any time you're trying to represent a "delta time", or your local timezone is likely to interfere.

For example, a five minute difference (300 seconds) would appear as follows in New York:

echo date('z:H:i:s', 300);
// 364:19:05:00

echo gmdate('z:H:i:s', 300);
// 0:00:05:00

Thanks for the 'z', though, Alex.  Up until now, I've always been dividing that out -- hadn't found it in the format list.  :-)
alex dot stevenson at t8design dot com
12-Sep-2006 06:50
A few months late on this, but I just saw cepercival at thatMailThatsHot dot com 's post, and think that it may be a bit easier to just use this as opposed to writing it by hand:

date("z:H:i:s", $endTimestamp - $startTimestamp);

Since the timestamps store seconds from the unix epoch, and the unix epoch occured at the very beginning of a year, you can get away with this.

It gets a little trickier to place the years, but it should work fine if you subtract out the number of years date("Y", 0) returns.  This would naturally require two seperate calls to the date function- one to find the year, and one to find the rest of the information.
cepercival at thatMailThatsHot dot com
11-Jul-2006 02:31
Hopefully this may be useful to someone out there!
I wanted a simple function to give me a duration for phone calls using a start timestamp and end timestamp. After finding an understandable example here http://www.brenlei.com/articles/php/dates/dates4.php i cobbled this together:

function callDuration($dateTimeBegin,$dateTimeEnd) {
      
      $dif=$dateTimeEnd - $dateTimeBegin;

      $hours = floor($dif / 3600);
      $temp_remainder = $dif - ($hours * 3600);
       
      $minutes = floor($temp_remainder / 60);
      $temp_remainder = $temp_remainder - ($minutes * 60);
       
      $seconds = $temp_remainder;
         
      // leading zero's - not bothered about hours
      $min_lead=':';
     if($minutes <=9)
        $min_lead .= '0';
      $sec_lead=':';
     if($seconds <=9)
        $sec_lead .= '0';
       
  // difference/duration returned as Hours:Mins:Secs e.g. 01:29:32

  return $hours.$min_lead.$minutes.$sec_lead.$seconds;
       
       }

obviously it can be easily extended to include days, weeks etc.
Stupidly simple I know but that's how i like it.
andreencinas at yahoo dot com dot br
28-Sep-2005 02:08
//function like dateDiff Microsoft
       //not error in year Bissesto

       function dateDiff($interval,$dateTimeBegin,$dateTimeEnd) {
         //Parse about any English textual datetime
         //$dateTimeBegin, $dateTimeEnd

         $dateTimeBegin=strtotime($dateTimeBegin);
         if($dateTimeBegin === -1) {
           return("..begin date Invalid");
         }

         $dateTimeEnd=strtotime($dateTimeEnd);
         if($dateTimeEnd === -1) {
           return("..end date Invalid");
         }

         $dif=$dateTimeEnd - $dateTimeBegin;

         switch($interval) {
           case "s"://seconds
               return($dif);

           case "n"://minutes
               return(floor($dif/60)); //60s=1m

           case "h"://hours
               return(floor($dif/3600)); //3600s=1h

           case "d"://days
               return(floor($dif/86400)); //86400s=1d

           case "ww"://Week
               return(floor($dif/604800)); //604800s=1week=1semana

           case "m": //similar result "m" dateDiff Microsoft
               $monthBegin=(date("Y",$dateTimeBegin)*12)+
                 date("n",$dateTimeBegin);
               $monthEnd=(date("Y",$dateTimeEnd)*12)+
                 date("n",$dateTimeEnd);
               $monthDiff=$monthEnd-$monthBegin;
               return($monthDiff);

           case "yyyy": //similar result "yyyy" dateDiff Microsoft
               return(date("Y",$dateTimeEnd) - date("Y",$dateTimeBegin));

           default:
               return(floor($dif/86400)); //86400s=1d
         }

       }
glashio at xs4all dot nl
27-Sep-2005 09:46
Calculate Sum BusinessDays (Mon till Fri) between two date's :

<?php
function businessdays($begin, $end) {
   
$rbegin = is_string($begin) ? strtotime(strval($begin)) : $begin;
   
$rend = is_string($end) ? strtotime(strval($end)) : $end;
    if (
$rbegin < 0 || $rend < 0)
        return
0;

   
$begin = workday($rbegin, TRUE);
   
$end = workday($rend, FALSE);

    if (
$end < $begin) {
       
$end = $begin;
       
$begin = $end;
    }

   
$difftime = $end - $begin;
   
$diffdays = floor($difftime / (24 * 60 * 60)) + 1;

    if (
$diffdays < 7) {
       
$abegin = getdate($rbegin);
       
$aend = getdate($rend);
        if (
$diffdays == 1 && ($astart['wday'] == 0 || $astart['wday'] == 6) && ($aend['wday'] == 0 || $aend['wday'] == 6))
            return
0;
       
$abegin = getdate($begin);
       
$aend = getdate($end);
       
$weekends = ($aend['wday'] < $abegin['wday']) ? 1 : 0;
    } else
       
$weekends = floor($diffdays / 7);
    return
$diffdays - ($weekends * 2);
}

function
workday($date, $begindate = TRUE) {
   
$adate = getdate($date);
   
$day = 24 * 60 * 60;
    if (
$adate['wday'] == 0) // Sunday
       
$date += $begindate ? $day : -($day * 2);
    elseif (
$adate['wday'] == 6) // Saterday
       
$date += $begindate ? $day * 2 : -$day;
    return
$date;
}
?>
daniel at globalnetstudios dot com
08-Jun-2005 08:49
This dateDiff() function can take in just about any timestamp, including UNIX timestamps and anything that is accepted by strtotime(). It returns an array with the ability to split the result a couple different ways. I built this function to suffice any datediff needs I had. Hope it helps others too.

<?php
 
/********* dateDiff() function **********
   * returns Array of Int values for difference between two dates
   * $date1 > $date2 --> positive integers are returned
   * $date1 < $date2 --> negative integers are returned
   *
   * $split recognizes the following:
   *   'yw' = splits up years, weeks and days (default)
   *   'y'  = splits up years and days
   *   'w'  = splits up weeks and days
   *   'd'  = total days
   *
   * examples:
   *   $dif1 = dateDiff() or dateDiff('yw')
   *   $dif2 = dateDiff('y')
   *   $dif3 = dateDiff('w')
   *   $dif4 = dateDiff('d')
   *
   * assuming dateDiff returned 853 days, the above
   * examples would have a print_r output of:
   *   $dif1 == Array( [y] => 2 [w] => 17 [d] => 4 )
   *   $dif2 == Array( [y] => 2 [d] => 123 )
   *   $dif3 == Array( [w] => 121 [d] => 6 )
   *   $dif4 == Array( [d] => 847 )
   *
   * note: [h] (hours), [m] (minutes), [s] (seconds) are always returned as elements of the Array
   */
 
function dateDiff($dt1, $dt2, $split='yw') {
   
$date1 = (strtotime($dt1) != -1) ? strtotime($dt1) : $dt1;
   
$date2 = (strtotime($dt2) != -1) ? strtotime($dt2) : $dt2;
   
$dtDiff = $date1 - $date2;
   
$totalDays = intval($dtDiff/(24*60*60));
   
$totalSecs = $dtDiff-($totalDays*24*60*60);
   
$dif['h'] = $h = intval($totalSecs/(60*60));
   
$dif['m'] = $m = intval(($totalSecs-($h*60*60))/60);
   
$dif['s'] = $totalSecs-($h*60*60)-($m*60);
   
// set up array as necessary
   
switch($split) {
    case
'yw': # split years-weeks-days
     
$dif['y'] = $y = intval($totalDays/365);
     
$dif['w'] = $w = intval(($totalDays-($y*365))/7);
     
$dif['d'] = $totalDays-($y*365)-($w*7);
      break;
    case
'y': # split years-days
     
$dif['y'] = $y = intval($totalDays/365);
     
$dif['d'] = $totalDays-($y*365);
      break;
    case
'w': # split weeks-days
     
$dif['w'] = $w = intval($totalDays/7);
     
$dif['d'] = $totalDays-($w*7);
      break;
    case
'd': # don't split -- total days
     
$dif['d'] = $totalDays;
      break;
    default:
      die(
"Error in dateDiff(). Unrecognized \$split parameter. Valid values are 'yw', 'y', 'w', 'd'. Default is 'yw'.");
    }
    return
$dif;
  }
?>
mail at completeideas dot com
06-Jun-2005 10:55
For those who are using pre MYSQL 4.1.1, you can use:

TO_DAYS([Date Value 1])-TO_DAYS([Date Value 2])

For the same result as:

DATEDIFF([Date Value 1],[Date Value 2])
mincklerstraat at softhome dot net
11-Oct-2004 10:43
Before you get too advanced using date functions, be sure also to see the calendar functions at http://www.php.net/manual/en/ref.calendar.php .
nickaubert at america's biggest isp dot com
12-Apr-2004 10:13
I ran into an issue using a function that loops through an array of dates where the keys to the array are the Unix timestamp for midnight for each date.  The loop starts at the first timestamp, then incremented by adding 86400 seconds (ie. 60 x 60 x 24).  However, Daylight Saving Time threw off the accuracy of this loop, since certain days have a duration other than 86400 seconds.  I worked around it by adding a couple of lines to force the timestamp to midnight at each interval.

<?php
  $ONE_DAY
= 90000;   // can't use 86400 because some days have one hour more or less
 
for ( $each_timestamp = $start_time ; $each_timestamp <= $end_time ; $each_timestamp +=  $ONE_DAY) {

   
/*  force midnight to compensate for daylight saving time  */
   
$this_timestamp_array = getdate( $each_timestamp );
   
$each_timestamp = mktime ( 0 , 0 , 0 , $this_timestamp_array[mon] , $this_timestamp_array[mday] , $this_timestamp_array[year] );

    
// do some stuff...
 
}
?>
scott_webster_2000 at yahoo dot com
20-Feb-2004 07:02
Here is a slight improvement over wwb_99@yahoo's entry.  (It works now.)

function date_diff($earlierDate, $laterDate) {
  //returns an array of numeric values representing days, hours, minutes & seconds respectively
  $ret=array('days'=>0,'hours'=>0,'minutes'=>0,'seconds'=>0);

  $totalsec = $laterDate - $earlierDate;
  if ($totalsec >= 86400) {
    $ret['days'] = floor($totalsec/86400);
    $totalsec = $totalsec % 86400;
  }
  if ($totalsec >= 3600) {
    $ret['hours'] = floor($totalsec/3600);
    $totalsec = $totalsec % 3600;
  }
  if ($totalsec >= 60) {
    $ret['minutes'] = floor($totalsec/60);
  }
  $ret['seconds'] = $totalsec % 60;
  return $ret;
}
php at sarge dot ch
28-Jan-2004 01:58
Additional thisone here (didn't test it yet but should work :D):

<?php
/**
 * Calculates the Difference between two timestamps
 *
 * @param integer $start_timestamp
 * @param integer $end_timestamp
 * @param integer $unit (default 0)
 * @return string
 * @access public
 */
function dateDifference($start_timestamp,$end_timestamp,$unit= 0){
 
$days_seconds_star= (23 * 56 * 60) + 4.091; // Star Day
 
$days_seconds_sun= 24 * 60 * 60; // Sun Day
 
$difference_seconds= $end_timestamp - $start_timestamp;
  switch(
$unit){
    case
3: // Days
     
$difference_days= round(($difference_seconds / $days_seconds_sun),2);
      return
'approx. '.$difference_hours.' Days';
    case
2: // Hours
     
$difference_hours= round(($difference_seconds / 3600),2);
      return
'approx. '.$difference_hours.' Hours';
    break;
    case
1: // Minutes
     
$difference_minutes= round(($difference_seconds / 60),2);
      return
'approx. '.$difference_minutes.' Minutes';
    break;
    default:
// Seconds
     
if($difference_seconds > 1){
        return
$difference_seconds.' Seconds';
      }
      else{
        return
$difference_seconds.' Second';
      }
  }
}
?>
php at elmegil dot net
20-Dec-2003 07:40
A much easier way to do days diff is to use Julian Days from the Calendar functions:

$start = gregoriantojd($smon, $sday, $syear);
$end = gregoriantojd($emon, $eday, $eyear);
$daysdiff = $end - $start;

You can see the obvious ways to wrap a function around that.
garyc at earthling dot net
19-Mar-2003 05:08
I needed to calculate the week number from a given date and vice versa, where the week starts with a Monday and the first week of a year may begin the year before, if the year begins in the middle of the week (Tue-Sun). This is the way weekly magazines calculate their issue numbers.

Here are two functions that do exactly that:

Hope somebody finds this useful.

Gary

/*  w e e k n u m b e r  -------------------------------------- //
weeknumber returns a week number from a given date (>1970, <2030)
Wed, 2003-01-01 is in week 1
Mon, 2003-01-06 is in week 2
Wed, 2003-12-31 is in week 53, next years first week
Be careful, there are years with 53 weeks.
// ------------------------------------------------------------ */

function weeknumber ($y, $m, $d) {
    $wn = strftime("%W",mktime(0,0,0,$m,$d,$y));
    $wn += 0; # wn might be a string value
    $firstdayofyear = getdate(mktime(0,0,0,1,1,$y));
    if ($firstdayofyear["wday"] != 1)    # if 1/1 is not a Monday, add 1
        $wn += 1;
    return ($wn);
}    # function weeknumber

/*  d a t e f r o m w e e k  ---------------------------------- //
From a weeknumber, calculates the corresponding date
Input: Year, weeknumber and day offset
Output: Exact date in an associative (named) array
2003, 12, 0: 2003-03-17 (a Monday)
1995,  53, 2: 1995-12-xx
...
// ------------------------------------------------------------ */

function datefromweek ($y, $w, $o) {

    $days = ($w - 1) * 7 + $o;

    $firstdayofyear = getdate(mktime(0,0,0,1,1,$y));
    if ($firstdayofyear["wday"] == 0) $firstdayofyear["wday"] += 7;
# in getdate, Sunday is 0 instead of 7
    $firstmonday = getdate(mktime(0,0,0,1,1-$firstdayofyear["wday"]+1,$y));
    $calcdate = getdate(mktime(0,0,0,$firstmonday["mon"], $firstmonday["mday"]+$days,$firstmonday["year"]));

    $date["year"] = $calcdate["year"];
    $date["month"] = $calcdate["mon"];
    $date["day"] = $calcdate["mday"];

    return ($date);

}    # function datefromweek
jlim at natsoft dot com dot my
26-Jan-2003 10:28
For a date() function that supports dates outside the range 1901 and 2038 (by using floats when needed) see adodb_date( ) in

http://php.weblogs.com/adodb_date_time_library
brighn (a) yahoo (.) com
03-Jan-2003 06:46
I needed a function that determined the last Sunday of the month. Since it's made for the website's "next meeting" announcement, it goes based on the system clock; also, if today is between Sunday and the end of the month, it figures out the last Sunday of *next* month. lastsunday() takes no arguments and returns the date as a string in the form "January 26, 2003". I could probably have streamlined this quite a bit, but at least it's transparent code. =)

  /* The two functions calculate when the next meeting will
     be, based on the assumption that the meeting will be on
     the last Sunday of the month. */ 

  function getlast($mon, $year) {
    $daysinmonth = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    $days = $daysinmonth[$mon-1];
    if ($mon == 2 && ($year % 4) == 0 && (($year % 100) != 0 ||
    ($year % 400) == 0)) $days++;
    if ($mon == 2 && ($year % 4) == 0 && ($year % 1000) != 0) $days++;
    $lastday = getdate(mktime(0,0,0,$mon,$days,$year));
    $wday = $lastday['wday'];
    return getdate(mktime(0,0,0,$mon,$days-$wday,$year));
  }

  function lastsunday() {
    $today = getdate();
    $mon = $today['mon'];
    $year = $today['year'];
    $mday = $today['mday'];
    $lastsun = getlast($mon, $year);
    $sunday = $lastsun['mday'];
    if ($sunday < $mday) {
      $mon++;
      if ($mon = 13) {
        $mon = 1;
        $year++;
      }
      $lastsun = getlast($mon, $year);
      $sunday = $lastsun['mday'];
    }
    $nextmeeting = getdate(mktime(0,0,0,$mon,$sunday,$year));
    $month = $nextmeeting['month'];
    $mday = $nextmeeting['mday'];
    $year = $nextmeeting['year'];
    return "$month $mday, $year";
  }
nightowl at NOS-PA-M dot uk2 dot net
30-Jul-2002 07:59
I wanted to find all records in my database which match the current week (for a call-back function). I made up this function to find the start and end of the current week :

function week($curtime) {
   
    $date_array = getdate (time());
    $numdays = $date_array["wday"];
   
    $startdate = date("Y-m-d", time() - ($numdays * 24*60*60));
    $enddate = date("Y-m-d", time() + ((7 - $numdays) * 24*60*60));

    $week['start'] = $startdate;
    $week['end'] = $enddate;
   
    return $week;
   
}
mwedgwood at ILUVSPAMhotmail dot com
31-Mar-2002 11:24
In vincentv's examples, you should use gmmktime instead of mktime for portability across time zones. For example:

function DateSub($timestamp, $unit, $amount) {
// Possible $units are: "hr", "min", "sec",
//          "mon", "day", or "yr"
// $amount should be an integer
    $delta_vars = array("hr"=>0, "min"=>0,
    "sec"=>0, "mon"=>1,
    "day"=>1,"yr"=>1970);
    $delta_vars[$unit] += $amount;
    $delta = gmmktime($delta_vars["hr"],
    $delta_vars["min"],
    $delta_vars["sec"],
    $delta_vars["mon"],
    $delta_vars["day"],
    $delta_vars["yr"]);
    return $timestamp - $delta;
}
php-contrib at i-ps dot nospam dot net
30-Jan-2002 03:07
Someone may find this info of some use:

Rules for calculating a leap year:

1) If the year divides by 4, it is a leap year (1988, 1992, 1996 are leap years)
2) Unless it divides by 100, in which case it isn't (1900 divides by 4, but was not a leap year)
3) Unless it divides by 400, in which case it is actually a leap year afterall (So 2000 was a leap year).

In practical terms, to work out the number of days in X years, multiply X by 365.2425, rounding DOWN to the last whole number, should give you the number of days.

The result will never be more than one whole day inaccurate, as opposed to multiplying by 365, which, over more years, will create a larger and larger deficit.
th at definitynet dot com
11-Jan-2001 08:00
I had some problems with dates between mySQL and PHP.  PHP had all these great date functions but I wanted to store a usable value in my database tables. In this case I was using TIMESTAMP(14)  <or 'YYYYMMDDHHMMSS'>.
This is perhaps the easiest way I have found to pull the PHP usable UNIX Datestamp from my mySQL datestamp stored in the tables:

Use the mySQL UNIX_TIMESTAMP() function in your SQL definition string. i.e.

$sql= "SELECT field1, field2, UNIX_TIMESTAMP(field3) as your_date
          FROM your_table
          WHERE field1 = '$value'";

The query will return a temp table with coulms "field1" "Field2" "your_date"

The "your_date" will be formatted in a UNIX TIMESTAMP!  Now you can use the PHP date() function to spew out nice date formats.

Sample using above $sql:
20010111002747  = Date Stored on mySQL table (TIMESTAMP(14))
979172867  = value returned as your_date in sql stmt (UNIX_TIMESTAMP)

if we use $newdate = date("F jS, Y -- g:ia", $row["your_date"]);
   --(after fetching our array from the sql results of course)--

echo "$newdate";              --Will produce:
January 11th, 2001 -- 12:27am

Hope this helps someone out there!
joey dot garcia at usa dot net
13-Nov-2000 09:13
I was trying to make a Month-At-A-Glance and I finally got it to work so I thought I'd share it too.  What you need to get this to work is the "Day Of The Week Number", i.e., Sunday=1 and the "Number Of Days in the Month".  I also used Allan Kent's Date/Time Column at PHPBuilder to get the required information.  I also added the process I used to the requried information.

Enjoy!

<html>
<head>
    <title>Month-At-A-Glance</title>
</head>
<body>
<?php
// *** These are here if you need to calculate the required values ***
// *** Reference Allan Kent's Column on Dates at PHPBuilder.com
//$thismonth =  mktime($hours, $minutes,$seconds ,$month, $day,$year);
//$firstday =  mktime($hours, $minutes,$seconds ,$month, 1,$year);
//$dayofweek=date("D",$thismonth);
//$firstdayofmonth=date("D",$firstday);
//$weekdaynum=array("Sun"=>1, "Mon"=>2, "Tue"=>3, "Wed"=>4, "Thu"=>5, "Fri"=>6, "Sat"=>7);
//$dayNumber=$weekdaynum[$dayofweek];

print "<table width=80% align=center border=1>\n";
print
"<tr><th>Sun(1)</th> <th>Mon(2)</th> <th>Tue(3)</th> <th>Wed(4)</th> <th>Thu(5)</th> <th>Fri(6)</th> <th>Sat(7)</th> </tr>";
$daysinmonth=31;//For July 2000 this is 31 days
$daycount=1;
$firstdayofmonth=7;//For July 2000 this is Sat, or day 7
for ($week=1; $week <= 6; $week++){
print
"<tr>\n";
   for(
$day=1; $day <=7; $day++){
        if( (
$day >= $firstdayofmonth) || ($week >1) ){
            print
"<td height=40px>";
                if (
$daycount <= $daysinmonth){
                    print
$daycount;
                   
$daycount++;
                }
            print
"&nbsp;</td>\n";
        }
        else{
            print
"<td height=40px> &nbsp; </td>\n";
        }
    }
print
"\n</tr>\n";
}
print
"</table>";
?>
</body>
</html>
teddk at box100 dot com
08-Sep-2000 12:02
There is an an excellent article by Allan Kent on PHP date/time. The full article can be found at:
http://www.phpbuilder.net/columns/akent20000610.php3

checkdate> <cyrus_unbind
Last updated: Sat, 24 Mar 2007
 
 
show source | credits | sitemap | contact | advertising | mirror sites