Changing the way that the DST offset is retrieved, given a timestamp.

This is a nightmare issue, as far as I can think of this is "the" solution.
This commit is contained in:
defacer 2005-03-05 22:23:08 +00:00
parent 24bba8390f
commit c9e72798d4

View File

@ -869,47 +869,107 @@ function get_user_dst_preset() {
$preset = get_record('dst_preset', 'id', $presetid); $preset = get_record('dst_preset', 'id', $presetid);
if (!empty($preset) && (time() >= $preset->next_change || time() < $preset->last_change)) { if(!empty($USER)) {
$preset = dst_update_preset($preset); if(empty($USER->dstoffsets)) {
update_record('dst_preset', $preset); $USER->dstoffsets = array(0 => 0);
for($i = 1970; $i < 2030; ++$i) {
$changes = dst_changes_for_year($i, $preset);
if($changes['activate'] != 0) {
$USER->dstoffsets[$changes['activate']] = dst_offset_for_year($i, $preset);
}
if($changes['deactivate'] != 0) {
$USER->dstoffsets[$changes['deactivate']] = 0;
}
}
$calcuntil = make_timestamp(2031, 1, 1, 00, 00, 00, get_user_timezone(99), false);
$USER->dstoffsets[$calcuntil] = NULL;
krsort($USER->dstoffsets);
}
} }
return $preset; return $preset;
} }
function dst_update_preset($dstpreset) { // This should be obsolete, but let's leave it inside a while longer
/*
function dst_update_preset($dstpreset, $time = NULL) {
// What's the date according to our user right now? // What's the date according to our user?
$now = time(); if($time === NULL) {
$date = usergetdate($now); $time = time();
}
$date = usergetdate($time);
$changes = dst_changes_for_year($date['year'], $dstpreset); $changes = dst_changes_for_year($date['year'], $dstpreset);
// Great... let's see where exactly we are now. if($changes['activate'] == 0 && $changes['deactivate'] == 0) {
if ($now < $changes['activate']) { // This timezone doesn't have DST, so don't do anything
// DST has not been turned on this year return $dstpreset;
$dstpreset->next_change = $changes['activate']; }
// For the last change, we need to fetch the previous year's DST deactivation timestamp else if($changes['activate'] == 0) {
$prevchanges = dst_changes_for_year($date['year'] - 1, $dstpreset); // There's only the "deactivate" time
$dstpreset->last_change = $prevchanges['deactivate']; if($time >= $changes['deactivate']) {
$dstpreset->current_offset = 0; $nextchanges = dst_changes_for_year($date['year'] + 1, $dstpreset);
$dstpreset->next_change = min($nextchanges['activate'], $nextchanges['deactivate']);
$dstpreset->current_offset = 0;
}
return $dstpreset;
}
else if($changes['deactivate'] == 0) {
// There's only the "activate" time
if($time >= $changes['activate']) {
$nextchanges = dst_changes_for_year($date['year'] + 1, $dstpreset);
$dstpreset->next_change = min($nextchanges['activate'], $nextchanges['deactivate']);
$dstpreset->current_offset = $dstpreset->apply_offset;
}
}
else if($changes['activate'] < $changes['deactivate']) {
// Northern hemisphere
} else if($now < $changes['deactivate']) { if ($time < $changes['activate']) {
// DST is on for this year right now // DST has not been turned on this year
$dstpreset->last_change = $changes['activate']; $dstpreset->next_change = $changes['activate'];
$dstpreset->next_change = $changes['deactivate']; $dstpreset->current_offset = 0;
$dstpreset->current_offset = $dstpreset->apply_offset;
} else if($time < $changes['deactivate']) {
// DST is on at this time
$dstpreset->next_change = $changes['deactivate'];
$dstpreset->current_offset = $dstpreset->apply_offset;
} else {
// DST has already been turned off; we are nearing the end of the year
$nextchanges = dst_changes_for_year($date['year'] + 1, $dstpreset);
$dstpreset->next_change = $nextchanges['activate'];
$dstpreset->current_offset = 0;
}
}
else if($changes['activate'] > $changes['deactivate']) {
// Southern hemisphere
} else { if ($time < $changes['deactivate']) {
// DST has already been turned off; we are nearing the end of the year // DST is still on from the previous year
$dstpreset->last_change = $changes['deactivate']; $dstpreset->next_change = $changes['deactivate'];
// For the next change, we need to fetch next year's DST activation timestamp $dstpreset->current_offset = $dstpreset->apply_offset;
$nextchanges = dst_changes_for_year($date['year'] + 1, $dstpreset);
$dstpreset->next_change = $nextchanges['activate']; } else if($time < $changes['activate']) {
$dstpreset->current_offset = 0; // DST is off at this time
$dstpreset->next_change = $changes['activate'];
$dstpreset->current_offset = 0;
} else {
// DST has been turned on; we are nearing the end of the year
$nextchanges = dst_changes_for_year($date['year'] + 1, $dstpreset);
$dstpreset->next_change = $nextchanges['deactivate'];
$dstpreset->current_offset = $dstpreset->apply_offset;
}
} }
return $dstpreset; return $dstpreset;
} }
*/
function dst_offset_for_year($year, $dstpreset) {
return $dstpreset->apply_offset * MINSECS;
}
function dst_changes_for_year($year, $dstpreset) { function dst_changes_for_year($year, $dstpreset) {
@ -942,24 +1002,29 @@ function dst_changes_for_year($year, $dstpreset) {
function dst_offset_on($time) { function dst_offset_on($time) {
$preset = get_user_dst_preset(); $preset = get_user_dst_preset();
if (empty($preset)) { if(empty($preset)) {
return 0; return 0;
} }
if ($time >= $preset->last_change && $time < $preset->next_change) { if(empty($USER) || empty($USER->dstchanges)) {
return $preset->current_offset * MINSECS;
}
// It's in some other time period, we need to recalculate
$changes = dst_changes_for_year(gmdate('Y', $time), $preset);
if ($time >= $changes['activate'] && $time < $changes['deactivate']) {
// Compensation required
return $preset->apply_offset * MINSECS;
} else {
return 0; return 0;
} }
$finaloffset = NULL;
foreach($USER->dstchanges as $from => $offset) {
if($from < $time) {
$finaloffset = $offset;
break;
}
}
if($finaloffset === NULL) {
// This means we haven't calculated far enough ahead, do it now?
error('Error in calculating DST offset for timestamp '.$time);
}
return $finaloffset;
} }
function find_day_in_month($index, $weekday, $month, $year) { function find_day_in_month($index, $weekday, $month, $year) {