The visitors went home this morning and it rained - perfect opportunity to pick up on a long overdue task and update my SunUpDown Joomla module to work with Joomla v3 and incidentally extend it so that it can work outside Europe. No urgency, but I know that sooner or later the only one of my sites I use it on will need to go J3, and I had a few requests for it to work elsewhere - in the end I simply took it off JED in the hope that someone else would fill the gap.

No great difficulty in updating a module to work on J3 if it is already working on J1.7+ unless it does something unusual. Update the XML file and while I'm about it move the style sheet into the media/ folder. Check that nothing is using the php DIRECTORY_SEPARATOR constant or its old Joomla DS alias.  Just replace with a forward slash which should work on any server. That gets the old version at least installing and working as it did.

Next some improvement to the layout and stylesheet including changing a couple of parameters defined in the XML. Pretty straightforward.

<?xml version="1.0" encoding="utf-8"?>
<extension type="module" version="3.3" method="upgrade" client="site">
... name, author copyright, licence etc etc ...
	<files>
... files and folders to include ...
	</files>
	<media destination="mod_sunupdown" folder="media">
        <filename>index.html</filename>
        <folder>css</folder>
    </media>
    <config>
        <fields name="params">
            <fieldset name="basic">
... parameter fields as required ...
			</fieldset>
	    </fields>
    </config>
</extension>

The old version had a vague attempt to make it work for any timezone by having the user specify an offset from GMT and then a function to calculate if daylight saving time is active at least for the UK.

	function isBST($date) {
	//returns true if date passed in is in British Summer Time
    	$Year = date("Y", $date);
   	 	$MarLast = $Year."-03-31";
    	$OctLast = $Year."-10-31";
    	//Find the last Sunday in March
    	if (date("w", strtotime($MarLast)) == 0) { //Sunday
    	    $LastMarSun = strtotime($MarLast);
    	} else {
    	    $LastMarSun = strtotime($MarLast." last sunday");
    	}
    	//Find the last Sunday in October
    	if (date("w", strtotime($OctLast)) == 0) { //Sunday
    	    $LastOctSun = strtotime($OctLast);
    	} else {
    	    $LastOctSun = strtotime($OctLast." last sunday");
    	}
    	$BSTStart = strtotime(date("Y-m-d", $LastMarSun)." 01:00:00");
    	$BSTEnd = strtotime(date("Y-m-d", $LastOctSun)." 01:00:00");
   
    	return (($date >= $BSTStart) && ($date <= $BSTEnd));
	} //end function is_bst	

The module helper was supposed to then get the sunrise and sunset times in GMT (having first used the php date_default_timezone_set() function in case the server time is set to NeverNeverLand or something) and apply the specified offset and daylight saving adjustment. Only it wasn't working properly.

This module actually dated back to Joomla 1.0 (it was my first) at which time it was PHP4 and date_default_timezone_set() didn't exist. Since then Joomla has also gained a parameter type for timezone so that should make it easier for the user to pick the right time for the location.

After some confusion caused by thinking that the timezone field type returned a GMT offset integer rather than the timezone name, and then not realising that using date_default_timezone_set() and date_offset_get() and date_sunrise() actually automatically takes account of daylight saving it all turns out to be stupidly simple

	function getSunUp( $params ) {
		date_default_timezone_set($params->get('tzone'));
		$offset = date_offset_get(new DateTime("now")); 
		$lat = $params->get('latitude');
		$long = $params->get('longitude');
		$rise = date_sunrise(time(), SUNFUNCS_RET_STRING, $lat, $long, 90+(5/6), $offset/3600);
		return $rise;
	} //end function getSunUp

This in the module helper.php and a corresponding getSunDown() was all that was needed. No need to calculate whether daylight saving is on or not - just so long as no clever dick wants a version that gives the times in UTC! So that isBST() function above can be pensioned off.

Incidentally the "90+(5/6)" in line 6 is setting the zenith - the angle to the vertical at which it is determined that the sun has set. It makes a couple of minutes difference but in the real world unless you are at sea in a calm its pretty unlikely that you can see the true horizon anyway - I'm tempted to round the times off to the nearest 5 minutes anyway.

Now resubmitted to JED where hopefully it will appear soon. Meantime you can download it here