Here's a function I made to make an array containing all days in a given year:
<?php
# Usage: generateYearArray(int $fyear);
# $fyear is the year that you want dates for.
function generateYearArray($fyear) {
$feb = cal_days_in_month(CAL_GREGORIAN, 2, $fyear);
$daysInYear = ($feb === 29) ? 366 : 365;
$array = array();
while ($daysInYear > 0) {
$array[] = date("Y-m-d", mktime(0, 0, 0, 1, $daysInYear, $fyear));
$daysInYear--;
}
sort($array);
return $array;
}
?>
Example:
generateYearArray(2008);
should return an array like:
Array(
[0] => "2008-01-01",
[1] => "2008-01-02",
...
[363] => "2008-12-29",
[364] => "2008-12-30",
[365] => "2008-12-31"
)
This function is released into the public domain.
mktime
(PHP 4, PHP 5)
mktime — Retourne le timestamp UNIX d'une date
Description
mktime() retourne un timestamp UNIX correspondant aux arguments fournis. Ce timestamp est un entier long, contenant le nombre de secondes entre le début de l'époque UNIX (1er Janvier 1970 00:00:00 GMT) et le temps spécifié.
Les arguments peuvent être omis, de droite à gauche, et tous les arguments manquants sont utilisés avec la valeur courante de l'heure et du jour.
Liste de paramètres
- hour
-
L'heure.
- minute
-
Les minutes
- second
-
Les secondes.
- month
-
Le nombre représentant le mois.
- day
-
Le nombre représentant le jour.
- year
-
L'année, peut être sur deux ou quatre chiffres, avec des valeurs allant de 0 à 69, correspondant au valeur 2000 à 2069 et 70 à 100, correspondant au valeur 1970 à 2000. Sur les systèmes où time_t un entier signé sur 32bits, ce qui est le plus courant de nos jours, la période valide pour year est quelque part près de 1901 et 2038. Cependant, avant PHP 5.1.0, cette intervalle était limitée de 1970 à 2038 sur quelques systèmes (i.e. Windows).
- is_dst
-
Ce paramètre peut être mis à 1 si l'heure d'hiver est appliquée (DST), 0 si elle ne l'est pas, et -1 (par défaut) si on ne sait pas. Si l'on ne sait pas, PHP tente de le traiter lui-même. Ceci peut occasionner des résultats inattendus (mais néanmoins correct). Quelques temps sont invalides si DST est activé sur les systèmes où PHP fonctionne ou is_dist est défini à 1. Si DST est activé e.g. 2:00, tous les temps entre 2:00 et 3:00 sont invalides et la fonction mktime() retourne une valeur indéfinie (généralement une valeur négative). Quelques systèmes (e.g. Solaris 8) activent DST à minuit, donc, le temps 0:30 du jour lorsque DST est activé est évalué à 23:30 du jour précédent.
Note: Depuis PHP 5.1.0, ce paramètre est déprécié. Comme résultat, le nouveau gestionnaire de fuseau horaire doit être utilisé à la place.
Valeurs de retour
mktime() retourne un timestamp Unix des arguments donnés. Si les arguments ne sont pas valides, la fonction retournera FALSE (avant PHP 5.1, elle retournait -1).
Erreurs / Exceptions
Chaque appel à une fonction date/heure générera un message de type E_NOTICE si le fuseau horaire n'est pas valide., et/ou un message de type E_STRICT si vous utilisez la configuration du système ou la variable d'environnement TZ. Voir aussi date_default_timezone_set()
Historique
| Version | Description |
|---|---|
| 3.0.10 | Ajout du paramètre is_dst |
| 5.1.0 | Le paramètre is_dst est déprécié. Fait que la fonction retourne FALSE en cas d'erreur, au lieu de -1. |
| 5.1.0 | Émet un message de type E_STRICT et E_NOTICE lors d'erreurs de fuseaux horaires. |
Exemples
Exemple #1 Exemple avec mktime()
mktime() est pratique pour faire des calculs de dates et des validations, car elle va automatiquement corriger les valeurs invalides. Par exemple, toutes les lignes suivantes vont retourner la même date : "Jan-01-1998".
<?php
echo date("M-d-Y", mktime(0, 0, 0, 12, 32, 1997));
echo date("M-d-Y", mktime(0, 0, 0, 13, 1, 1997));
echo date("M-d-Y", mktime(0, 0, 0, 1, 1, 1998));
echo date("M-d-Y", mktime(0, 0, 0, 1, 1, 98));
?>
Exemple #2 Dernier jour du mois suivant
Le dernier jour d'un mois peut être décrit comme le jour "0" du mois suivant, et non pas le jour -1. Les deux exemples suivants vont donner : "Le dernier jour de Février 2000 est: 29".
<?php
$lastday = mktime(0, 0, 0, 3, 0, 2000);
echo strftime("Le dernier jour de Fevrier 2000 est : %d", $lastday);
$lastday = mktime(0, 0, 0, 4, -31, 2000);
echo strftime("Le dernier jour de Fevrier 2000 est : %d", $lastday);
?>
Notes
Avant PHP 5.1.0, les valeurs négatives des timestamp ne sont pas supportées sous toutes les versions actuelles de Microsoft Windows. De ce fait, l'intervalle valide pour les années est de 1970 à 2038, inclus.
mktime
01-Jun-2008 07:34
22-May-2008 02:34
This script is for creating servertime with auto detect server timezone.
<? php
$month = date(m); //* Get Current Month //
$day = date(j); //* Get Current Day //
$year = date(Y); //* Get Current Year //
$hour = date(G); //* Get Current Hour (24 Hours Format) //
$min = date(i); //* Get Current Minutes //
$sec = date(s); //* Get Current Seconds //
$gmt = date(O); //* Get Current Timezone //
$servertime = date("D \\- M j\\, Y \\- g:i A", mktime($hour+$gmt, $minutes, $sec, $month, $day, $year, 0));
print $servertime;
?>
If you want to input a multiple timezone. just copy the "$gmt = date(O). Then add increments to "$gmt" and replace the "date(O)" to any timezone you want.
For example:
I need only 2 timezone, Standard GMT and Pacific Timezone.
I will remove "$gmt" and replace it with "$gmt1" and "$gmt2".
Then for "$gmt1" I will replace the "date(O)" with 0, so my Timezone1 is equal to Standard GMT.
Then for "$gmt2" I will replace the "date(O)" with -8, so my Timezone2 is equal to Pacific Timezone.
Wait we need an output. To get the output for two timezone we need also two output script.
echo date("D \\- M j\\, Y \\- g:i A", mktime($hour+$gmt1, $minutes, $sec, $month, $day, $year, 0));
echo date("D \\- M j\\, Y \\- g:i A", mktime($hour+$gmt2, $minutes, $sec, $month, $day, $year, 0));
Enjoy scripting,
-JhunTech09
13-May-2008 04:34
It seems mktime() doesn't return negative timestamps on Linux systems with a version of glibc <= 2.3.3.
15-Apr-2008 03:18
> You said :
> mktime() seems to produce an incorrect result when you have months and dates prefixed with 0.
> eg. mktime(0, 0, 0, 04, 08, 2008);
> will produce an incorrect result where as
> mktime(0, 0, 0, 4, 8, 2008);
> produces the correct result.
This has nothing to do with mktime! It's the normal behaviour of PHP that a ANY number prefixed with '0' is treated as Octal!
Try: print 015; // prints 13 which is the decimal representation of 018 Octal
It's not a BUG it's a FEATURE ;-)
12-Apr-2008 05:59
In response to : zhenya dot t at livelynk dot com
You said :
mktime() seems to produce an incorrect result when you have months and dates prefixed with 0.
eg. mktime(0, 0, 0, 04, 08, 2008);
will produce an incorrect result where as
mktime(0, 0, 0, 4, 8, 2008);
produces the correct result.
---------------------------------------------------
Resolution:
You can simply call the function intval(<your parameter>) inside the function:
eg. mktime(0, 0, 0, intval('04'), intval('08'), 2008);
will produce a correct result
05-Apr-2008 06:05
Reply to post:
> Anonymous
> 04-Apr-2008 04:30
>
> While you might expect mktime() to give you the time of midnight if the hours parameter is set to zero, it may not. Instead it returns noon in this example. PHP 5.2.4.
> Example:
> $ts_now = date('Y-m-d h:i:s'); // 2008-04-04 07:30:00
> $ts_then = date('Y-m-d h:i:s', mktime(0, 0, 0, date("m"), date("d"), date("Y")+1)); // 2009-04-04 12:00:00
You mistakenly used "h" which stands for hours in 12-hours format.
Use "H" instead and you'll see that the function gives you the time of midnight correctly.
04-Apr-2008 01:30
While you might expect mktime() to give you the time of midnight if the hours parameter is set to zero, it may not. Instead it returns noon in this example. PHP 5.2.4.
Example:
$ts_now = date('Y-m-d h:i:s'); // 2008-04-04 07:30:00
$ts_then = date('Y-m-d h:i:s', mktime(0, 0, 0, date("m"), date("d"), date("Y")+1)); // 2009-04-04 12:00:00
21-Mar-2008 03:05
Another useful function that I have created years ago. Useful for all calendar applications, if you have to switch to a date given by a week number and a specific day (e.g. tuesday in week 12: mktimefromcw(2008, 12, 2)).
/**
* @return timestamp
* @param integer year
* @param integer woy
* @param integer dow
* @desc This function retrieves the time for the given year, week of year and day of the week and returns it.
*/
function mktimefromcw($year, $woy=1, $dow=1) {
# $year = year (four digits)
# $woy = week of the year (1..53)
# $dow = day of the week (1..7)
$dow = ($dow) % 7;
$woy = ($woy) - 1;
# Get reference value (this is the first monday of the first week of the year, not easy to calculate)
$fdoy_timestamp = mktime(0,0,0,1,1,$year);
$fdoy = ((date("w", $fdoy_timestamp) + 6) % 7) + 1;
if($fdoy == 1) {
# This first day of the year is a monday
$fcwstart = $fdoy_timestamp;
}
elseif($fdoy < 5) {
# The first day if before Friday, therefor the first Monday can be found in the previos year (this is no fun, believe in it!).
$fcwstart = strtotime("last Monday", $fdoy_timestamp);
}
else {
# The first day is a friday or later, so the first days belong to calender week 53 (yes, this is possible!) of the previous year, do not count them for this year.
$fcwstart = strtotime("next Monday", $fdoy_timestamp);
}
# Create timestamp
$timestr = date("d F Y", $fcwstart)." +$woy week +$dow day";
$time = strtotime($timestr);
# Return timestamp
return $time;
}
17-Mar-2008 07:13
Here some example i have implemented. I think it will be helpful someone
function fullDateFormat( $value ){
$d = explode("-", $value);
$cdate = date ("F j, Y", mktime (0,0,0,$d[1],$d[2],$d[0]));
echo $cdate;
}
//-----Enter date format like mysql date (e.g. 2000-01-30)------//
fullDateFormat("2008-03-17");
//Output like: March 17, 2008
function detailsDateFormat( $value ){
$d = explode("-", $value);
$cdate = date ("l F j, Y", mktime (0,0,0,$d[1],$d[2],$d[0]));
echo $cdate;
}
//-----Enter date format like mysql date (e.g. 2000-01-30)------//
detailsDateFormat("2008-03-17");
//Output like: Monday March 17, 2008
05-Mar-2008 10:45
Converting date() style strings to unix epoch time was giving me an "A non well formed numeric value encountered in" error. Simply resolved with an (int) call on the string:
<?php
$ue_time = time();
$old_date = date('Y-m-d');
$old_time = date('h:i');
$new_date = str_replace('-', ', ', $old_date);
$new_time = str_replace(':', ', ', $old_time);
$convert_date = $new_time.', '.$new_date;
$convert_date = (int)$convert_date;
$converted = mktime ($convert_date);
echo $ue_time.' vs '.$old_date.' '.$old_time.' converted = '.$converted;
?>
20-Feb-2008 10:21
<?php
//Beware of this when comparing dates:
function daysBetween($date1, $date2)
{
$d1 = explode("-", $date1);
$d2 = explode("-", $date2);
$year1 = $d1[0];
$month1 = $d1[1];
$day1 = $d1[2];
$year2 = $d2[0];
$month2 = $d2[1];
$day2 = $d2[2];
$deadline1 = mktime(0, 0, 0, $month1, $day1, $year1, 0);
$deadline2 = mktime(0, 0, 0, $month2, $day2, $year2, 0);
/* If you dont put 0 at last parameter both mktime calls, and
a Daylight Saving Time is not specified,
a float days number can be returned. Is better to pass 0
in both mktimes and round the result: */
$res = round( ($deadline2 - $deadline1) / (60 * 60 * 24) );
return $res;
}
/* My Test dates: */
echo daysBetween('2008-3-5','2008-3-11');
?>
03-Feb-2008 04:45
// How to get the UNIX Time for Sunday of any week of the year. I need it for consistant weekly features regardless of the year.
// Current Week Number
$weeknumber = date("W");
// UNIX Time for Jan 1, (current year)
$firstweek = mktime(0,0,0,1,1,date("Y"));
// UNIX Time for the start of the current week (Usually not a Sunday)
$currentweek = $firstweek+($weeknumber*604800)-604800;
// Checks what day of the week it is, then adds a day until its Sunday
$sundaycheck = date("w",$currentweek);
do{
if($sundaycheck!=0){
$currentweek += 86400;
$sundaycheck = date("w",$currentweek);
}
}while($sundaycheck!=0);
echo date("l jS F, Y @ H:i:s a", $currentweek)."<br>";
// Will display the Sunday of the current week.
02-Feb-2008 05:01
Heres a way to get the UNIX timestamp for the first day of this week:
<?php
$week = mktime(0, 0, 0, date("n"), date("j"), date("Y")) - (date("N")*3600*24);
echo date("l jS F, Y @ H:i:s a", $week);
?>
In my case this outputted:
Sunday 27th January, 2008 @ 00:00:00 am
(and today is Saturday 2nd February, 2008 @ 16:59:41 pm)
This is useful for (what i am doing which is) site stats pages. Can be used to give your mysql query a cut off date for example, for all the visitors this week, or how many posts this week or whatever it may be
xjden
30-Jan-2008 09:58
Just a small thing to think about if you are only trying to pull the month out using mktime and date. Make sure you place a 1 into day field. Otherwise you will get incorrect dates when a month is followed by a month with less days when the day of the current month is higher then the max day of the month you are trying to find.. (Such as today being Jan 30th and trying to find the month Feb.)
17-Jan-2008 07:42
Taking a sample from a fellow poster a bit up, I've made this quite simple MYSQL date to timestamp which will convert both date or date/time fields.
function MySQLtoTimestamp($mysqlDate) {
if (strlen($mysqlDate) > 10) {
list($year, $month, $day_time) = explode('-', $mysqlDate);
list($day, $time) = explode(" ", $day_time);
list($hour, $minute, $second) = explode(":", $time);
$ts = mktime($hour, $minute, $second, $month, $day, $year);
} else {
list($year, $month, $day) = explode('-', $mysqlDate);
$ts = mktime(0, 0, 0, $month, $day, $year);
}
return $ts;
}
27-Dec-2007 09:39
There was one requirement of finding recurring date for daily, monthly, quarterly and yearly subscription.
Following is the example to find out next recurring dates.
Logic : Code is taking care of following things.
1. Date is valid date
2. If next recurring date is not valid than it will take last date of month.
3. This code will useful to those who are interested to keep track of recurring payments on his own database
rather than payment gateway.
4. Code will allow you to find dates for daily, monthly, quarterly and yearly.
<?PHP
function getDates($bdate,$duration) {
$aDate = explode("-",$bdate);
$datetime = mktime(0, 0, 0, $aDate[1], $aDate[2], $aDate[0]);
switch($duration) {
case 0:
for($i=0;$i<12;$i++) {
$nextmonth = date("Y-m-d",mktime(0, 0, 0, date("m",$datetime),
date("d",$datetime)+1+$i, date("Y",$datetime)));
echo $nextmonth."<br><br>";
}
break;
case 1:
for($i=0;$i<12;$i++) {
$tempnextmonth = ($aDate[1]+1+$i)%12;
if($tempnextmonth == 0) {
$tempnextmonth = 12;
}
$nextyear = date("Y",mktime(0, 0, 0, date("m",$datetime)+1+$i,
date("d",$datetime), date("Y",$datetime)));
if (checkdate(str_pad($tempnextmonth,2,0,STR_PAD_LEFT),
$aDate[2],$nextyear) == false) {
echo $nextyear."-".str_pad($tempnextmonth,2,0,STR_PAD_LEFT)."-".
date('d', mktime(0, 0, 0, ($tempnextmonth + 1), 0, $nextyear))
."<br><br>";
}
else {
echo $nextyear."-".str_pad($tempnextmonth,2,0,STR_PAD_LEFT)."-".
$aDate[2]."<br><br>";
}
}
break;
case 2:
for($i=0;$i<12;$i++) {
$tempnextmonth = ($aDate[1]+4+(4*$i))%12;
if($tempnextmonth == 0) {
$tempnextmonth = 12;
}
$nextyear = date("Y",mktime(0, 0, 0, date("m",$datetime)+4+(4*$i),
date("d",$datetime), date("Y",$datetime)));
if (checkdate(str_pad($tempnextmonth,2,0,STR_PAD_LEFT),
$aDate[2],$nextyear) == false) {
echo $nextyear."-".str_pad($tempnextmonth,2,0,STR_PAD_LEFT)."-".
date('d', mktime(0, 0, 0, ($tempnextmonth + 1), 0, $nextyear)).
"<br><br>";
}
else {
echo $nextyear."-".str_pad($tempnextmonth,2,0,STR_PAD_LEFT)."-".
$aDate[2]."<br><br>";
}
}
break;
case 3:
for($i=0;$i<12;$i++) {
$nextmonth = date("Y-m-d",mktime(0, 0, 0, date("m",$datetime),
date("d",$datetime), date("Y",$datetime)+1+$i));
echo $nextmonth."<br><br>";
}
break;
}
}
?>
How to use this function?
<?PHP getDates(date("Y-m-d"),$period); ?>
You can set $period as your recurring period time.
0 - Daily Dates
1 - Monthly Dates
2 - Quarterly Dates
3 - Yearly Dates
18-Nov-2007 03:54
I made this simple class to add/remove time to my subscription service. It makes it easy to make new time without having to write the whole mktime line everytime. I'm posting it here, as it might help somebody.
<?php
class mkTime {
var $day = 0;
var $month = 0;
var $year = 0;
var $hour = 0;
var $minute = 0;
var $sec = 0;
var $iniTime;
var $returnFormat = "Y-m-d H:i:s";
function addTime() {
$newTime = mktime(
date("H",$this->iniTime)+$this->hour,
date("i",$this->iniTime)+$this->minute,
date("s",$this->iniTime)+$this->sec,
date("m",$this->iniTime)+$this->month,
date("d",$this->iniTime)+$this->day,
date("Y",$this->iniTime)+$this->year
);
$rtnTime = date($this->returnFormat,$newTime);
return $rtnTime;
}
function removeTime() {
$newTime = mktime(
date("H",$this->iniTime)-$this->hour,
date("i",$this->iniTime)-$this->minute,
date("s",$this->iniTime)-$this->sec,
date("m",$this->iniTime)-$this->month,
date("d",$this->iniTime)-$this->day,
date("Y",$this->iniTime)-$this->year
);
$rtnTime = date($this->returnFormat,$newTime);
return $rtnTime;
}
}
$t = new mkTime; // call the class
$t->iniTime = time(); // set initial time
$t->year = 1; // add/remove a year
$newTime = $t->addTime(); // call the add time function
echo "$newTime<br/><br/>"; // write result to browser
$t = new mkTime; // call the class
$t->iniTime = time(); // set initial time
$t->year = 1; // add/remove a year
$t->returnFormat = "d/m-Y @ H:i:s"; // time return format
$newTime = $t->removeTime(); // call the remove time function
echo "$newTime<br/><br/>"; // write result to browser
?>
06-Sep-2007 07:58
The maximum possible date accepted by mktime() and gmmktime() is dependent on the current location time zone.
For example, the 32-bit timestamp overflow occurs at 2038-01-19T03:14:08+0000Z. But if you're in a UTC -0500 time zone (such as EST in North America), the maximum accepted time before overflow (for older PHP versions on Windows) is 2038-01-18T22:14:07-0500Z, regardless of whether you're passing it to mktime() or gmmktime().
31-Aug-2007 04:31
NB: one 'gotcha' with the implementation of mktime()'s parameters:
<?php
for( $i = 1 ; $i <= 12 ; $i++ )
{
echo "Month '$i' is: " . date( "F" , mktime( 0 , 0 , 0 , $i ) ) . "\n";
}
?>
Will output:
Month '1' is: January
Month '2' is: March
Month '3' is: March
Month '4' is: May
Month '5' is: May
Month '6' is: July
Month '7' is: July
Month '8' is: August
Month '9' is: October
Month '10' is: October
Month '11' is: December
Month '12' is: December
on the 31st day of every month.
Why? Because the 5th parameter "day" defaults to "right now," which will not work reliably for days after the 28th.
To make sure this doesn't happen, specify the first day of the month:
<?php
mktime( 0 , 0 , 0 , $i , 1 )
?>
02-Aug-2007 05:46
As per derrick miller's contribution for MySQL date stamps (which equally applies to pgSQL)... I find this processes a little faster than exploding the string:
(All done in one statement)
function unix_date($input_date)
{ // take date string such as "1985-07-25" and return the Unix timestamp
return mktime(0, 0, 0, substr($input_date, 5, 2), substr($input_date, 8, 2), substr($input_date, 0,4));
}
17-Jul-2007 06:52
Finding out the number of days in a given month and year, accounting for leap years when February has more than 28 days.
function days_in_month($year, $month) {
return( date( "t", mktime( 0, 0, 0, $month, 1, $year) ) );
}
Hope it helps a soul out there.
11-Jul-2007 03:04
It may be useful to note that no E_WARNINGS or E_NOTICES are give if you specify a date <1901 or >2038 on systems where time_t is a 32bit signed integer.
If a date is specified outside of the allowed range you may get some unexpected results as no timestamp will be returned.
08-Apr-2007 11:29
Simple date compare:
mktime(0, 0, 0) >= mktime(0, 0, 0, $_POST['MonthVld'], $_POST['DayVld'], $_POST['YrVld'])
mktime(0, 0, 0) creates a unix time of the current date.
mktime(0, 0, 0, $_POST['MonthVld'], $_POST['DayVld'], $_POST['YrVld']) creates a unix time of the date that your user enters.
31-Mar-2007 06:46
You cannot simply subtract or add month VARs using mktime to obtain previous or next months as suggested in previous user comments (at least not with a DD > 28 anyway).
If the date is 03-31-2007, the following yeilds March as a previous month. Not what you wanted.
<?php
$dateMinusOneMonth = mktime(0, 0, 0, (3-1), 31, 2007 );
$lastmonth = date("n | F", $dateMinusOneMonth);
echo $lastmonth; //---> 3 | March
?>
mktime correctly gives you back the 3rd of March if you subtract 1 month from March 31 (there are only 28 days in Feb 07).
If you are just looking to do month and year arithmetic using mktime, you can use general days like 1 or 28 to do stuff like this:
<?php
$d_daysinmonth = date('t', mktime(0,0,0,$myMonth,1,$myYear)); // how many days in month
$d_year = date('Y', mktime(0,0,0,$myMonth,1,$myYear)); // year
$d_isleapyear = date('L', mktime(0,0,0,$myMonth,1,$myYear)); // is YYYY a leapyear?
$d_firstdow = date('w', mktime(0,0,0,$myMonth,'1',$myYear)); // FIRST falls on what day of week (0-6)
$d_firstname = date('l', mktime(0,0,0,$myMonth,'1',$myYear)); // FIRST falls on what day of week Full Name
$d_month = date('n', mktime(0,0,0,$myMonth,28,$myYear)); // month of year (1-12)
$d_monthname = date('F', mktime(0,0,0,$myMonth,28,$myYear)); // Month Long name (July)
$d_month_previous = date('n', mktime(0,0,0,($myMonth-1),28,$myYear)); // PREVIOUS month of year (1-12)
$d_monthname_previous = date('F', mktime(0,0,0,($myMonth-1),28,$myYear)); // PREVIOUS Month Long name (July)
$d_month_next = date('n', mktime(0,0,0,($myMonth+1),28,$myYear)); // NEXT month of year (1-12)
$d_monthname_next = date('F', mktime(0,0,0,($myMonth+1),28,$myYear)); // NEXT Month Long name (July)
$d_year_previous = date('Y', mktime(0,0,0,$myMonth,28,($myYear-1))); // PREVIOUS year
$d_year_next = date('Y', mktime(0,0,0,$myMonth,28,($myYear+1))); // NEXT year
$d_weeksleft = (52 - $d_weekofyear); // how many weeks left in year
$d_daysinyear = $d_isleapyear ? 366 : 365; // set correct days in year for leap years
$d_daysleft = ($d_daysinyear - $d_dayofyear); // how many days left in year
?>
11-Mar-2007 10:31
This function returns no negative results inside of XEN guests.
24-Feb-2007 08:17
Here's a handy function which will convert dates in MySQL format (yyyy-mm-dd) to a Unix timestamp. While this can also be done within MySQL queries via the UNIX_TIMESTAMP() function, it is not always convenient to do so.
// Returns the Unix timestamp of a MySQL date (YYYY-MM-DD)
function mysqldate_to_unix_timestamp($date) {
list($year, $month, $day) = explode('-', $date);
return mktime(0, 0, 0, $month, $day, $year);
}
29-Jan-2007 07:35
To Stephen:
You left out one other important difference between human time and timestamps, leap seconds, these get added and removed as needed up to twice a year depending on the earths rotational speed (if the earth spins faster or slower over a period of time).
08-Jan-2007 11:43
There are several warnings here about using mktime() to determine a date difference because of daylight savings time. However, nobody seems to have mentioned the other obvious problem, which is leap years.
Leap years mean that any effort to use mktime() and time() to determine the age (positive or negative) of some timestamp in years will be flawed. There are some years that are 366 days long, therefore you cannot say that there is a set number of seconds per year.
Timestamps are good for determining *real* time, which is not the same thing as *human calendar* time. The Gregorian calendar is only an approximation of real time, which is tweaked with daylight savings time and leap years to make it conform more to humans' expectations of how time should or ought to work. Timestamps are not tweaked and therefore are the only authoritative way of recording in computers a proper order of succession of events, but they cannot be integrated with a Gregorian system unless you take both leap years and DST into account. Otherwise, you may get the wrong number of years when you are approaching a value of exactly X years.
As for PHP, you could still use timestamps as a way of determining age if you took into account not only DST but also whether or not each year is a leap year and adjusted your calculations accordingly. However, this could become messy and inefficient.
There is an alternative approach to calculating days given the day, month and year of the dates to be compared. Compare the years first, and then compare the month and day - if the month and day have already passed (or, if you like, if they match the current month and day), then add 1 to the total for the years.
This solution works because it stays within the Gregorian system and doesn't venture into the world of timestamps.
Here is a good discussion of this issue:
http://forums.devshed.com/php-development-5/
need-to-get-the-age-between-dob-
and-today-29925.html?&highlight=age+leap
[the above link was too long; combine the three lines to get the URL]
There is also the issue of leap seconds, but this will only arise if you literally need to get the *exact* age in seconds. In that case, of course, you would also need to verify that your timestamps are exactly correct and are not delayed by script processing time, plus you would need to determine whether your system conforms to UTC, etc. I expect this will hardly be an issue for anybody using PHP, however if you are interested there is an article on this issue on Wikipedia:
http://en.wikipedia.org/wiki/Leap_second
07-Nov-2006 01:42
There are several notes for mktime which use the number 86400 to differentiate two days. However this technique may pose a problem in case there is a day where the hour change between the two dates to compare.
Consequently, if you want the timestamp difference between the day where the hour change and the next day, it will not be equals to 86400 but either 82800 in case its the winter change of hour day or 90000 for the summer change of hour day.
For example in 2006 :
<?php
echo mktime(0,0,0,10,29,2006) - mktime(0,0,0,10,30,2006); // -90 000
?>
31-Oct-2006 10:28
As I see it, this function should default to zero for the first 3 arguments but one for the next two.
It makes sense to talk about the 0th hour of the day (midnight) or the 0th minute of the hour or the 0th second of the minute, but it makes no sense to talk about the 0th day of the month or the 0th month of the year.
The example of why this change should happen is below:
<select id="month" name="month">
<?php
for ($i = 1; $i <= 12; $i++)
echo '<option value="'.$i.'">'.date('F',mktime(0,0,0,$i)).'</option>';
?>
</select>
Produces a list of meaningless months. To make it useful, you have to add an extra argument to mktime.
<?php
mktime(0,0,0,$i,1)
?>
24-Aug-2006 07:07
In response to the post by "nicky" on July 9, 2006:
Just so everyone's clear, if you have a date string formatted in a standard way, you'll probably want to go ahead and use PHP's built-in strtotime() function. The advantage to using nicky's str2time() function seems to be that you can specify how the date string you're passing in is formatted, so you can deal with non-standard date strings.
09-Jul-2006 01:08
here's a function to generate a timestamp from a certain date by using patterns:
<?php
function str2time($strStr, $strPattern = null)
{
// an array of the valide date characters, see: http://php.net/date#AEN21898
$arrCharacters = array(
'd', // day
'm', // month
'y', // year, 2 digits
'Y', // year, 4 digits
'H', // hours
'i', // minutes
's' // seconds
);
// transform the characters array to a string
$strCharacters = implode('', $arrCharacters);
// splits up the pattern by the date characters to get an array of the delimiters between the date characters
$arrDelimiters = preg_split('~['.$strCharacters.']~', $strPattern);
// transform the delimiters array to a string
$strDelimiters = quotemeta(implode('', array_unique($arrDelimiters)));
// splits up the date by the delimiters to get an array of the declaration
$arrStr = preg_split('~['.$strDelimiters.']~', $strStr);
// splits up the pattern by the delimiters to get an array of the used characters
$arrPattern = preg_split('~['.$strDelimiters.']~', $strPattern);
// if the numbers of the two array are not the same, return false, because the cannot belong together
if (count($arrStr) !== count($arrPattern)) {
return false;
}
// creates a new array which has the keys from the $arrPattern array and the values from the $arrStr array
$arrTime = array();
for ($i = 0;$i < count($arrStr);$i++) {
$arrTime[$arrPattern[$i]] = $arrStr[$i];
}
// gernerates a 4 digit year declaration of a 2 digit one by using the current year
if (isset($arrTime['y']) && !isset($arrTime['Y'])) {
$arrTime['Y'] = substr(date('Y'), 0, 2) . $arrTime['y'];
}
// if a declaration is empty, it will be filled with the current date declaration
foreach ($arrCharacters as $strCharacter) {
if (empty($arrTime[$strCharacter])) {
$arrTime[$strCharacter] = date($strCharacter);
}
}
// checks if the date is a valide date
if (!checkdate($arrTime['m'], $arrTime['d'], $arrTime['Y'])) {
return false;
}
// generates the timestamp
$intTime = mktime($arrTime['H'], $arrTime['i'], $arrTime['s'], $arrTime['m'], $arrTime['d'], $arrTime['Y']);
// returns the timestamp
return $intTime;
}
// example
$time = str2time('06-07-08 07:58:02', 'd-m-y H:i:s');
var_dump($time);
var_dump(date('d.m.Y H:i:s', $time));
?>
08-May-2006 01:40
Negative timestamps give problem also using linux as guest operating system inside WMvare with Windows host operating system.
14-Nov-2005 09:21
A trivial way to avoid having to remember the quirky order of variables.
It's also more convenient to use because you can ignore the last three (time) variables if all you want to do is manupulate the date components.
Just include the following function at the top of your script and call ansi_mktime instead of mktime.
function ansi_mktime($y=0, $month=0, $d=0, $h=0, $min=0, $s=0){
return mktime($h, $min, $s, $month, $d, $y);
}
// eg:
$day = 14;
echo date("dS \d\a\y of M Y", ansi_mktime(2005, 11, $day + 7))
// output: 21st day of Nov 2005
07-Aug-2005 12:25
In response to Hayden...
I hate to inform you of this after you've worked out your own function for date validation, but PHP has a function called checkdate(). It does the exact same thing as your isvaliddate() function.
07-Jun-2005 02:33
Here is a quick way to check the a date is valid. I use this when I get users to enter dates via drop downs, which leave open the possibility for impossible dates like 30-Feb-2005 and 31-Jun-2005 etc. This is only necessary as mktime() will accept these invalid dates, which is, in my case, sometimes not the desired handling.
<?php
function isvaliddate($day, $month, $year) {
$day = intval($day);
$month = intval($month);
$year = intval($year);
$time = mktime(0,0,0,$month,$day,$year);
if ($day != date("j",$time)) return false;
if ($month != date("n",$time)) return false;
if ($year != date("Y",$time)) return false;
return true;
}
?>
Note that date("Y",$time) checks the year as a 4 digit year. That line could be replaced as shown below to allow for the 2 digit notation as well.
Also the order the arguments need to be specified is day, month, year, because I come from NZ and that is the format we use here. If you prefer another format, for example month, day, year, just change the order of the arguments on the first line.
<?php
function isvaliddate($day, $month, $year) {
$day = intval($day);
$month = intval($month);
$year = intval($year);
$time = mktime(0,0,0,$month,$day,$year);
if ($day != date("j",$time)) return false;
if ($month != date("n",$time)) return false;
if (($year != date("Y",$time)) AND ($year != date("y",$time))) return false;
return true;
}
?>
Hope this helps someone!
Cheers,
Hayden.
27-May-2005 03:40
cdblog at gmail dot com didn't clarify exactly what his function does: it returns the week number WITHIN THE CURRENT MONTH, i.e. the first day of the month is in week 1, the eighth day is in week 2, the fifteenth is in week 3, the 22nd is in week 4, and the 29th is in week 5. A useful function, if you need such things.
26-May-2005 11:06
