|
|
XXII. Функции для работы с датой и временем
Эти функции позволяют получить дату и время на сервере,
где выполняется PHP скрипт.
Используя эти функции, дату и время можно представить в различных
форматах.
Замечание:
Обратите внимание, что работа этих функций зависит от текущей локали
на сервере. Также следует принимать во внимание летнее время
и високосные годы.
Эти функции всегда доступны. Для использования этих функций не требуется проведение установки,
поскольку они являются частью ядра PHP. Данное расширение не определяет никакие директивы конфигурации в php.ini. Данное расширение не определяет никакие типы ресурсов. Данное расширение не определяет никакие константы.
add a note
User Contributed Notes
Функции для работы с датой и временем
venoel at rin dot ru
26-Oct-2007 03:51
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*3600;
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 hours instead 3.
venoel at rin dot ru
26-Oct-2007 03:35
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.
venoel at rin dot ru
26-Oct-2007 03: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.
venoel at rin dot ru
26-Oct-2007 03:28
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 12: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 01: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 01: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);
echo format_duration(3600);
echo format_duration(11111111);
?>
Darren Edwards
06-Sep-2007 08: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.
carsten dot klein at abstraxion dot org
23-Aug-2007 02:15
Regarding the routine below that should have correctly calculated the duration between two dates:
The author of the below posting should have tested the code better, erm...
The code partly works, but: it does blatantly fail in a very few specific scenarios, therefore I'd like to have the below posting and this one removed. The below since it is actually unusable (I will post the corrected version as soon as I have it up and running) since it will calculate wrong values in cases where the month February is involved.
In that case, either the years are calculated incorrectly or there is a difference in the calculated months a/o days.
Please remove, thanks and sorry for the inconvenience. I will repost the corrected version asap.
Regards
Carsten
carsten dot klein at abstraxion dot org
22-Aug-2007 03:02
This will calculate the duration between two arbitrary dates that are valid within the given unix timestamp range. It also takes care of leap years, that is, if the minimum date is a leap year and the beginning month is February it will take into account the leap days, if any.
The below routine assumes that you a DateTime object that supports the following methods:
getYear(), getMonth(), getDayOfMonth(), getHourOfDay(), getMinuteOfHour(), and getSecondOfMinute()
Adapt as you wish.
---8<--- snip --->8---
$min = DateTime::fromString( "1980-02-01 01:01:00" );
$max = DateTime::fromString( "2004-01-02 14:10:00" );
echo "min: " . $min . "<br>";
echo "max: " . $max . "<br>";
$rtmcorr = 0; // TM correction
$rthcorr = 0; // TH correction
$rdcorr = 0; // D correction
$rmcorr = 0; // M correction
$rycorr = 0; // Y correction
$my = $max->getYear();
$mm = $max->getMonth();
$md = $max->getDayOfMonth();
$mth = $max->getHourOfDay();
$mtm = $max->getMinuteOfHour();
$mts = $max->getSecondOfMinute();
$ny = $min->getYear();
$nm = $min->getMonth();
$nd = $min->getDayOfMonth();
$nth = $min->getHourOfDay();
$ntm = $min->getMinuteOfHour();
$nts = $min->getSecondOfMinute();
$ry = 0;
$rm = 0;
$rd = 0;
$rth = 0;
$rtm = 0;
$rts = 0;
// rts
if ( $my == $ny && $mm == $nm && $md == $nd && $mth == $nth && $mtm == $ntm )
{
$rts = $mts - $nts;
}
else
{
$rts = 60 - ( $nts == 0 ? 60 : $nts ) + $mts;
$rtmcorr = $rts == 0 ? 0 : ( $rts > 60 ? 1 : -1 );
$rts = $rts % 60;
}
echo "rts: " . $rts . "<br>";
echo "rtmcorr: " . $rtmcorr . "<br>";
// rtm
if ( $my == $ny && $mm == $nm && $md == $nd && $mth == $nth )
{
$rtm = $mtm - $ntm + $rtmcorr;
}
else
{
$rtm = 60 - ( $ntm == 0 ? 60 : $ntm ) + $mtm;
$rtmcorr = $rtm == 0 ? 0 : ( $rtm > 60 ? 1 : -1 );
$rtm = $rtm % 60;
}
echo "rtm: " . $rtm . "<br>";
echo "rthcorr: " . $rthcorr . "<br>";
// rth
if ( $my == $ny && $mm == $nm && $md == $nd )
{
$rth = $mth - $nth + $rthcorr;
}
else
{
$rth = 24 - ( $nth == 0 ? 24 : $nth ) + ( $md - $nd ) * 24 + $mth + $rthcorr;
$rdcorr = $rth == 0 || $rth > 24 ? 0 : -1; //( $rth > 24 ? 0 : -1 );
$rth = $rth % 24;
}
echo "rth: " . $rth . "<br>";
echo "rdcorr: " . $rdcorr . "<br>";
$isLeapYear = ( $ny % 4 == 0 || $ny % 100 == 0 ) && ! ( $ny % 400 == 0 );
$daysInMonthCorrection = $nm == 2 ? ( $isLeapYear ? -1 : -2 ) : ( $nm == 8 ? 1 : ( $nm % 2 == 0 ? 0 : 1 ) );
$daysInMonth = 30 + $daysInMonthCorrection;
echo "daysInMonth: " . $daysInMonth . "<br>";
echo "daysInMonthCorrection: " . $daysInMonthCorrection . "<br>";
$doff = 0;
$mcorr = 0;
if ( $my == $ny && $mm == $nm )
{
$rd = $md - $nd + $rdcorr;
}
else
{
$rd = $daysInMonth - ( $nd == 1 ? $daysInMonth + 1 : $nd ) + $md + $rdcorr;
$rmcorr = $rd == 0 ? 0 : ( $rd > $daysInMonth ? 1 : -1 );
$rd = $rd % $daysInMonth;
}
echo "rd: " . $rd . "<br>";
echo "rmcorr: " . $rmcorr . "<br>";
$moff = 0;
$ycorr = 0;
if ( $my == $ny )
{
$rm = $mm - $nm + $mcorr;
}
else
{
$rm = 12 - ( $nm == 1 ? 13 : $nm ) + $mm + $mcorr;
$rycorr = $rm == 0 ? 0 : ( $rm > 12 ? 1 : -1 );
$rm = $rm % 12;
}
echo "rm: " . $rm . "<br>";
echo "rycorr: " . $rycorr . "<br>";
$ry = $my - $ny + $rycorr;
echo "ry: " . $ry . "<br><br>";
echo "result: $ry-$rm-$rd $rth:$rtm:$rts";
This will yield:
min: 01.02.1980 01:01:00
max: 02.01.2004 14:10:00
rts: 0
rtmcorr: 0
rtm: 9
rthcorr: 0
rth: 13
rdcorr: 0
daysInMonth: 29
daysInMonthCorrection: -1
rd: 1
rmcorr: -1
rm: 11
rycorr: -1
ry: 23
result: 23-11-1 13:9:0
Hope this helps.
If there are any bugs, please feel free to contact me and we will surely get it straight the next time ;-)
chad 0x40 herballure 0x2e com
24-May-2007 11:50
A number of functions, all of which use the OO interface to the new DateTime classes, are documented as having been available since PHP 5.1. This is not entirely true; although they exist in the PHP 5.1 sources, they're protected by '#ifdef EXPERIMENTAL_DATE_SUPPORT' blocks. Therefore, they aren't really available in those releases without extreme measures.
The new datetime support did not officially arrive until the 5.2 series.
wes9999 at myfastmail dot com
18-Apr-2007 08:33
Regarding the dateDiff function submitted by andreencinas at yahoo dot com dot br:
http://us3.php.net/manual/en/ref.datetime.php#57251
A daylight savings time problem was discovered when doing the datediff (in days) on 4/1/2005 and 5/1/2005, for example.
I expected to get 30 days, but instead I got 29 days. This was due to the fact that dateDiff uses strtotime on each of these dates, then subtracts them, then divides by 86400 to get days. The resulting difference is 29.958333333333, and then the function takes the floor of this number, producing 29.
The reason for this is that an hour of time is lost during the switch to DST.
A quick solution is to replace floor() with round(), but I'm open to other solutions.
gnrfan at gnrfan dot org
04-Apr-2007 08:44
function date_diff_as_text($ts1, $ts2) {
/*
$ts1 = "2007-01-05 10:30:45";
$ts2 = "2007-01-06 10:31:46";
echo date_diff_as_text($ts1, $ts2);
*/
$ts1 = strtotime($ts1);
$ts2 = strtotime($ts2);
$diff = abs($ts1-$ts2);
$sec_min = 60;
$sec_hour = $sec_min*60;
$sec_dias = $sec_hour*24;
$dias = intval($diff/$sec_dias);
$hours = intval($diff/$sec_hour)%24;
$minutes = intval($diff/$sec_min)%60;
$seconds = $diff%60;
if ($dias > 0) {
$result = "$days day";
if ($dias > 1) {
$result .= "s";
}
}
if ($hours > 0) {
$result .= " $hours hour";
if ($hours > 1) {
$result .= "s";
}
}
if ($minutes > 0) {
$result .= " $minutes minute";
if ($minutes > 1) {
$result .= "s";
}
}
if ($seconds > 0) {
$result .= " $seconds second";
if ($seconds > 1) {
$result .= "s";
}
}
$result = explode(" ", $result);
if (count($result)>2) {
end($result);
$key1 = key($result);
prev($result);
$key2 = key($result);
$aux = $result[$key2];
$aux .= " ".$result[$key1];
unset($result[$key1]);
unset($result[$key2]);
$result = implode(" ", $result);
$result .= " y $aux";
} else {
$result = implode(" ", $result);
}
return $result;
}
Leopoldo A dot Oducado (poducado at comfsm dot fm)
15-Feb-2007 07: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");
?>
h3 at valleyfield dot net
30-Jan-2007 10:56
EXCEL DATES TO UNIX TIMESTAMPS 2.0
----------------------------
In reply of the comment left on 24-Mar-2003 10:17
The function is broken, and they output date was alwasy offset of 1 day. I think it is caused by a leap year bug in excel. Here is a fixed version, now the date match exactly what they should match.
function xl2timestamp($timestamp) {
return ($timestamp - 25568) * 86400;
}
eg;
echo date('Y-m-d',xl2timestamp(38976));
I found the infos on this bug in;
http://tinyurl.com/28lltv
cheers.
owolawi at hotmail dot com
28-Jan-2007 03:02
#=========================================
# a function to subtract from or add seconds or minutes or hours or days or months or weeks or years to a specified date and return the updated date
#=========================================
#$newdate = dateadd("d",3,"2006-12-12"); # add 3 days to date
#$newdate = dateadd("s",3,"2006-12-12"); # add 3 seconds to date
#$newdate = dateadd("m",3,"2006-12-12"); # add 3 minutes to date
#$newdate = dateadd("h",3,"2006-12-12"); # add 3 hours to date
#$newdate = dateadd("ww",3,"2006-12-12"); # add 3 weeks days to date
#$newdate = dateadd("m",3,"2006-12-12"); # add 3 months to date
#$newdate = dateadd("yyyy",3,"2006-12-12"); # add 3 years to date
#$newdate = dateadd("d",-3,"2006-12-12"); # subtract 3 days from date
function dateAdd($interval,$number,$dateTime) {
$dateTime = (strtotime($dateTime) != -1) ? strtotime($dateTime) : $dateTime;
$dateTimeArr=getdate($dateTime);
$yr=$dateTimeArr[year];
$mon=$dateTimeArr[mon];
$day=$dateTimeArr[mday];
$hr=$dateTimeArr[hours];
$min=$dateTimeArr[minutes];
$sec=$dateTimeArr[seconds];
switch($interval) {
case "s"://seconds
$sec += $number;
break;
case "n"://minutes
$min += $number;
break;
case "h"://hours
$hr += $number;
break;
case "d"://days
$day += $number;
break;
case "ww"://Week
$day += ($number * 7);
break;
case "m": //similar result "m" dateDiff Microsoft
$mon += $number;
break;
case "yyyy": //similar result "yyyy" dateDiff Microsoft
$yr += $number;
break;
default:
$day += $number;
}
$dateTime = mktime($hr,$min,$sec,$mon,$day,$yr);
$dateTimeArr=getdate($dateTime);
$nosecmin = 0;
$min=$dateTimeArr[minutes];
$sec=$dateTimeArr[seconds];
if ($hr==0){$nosecmin += 1;}
if ($min==0){$nosecmin += 1;}
if ($sec==0){$nosecmin += 1;}
if ($nosecmin>2){ return(date("Y-m-d",$dateTime));} else { return(date("Y-m-d G:i:s",$dateTime));}
}
bgold at matrix-consultants dot com
16-Jan-2007 05: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 01: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;
James
21-Dec-2006 01:20
info at flash-ultra dot de, you could just use UNIX_TIMESTAMP(DATE) in your SQL query.
info at flash-ultra dot de
18-Dec-2006 04:17
This is a function to convert a mysql-datetime to an unix-timestamp.
function mysqlDatetimeToUnixTimestamp($datetime){
$val = explode(" ",$datetime);
$date = explode("-",$val[0]);
$time = explode(":",$val[1]);
return mktime($time[0],$time[1],$time[2],$date[1],$date[2],$date[0]);
}
mikeb at tracersinfo dot com
06-Nov-2006 11: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 09: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 05: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.
gary at gmartellino dot com
04-May-2006 10:35
here's a quick script i used to find recurring dates, it offers some flexibility in how you want to iterate though the dates
<?php
class recur {
var $endOption; var $endValue; var $start; function interval($type, $spread){
$startDate = explode("-", $this->start);
$time = mktime(0, 0, 0, $startDate[1], $startDate[2], $startDate[0]);
$dates[] = $this->start;
if($this->endOption == "endAfter"){
for($i = 1; $i < $this->endValue; $i++){
$futureTime = strtotime("+$spread $type", $time);
$dates[] = date("Y-m-d", $futureTime);
$time = $futureTime;
}
return $dates;
}else if($this->endOption == "endBy"){
$endDate = explode("-", $this->endValue);
$endTime = mktime(0, 0, 0, $endDate[1], $endDate[2], $endDate[0]);
while($endTime > $time){
$futureTime = strtotime("+$spread $type", $time);
if($futureTime > $endTime){
break;
}
$dates[] = date("Y-m-d", $futureTime);
$time = $futureTime;
}
return $dates;
}
}
}
?>
example:
<?php
include("includes/recur.class.php");
$recur = new recur();
$recur->endOption = "endBy";
$recur->endValue = '2006-12-09';
$recur->start = '2006-04-28';
print_r($recur->interval("day", 4));
?>
rugby7s at gmail dot com
08-Mar-2006 07:00
I had same problem nickaubert had with trying to compute timestamp for a span of dates that was daylight savings compliant.
OLD CODE:
/***********************************************
*Note - This is the old code that doesn't handle daylights savings time
***********************************************/
for($i=$start_date; $i<=$end_date; $i=($i+(24*60*60))){
//--- DO something $i is timestamp
}
NEW CODE:
for($i=$start_date;$i<=$end_date;
$i=(mktime(0,0,0,date('n',$i),date('d',$i)+1,date('Y',$i)))){
//--- DO something $i is timestamp
}
03-Mar-2006 07:50
A quick one liner to round a timestamp to the next full hour.
ie, 8:36 => 9:00, 9:02 => 10:00
$timestamp = ceil(time()/3600)*3600;
worm (zantATglazovDOTnet)
25-Jan-2006 06:44
Function for converting RFC 2822 formatted date to timestamp
<?php
function Rfc2822ToTimestamp($date){
$aMonth = array(
"Jan"=>"1", "Feb"=>"2", "Mar"=>"3", "Apr"=>"4", "May"=>"5",
"Jun"=>"6", "Jul"=>"7", "Aug"=>"8", "Sep"=>"9", "Oct"=>"10",
"Nov"=>"11", "Dec"=>"12");
list( , $day, $month, $year, $time) = explode(" ", $date);
list($hour, $min, $sec) = explode(":", $time);
$month = $aMonth[$month];
return mktime($hour, $min, $sec, $month, $day, $year);
}
?>
Jeff
03-Nov-2005 07:29
Here is a somewhat simpler function for getting the number of business days between two dates
<?php
function WorkDays( $startTime, $endTime )
{
$workdays = 0 ;
while( $startTime <= $endTime )
{
if( date('w', $startTime ) != 6 && date( 'w', $startTime) != 0 )
{
$workdays++ ;
}
$startTime += 86400 ;
}
return $workdays ;
}
?>
cupidomind at yahoo dot fr
14-Oct-2005 08:18
Hi I just want to say thanks a lot to the man who wrote a solution about a problem of the date-difference.
/*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.*/
rycker+phpdate at gmail dot com
04-Oct-2005 12:30
Function for converting MySQL timestamp to Datetime format
function TimestampToDatetime($Tstamp) {
$dt[0] = substr($Tstamp,0,4);
$dt[1] = substr($Tstamp,4,2);
$dt[2] = substr($Tstamp,6,2);
$tm[0] = substr($Tstamp,8,2);
$tm[1] = substr($Tstamp,10,2);
$tm[2] = substr($Tstamp,12,2);
return (join($dt,"-") . " " . join($tm,":"));
}
andreencinas at yahoo dot com dot br
28-Sep-2005 05: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 12: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) $date += $begindate ? $day : -($day * 2);
elseif ($adate['wday'] == 6) $date += $begindate ? $day * 2 : -$day;
return $date;
}
?>
Eric Z (ezsomething at hotmail)
01-Sep-2005 02:56
I was having a horrible time trying to get a good list of timezones, how to set them locally (for the user/client), and how best to keep this information. Building on the notes of this site (thanks everyone), I constructed code that should work on just about any un*x based platform. It reads the local timezone table and gives your a nested array of the continents and regions of the file -- the natural continent sorting is even by the most populated areas (thanks Paul Eggert!).
Afterwards, all you have to do is export the timezone string with an environmental set.. which works just fine if php is running as an apache model; haven't tested it for commandline, but I suspect it's okay there, too.
<?php
if (isset($_SESSION[PROFILE_TZOFFSET]))
putenv('TZ='.$_SESSION[PROFILE_TZOFFSET]);
?>
Here's how to load the timezones... the nested array makes it easy to insert into html lists or other well-behaved objects.
<?php
function getTimezoneData() {
$zoneNames = array();
$zoneSource = '/usr/share/zoneinfo/zone.tab';
$zoneHandle = fopen($zoneSource, "r");
if (!$zoneHandle) return NULL; while (!feof($zoneHandle)) {
$zoneLine = ltrim(fgets($zoneHandle, 4096));
if ($zoneLine[0]=='#') continue; $zoneParts = explode("\t",$zoneLine); if (count($zoneParts) < 3) continue; $nameParts = explode('/', $zoneParts[2], 2); $zoneKey = $nameParts[0]; $insertArray = &$zoneNames; if (count($nameParts) > 1) { if (!isset($zoneNames[$zoneKey])) $zoneNames[$zoneKey] = array();
$insertArray = &$zoneNames[$zoneKey]; $zoneKey = trim($nameParts[1]); }
$zoneKey = preg_replace('/[_]/',' ', $zoneKey);
$insertArray[$zoneKey] = trim($zoneParts[2]); } fclose($zoneHandle);
return $zoneNames;
}
?>
daniel at globalnetstudios dot com
08-Jun-2005 11: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
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);
switch($split) {
case 'yw': $dif['y'] = $y = intval($totalDays/365);
$dif['w'] = $w = intval(($totalDays-($y*365))/7);
$dif['d'] = $totalDays-($y*365)-($w*7);
break;
case 'y': $dif['y'] = $y = intval($totalDays/365);
$dif['d'] = $totalDays-($y*365);
break;
case 'w': $dif['w'] = $w = intval($totalDays/7);
$dif['d'] = $totalDays-($w*7);
break;
case 'd': $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 01: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])
r00t_ at mail dot ru
06-May-2005 12:33
Function generate one month calendar like
February
Mon Tue Wed Thu Fri Sat Sun
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28
(default in russian locale)
<?php
$year = (int)$_GET["year"];
$month = (int)$_GET["month"];
draw_month_cal($year, $month);
function draw_month_cal($year, $month, $locale = array ('ru_RU.CP1251', 'rus_RUS.1251'))
{
if (checkdate($month, 1, $year) && setlocale (LC_TIME, $locale)) {
if (!$day = date("w", $f_day = mktime(0, 0, 0, $month, 1, $year)))
$day = 7; print "<table border=0><tr><th colspan=7>" . strftime("%B", $f_day) . "</td></tr><tr>"; for ($i = 8; --$i;)
print "<th>" . strftime("%a", mktime(0, 0, 0, $month, 16 - $i - $day, $year)) . "</th>"; print "</tr><tr>" . str_repeat("<td></td>", --$day); while (checkdate($month, ++$i, $year)) { print "<td>$i</td>";
if (!(++$day % 7)) print "</tr><tr>"; }
print "</tr></table>";
}
}
?>
info at programare dot org
05-May-2005 10:34
A simple DateAdd() function:
function DateAdd($v,$d=null , $f="d/m/Y"){
$d=($d?$d:date("Y-m-d"));
return date($f,strtotime($v." days",strtotime($d)));
}
Then use it:
echo DateAdd(2); // 2 days after
echo DateAdd(-2,0,"Y-m-d"); // 2 days before with gigen format
echo DateAdd(3,"01/01/2000"); // 3 days after given date
datavortex at gmail dot com
18-Mar-2005 03:19
This is a litttle function I cobbled together from my own code, and snippets from this site to calculate the difference between two datetimes without having to confine it to simply one interval. This will tell you how many weeks, days, hours, minutes, and seconds there are between the given datetimes, and also makes a little English string you can use.
This could easily be expanded to include months, and years, but I didn't want to have to deal with any of the leap year and variable month length stuff.
<?
function dateDiff($dateTimeBegin,$dateTimeEnd) {
$dateTimeBegin =strtotime($dateTimeBegin);
$dateTimeEnd =strtotime($dateTimeEnd);
if($dateTimeEnd === -1 || $dateTimeBegin === -1) {
# error condition
return false;
}
$diff = $dateTimeEnd - $dateTimeBegin;
if ($diff < 0) {
# error condition
return false;
}
$weeks = $days = $hours = $minutes = $seconds = 0; # initialize vars
if($diff % 604800 > 0) {
$rest1 = $diff % 604800;
$weeks = ($diff - $rest1) / 604800; # seconds a week
if($rest1 % 86400 > 0) {
$rest2 = ($rest1 % 86400);
$days = ($rest1 - $rest2) / 86400; # seconds a day
if( $rest2 % 3600 > 0 ) {
$rest3 = ($rest2 % 3600);
$hours = ($rest2 - $rest3) / 3600; # seconds an hour
if( $rest3 % 60 > 0 ) {
$seconds = ($rest3 % 60);
$minutes = ($rest3 - $seconds) / 60; # seconds a minute
} else {
$minutes = $rest3 / 60;
}
} else {
$hours = $rest2 / 3600;
}
} else {
$days = $rest1/ 86400;
}
}else {
$weeks = $diff / 604800;
}
$string = array();
if($weeks > 1) {
$string[] = "$weeks weeks";
} elseif ($weeks == 1) {
$string[] = "a week";
}
if($days > 1) {
$string[] = "$days days";
} elseif($days == 1) {
$string[] = "a day";
}
if($hours > 1) {
$string[] = "$hours hours";
} elseif ($hours == 1) {
$string[] = "an hour";
}
if($minutes > 1) {
$string[] = "$minutes minutes";
} elseif ($minutes == 1) {
$string[] = "a minute";
}
if($seconds > 1) {
$string[] = "$seconds seconds";
} elseif($seconds == 1) {
$string[] = "a second";
}
# join together all the strings in the array above except the last element
$text = join(', ', array_slice($string,0,sizeof($string)-1)) . ", and ";
$text .= array_pop($string); # put the last one on after the and
return array($text, $weeks, $days, $hours, $minutes, $seconds);
?>
JMPZ art JMPZ dort ORG
03-Mar-2005 08:31
If you are dealing with a date in a database, you could just use the mysql function DATEDIFF(expr1,expr2) To calculate the difference without big bulky php functions.
andreencinas at yahoo dot com dot br
18-Jan-2005 08:56
//function like dateDiff Microsoft
//bug update for previous
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
}
}
Elizalde Baguinon
07-Jan-2005 06:46
I evaluated the modified version of Xiven's datediff (below) and I saw some errors. I switched the lines of getting the seconds and the formatting of date. I was testing the datediff() function with a "d" interval. Here I added my test code.
$dateA = "2004-12-31";
$dateB = "2005-01-01";
function datediff($interval, $date1, $date2) {
// Function roughly equivalent to the ASP "DateDiff" function
/* Get the seconds first */
$seconds = strtotime($date2) - strtotime($date1);
$date1=date("Y-m-d", strtotime($date1));
$date2=date("Y-m-d",strtotime($date2));
switch($interval) {
case "y":
list($year1, $month1, $day1) = split('-', $date1);
list($year2, $month2, $day2) = split('-', $date2);
$time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
$time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
$diff = $year2 - $year1;
if($month1 > $month2) {
$diff -= 1;
} elseif($month1 == $month2) {
if($day1 > $day2) {
$diff -= 1;
} elseif($day1 == $day2) {
if($time1 > $time2) {
$diff -= 1;
}
}
}
break;
case "m":
/* parses the year, month and days. split() was replaced with explode(), PHP Manual says it's faster */
list($year1, $month1, $day1) = explode('-', $date1);
list($year2, $month2, $day2) = explode('-',$date2);
$time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
$time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
$diff = ($year2 * 12 + $month2) - ($year1 * 12 + $month1);
if($day1 > $day2) {
$diff -= 1;
} elseif($day1 == $day2) {
if($time1 > $time2) {
$diff -= 1;
}
}
break;
case "w":
// Only simple seconds calculation needed from here on
$diff = floor($seconds / 604800);
break;
case "d":
$diff = floor($seconds / 86400);
break;
case "h":
$diff = floor($seconds / 3600);
break;
case "i":
$diff = floor($seconds / 60);
break;
case "s":
$diff = $seconds;
break;
}
//return the +ve integer only
if ($diff<0){
$diff=0-$diff;
}
return $diff;
}
echo "x: $dateA<br>";
echo "y: $dateB<br>";
echo "<br>";
echo datediff ("d",$dateA, $dateB);
Ruby
06-Jan-2005 08:09
just modified from Xiven
function datediff($interval, $date1, $date2) {
// Function roughly equivalent to the ASP "DateDiff" function
//set the date format first
$date1= date("Y-m-d", strtotime($date1));
$date2= date("Y-m-d",strtotime($date2));
$seconds = $date2 - $date1;
switch($interval) {
case "y":
list($year1, $month1, $day1) = split('-', $date1);
list($year2, $month2, $day2) = split('-', $date2);
$time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
$time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
$diff = $year2 - $year1;
if($month1 > $month2) {
$diff -= 1;
} elseif($month1 == $month2) {
if($day1 > $day2) {
$diff -= 1;
} elseif($day1 == $day2) {
if($time1 > $time2) {
$diff -= 1;
}
}
}
break;
case "m":
list($year1, $month1, $day1) = split('-', $date1);
list($year2, $month2, $day2) = split('-',$date2);
$time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
$time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
$diff = ($year2 * 12 + $month2) - ($year1 * 12 + $month1);
if($day1 > $day2) {
$diff -= 1;
} elseif($day1 == $day2) {
if($time1 > $time2) {
$diff -= 1;
}
}
break;
case "w":
// Only simple seconds calculation needed from here on
$diff = floor($seconds / 604800);
break;
case "d":
$diff = floor($seconds / 86400);
break;
case "h":
$diff = floor($seconds / 3600);
break;
case "i":
$diff = floor($seconds / 60);
break;
case "s":
$diff = $seconds;
break;
}
//return the +ve integer only
if ($diff <0)
{
$diff= 0-$diff;
}
return $diff;
}
charles at etherscapes dot com
04-Jun-2004 04:54
There are two dates that I know of that produce an incorrect result for the date functions above: 2004-04-04 and 2004-04-05. The days difference is zero instead of one.
jens at jebecs dot de
03-Jun-2004 04:29
There is an error in vincentv's post from 07-Feb-2001 11:23:
In function dayDiff(..) the return statement must be replaced by:
<?
return ( (getYear($timestamp1)*365 + $dayInYear1) -
(getYear($timestamp2)*365 + $dayInYear2) );
?>
nickaubert at america's biggest isp dot com
12-Apr-2004 01: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; for ( $each_timestamp = $start_time ; $each_timestamp <= $end_time ; $each_timestamp += $ONE_DAY) {
$this_timestamp_array = getdate( $each_timestamp );
$each_timestamp = mktime ( 0 , 0 , 0 , $this_timestamp_array[mon] , $this_timestamp_array[mday] , $this_timestamp_array[year] );
}
?>
pk_jsp at rediffmail dot com
12-Apr-2004 12:06
Just want to add a comment to the function datediff given by Xiven that simple difference of 2 dates as in
$seconds = $date2 - $date1; will nor work instead the following need to be used.
$seconds = strtotime($date2) - strtotime($date1);
scott_webster_2000 at yahoo dot com
20-Feb-2004 10: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 04:58
Additional thisone here (didn't test it yet but should work :D):
<?php
function dateDifference($start_timestamp,$end_timestamp,$unit= 0){
$days_seconds_star= (23 * 56 * 60) + 4.091; $days_seconds_sun= 24 * 60 * 60; $difference_seconds= $end_timestamp - $start_timestamp;
switch($unit){
case 3: $difference_days= round(($difference_seconds / $days_seconds_sun),2);
return 'approx. '.$difference_hours.' Days';
case 2: $difference_hours= round(($difference_seconds / 3600),2);
return 'approx. '.$difference_hours.' Hours';
break;
case 1: $difference_minutes= round(($difference_seconds / 60),2);
return 'approx. '.$difference_minutes.' Minutes';
break;
default: if($difference_seconds > 1){
return $difference_seconds.' Seconds';
}
else{
return $difference_seconds.' Second';
}
}
}
?>
wwb_99 at yahoo dot com
25-Jan-2004 01:12
Handy little function getting the total difference in dates.
function DateDiff($tfirst, $tsecond)
{
//returns an array with numeric values for in an array measuring days, hours, minutes & seconds
$ret=array();
$totalsec=$tsecond-$tfirst;
$ret['days']=round(($totalsec/86400));
$totalsec=$totalsec % 86400;
$ret['hours']=round(($totalsec/3600));
$totalsec=$totalsec % 3600;
$ret['minutes']=round(($totalsec/60));
$ret['seconds']=$totalsec % 60;
return $ret;
}
php at elmegil dot net
20-Dec-2003 10: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.
vincentv at thevoid dot demon dot nl
19-Nov-2003 01:56
A rectification to the some of the functions i posted a while ago.
They do not work correctly under all circumstances (in my small test cases they worked) which is due to the fact that when you create a date using mktime, which returns a certain amount of seconds, this is not valid for every month since each month has a different amount of seconds.
The solution is to break up the original timestamp, add to it's seperate parts and create a new timestamp.
Old:
=====
function sub($timestamp, $seconds,$minutes,$hours,$days,$months,$years) {
$mytime = mktime(1+$hours,0+$minutes,0+$seconds,1+$months,1+$days,1970+$years);
return $timestamp - $mytime;
}
function add($timestamp, $seconds,$minutes,$hours,$days,$months,$years) {
$mytime = mktime(1+$hours,0+$minutes,0+$seconds,1+$months,1+$days,1970+$years);
return $timestamp + $mytime;
}
=====
New:
=====
function add($timestamp, $seconds, $minutes, $hours, $days, $months, $years) {
$timePieces = getdate($timestamp);
return mktime( $timePieces["hours"] + $hours,
$timePieces["minutes"] + $minutes,
$timePieces["seconds"] + $seconds,
$timePieces["mon"] + $months,
$timePieces["mday"] + $days,
$timePieces["year"] + $years );
}
function sub($timestamp, $seconds, $minutes, $hours, $days, $months, $years) {
$timePieces = getdate($timestamp);
return mktime( $timePieces["hours"] - $hours,
$timePieces["minutes"] - $minutes,
$timePieces["seconds"] - $seconds,
$timePieces["mon"] - $months,
$timePieces["mday"] - $days,
$timePieces["year"] - $years );
}
=====
Regards,
- Vincent
CodeDuck at gmx dot net
07-Nov-2003 06:30
in reply to dkan at netscreen dot com 29-Aug-2003 07:40
> Zero-padding is easier to read and less complicated if you
> use the substr() function instead of an if-then statement.
my two versions of printtime with padding:
<?
function printtime() {
$timenow = getdate();
printf(
'%02d %02d %02d',
$timenow["hours"],
$timenow["minutes"],
$timenow["seconds"]
);
}
?>
or the better one:
<?
function printtime() {
echo date('H i s');
}
?>
Xiven
02-Oct-2003 06:09
One thing PHP really lacks IMHO is an equivalent of ASP's "DateDiff" function. Here's a function that comes close to duplicating the functionality:
<?php
function datediff($interval, $date1, $date2) {
$seconds = $date2 - $date1;
switch($interval) {
case "y":
list($year1, $month1, $day1) = split('-', date('Y-m-d', $date1));
list($year2, $month2, $day2) = split('-', date('Y-m-d', $date2));
$time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
$time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
$diff = $year2 - $year1;
if($month1 > $month2) {
$diff -= 1;
} elseif($month1 == $month2) {
if($day1 > $day2) {
$diff -= 1;
} elseif($day1 == $day2) {
if($time1 > $time2) {
$diff -= 1;
}
}
}
break;
case "m":
list($year1, $month1, $day1) = split('-', date('Y-m-d', $date1));
list($year2, $month2, $day2) = split('-', date('Y-m-d', $date2));
$time1 = (date('H',$date1)*3600) + (date('i',$date1)*60) + (date('s',$date1));
$time2 = (date('H',$date2)*3600) + (date('i',$date2)*60) + (date('s',$date2));
$diff = ($year2 * 12 + $month2) - ($year1 * 12 + $month1);
if($day1 > $day2) {
$diff -= 1;
} elseif($day1 == $day2) {
if($time1 > $time2) {
$diff -= 1;
}
}
break;
case "w":
$diff = floor($seconds / 604800);
break;
case "d":
$diff = floor($seconds / 86400);
break;
case "h":
$diff = floor($seconds / 3600);
break;
case "i":
$diff = floor($seconds / 60);
break;
case "s":
$diff = $seconds;
break;
}
return $diff;
}
?>
dkan at netscreen dot com
29-Aug-2003 01:40
Zero-padding is easier to read and less complicated if you use the substr() function instead of an if-then statement.
function printtime() {
$timenow = getdate();
$hours = substr("0" . $timenow["hours"], -2);
$minutes = substr("0" . $timenow["minutes"], -2);
$seconds = substr("0" . $timenow["seconds"], -2);
print($hours . " " . $minutes . " " . $seconds);
}
bitbuster at example dot com
24-Jul-2003 08:01
If you have to compare timestamps, I suggest you do it inside the database.. postgres, for example, allows statements like this:
select (current_timestamp < (select zeitdatum from time_test where zahl=5) );
menaurus at gmx dot de
16-Jul-2003 04: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;
you NOSPAM don't need 2 know ETC
24-Mar-2003 07:17
EXCEL DATES TO UNIX TIMESTAMPS
----------------------------
I get a lot of dates which are sent to me in those dastardly Excel spreadsheet things. For example, the date 15 April 1976, Excel stores as 27865.
I convert these to UNIX timestamps using the little function below.
<?
function xl2timestamp($xl_date)
{
$timestamp = ($xl - 25569) * 86400;
return $timestamp;
}
?>
garyc at earthling dot net
18-Mar-2003 08: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
balin
16-Feb-2003 01:23
this function count days between $start and $end dates in mysql format (yyyy-mm-dd)
if one of paramters is 0000-00-00 will return 0
$start date must be less then $end
<?
//For Count Days
function count_days($start, $end)
{
if( $start != '0000-00-00' and $end != '0000-00-00' )
{
$timestamp_start = strtotime($start);
$timestamp_end = strtotime($end);
if( $timestamp_start >= $timestamp_end ) return 0;
$start_year = date("Y",$timestamp_start);
$end_year = date("Y", $timestamp_end);
$num_days_start = date("z",strtotime($start));
$num_days_end = date("z", strtotime($end));
$num_days = 0;
$i = 0;
if( $end_year > $start_year )
{
while( $i < ( $end_year - $start_year ) )
{
$num_days = $num_days + date("z", strtotime(($start_year + $i)."-12-31"));
$i++;
}
}
return ( $num_days_end + $num_days ) - $num_days_start;
}
else
{
return 0;
}
}
?>
brighn (a) yahoo (.) com
02-Jan-2003 09: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";
}
visualmind at php dot net
25-Dec-2002 12:49
Here's a new function for Hejri (Hijri) date conversion, It has a better flawless calculation than the previous posted function and it's implemented to be an official alternative for the php DATE function which returns Arabic Translated date and optionally Hejri converted.
Note: to view arabic titles correctly change view-encoding to Arabic-Windows (windows-1256)
function arabicDate($format, $timestamp) {
/*
written by Salah Faya (visualmind@php.net) http://www.php4arab.info/scripts/arabicDate
$format:
[*]hj|ar|en:[jdl][Fmn][Yy][Aa] (php.date function handles the rest chars)
* will add <span dir=rtl lang=ar-sa>..</span>
examples:
echo arabicDate('hj:l d-F-Y
|
|