PHP daylight saving time detection
Asked Answered
G

4

34

I need to send an email to users based wherever in the world at 9:00 am local time. The server is in the UK. What I can do is set up a time difference between each user and the server's time, which would then perfectly work if DST didn't exist.

Here's an example to illustrate it:

  • John works in New York, -5 hours from the server (UK) time
  • Richard works in London, UK, so 0 hour difference with the server.

When the server goes from GMT to GMT +1 (BST) at 2:00am on a certain Sunday, this means that John now has a -6H time difference now.

This scenario I can still handle by updating all the users outside the server's local time, but once I've moved forward/backward the time of all the other users, I still need a way to detect when (time and date) the users living outside the UK will (or will not) change their local time to a probable DST one.

I need a PHP method to know/detect when other parts of the world will enter/exit DST.

Greenway answered 27/5, 2011 at 16:35 Comment(0)
R
29

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.

Runic answered 27/5, 2011 at 18:40 Comment(3)
As I do already use the strtotime on several places in my code, I think your answer is the best one, even if I still have a lot to do in particular integrating this into my crontab job (I'll use the TZ= tag). CheersGreenway
this wont work if time specified is in DST especially when it goes -1.Misreckon
@Misreckon Are you sure? It should work whether the day mentioned falls on DST or not, by doing the conversion for that city correctly. However, note that when you use date() subsequently with that timestamp, it uses the default timezone set with date_default_timezone_set()!Ouellette
K
28

As Jimmy points out you can use timezone transitions, but this is not available on PHP <5.3. as dateTimeZone() is PHP>=5.2.2 but getTransitions() with arguments is not! In that case here is a function that can give you timezone data, including whether in DST or not.

function timezonez($timezone = 'Europe/London'){
    $tz = new DateTimeZone($timezone);
    $transitions = $tz->getTransitions();
    if (is_array($transitions)){
        foreach ($transitions as $k => $t){
            // look for current year
            if (substr($t['time'],0,4) == date('Y')){
                $trans = $t;
                break;
            }
        }
    }
    return (isset($trans)) ? $trans : false;
}

Having said that, there is a simpler method using date() if you just need to know whether a timezone is in DST. For example if you want to know if UK is in DST you can do this:

date_default_timezone_set('Europe/London');
$bool = date('I'); // this will be 1 in DST or else 0

... or supply a timestamp as a second arg to date() if you want to specify a datetime other than your current server time.

Kilo answered 14/6, 2012 at 12:2 Comment(3)
for me, to ignore summer time: default time zone Europe/Paris, if (date('I')==1){ date_default_timezone_set('Europe/London');} cause I want always UTC+1Ictus
@khaled_webdev: then use the "+01:00" time-zone.Sourdough
date("I") helped me with a related question. Handy to have the booleanFerrotype
T
16

Changing my answer a bit: DateTimeZone::getTransitions looks like it will do what you need, provided you have PHP >= 5.2.

From a comment in the documentation:

<?php 
$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. Now get the data: 
$offset = $transition[0]['offset']; 
$abbr = $transition[0]['abbr']; 
?>

So here, all we need to do is pass in the timezone we want to check and we can know if that timezone is in DST/what the offset is. You'll then need to check the offset against GMT to see if you want to send your e-mail now, or not now.

Tahoe answered 27/5, 2011 at 16:40 Comment(5)
Hi Jimmy, could you be more precise in your reply and not just give me a PHP function. It's not really helping me out on how to solve this issue. Cheers, Nicolas.Greenway
@Greenway - you need to find the timezone in the array and then check the dst field for that timezone.Narda
@Greenway I revised my answer a bit with a more straightforward method and offered a note on what to do with that. Hope it helps.Tahoe
@JimmySawczuk - please see my answer below regarding this solution on PHP <5.3Kilo
Works like a charm..!! thanx buddy..!!Dovap
M
0

I created this PHP function to see if a time value is BST or not:

<?php
function isBST($timestamp)
{
    $baseDate = date("m/d/Y H:i:s", $timestamp);
    $clocktime=strtotime($baseDate." Europe/London")."\n";
    $utctime=strtotime($baseDate." UTC")."\n";
    //echo "$a \n$b \n";
    if ($clocktime!=$utctime)
    {
        return true;
    }
    else
    {
        return false;
    }
}

?>
Mansour answered 23/2, 2023 at 14:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.