Reputation: 31
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
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
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