Par Kevin Nadin, conférencier Padawan / @kevinjhappy - Forum PHP 2017
date()
$testDate = date('Y-m-d');
echo $testDate;
// 2017-05-26
$testDate = date('Y-m-d H:i:s');
echo $testDate;
// 2017-05-26 16:25:08
date()
accepte un timestamp comme second paramètre
string date ( string $format [, int $timestamp = time() ] )
Un timestamp unix est le nombre de secondes écoulées depuis le
1er Janvier 1970 sans fuseau horaire
Vient des normes de l'IEEE qui ont standardisé cette date en marquant le début de l'ère UNIX
mktime()
Prends en entrée 6 paramètres :
Attention à leur ordre !
$hour = 0;
$minute = 0;
$second = 0;
$month = 10;
$day = 24;
$year = 2016;
$timestamp = mktime($hour, $minute, $second, $month, $day, $year);
$myDate = date('Y-m-d', $timestamp);
echo $myDate; // 2016-10-24
mktime
semble un peu moisi...Ouais c'est vrai, cela peut être très compliqué.
Mais cela peut apporter une précision chirurgicale
// I want to get the last day of last month, we are the 26th May 2017
$month = date('m') - 1;
$year = date('Y');
// get the timestamp of last month
$timestampLastMonth = mktime(0, 0, 0, $month, 1, $year);
// get the last day of the month, so the 30th April
$lastDayOfTheMonth = date('t', $timestampLastMonth);
$timestampLastDayOfLastMonth = mktime(
0, 0, 0, $month, $lastDayOfTheMonth, $year
);
// I have the correct timestamp, I can call the function date
$lastDayOfLastMonth = date('Y-m-d', $timestampLastDayOfLastMonth);
echo $lastDayOfLastMonth; // 2017-04-30
// I want to get the last day of last month, we are the 26th May 2017
// made in one line
$lastDayOfLastMonth = date(
'Y-m-d',
mktime(
0,
0,
0,
date('m') - 1,
date('t',
mktime(
0,
0,
0,
date('m') - 1,
1,
date('Y')
)),
date('Y')
)
);
// => 2017-04-30
Si j'essaye de mettre le 33 janvier
echo date('Y-m-d', mktime(0, 0, 0, 1, 33, 2017));
// 2017-02-02
Cela va prendre la date du 31 janvier + 2 jours
strtotime()
Supposons, nous sommes le 2017-05-26 :
$firstDayOfLastMonth = date('Y-m-d', strtotime("first day of last month"));
// => 2017-04-01
$lastDayOfLastMonth = date('Y-m-d', strtotime("last Day of Last Month"));
// => 2017-04-30
$lastSunday = date('Y-m-d', strtotime("last Sunday"));
// => 2017-05-21
$mondayOfLastWeek = date('Y-m-d', strtotime("last Monday of Last Week"));
// => 2017-05-15
strtotime
est bien ?// WARNING !! first Specific day of last week
// will not give you what you want
$date = date('Y-m-d', strtotime("First Monday of Last Week"));
// => 2017-04-24
// WARNING !! if you are the 31th, Last month will give you
// the day one of this month
$timeThirtyOneOctober = mktime(0,0,0,10,31,2017);
$wrongDate = date('Y-m-d', strtotime("Last Month", $timeThirtyOneOctober));
// => 2017-10-01
// Only way to get it right is by using this
$goodDate = date('Y-m-d', strtotime(
"Last Day of Last Month",
$timeThirtyOneOctober
));
// => 2017-09-30
// WARNING, some sentences may seem ok but do not work at all
$wrongDate = date('Y-m-d', strtotime("Monday of Last Week"));
// => 1970-01-01
// You can't construct with strtotime the 13th of this month
$dayThirteenOfThisMonth = date(
'Y-m-d',
mktime(0, 0, 0, date('m'), 13, date('Y'))
);
// => 2017-05-13
DateTime
Parce que les comportements sont les mêmes !
$firstDayOfThisMonth = new \DateTime('first day of this month');
echo $firstDayOfThisMonth->format('Y-m-d');
// 2017-05-01
$dayFifteenOfThisMonth = new \DateTime();
$dayFifteenOfThisMonth->setTime(0, 0, 0);
$dayFifteenOfThisMonth->setDate(
(int) $dayFifteenOfThisMonth->format('Y'),
(int) $dayFifteenOfThisMonth->format('m'),
15
);
echo $dayFifteenOfThisMonth->format('Y-m-d');
// 2017-05-15
// first Specific day of last Week
// Today is 2017-05-26
$date = new DateTime("First Monday of Last Week");
echo $date->format('Y-m-d') ;
// 2017-04-24
// sentences that may seems ok but does not work at all
$wrongDate = new DateTime("Monday of Last Week");
echo $wrongDate->format('Y-m-d');
// Fatal error: Uncaught Exception: DateTime::__construct():
// Failed to parse time string (Monday of Last Week)
// WARNING !! if you are the 31th, Last month will give you
// the day one of this month
$lastMonthDate = new DateTime("2017-10-31");
$lastMonthDate->modify('Last Month');
echo $lastMonthDate->format('Y-m-d');
// 2017-10-01
// Only way to get it right is by using this
$lastMonthDate = new DateTime("2017-10-31");
$lastMonthDate->modify('Last Day of Last Month');
echo $lastMonthDate->format('Y-m-d');
// 2017-09-30
//Taking the last month of a 31th of this month
$date = Carbon::createFromDate(2016, 10, 31);
Carbon::useMonthsOverflow(false);
$date->subMonth(1);
echo $date->format('Y-m-d');
// 2016-09-30
DateTimeImmutable
DateTime()
$date = new DateTimeImmutable("2017-05-26");
$newDate = $date->setDate(2017, 07, 12);
echo $date->format('Y-m-d'), " <=> ", $newDate->format('Y-m-d');
// 2017-05-26 <=> 2017-07-12
DateTimeImmutable::createFromMutable
// create a specific date
$date = new DateTime('2017-09-15');
$myNewDate = DateTimeImmutable::createFromMutable($date);
echo $myNewDate->format('Y-m-d');
// 2017-09-15
DateTimeZone
// set a date with a Timezone
$date = new DateTime('2017-05-01', new DateTimeZone('Europe/Paris'));
echo "Europe/Paris " , $date->format('Y-m-d H:i:s P');
// Europe/Paris 2017-05-01 00:00:00 +02:00
$date->setDate(2017, 01, 01);
echo "Europe/Paris en hiver " , $date->format('Y-m-d H:i:s P');
// Europe/Paris en hiver 2017-01-01 00:00:00 +01:00
$date->setTimezone(new DateTimeZone('Australia/Sydney'));
echo "Australia/Sydney " , $date->format(\DateTime::ISO8601);
// Australia/Sydney 2017-01-01T10:00:00+1100
// set a date with a Timezone in number of hours
$date = new DateTime('2017-05-01', new DateTimeZone('+02:00'));
echo "UTC + 2 hours " , $date->format('Y-m-d H:i:sP') ;
// UTC + 2 hours 2017-05-01 00:00:00+02:00
$utcDate = new DateTime('2017-05-01', new DateTimeZone('UTC'));
echo "UTC date " , $utcDate->format('Y-m-d H:i:sP');
// UTC date 2017-05-01 00:00:00+00:00
// today in Paris, let's try to get the location of the timezone
$dateInParis = new DateTime('now', new \DateTimeZone('Europe/Paris'));
print_r($dateInParis->getTimezone()->getLocation());
/*Array (
[country_code] => FR
[latitude] => 48.86666
[longitude] => 2.33333
[comments] =>
)*/
// now if we received this date in string format
$newDateInParis = new DateTime($dateInParis->format('Y-m-d H:i:sP'));
var_dump($newDateInParis->getTimezone()->getLocation());
// bool(false)
// today in Paris, let's try to get the location of the timezone
$dateInParis = new DateTime('now', new \DateTimeZone('Europe/Paris'));
$newDateInParis = new DateTime(
$dateInParis->format('Y-m-d H:i:s'),
$dateInParis->getTimezone()
);
print_r($newDateInParis->getTimezone()->getLocation());
/* Array (
[country_code] => FR
[latitude] => 48.86666
[longitude] => 2.33333
[comments] =>
)*/
DateInterval
DateTime->diff
, cela donnera un intervale// set a date Interval
$dateInterval = new DateInterval('P2Y4DT6H8M');
echo $dateInterval->format('%y years, %d days and %h hours, %i minutes');
// 2 years, 4 days and 6 hours, 8 minutes
// equals to :
$dateInterval = DateInterval::createFromDateString(
'2 year + 4 day + 6 hour + 8 minutes'
);
echo $dateInterval->format('%y years, %d days and %h hours, %i minutes');
// 2 years, 4 days and 6 hours, 8 minutes
Demande simple : extraire les 10 derniers jours
// we set default dates, today is 2017-05-29
$endDate = new DateTime();
$startDate = new DateTime();
// substract 10 days with the object DateInterval
$startDate->sub(new DateInterval('P10D'));
// or you can use Date Interval with regular string
$startDate->sub(new DateInterval::createFromDateString('10 Days'));
// or you can use the construct if you don't like DateInterval
$startDate = new DateTime("now - 10 days");
// startDate = 2017-05-19 , endDate = 2017-05-29
Demande : extraire la dernière demi-semaine, soit du lundi au mercredi, ou du jeudi au dimanche
// If today is between Monday to Wednesday,
// We want to get dates from last Thursday to last Sunday
$today = new DateTime();
// 'N' indicate the day number, Monday = 1, Tuesday = 2 ... Sunday = 7
if ($today->format('N') < 4 ){
$startDate = new DateTime('Last Thursday');
$endDate = new DateTime('Last Sunday');
}
// else, today is between Thursday to Sunday,
// we want to get dates from Last Monday to Last Wednesday
else {
$startDate = new DateTime('Last Monday');
$endDate = new DateTime('Last Wednesday');
}
Demande: extraire la dernière semaine, mais si la semaine est à cheval entre 2 mois, il faut prendre le 1er jour du mois
// We need to check If the Last Monday is in the last month
$lastMondayDate = new DateTime('Last Monday');
$lastDayOfLastMonthDate = new DateTime('Last Day of Last Month');
// if the last monday is indeed in the past month,
// we take the first day of this month
if ($lastMondayDate->format('m') === $lastDayOfLastMonthDate->format('m')){
$startDate = new DateTime('First Day of This Month');
}
// else we take the last monday
else{
$startDate = $lastMondayDate ;
}
// in both cases, end date is the Last Sunday
$endDate = new DateTime('Last Sunday');
// Today is 2017-05-29
$date = new DateTime("first day of last month");
echo $date->format('Y-m-d') , ' => ';
$date->setDate(2013, 2, 3);
echo $date->format('Y-m-d');
// Today is : 2017-05-29
$date = new DateTime("first day of last month");
echo $date->format('Y-m-d') , ' => ';
$date->setDate(2013, 2, 3);
echo $date->format('Y-m-d');
// in PHP 7.0.17 - 7.0.19, 7.1.3 - 7.2.0rc2
// 2017-04-01 => 2013-02-03
// in PHP 5.6.0 - 5.6.30, 7.0.0 - 7.0.16, 7.1.0 - 7.1.2
// 2017-04-01 => 2013-02-01
// Anoter Exemple, we create with Last day of this month
$date = new DateTime("last day of this month");
echo $date->format('Y-m-d') , ' => ';
$date->setDate(2012, 2, 03);
echo $date->format('Y-m-d');
// in PHP 7.0.17 - 7.0.19, 7.1.3 - 7.2.0rc2
// 2017-05-31 => 2012-02-03
// in PHP 5.6.0 - 5.6.30, 7.0.0 - 7.0.16, 7.1.0 - 7.1.2
// 2017-05-31 => 2012-02-29
Finalement il a calculé le dernier jour de Février 2012 (année bissextile)
Si vous travaillez sur une version inférieure à 7.1.3, cela risque de ne pas marcher...
DateTimeImmutable
avec DateTimeZone
sont les plus utilisésdate()
avec des timestamps étaient surtout utilisées en procédural