pIPA
pIPA

Reputation: 31

How to know whether current time in DST or not?

How do I know whether the current time of a particular city of the world is in DST or not? Is there a PHP function?

Upvotes: 3

Views: 1628

Answers (2)

Jon Skeet
Jon Skeet

Reputation: 1500285

I'm not a PHP person, but it looks like this is feasible - but awkward.

Given a DateTimeZone, you can find the current offset and a set of transitions. So if you ask for the transitions at "now", you can find out information about the current part of the time zone. A slightly modified example from the docs:

$theTime = time(); # specific date/time we're checking, in epoch seconds. 

$tz = new DateTimeZone('America/Los_Angeles'); 
$transition = $tz->getTransitions($theTime,$theTime); 

# only one array should be returned into $transition.
$dst = $transition[0]['isdst']; 

Upvotes: 4

Mikel
Mikel

Reputation: 25606

Well, it sounds like isdst is supposed to do the right thing, but I've been bitten before, so here's a quick port of my C++ timezone code to PHP:

// given a timezone and a timestamp
// return true if timezone has DST at timestamp, false otherwise
// timezone defaults to current timezone
// timestamp defaults to now
function is_dst($timezone = null, $time = null) {
    $oldtimezone = date_default_timezone_get();
    if (isset($timezone)) {
        date_default_timezone_set($timezone);
    }

    if (!isset($time)) {
        $time = time();
    }

    $tm = localtime($time, true);
    $isdst = $tm['tm_isdst'];
    $offset = 0;
    //$dsttime = mktime_array($tm);
    //echo strftime("%c", $dsttime);

    $tm['tm_isdst'] = 0;
    $nondsttime = mktime_array($tm);
    $offset = $nondsttime - $time;

    date_default_timezone_set($oldtimezone);

    return $offset != 0;
}

function mktime_array($tm) {
    return mktime($tm['tm_hour'], $tm['tm_min'], $tm['tm_sec'], $tm['tm_mon']+1, $tm['tm_mday'], $tm['tm_year']+1900, isset($tm['tm_isdst'])? $tm['tm_isdst']: -1);
}

And some code you can use to test it:

foreach (array(null, "Australia/Sydney", "UTC", "America/Los_Angeles") as $tz) {
    $isdst = is_dst($tz);
    if (isset($tz)) {
        echo $tz;
    }
    else {
        echo "current timezone";
    }
    echo " ";
    if ($isdst) {
        echo "has daylight savings now\n";
    }
    else {
        echo "has standard time now\n";
    }
}

// tests based on known transitions for Sydney (AEST)
foreach (array(null, "2011-04-03 01:59:00", "2011-04-03 02:00:00", "2011-10-02 01:59:00", "2011-10-02 03:00:00") as $timestr) {
    $tz = "Australia/Sydney";
    if (isset($timestr)) {
        $tm = strptime($timestr, "%Y-%m-%d %H:%M:%S");
        $time = mktime_array($tm);
    }
    else {
        $time = time();
    }
    $isdst = is_dst($tz, $time);
    if (isset($tz)) {
        echo $tz;
    }
    else {
        echo "current timezone";
    }
    echo " ";
    if ($isdst) {
        echo "has daylight savings at $timestr\n";
    }
    else {
        echo "has standard time at $timestr\n";
    }
}

For me, it prints:

current timezone has daylight savings now
Australia/Sydney has daylight savings now
UTC has standard time now
America/Los_Angeles has standard time now
Australia/Sydney has daylight savings at 
Australia/Sydney has daylight savings at 2011-04-03 01:59:00
Australia/Sydney has standard time at 2011-04-03 02:00:00
Australia/Sydney has standard time at 2011-10-02 01:59:00
Australia/Sydney has daylight savings at 2011-10-02 03:00:00

Upvotes: 2

Related Questions