Jump to content
Larry Ullman's Book Forums

Issue With Daylight Saving Time


Recommended Posts

I'm having the following issue to build-up a liturgical calendar; the mistake is related to the daylight saving time, which adds 1h and makes my whole construction invalid:

<?php
	$date = strtotime('09-05-2013');
	echo "Date: ".$date."<br />";
	// May 9th, 2013 is the effective date of Ascension

	//The year can be easily extracted from the date
	$year = date('Y', $date);
	echo "Year: ".$year."<br />";

	// The date of Easter can be easily extracted thanks to the corresponding php-native "easter_date" function
	$easter = easter_date($year);

	// The ascension is 39 days after Easter
	$ascension = ($easter + (39*86400));
	echo "Ascension: ".$ascension."<br />";

	if ($date == $ascension) {
		echo "It's Ascension";
	} else {
		echo "There is a mistake in the code"; }
?>

 

The problem is: the date of 09-05-2013 gives a string which is 3600 sec. more than the calculated value based on Easter.
What can I do to define correctly the $ascension value from Easter, knowing that the daylight saving change does not always occur every year between Easter and Ascension?

 

Link to comment
Share on other sites

Look at the notes in the manual. As it says there, easter_date() is based on the TZ environment variable rather than the default time zone. They do attach a function to solve the problem: :)

/**
 * Get Unix timestamp for midnight on Easter of a given year
 *
 * This function fixes easter_days()'s TZ environment problem
 */
function get_easter_datetime($year) {
   $days = easter_days($year);

   $date = new DateTime("$year-03-21");
   $date->add(new DateInterval("P{$days}D"));

   // Get the correct timestamp from the object
   return $date->getTimestamp();
}

Hope that helps you out.

Edited by Antonio Conte
Link to comment
Share on other sites

Yes, it's object oriented. That doesn't really matter in the end here, though. Both the classes used are part of PHP, so you can drop the exact (updated) code I posted into your own code and use it. You don't have to understand the underlaying logic of DateTime or DateInterval to play with them. ;)

 

This should give you what you want

// Paste the function into your code (like below) Or require/include a file with it
function get_easter_datetime($year) {
    $days = easter_days($year);    

    // Create a DateTime object 
    $date = new DateTime("$year-03-21");

    // and add the number of days after March 21
    // on which Easter falls for the given year
    $date->add(new DateInterval("P{$days}D"));
    
    // Return the result as a unix timestamp
    return $date->getTimestamp();
}

$date = strtotime('09-05-2013');
echo "Date: ".$date."<br />";
// May 9th, 2013 is the effective date of Ascension

// The year can be easily extracted from the date
$year = date('Y', $date);
echo "Year: ".$year."<br />";

// Work with function here
$easter = get_easter_datetime($year);

// The ascension is 39 days after Easter
$ascension = ($easter + (39*86400));
echo "Ascension: ".$ascension."<br />";
echo ($date == $ascension) ? "It's Ascension" : "There is a mistake in the code";

Assuming your logic is sound, this should work perfectly. It's as simple as pasting the function into your project and using get_easter_datetime() instead of easter_days().

 

Edit: Really sorry. I didn't notice the object was returned rather than a value. I ammended the function to return a unix timestamp instead.

 

Edit 2: Added explanatory comments to the function.

Link to comment
Share on other sites

 Share

×
×
  • Create New...