How can I detect day light savings automatically in PHP?
echo date('I');
The I (capital i) is a 1/0 denoting whether or not daylight saving is currently in effect.
http://php.net/manual/en/function.date.php
hope it helps.
PHP daylight saving time detection
Do you need to know all the details of DST transition yourself? or do you just need to know when is 9:00 am in a given timezone?
If it's the latter, PHP can use your operating system's timezone database to do that for you. The strtotime() function is remarkably good at "figuring out" what you mean:
echo strtotime("today 9:00 am America/New_York"); // prints "1306501200"
echo strtotime("today 9:00 am Europe/London"); // prints "1306483200"
Just make sure you're using one of the PHP supported timezones.
PHP DST detection via date() has reversed
Issue resolved: https://bugs.php.net/bug.php?id=76983
Apparently, Dublin timezone has an exception based on some historical offset.
I am yet to fully understand the reasoning behind this, but it explains the issue technically.
Can I test for daylight saving time (DST) using PHP date()?
When you do strtotime
you get an integer. You have lost all information of timezone, DST etc, you just get an integer. See http://php.net/manual/en/function.strtotime.php
If you want to work with that kind of information, you should use the DateTime
class and functions: http://php.net/manual/en/class.datetime.php
You could, but I think you're better off using DateTime
, set the current timezone to wherever you wish information from:
date_default_timezone_set('UTC');
(from the date()
manual, example 1: http://www.php.net/manual/en/function.date.php )
PHP - using date to find out daylight savings time
You can't use strtotime
because it creates a UTC timestamp, which removes the timezone information. Instead, just use DateTime
$date = new DateTime('30-Mar-2013 America/Los_Angeles');
echo $date->format('I');
# 1
$date = new DateTime('31-Mar-2013 America/Los_Angeles');
echo $date->format('I');
# 1
$date = new DateTime('09-Mar-2013 America/Los_Angeles');
echo $date->format('I');
# 0
$date = new DateTime('10-Mar-2013 America/Los_Angeles');
echo $date->format('I');
# 0
Notice that the DST is still 0 on that last one? That's because the transition happens at 2:00 AM:
$date = new DateTime('10-Mar-2013 01:00 America/Los_Angeles');
echo $date->format('I');
# 0
$date = new DateTime('10-Mar-2013 02:00 America/Los_Angeles');
echo $date->format('I');
# 1
This is a "spring-forward" transition, where the clock jumps from 2:00 to 3:00.
Beware of ambiguity during fall-back transitions, where the clock jumps from 2:00 back to 1:00
$date = new DateTime('3-Nov-2013 01:00 America/Los_Angeles');
echo $date->format('I');
# 1
There are two 1:00 AMs, and this is taking the first one. It is ambiguous, because we might have meant the second one, and that is not represented.
One would think that PHP would allow either of the following:
new DateTime('3-Nov-2013 01:00 -0700 America/Los_Angeles') #PDT
new DateTime('3-Nov-2013 01:00 -0800 America/Los_Angeles') #PST
But these don't seem to work when I tested. I also tried ISO format dates. Anyone know how to properly distinguish ambiguous values in PHP? If so, please edit or update in comments. Thanks.
PHP daylight saving wrong timezone
Your $ref
variable is representing "now". In the echo
statements, you pass $ref
to getOffset
, so it is getting the current offset as of now. Instead, pass $date1
or $date2
.
echo $date1->getTimeZone()->getOffset($date1);
echo "\n";
echo $date2->getTimeZone()->getOffset($date2);
echo "\n";
Or better yet, just call getOffset()
directly:
echo $date1->getOffset();
echo "\n";
echo $date2->getOffset();
echo "\n";
DateTime::diff and end of Daylight Saving Time
Yes, this is a bug PHP currently doesn't handle DST transitions. Bug reports #51051 (still open) and #55253 (fixed in PHP 5.3.9) describe the problems you're having.Best practice is to do all your date calculations in UTC, which avoids this problem. See this post for further details
PHP Daylight savings conundrum
Have you tried looking at DateTimeZone::getTransitions() ?
http://www.php.net/manual/en/datetimezone.gettransitions.php
In particular use the [offset] and [isdst] properties.
- When they save the time, find the first transition before the current date that is NOT DST. (Typically one of the two values in the past year). Convert using the offset of the non-DST period
- When retrieving the value and you are currently in a DST period use the offset of a non-DST period to translate the time, not the current offset.
Taking your EST example, in August even though you are in EDT, you save values using the EST conversion of -5.
When pulling the value back out if they view that value in January you add 5, and if you are in August you add 4.
This will work for 95% of cases I'm assuming that the switches are consistent. If Eastern decided to merge with Central, you could have transitions that run –5/–4/–5/–4/–5/–5/–6/–5/–6/–6 and that would mess things up.
There's no magic bullet for this one. I don't know the details of your app structure, you may just have to try adding 3 hours to the midnight of whatever day you are on so that any recurring daily appointment is stored as a time only.
Automatically get the time taking day light saving hours into account
Don't rely on php.ini settings. If you want control over the timezone, control the timezone:
<?php
$date = new DateTime();
$date->setTimezone(new DateTimeZone('Europe/London'));
$date->format('Y-m-d H:i:s e')
Replace "Europe/London" with whatever your definition of "actual time" is.
As an aside: if date_default_timezone_get()
returns UTC, then the output of $date->format()
is the same on every machine with a correct clock. That's the point of UTC.
How to find the date and time daylight savings begins
I ended up working it our based on some code from this ticket.
$tz = new DateTimeZone('Australia/Sydney');
$transitions = $tz->getTransitions();
if (is_array($transitions)) {
foreach ($transitions AS $k => $t){
// Look for current year
if (substr($t['time'],0,4) == date('Y')) {
// If isdst is set to 1, that means daylight savings starts on this date
if (!empty($t['isdst'])) {
$trans = $t;
// If isdst is empty, that means daylight savings has already started
// so I'll go back to the previous transition
} else {
$prev_k = $k - 1;
$trans = $transitions[$prev_k];
}
break;
}
}
}
echo '<pre>';
print_r($trans);
echo '</pre>';
Related Topics
How to Throttle My Site's API Users
How to Create Static Classes in PHP (Like in C#)
How to Easily Switch Between PHP Versions on MAC Osx
What Does Double Question Mark () Operator Mean in PHP
How to Catch a "Catchable Fatal Error" on PHP Type Hinting
How to Convert Boolean to String
Too Much Data with Var_Dump in Symfony2 Doctrine2
PHP Carbon, Get All Dates Between Date Range
Laravel 5 Not Finding CSS Files
Get Next and Previous Day with PHP
How to Display String That Contains HTML in Twig Template
PHP Syntax Question: What Does the Question Mark and Colon Mean
How to Integrate Wordpress Template with Codeigniter