DST nigthmare in php

I hate Daylight Saving Time since my early childhood. There is nothing more that bad, as waking up earlier in autumn. But someone have decided, that this will save a little more money on electricity, programmers should deal with it somehow.
But there is something, that I don’t like even more – it is Israel Daylight Saving Time. And programmers working with Israeli customers, should deal somehow with it also.

I developed recently a widget for displaying Zmanim data in WordPress sites (special time during the day, when it is possible to pray). I used pretty simple DST detection mechanism, until one of users complained, that in Israel time did’t switched recently. Jews like to do things differently, then others and time is no exception.
There are lot of ways how to deal with this problem. Microsoft just hardcoded all dates till 2023 in Windows 7. Now we know approximate End-Of-Life of Windows 7 😉
I have the following function to deal with DST in Israel and all over the world:

function dstWindow ($ts=mktime(), $location="None")
{
$in_dst="false";
$week_day=date("w",$ts);
$sunday_ts=$ts-(60 * 60 * 24*($week_day));
$month=date("m",$ts);
$sunday_month=date("m",$sunday_ts);
$sunday=date("j", $sunday_ts);
$hour=date("H",$sunday_ts);
$day=date("j",$ts);
$year=date("Y",$ts);
if (preg_match("/.*Israel.*/i",$location))
{
    $jdCurrent_t = gregoriantojd($month, $day, $year);
    $jewishDate_t = jdtojewish($jdCurrent_t);
    list($jewishMonth_t, $jewishDay_t, $jewishYear_t) = split('/', $jewishDate_t);
     
    if (($jewishMonth_t >=1) && ($jewishMonth_t <=7)) // DETECT IF CURRENT DATE IS BETWEEN TISHREI AND NISSAN MONTHS
    {
        $in_dst="true";
        if ($jewishMonth_t >=1) // IF NEW YEAR ALREADY STARTED
        {
            $in_dst="false";
            if (($jewishMonth_t == 1) && ($jewishDay_t <= 10)) //IF BEFORE YOM KIPPUR
            {
                $jdYomKipur = jewishtojd(1,10,$jewishYear_t);
                $gregrianYomKipur= jdtogregorian($jdYomKipur);
                list($grMonth,$grDay,$grYear) = split('/', $gregrianYomKipur);
                $YomKipur_ts = mktime(0,0,0,$grMonth, $grDay, $grYear);
                $week_dayYomKipur=date("w",$YomKipur_ts);
                $sundayBeforeYomKipur_ts = $YomKipur_ts-(60 * 60 * 24*($week_dayYomKipur)); //DETECT SUNDAY BEFORE YOM KIPPUR

                if ($ts < $sundayBeforeYomKipur_ts) $in_dst="true"; //IF CURRENT DATE IS BEFORE SUNDAY PRECEEDING YOM KIPPUR, THEN IT IS STILL DST WINDOW
            }
        }
        if ($jewishMonth_t ==7) //IF NISSAN MONTH CAME. TODO: LEAP YEAR DETECTION NEED TO BE ADDED - THIS WILL BE 8TH MONTH
        {
            if ($jewishDay_t <= 15 ) $in_dst="false"; //IF THERE WAS NO SEDER YET, THEN WE ARE STILL OUT OF DST WINDOW
        }
    }
}else{
    if( ($sunday_month>=3) && ($sunday_month<=10) ) // IS CURRENT DATE INSIDE OF MARCH->OCT WINDOW?
    {
        $in_dst="true";
        if($sunday_month=="3") //IS IT MARCH?
	    {
		    if ($sunday>=25 ) //IS IT THE LAST SUN OF THE MONTH?
            {
                $in_dst="true";
            }else{
			    $in_dst="false";
		    }
	    }
        elseif($sunday_month=="10") //IS IT OCT?
        {
            if ($sunday>=25 ) //IS IT THE LAST SUN OF THE MONTH?
            {
                $in_dst="false";
            }else{
	        $in_dst="true";
	    }
        }
    }
}
return $in_dst;
}

Note: this code misses detection either it is Jewish leap year or not. If leap, then month when DST window is false is 8.

Update: I redesigned mechanism of detection weekend between Rosh haShana and Yom Kippur.

3 comments

  1. Moishe,
    Here is a very simple Java method (part of the KosherJava Zmanim API) that takes the Jewish year as a param and returns if it is a Jewish leap year. This seems to be your only TODO item. I plan on looking at your code since my host’s version of Java (and therefore the timezone db) is out of date, and it will result in the same issue that you ran into.

    [java]
    public static boolean isJewishLeapYear(int year) {
    return ((7 * year) + 1) % 19 < 7;
    }
    [/java]

Leave a Reply

%d bloggers like this: