PHP Daylight Saving Time Detection

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



Leave a reply



Submit