14

In PHP, you can tell if a given date is during the Daylight Savings Time period by using something like this:

$isDST = date("I", $myDate); // 1 or 0

The problem is that this only tells you whether that one point in time is in DST. Is there a reliable way to check whether DST is in effect at any time in that timezone?


Edit to clarify:

  • Brisbane, Australia does not observe daylight savings at any time of the year. All year around, it is GMT+10.
  • Sydney, Australia does, from October to March when it changes from GMT+10 to GMT+11.

I'm wondering if there would be some existing method, or a way to implement a method which works as such:

timezoneDoesDST('Australia/Brisbane');  // false
timezoneDoesDST('Australia/Sydney');  // true
Lance Roberts
  • 22,383
  • 32
  • 112
  • 130
nickf
  • 537,072
  • 198
  • 649
  • 721
  • I don't understand what you want. Could you rephrase the question somehow? Or maybe give some example? I don't know. – Ionuț G. Stan Oct 19 '09 at 01:23
  • These aussies are weird (no offence meant) in regard to DST: http://www.bcl.com.au/times-daylight-saving.htm – Ionuț G. Stan Oct 19 '09 at 01:42
  • Yeah, there's even a political party whose only policy is to introduce daylight savings in South East Queensland... – nickf Oct 19 '09 at 01:46

5 Answers5

15

I've found a method which works using PHP's DateTimezone class (PHP 5.2+)

function timezoneDoesDST($tzId) {
    $tz = new DateTimeZone($tzId);
    $trans = $tz->getTransitions();
    return ((count($trans) && $trans[count($trans) - 1]['ts'] > time()));
}

or, if you're running PHP 5.3+

function timezoneDoesDST($tzId) {
    $tz = new DateTimeZone($tzId);
    return count($tz->getTransitions(time())) > 0;
}

The getTransitions() function gives you information about each time the offset changes for a timezone. This includes historical data (Brisbane had daylight savings in 1916.. who knew?), so this function checks if there's an offset change in the future or not.

nickf
  • 537,072
  • 198
  • 649
  • 721
  • For Brisbane - I ran the first 5.2PHP version ✅. Second 5.3PHP example ❌ - reported incorrectly that Brisbane was on DST. I'm on 7.2.8 – Simon Dec 26 '19 at 14:16
15

Actually nickf method didn't works for me so I reworked it a little ...

/**
* Finds wherever a TZ is experimenting dst or not
* @author hertzel Armengol <emudojo @ gmail.com>
* @params string TimeZone -> US/Pacific for example
*
*/
function timezoneExhibitsDST($tzId) {
    $tz = new DateTimeZone($tzId);
    $date = new DateTime("now",$tz);  
    $trans = $tz->getTransitions();
    foreach ($trans as $k => $t) 
      if ($t["ts"] > $date->format('U')) {
          return $trans[$k-1]['isdst'];    
    }
}

// Usage  

var_dump(timezoneExhibitsDST("US/Pacific")); --> prints false
var_dump(timezoneExhibitsDST("Europe/London")); --> prints false
var_dump(timezoneExhibitsDST("America/Chicago")); --> prints false

same function call will return true in 1 month (March) hope it helps

sra
  • 23,820
  • 7
  • 55
  • 89
hertzel
  • 151
  • 1
  • 2
3

DateTimeZone::getTransitions might help.

You could probably wing it:

$hasDst = date("I", strtotime('June 1')) !== date("I", strtotime('Jan 1'));

Otherwise you'd need to parse the text-based zoneinfo data files.

Steve Clay
  • 8,671
  • 2
  • 42
  • 48
0

I don't think so, but since almost every country that observes DST changes its time for an entire season or two, you could try to test 4 points during any given year.

For example, test date("I", $date) for 2009/01/01, 2009/04/01, 2009/07/01 and 2009/10/01. If that timezone falls into DST, then at least one of those dates will return 1.

Seb
  • 24,920
  • 5
  • 67
  • 85
0

date has to be on the user/server timezone for it to work, and you can't use a range with date as you do with getTransitions

hertzel
  • 151
  • 1
  • 2