DO
-- once if not dst, twice if dst
daysSinceBase: CARDINAL = hrs / 24;
daysInFourYears: CARDINAL = ( 3*365 + 366 );
fourYears: CARDINAL = daysSinceBase / daysInFourYears;
daysBeyondFourYears: CARDINAL = daysSinceBase MOD daysInFourYears;
pseudoDaysBeyond:
CARDINAL =
-- corrected as if every year had 366 days
daysBeyondFourYears + (MAX[31+29,daysBeyondFourYears]-(31+29))/365;
oddYears: [0..4) = pseudoDaysBeyond / 366;
dayOfYear: CARDINAL = (pseudoDaysBeyond MOD 366)+1; -- one's origin, 366-day year
unpacked.year ¬ gmtBaseYear + 4*fourYears + oddYears;
unpacked.weekday ¬ startWeekday;
THROUGH [0..daysSinceBase MOD 7)
DO unpacked.weekday ¬
SUCC[unpacked.weekday];
IF unpacked.weekday = unspecified
THEN unpacked.weekday ¬ FIRST[DayOfWeek];
ENDLOOP;
FOR month: MonthOfYear
IN MonthOfYear[January..December]
DO
IF dayOfYear <= monthTable[SUCC[month]] THEN {unpacked.month ¬ month; EXIT};
REPEAT FINISHED => ERROR
ENDLOOP;
unpacked.day ¬ dayOfYear-monthTable[unpacked.month];
unpacked.hour ¬ hrs MOD 24;
{
yearStart:
CARDINAL = fourYears * daysInFourYears +
(IF oddYears = 0 THEN 0 ELSE 366 + (oddYears-1)*365);
unpacked.daysThisYear ¬ daysSinceBase - yearStart;
unpacked.secondsThisYear ¬ secs - ((LONG[yearStart] * 24) * 60) * 60;
};
IF unpacked.dst = yes
OR tp.zone = unspecifiedZone
OR NOT CheckDateGE[unpacked, tp.beginDST, 2]
OR CheckDateGE[unpacked, tp.endDST, 1]
THEN EXIT;
hrs ¬ hrs+1;
unpacked.dst ¬ yes;
ENDLOOP;