summaryrefslogtreecommitdiff
path: root/ipl/procs/calendar.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/procs/calendar.icn')
-rw-r--r--ipl/procs/calendar.icn998
1 files changed, 998 insertions, 0 deletions
diff --git a/ipl/procs/calendar.icn b/ipl/procs/calendar.icn
new file mode 100644
index 0000000..ad65239
--- /dev/null
+++ b/ipl/procs/calendar.icn
@@ -0,0 +1,998 @@
+############################################################################
+#
+# File: calendar.icn
+#
+# Subject: Procedures for data and time calculation and conversion
+#
+# Author: Robert J. Alexander
+#
+# Date: March 25, 2002
+#
+############################################################################
+#
+# This file is in the public domain.
+#
+############################################################################
+#
+# Procedures in this file supersede several procedures in datetime.icn.
+#
+############################################################################
+#
+# Setting up
+# ----------
+# You will probably want to set a platform environment variable
+# "Cal_TimeZone" to an appropriate local time zone ID string
+# before using this library. Look at the time zone data at the
+# end of this source file and choose an ID for your locale.
+# Common ones for USA are "PST", "MST", "CST", and "EST", although
+# there are more specific ones such as "America/Arizona" that
+# handle special rules. If environment variables are not supported
+# for your platform or your implementation of Icon, explicitly specify
+# the default time zone in your program: e.g.
+#
+# Cal_CurrentTimeZone := Cal_GetTimeZone("PST").
+#
+# If your system uses a base year for date calculation that is
+# different from 1970, your can specify it in an environment
+# variable "Cal_DateBaseYear" or set it directly in the global
+# variable by the same name. Unix and Windows use the library's
+# default value of 1970, but Macintosh used to use 1984 (I'm
+# not sure if Apple have yet seen fit to conform to
+# the 1970 quasi-standard). This setting doesn't matter unless you
+# want your "seconds" values to be the same as your system's.
+#
+# GMT and local time
+# ------------------
+# GMT (Greenwich Mean Time) is a universal time standard (virtually
+# equivalent to "Coordinated Universal Time" (UTC), except for some
+# millisecond differences).
+#
+# Time forms
+# ----------
+# There are two fundamental date/time forms supported by this
+# library: a form in which computation is easy (the "seconds" form)
+# and a form in which formatting is easy (the "calendar record"
+# form).
+# - Seconds -- the time is be represented as an integer that is
+# the number of seconds relative to the beginning of
+# Cal_DateBaseYear, GMT. Cal_DateBaseYear is
+# usually 1970, but can be changed). The "seconds" form is
+# a universal time, independent of locale.
+# - Cal_Rec -- a "calendar record", which has fields for date and
+# time components: year, month, day, hour, minutes, seconds,and
+# day-of-week.
+# The "Cal_Rec" form is usually in terms of local time, including
+# accounting for daylight savings time according to local rules.
+#
+# Notes
+# -----
+# - Several procedures have a final "timeZone" parameter. In those
+# procedures the timeZone parameter is optional and, if omitted,
+# Cal_CurrentTimeZone is used.
+#
+# - The time zone table and list consume around 30KB that can be
+# "freed" by setting both Cal_TimeZoneTable and Cal_TimeZoneList
+# to &null. Procedures Cal_GetTimeZoneTable() and
+# Cal_GetTimeZoneList() will re-create the structures and assign
+# them back to their globals. For many applications, those
+# structures are no longer needed after program initialization.
+#
+# - The global variables are automatically initialized by
+# the Cal_ procedures. However, if you want to use the globals
+# before using any procedures, they must be explicitly initialized
+# by calling Cal_Init().
+#
+# - Time zone records in the time zone structures should be viewed
+# as read-only. If you want to make temporary changes to the
+# fields, copy() the time zone record.
+#
+# Global variables
+# ----------------
+# The following global variables are useful in date and time
+# operations (R/O means please don't change it):
+#
+# - Cal_SecPerMin - (R/O) Seconds per minute.
+# - Cal_SecPerHour - (R/O) Seconds per hour.
+# - Cal_SecPerDay - (R/O) Seconds per day.
+# - Cal_SecPerWeek - (R/O) Seconds per week.
+# - Cal_MonthNames - (R/O) List of month names.
+# - Cal_DayNames - (R/O) List of day names.
+# - Cal_CurrentTimeZone - Current default time zone record --
+# can be changed at any time. Initialized
+# to the time zone whose ID is in
+# environment variable "Cal_TimeZone" if
+# set, or to GMT.
+# - Cal_TimeZoneGMT - (R/O) The GMT time zone record. Can be used
+# as a timeZone parameter to "turn off"
+# conversion to or from local.
+# - Cal_DateBaseYear - The base year from which the "seconds"
+# form is calculated, initialized to
+# the value of environment variable
+# "Cal_DateBaseYear" if set, or 1970 (the
+# year used by both Unix and MS-Windows)
+# - Cal_TimeZoneTable - A table of time zones keyed by the
+# time zone's ID string
+# - Cal_TimeZoneList - A list of time zones ordered by
+# increasing offset from GMT
+#
+# Initialization procedure
+# ------------------------
+# Cal_Init()
+# Initializes global variables. Called implicitly by
+# the Cal_ procedures.
+#
+# Cal_Rec (calendar record) procedures
+# ------------------------------------
+# Cal_Rec(year,month,day,hour,min,sec,weekday) =20
+# Cal_Rec record constructor. All values are integers in
+# customary US usage (months are 1-12, weekdays are 1-7 with
+# 1 -> Sunday)
+#
+# Cal_SecToRec(seconds,timeZone)
+# Converts seconds to a Cal_Rec, applying conversion rules
+# of "timeZone". To suppress conversion, specify timeZone =
+# Cal_TimeZoneGMT.
+#
+# Cal_RecToSec(calRec,timeZone)
+# Converts a Cal_Rec to seconds, applying conversion rules
+# of "timeZone". To suppress conversion, specify timeZone =
+# Cal_TimeZoneGMT.
+#
+# Time zone procedures
+# --------------------
+# Cal_GetTimeZone(timeZoneName)
+# Gets a time zone given a time zone ID string. Fails if
+# a time zone for the given ID cannot be produced.
+#
+# Cal_GetTimeZoneList()
+# Returns the tine zone list that is the value of
+# Cal_TimeZoneList, unless that global has been explicitly
+# set to &null. If the global is null, a new list is built,
+# assigned to Cal_TimeZoneList, and returned.
+#
+# Cal_GetTimeZoneTable()
+# Returns the tine zone table that is the value of
+# Cal_TimeZoneTable, unless that global has been explicitly
+# set to &null. If the global is null, a new table is built,
+# assigned to Cal_TimeZoneTable, and returned. In building
+# the table, Cal_GetTimeZoneList() is called so global
+# variable Cal_TimeZoneList is also set.
+#
+# Date/time calculation procedures
+# --------------------------------
+# Cal_LocalToGMTSec(seconds,timeZone)
+# Converts seconds from local to GMT using the rules of
+# timeZone.
+#
+# Cal_GMTToLocalSec(seconds,timeZone)
+# Converts seconds from GMT to local using the rules of
+# timeZone.
+#
+# Cal_IsLeapYear(year)
+# Returns the number of seconds in a day if year is a leap
+# year, otherwise fails.
+#
+# Cal_LeapYearsBetween(loYear,hiYear)
+# Returns the count of leap years in the range of years n
+# where loYear <= n < hiYear.
+#
+# Cal_IsDST(seconds,timeZone)
+# Returns the DST offset in hours if seconds (local time)
+# is in the DST period, otherwise fails.
+#
+# Cal_NthWeekdayToSec(year,month,weekday,n,fromDay)
+# Returns seconds of nth specified weekday of month, or fails
+# if no such day. This is mainly an internal procedure for
+# DST calculations, but might have other application.
+#
+# Date/time formatting procedures
+# -------------------------------
+# Cal_DateLineToSec(dateline,timeZone)
+# Converts a date in something like Icon's &dateline format
+# (Wednesday, February 11, 1998 12:00 am) to "seconds" form.
+#
+# Cal_DateToSec(date,timeZone)
+# Converts a date string in something like Icon &date format
+# (1998/02/11) to "seconds" form.
+#
+# Cal_SecToDate(seconds,timeZone)
+# Converts "seconds" form to a string in Icon's
+# &date format (1998/02/11).
+#
+# Cal_SecToDateLine(seconds,timeZone)
+# Converts "seconds" form to a string in Icon's &dateline
+# format (Wednesday, February 11, 1998 12:00 am).
+#
+# Cal_SecToUnixDate(seconds,timeZone)
+# Converts "seconds" form to a string in typical UNIX
+# date/time format (Jan 14 10:24 1991).
+#
+# Time-only formatting procedures
+# -------------------------------
+# Cal_ClockToSec(seconds)
+# Converts a time in the format of &clock (19:34:56) to
+# seconds past midnight.
+#
+# Cal_SecToClock(seconds)
+# Converts seconds past midnight to a string in the format of
+# &clock (19:34:56).
+#
+############################################################################
+#
+# See also: datetime.icn, datefns.icn
+#
+############################################################################
+
+global Cal_DateBaseYear,Cal_CurrentTimeZone,Cal_TimeZoneGMT,
+ Cal_SecPerMin,Cal_SecPerHour,Cal_SecPerDay,Cal_SecPerWeek,
+ Cal_MonthNames,Cal_DayNames,Cal_TimeZoneList,Cal_TimeZoneTable
+
+record Cal_Rec(year,month,day,hour,min,sec,weekday)
+
+record Cal_TimeZoneRec(id,hoursFromGMT,data)
+record Cal_TimeZoneData(dstOffset,startYear,
+ startMode,startMonth,startDay,startDayOfWeek,startTime,
+ endMode,endMonth,endDay,endDayOfWeek,endTime)
+
+#
+# Initialize the date globals -- although done automatically by many
+# calls to date procedures, it's not a bad idea to call this explicitly
+# before using.
+#
+procedure Cal_Init(initialTimeZone) #: initialize calendar globals
+ local tzTbl
+ initial {
+ Cal_SecPerMin := 60
+ Cal_SecPerHour := Cal_SecPerMin * 60
+ Cal_SecPerDay := Cal_SecPerHour * 24
+ Cal_SecPerWeek := Cal_SecPerDay * 7
+ Cal_MonthNames := ["January","February","March","April","May","June",
+ "July","August","September","October","November","December"]
+ Cal_DayNames := ["Sunday","Monday","Tuesday","Wednesday","Thursday",
+ "Friday","Saturday"]
+ /Cal_DateBaseYear := integer(getenv("Cal_DateBaseYear")) | 1970
+ tzTbl := Cal_GetTimeZoneTable()
+ Cal_TimeZoneGMT := tzTbl["GMT"]
+ /Cal_CurrentTimeZone := \initialTimeZone |
+ tzTbl["" ~== getenv("Cal_TimeZone")] | Cal_TimeZoneGMT
+ }
+ return
+end
+
+#
+# Produces a date record computed from the seconds since the start of
+# DateBaseYear.
+#
+procedure Cal_SecToRec(seconds,timeZone)
+ local day,hour,min,month,secs,weekday,year
+ static secPerYear
+ initial {
+ Cal_Init()
+ secPerYear := 365 * Cal_SecPerDay
+ }
+ seconds := integer(seconds) | runerr(101,seconds)
+ /timeZone := Cal_CurrentTimeZone
+ seconds := Cal_GMTToLocalSec(seconds,timeZone)
+ weekday := (seconds / Cal_SecPerDay % 7 + 4) % 7 + 1
+ year := Cal_DateBaseYear + seconds / secPerYear
+ seconds -:= (year - Cal_DateBaseYear) * secPerYear +
+ Cal_LeapYearsBetween(Cal_DateBaseYear,year) * Cal_SecPerDay
+ while seconds < 0 do {
+ year -:= 1
+ seconds +:= if Cal_IsLeapYear(year) then 31622400 else 31536000
+ }
+ month := 1
+ every secs :=
+ 2678400 |
+ (if Cal_IsLeapYear(year) then 2505600 else 2419200) |
+ 2678400 |
+ 2592000 |
+ 2678400 |
+ 2592000 |
+ 2678400 |
+ 2678400 |
+ 2592000 |
+ 2678400 |
+ 2592000 |
+ 2678400 do {
+ if seconds < secs then break
+ month +:= 1
+ seconds -:= secs
+ }
+ day := seconds / Cal_SecPerDay + 1
+ seconds %:= Cal_SecPerDay
+ hour := seconds / Cal_SecPerHour
+ seconds %:= Cal_SecPerHour
+ min := seconds / Cal_SecPerMin
+ seconds %:= Cal_SecPerMin
+ return Cal_Rec(year,month,day,hour,min,seconds,weekday)
+end
+
+#
+# Converts a Cal_Rec to seconds since start of DateBaseYear.
+#
+procedure Cal_RecToSec(calRec,timeZone)
+ local day,hour,min,month,sec,seconds,year
+ static days
+ initial {
+ Cal_Init()
+ days := [
+ 0,
+ 2678400,
+ 5097600,
+ 7776000,
+ 10368000,
+ 13046400,
+ 15638400,
+ 18316800,
+ 20995200,
+ 23587200,
+ 26265600,
+ 28857600]
+ }
+ /timeZone := Cal_CurrentTimeZone
+ year := \calRec.year | +&date[1+:4]
+ month := \calRec.month | +&date[6+:2]
+ day := \calRec.day | +&date[9+:2]
+ hour := \calRec.hour | 0
+ min := \calRec.min | 0
+ sec := \calRec.sec | 0
+ seconds := ((year - Cal_DateBaseYear) * 365 +
+ Cal_LeapYearsBetween(Cal_DateBaseYear,year)) * Cal_SecPerDay
+ month > 2 & seconds +:= Cal_IsLeapYear(year)
+ seconds +:= days[month] + (day - 1) * Cal_SecPerDay +
+ hour * Cal_SecPerHour + min * Cal_SecPerMin + sec
+ return Cal_LocalToGMTSec(seconds,timeZone)
+end
+
+#
+# Gets the time zone record with ID "timeZoneName".
+#
+procedure Cal_GetTimeZone(timeZoneName)
+ return \Cal_GetTimeZoneTable()[timeZoneName]
+end
+
+#
+# Builds a table of time zones with keys the time zone names and values
+# the time zone records (Cal_TimeZoneRec).
+#
+procedure Cal_GetTimeZoneTable()
+ local tzTbl,x
+ return \Cal_TimeZoneTable | {
+ tzTbl := table()
+ every x := !Cal_GetTimeZoneList() do
+ tzTbl[x.id] := x
+ Cal_TimeZoneTable := tzTbl
+ }
+end
+
+#
+# Builds a list of time zones ordered by increasing offset from GMT.
+#
+procedure Cal_GetTimeZoneList()
+ return \Cal_TimeZoneList | (Cal_TimeZoneList := Cal_MakeTimeZoneList())
+end
+
+procedure Cal_LocalToGMTSec(seconds,timeZone)
+ initial Cal_Init()
+ /timeZone := Cal_CurrentTimeZone
+ seconds -:= Cal_IsDST(seconds,timeZone) * Cal_SecPerHour
+ seconds -:= timeZone.hoursFromGMT * Cal_SecPerHour
+ return integer(seconds)
+end
+
+procedure Cal_GMTToLocalSec(seconds,timeZone)
+ initial Cal_Init()
+ /timeZone := Cal_CurrentTimeZone
+ seconds +:= timeZone.hoursFromGMT * Cal_SecPerHour
+ seconds +:= Cal_IsDST(seconds,timeZone) * Cal_SecPerHour
+ return integer(seconds)
+end
+
+#
+# Fails unless year is a leap year.
+#
+procedure Cal_IsLeapYear(year) #: determine if year is leap
+ initial Cal_Init()
+ return year % 4 = 0 & (year % 100 ~= 0 | year % 400 = 0) & Cal_SecPerDay
+end
+
+#
+# Counts leap years in the range [loYear,hiYear).
+#
+procedure Cal_LeapYearsBetween(loYear,hiYear)
+ loYear -:= 1; hiYear -:= 1
+ return (hiYear / 4 - loYear / 4) -
+ (hiYear / 100 - loYear / 100) +
+ (hiYear / 400 - loYear / 400)
+end
+
+#
+# If "seconds" represents a time in the DST period for the specified time
+# zone, returns the number of hours by which to adjust standard time to
+# daylight savings time, otherwise fails. "seconds" are local, but not
+# adjusted for DST.
+#
+procedure Cal_IsDST(seconds,timeZone) #: determines if seconds (local) is DST
+ local data,calRec,year,month,startMonth,endMonth,dstOffset,result
+ /timeZone := Cal_CurrentTimeZone
+ if not (data := \timeZone.data) then fail
+ dstOffset := data.dstOffset
+ calRec := Cal_SecToRec(seconds,Cal_TimeZoneGMT)
+ year := calRec.year
+ if year < data.startYear then fail
+ month := calRec.month
+ startMonth := data.startMonth
+ endMonth := data.endMonth
+ return {
+ if startMonth < endMonth then
+ Cal_ApplyDSTRule(seconds,year,month,dstOffset,
+ data.startMode,startMonth,data.startDay,data.startDayOfWeek,
+ data.startTime,
+ data.endMode,endMonth,data.endDay,data.endDayOfWeek,
+ data.endTime - integer(dstOffset * Cal_SecPerHour)) & dstOffset
+ else
+ not Cal_ApplyDSTRule(seconds,year,month,dstOffset,
+ data.endMode,endMonth,data.endDay,data.endDayOfWeek,
+ data.endTime - integer(dstOffset * Cal_SecPerHour),
+ data.startMode,startMonth,data.startDay,data.startDayOfWeek,
+ data.startTime) & dstOffset
+ }
+end
+
+#
+# Calculates number of seconds on the "n"th "weekday" of "month" of "year"
+# following or preceding "fromDay" (e.g. the 3rd Wednesday of April 1998
+# on or following the 5th).
+# If n is negative, n is counted from the end of the month. Fails if
+# the day does not exist (i.e., n is out of range for that month).
+#
+# The "time window" in which the day counting takes place, in the
+# absense of a "fromDay", is the entire month specified. By providing a
+# nonnull "fromDay", the window can be restricted to days including and
+# following "fromDay" (if it is positive), or preceding (and not including,
+# if it is negative).
+#
+# Examples:
+# For first Sunday in April on or after the 5th:
+# NthWeekdayToSec(1998,4,1,1,5)
+# For last Sunday in October, 1998:
+# NthWeekdayToSec(1998,10,1,-1)
+#
+procedure Cal_NthWeekdayToSec(year,month,weekday,n,fromDay) #: gets seconds of nth specified weekday of month
+ local startOfMonth,endOfMonth,lastDay
+ startOfMonth := Cal_RecToSec(Cal_Rec(year,month,1),Cal_TimeZoneGMT)
+ endOfMonth := Cal_RecToSec(Cal_Rec(year,month + 1,1),Cal_TimeZoneGMT)
+ if \fromDay then
+ if fromDay > 0 then
+ startOfMonth +:= (fromDay - 1) * Cal_SecPerDay
+ else if fromDay < 0 then
+ endOfMonth := startOfMonth + (-fromDay - 1) * Cal_SecPerDay
+ return {
+ if n > 0 then {
+ endOfMonth > (startOfMonth + ((weekday + 7 -
+ Cal_SecToRec(startOfMonth,Cal_TimeZoneGMT).weekday) % 7) *
+ Cal_SecPerDay + (n - 1) * Cal_SecPerWeek)
+ }
+ else if n < 0 then {
+ lastDay := endOfMonth - Cal_SecPerDay
+ startOfMonth <= (lastDay -
+ ((Cal_SecToRec(lastDay,Cal_TimeZoneGMT).weekday +
+ 7 - weekday) % 7) * Cal_SecPerDay + (n + 1) * Cal_SecPerWeek)
+ }
+ }
+end
+
+#
+# Converts a date in long form to seconds since start of DateBaseYear.
+#
+procedure Cal_DateLineToSec(dateline,timeZone) #: convert &dateline to seconds
+ local day,halfday,hour,min,month,sec,year
+ static months
+ initial {
+ Cal_Init()
+ months := table()
+ months["jan"] := 1
+ months["feb"] := 2
+ months["mar"] := 3
+ months["apr"] := 4
+ months["may"] := 5
+ months["jun"] := 6
+ months["jul"] := 7
+ months["aug"] := 8
+ months["sep"] := 9
+ months["oct"] := 10
+ months["nov"] := 11
+ months["dec"] := 12
+ }
+ map(dateline) ? {
+ tab(many(' \t'))
+ =("sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "sat") &
+ tab(many(&letters)) | &null & tab(many(' \t,')) | &null
+ month := 1(tab(many(&letters)),tab(many(' \t')) | &null)
+ day <- integer(1(tab(many(&digits)),tab(many(' \t,')) | &null)) | &null &
+ year <- integer(1(tab(many(&digits)),tab(many(' \t')) | &null)) | &null &
+ (hour <- integer(tab(many(&digits))) &
+ ((=":" & min <- integer(tab(many(&digits)))) &
+ ((=":" & sec <- integer(tab(many(&digits)))) | &null) | &null) &
+ tab(many(' \t')) | &null & halfday := =("am" | "pm") | &null &
+ tab(many(' \t')) | &null) | &null & pos(0)
+ }
+ \month := \months[month[1+:3]] | fail
+ if not /(halfday | hour) then {
+ if hour = 12 then hour := 0
+ if halfday == "pm" then
+ hour +:= 12
+ }
+ return Cal_RecToSec(Cal_Rec(year,month,day,hour,min,sec),timeZone)
+end
+
+#
+# Converts a date in Icon &date format (yyyy/mm/dd) do seconds
+# past DateBaseYear.
+#
+procedure Cal_DateToSec(date,timeZone) #: convert &date to seconds
+ date ? return Cal_RecToSec(Cal_Rec(+1(tab(find("/")),move(1)),
+ +1(tab(find("/")),move(1)),+tab(0)),timeZone)
+end
+
+#
+# Converts seconds past DateBaseYear to a &date in Icon date format
+# (yyyy,mm,dd).
+#
+procedure Cal_SecToDate(seconds,timeZone) #: convert seconds to &date
+ local r
+ r := Cal_SecToRec(seconds,timeZone)
+ return right(r.year,4,"0") || "/" || right(r.month,2,"0") || "/" ||
+ right(r.day,2,"0")
+end
+
+#
+# Produces a date in the same format as Icon's &dateline.
+#
+procedure Cal_SecToDateLine(seconds,timeZone) #: convert seconds to &dateline
+ local d,hour,halfday
+ d := Cal_SecToRec(seconds,timeZone)
+ if (hour := d.hour) < 12 then {
+ halfday := "am"
+ }
+ else {
+ halfday := "pm"
+ hour -:= 12
+ }
+ if hour = 0 then hour := 12
+ return Cal_DayNames[d.weekday] || ", " || Cal_MonthNames[d.month] || " " ||
+ d.day || ", " || d.year || " " || hour || ":" ||
+ right(d.min,2,"0") || " " || halfday
+end
+
+#
+# Returns a date and time in UNIX format: Jan 14 10:24 1991
+#
+procedure Cal_SecToUnixDate(seconds,timeZone) #: convert seconds to UNIX time
+ local d
+ d := Cal_SecToRec(seconds,timeZone)
+ return Cal_MonthNames[d.month][1+:3] || " " || d.day || " " ||
+ d.hour || ":" || right(d.min,2,"0") || " " || d.year
+end
+
+#
+# Converts a time in the format of &clock to seconds past midnight.
+#
+procedure Cal_ClockToSec(seconds) #: convert &date to seconds
+ seconds ? return (
+ (1(tab(many(&digits)),move(1)) * 60 +
+ 1(tab(many(&digits)),move(1) | &null)) * 60 +
+ (tab(many(&digits)) | 0)
+ )
+end
+
+#
+# Converts seconds past midnight to a string in the format of &clock.
+#
+procedure Cal_SecToClock(seconds) #: convert seconds to &clock
+ local sec
+ sec := seconds % 60
+ seconds /:= 60
+ return right(seconds / 60,2,"0") || ":" || right(seconds % 60,2,"0") ||
+ ":" || right(sec,2,"0")
+end
+
+#
+# Internal procedure to help process DST rules.
+#
+procedure Cal_ApplyDSTRule(seconds,year,month,dstOffset,
+ startMode,startMonth,startDay,startDayOfWeek,startTime,
+ endMode,endMonth,endDay,endDayOfWeek,endTime)
+ if startMonth <= month <= endMonth &
+ (startMonth < month < endMonth |
+ (month = startMonth &
+ seconds >= Cal_DSTDayOfMonthToSec(
+ year,startMonth,startMode,startDay,startDayOfWeek) +
+ startTime) |
+ (month = endMonth &
+ seconds < Cal_DSTDayOfMonthToSec(
+ year,endMonth,endMode,endDay,endDayOfWeek) +
+ endTime)) then
+ return
+end
+
+#
+# Internal procedure to calculate seconds at the start of the day
+# specified for DST start or end.
+#
+procedure Cal_DSTDayOfMonthToSec(year,month,mode,day,dayOfWeek)
+ return case mode of {
+ "dayOfMonth": Cal_RecToSec(Cal_Rec(year,month,day),Cal_TimeZoneGMT)
+ "dayOfWeek": Cal_NthWeekdayToSec(year,month,dayOfWeek,day)
+ "dayOfWeekStarting": Cal_NthWeekdayToSec(year,month,dayOfWeek,1,day)
+ "dayOfWeekEnding":
+Cal_NthWeekdayToSec(year,month,dayOfWeek,-1,-day)
+ default: runerr(500)
+ }
+end
+
+#
+# Time zone data, ordered by increasing hoursFromGMT
+#
+procedure Cal_MakeTimeZoneList()
+ local data1,data2,data3,data4,data5,data6,data7,data8,data9,data10,
+ data11,data12,data13,data14,data15,data16,data17,data18,data19,data20,
+ data21,data22,data23,data24,data25,data26,data27,data28,data29,data30,
+ data31,data32,data33
+ data1 := Cal_TimeZoneData(1,0,"dayOfWeekStarting",4,1,1,7200,"dayOfWeek",10,-1,1,7200)
+ data2 := Cal_TimeZoneData(0.5,0,"dayOfWeek",10,-1,1,0,"dayOfWeekStarting",3,1,1,0)
+ data3 := Cal_TimeZoneData(1,0,"dayOfWeekStarting",10,9,1,0,"dayOfWeekStarting",3,9 ,1,0)
+ data4 := Cal_TimeZoneData(1,0,"dayOfWeekStarting",4,1,1,0,"dayOfWeekStarting",10,8 ,1,3600)
+ data5 := Cal_TimeZoneData(1,0,"dayOfWeekStarting",4,1,1,3600,"dayOfWeek",10,-1,1,7200)
+ data6 := Cal_TimeZoneData(1,0,"dayOfWeekStarting",4,1,1,0,"dayOfWeek",10,-1,1,0)
+ data7 := Cal_TimeZoneData(1,0,"dayOfWeekStarting",10,1,1,0,"dayOfWeekStarting",2,11,1,0)
+ data8 := Cal_TimeZoneData(1,0,"dayOfWeekStarting",9,8,1,0,"dayOfWeekStarting",4,16 ,1,0)
+ data9 := Cal_TimeZoneData(1,0,"dayOfMonth",10,1,0,0,"dayOfMonth",3,1,0,0)
+ data10 := Cal_TimeZoneData(1,0,"dayOfWeek",3,-1,7,79200,"dayOfWeek",10,-1,7,79200)
+ data11 := Cal_TimeZoneData(1,0,"dayOfWeek",3,-1,1,0,"dayOfWeek",10,-1,1,0)
+ data12 := Cal_TimeZoneData(1,0,"dayOfWeek",3,-1,1,3600,"dayOfWeek",10,-1,1,3600)
+ data13 := Cal_TimeZoneData(1,0,"dayOfWeek",3,-1,1,7200,"dayOfWeek",10,-1,1,7200)
+ data14 := Cal_TimeZoneData(1,0,"dayOfWeek",3,-1,5,7200,"dayOfWeekStarting",10,1,5,10800)
+ data15 := Cal_TimeZoneData(1,0,"dayOfWeekStarting",9,1,1,7200,"dayOfWeekStarting",4 ,1,1,7200)
+ data16 := Cal_TimeZoneData(1,0,"dayOfWeek",3,-1,1,3600,"dayOfWeek",10,-1,1,7200)
+ data17 := Cal_TimeZoneData(1,0,"dayOfWeek",3,-1,1,7200,"dayOfWeek",10,-1,1,10800)
+ data18 := Cal_TimeZoneData(1,0,"dayOfWeek",3,-1,1,0,"dayOfWeek",9,-1,1,0)
+ data19 := Cal_TimeZoneData(1,0,"dayOfWeek",4,-1,6,3600,"dayOfWeek",9,-1,6,10800)
+ data20 := Cal_TimeZoneData(1,0,"dayOfWeek",3,-1,1,10800,"dayOfWeek",10,-1,1,10800)
+ data21 := Cal_TimeZoneData(1,0,"dayOfWeekStarting",3,15,6,0,"dayOfWeekStarting",9,1 ,1,0)
+ data22 := Cal_TimeZoneData(1,0,"dayOfWeekStarting",4,1,6,0,"dayOfWeekStarting",9,15 ,6,3600)
+ data23 := Cal_TimeZoneData(1,0,"dayOfWeek",3,-1,1,7200,"dayOfWeek",9,-1,1,10800)
+ data24 := Cal_TimeZoneData(1,0,"dayOfMonth",4,1,0,0,"dayOfMonth",10,1,0,0)
+ data25 := Cal_TimeZoneData(1,0,"dayOfMonth",4,1,0,10800,"dayOfMonth",10,1,0,14400)
+ data26 := Cal_TimeZoneData(1,0,"dayOfMonth",3,21,0,0,"dayOfMonth",9,23,0,0)
+ data27 := Cal_TimeZoneData(1,0,"dayOfWeek",3,-1,1,18000,"dayOfWeek",10,-1,1,18000)
+ data28 := Cal_TimeZoneData(1,0,"dayOfWeekStarting",4,7,1,0,"dayOfWeek",9,-1,1,0)
+ data29 := Cal_TimeZoneData(1,0,"dayOfWeek",10,-1,1,7200,"dayOfWeek",3,-1,1,10800)
+ data30 := Cal_TimeZoneData(0.5,0,"dayOfWeek",10,-1,1,7200,"dayOfWeek",3,-1,1,10800)
+ data31 := Cal_TimeZoneData(1,0,"dayOfWeek",11,-1,1,7200,"dayOfWeekStarting",3,1,1,10800)
+ data32 := Cal_TimeZoneData(1,0,"dayOfWeekStarting",10,1,1,7200,"dayOfWeekStarting", 3,15,1,10800)
+ data33 :=
+Cal_TimeZoneData(1,0,"dayOfWeekStarting",10,1,1,9900,"dayOfWeekStarting", 3,15,1,13500)
+ return [
+ Cal_TimeZoneRec("Pacific/Niue",-11),
+ Cal_TimeZoneRec("Pacific/Apia",-11),
+ Cal_TimeZoneRec("MIT",-11),
+ Cal_TimeZoneRec("Pacific/Pago_Pago",-11),
+ Cal_TimeZoneRec("Pacific/Tahiti",-10),
+ Cal_TimeZoneRec("Pacific/Fakaofo",-10),
+ Cal_TimeZoneRec("Pacific/Honolulu",-10),
+ Cal_TimeZoneRec("HST",-10),
+ Cal_TimeZoneRec("America/Adak",-10,data1),
+ Cal_TimeZoneRec("Pacific/Rarotonga",-10,data2),
+ Cal_TimeZoneRec("Pacific/Marquesas",-9.5),
+ Cal_TimeZoneRec("Pacific/Gambier",-9),
+ Cal_TimeZoneRec("America/Anchorage",-9,data1),
+ Cal_TimeZoneRec("AST",-9,data1),
+ Cal_TimeZoneRec("Pacific/Pitcairn",-8.5),
+ Cal_TimeZoneRec("America/Vancouver",-8,data1),
+ Cal_TimeZoneRec("America/Tijuana",-8,data1),
+ Cal_TimeZoneRec("America/Los_Angeles",-8,data1),
+ Cal_TimeZoneRec("PST",-8,data1),
+ Cal_TimeZoneRec("America/Dawson_Creek",-7),
+ Cal_TimeZoneRec("America/Phoenix",-7),
+ Cal_TimeZoneRec("PNT",-7),
+ Cal_TimeZoneRec("America/Edmonton",-7,data1),
+ Cal_TimeZoneRec("America/Mazatlan",-7,data1),
+ Cal_TimeZoneRec("America/Denver",-7,data1),
+ Cal_TimeZoneRec("MST",-7,data1),
+ Cal_TimeZoneRec("America/Belize",-6),
+ Cal_TimeZoneRec("America/Regina",-6),
+ Cal_TimeZoneRec("Pacific/Galapagos",-6),
+ Cal_TimeZoneRec("America/Guatemala",-6),
+ Cal_TimeZoneRec("America/Tegucigalpa",-6),
+ Cal_TimeZoneRec("America/El_Salvador",-6),
+ Cal_TimeZoneRec("America/Costa_Rica",-6),
+ Cal_TimeZoneRec("America/Winnipeg",-6,data1),
+ Cal_TimeZoneRec("Pacific/Easter",-6,data3),
+ Cal_TimeZoneRec("America/Mexico_City",-6,data1),
+ Cal_TimeZoneRec("America/Chicago",-6,data1),
+ Cal_TimeZoneRec("CST",-6,data1),
+ Cal_TimeZoneRec("America/Porto_Acre",-5),
+ Cal_TimeZoneRec("America/Bogota",-5),
+ Cal_TimeZoneRec("America/Guayaquil",-5),
+ Cal_TimeZoneRec("America/Jamaica",-5),
+ Cal_TimeZoneRec("America/Cayman",-5),
+ Cal_TimeZoneRec("America/Managua",-5),
+ Cal_TimeZoneRec("America/Panama",-5),
+ Cal_TimeZoneRec("America/Lima",-5),
+ Cal_TimeZoneRec("America/Indianapolis",-5),
+ Cal_TimeZoneRec("IET",-5),
+ Cal_TimeZoneRec("America/Nassau",-5,data1),
+ Cal_TimeZoneRec("America/Montreal",-5,data1),
+ Cal_TimeZoneRec("America/Havana",-5,data4),
+ Cal_TimeZoneRec("America/Port-au-Prince",-5,data5),
+ Cal_TimeZoneRec("America/Grand_Turk",-5,data6),
+ Cal_TimeZoneRec("America/New_York",-5,data1),
+ Cal_TimeZoneRec("EST",-5,data1),
+ Cal_TimeZoneRec("America/Antigua",-4),
+ Cal_TimeZoneRec("America/Anguilla",-4),
+ Cal_TimeZoneRec("America/Curacao",-4),
+ Cal_TimeZoneRec("America/Aruba",-4),
+ Cal_TimeZoneRec("America/Barbados",-4),
+ Cal_TimeZoneRec("America/La_Paz",-4),
+ Cal_TimeZoneRec("America/Manaus",-4),
+ Cal_TimeZoneRec("America/Dominica",-4),
+ Cal_TimeZoneRec("America/Santo_Domingo",-4),
+ Cal_TimeZoneRec("America/Grenada",-4),
+ Cal_TimeZoneRec("America/Guadeloupe",-4),
+ Cal_TimeZoneRec("America/Guyana",-4),
+ Cal_TimeZoneRec("America/St_Kitts",-4),
+ Cal_TimeZoneRec("America/St_Lucia",-4),
+ Cal_TimeZoneRec("America/Martinique",-4),
+ Cal_TimeZoneRec("America/Montserrat",-4),
+ Cal_TimeZoneRec("America/Puerto_Rico",-4),
+ Cal_TimeZoneRec("PRT",-4),
+ Cal_TimeZoneRec("America/Port_of_Spain",-4),
+ Cal_TimeZoneRec("America/St_Vincent",-4),
+ Cal_TimeZoneRec("America/Tortola",-4),
+ Cal_TimeZoneRec("America/St_Thomas",-4),
+ Cal_TimeZoneRec("America/Caracas",-4),
+ Cal_TimeZoneRec("Antarctica/Palmer",-4,data3),
+ Cal_TimeZoneRec("Atlantic/Bermuda",-4,data1),
+ Cal_TimeZoneRec("America/Cuiaba",-4,data7),
+ Cal_TimeZoneRec("America/Halifax",-4,data1),
+ Cal_TimeZoneRec("Atlantic/Stanley",-4,data8),
+ Cal_TimeZoneRec("America/Thule",-4,data1),
+ Cal_TimeZoneRec("America/Asuncion",-4,data9),
+ Cal_TimeZoneRec("America/Santiago",-4,data3),
+ Cal_TimeZoneRec("America/St_Johns",-3.5,data1),
+ Cal_TimeZoneRec("CNT",-3.5,data1),
+ Cal_TimeZoneRec("America/Fortaleza",-3),
+ Cal_TimeZoneRec("America/Cayenne",-3),
+ Cal_TimeZoneRec("America/Paramaribo",-3),
+ Cal_TimeZoneRec("America/Montevideo",-3),
+ Cal_TimeZoneRec("America/Buenos_Aires",-3),
+ Cal_TimeZoneRec("AGT",-3),
+ Cal_TimeZoneRec("America/Godthab",-3,data10),
+ Cal_TimeZoneRec("America/Miquelon",-3,data1),
+ Cal_TimeZoneRec("America/Sao_Paulo",-3,data7),
+ Cal_TimeZoneRec("BET",-3,data7),
+ Cal_TimeZoneRec("America/Noronha",-2),
+ Cal_TimeZoneRec("Atlantic/South_Georgia",-2),
+ Cal_TimeZoneRec("Atlantic/Jan_Mayen",-1),
+ Cal_TimeZoneRec("Atlantic/Cape_Verde",-1),
+ Cal_TimeZoneRec("America/Scoresbysund",-1,data11),
+ Cal_TimeZoneRec("Atlantic/Azores",-1,data11),
+ Cal_TimeZoneRec("Africa/Ouagadougou",0),
+ Cal_TimeZoneRec("Africa/Abidjan",0),
+ Cal_TimeZoneRec("Africa/Accra",0),
+ Cal_TimeZoneRec("Africa/Banjul",0),
+ Cal_TimeZoneRec("Africa/Conakry",0),
+ Cal_TimeZoneRec("Africa/Bissau",0),
+ Cal_TimeZoneRec("Atlantic/Reykjavik",0),
+ Cal_TimeZoneRec("Africa/Monrovia",0),
+ Cal_TimeZoneRec("Africa/Casablanca",0),
+ Cal_TimeZoneRec("Africa/Timbuktu",0),
+ Cal_TimeZoneRec("Africa/Nouakchott",0),
+ Cal_TimeZoneRec("Atlantic/St_Helena",0),
+ Cal_TimeZoneRec("Africa/Freetown",0),
+ Cal_TimeZoneRec("Africa/Dakar",0),
+ Cal_TimeZoneRec("Africa/Sao_Tome",0),
+ Cal_TimeZoneRec("Africa/Lome",0),
+ Cal_TimeZoneRec("GMT",0),
+ Cal_TimeZoneRec("UTC",0),
+ Cal_TimeZoneRec("Atlantic/Faeroe",0,data12),
+ Cal_TimeZoneRec("Atlantic/Canary",0,data12),
+ Cal_TimeZoneRec("Europe/Dublin",0,data12),
+ Cal_TimeZoneRec("Europe/Lisbon",0,data12),
+ Cal_TimeZoneRec("Europe/London",0,data12),
+ Cal_TimeZoneRec("Africa/Luanda",1),
+ Cal_TimeZoneRec("Africa/Porto-Novo",1),
+ Cal_TimeZoneRec("Africa/Bangui",1),
+ Cal_TimeZoneRec("Africa/Kinshasa",1),
+ Cal_TimeZoneRec("Africa/Douala",1),
+ Cal_TimeZoneRec("Africa/Libreville",1),
+ Cal_TimeZoneRec("Africa/Malabo",1),
+ Cal_TimeZoneRec("Africa/Niamey",1),
+ Cal_TimeZoneRec("Africa/Lagos",1),
+ Cal_TimeZoneRec("Africa/Ndjamena",1),
+ Cal_TimeZoneRec("Africa/Tunis",1),
+ Cal_TimeZoneRec("Africa/Algiers",1),
+ Cal_TimeZoneRec("Europe/Andorra",1,data13),
+ Cal_TimeZoneRec("Europe/Tirane",1,data13),
+ Cal_TimeZoneRec("Europe/Vienna",1,data13),
+ Cal_TimeZoneRec("Europe/Brussels",1,data13),
+ Cal_TimeZoneRec("Europe/Zurich",1,data13),
+ Cal_TimeZoneRec("Europe/Prague",1,data13),
+ Cal_TimeZoneRec("Europe/Berlin",1,data13),
+ Cal_TimeZoneRec("Europe/Copenhagen",1,data13),
+ Cal_TimeZoneRec("Europe/Madrid",1,data13),
+ Cal_TimeZoneRec("Europe/Gibraltar",1,data13),
+ Cal_TimeZoneRec("Europe/Budapest",1,data13),
+ Cal_TimeZoneRec("Europe/Rome",1,data13),
+ Cal_TimeZoneRec("Europe/Vaduz",1,data13),
+ Cal_TimeZoneRec("Europe/Luxembourg",1,data13),
+ Cal_TimeZoneRec("Africa/Tripoli",1,data14),
+ Cal_TimeZoneRec("Europe/Monaco",1,data13),
+ Cal_TimeZoneRec("Europe/Malta",1,data13),
+ Cal_TimeZoneRec("Africa/Windhoek",1,data15),
+ Cal_TimeZoneRec("Europe/Amsterdam",1,data13),
+ Cal_TimeZoneRec("Europe/Oslo",1,data13),
+ Cal_TimeZoneRec("Europe/Warsaw",1,data16),
+ Cal_TimeZoneRec("Europe/Stockholm",1,data13),
+ Cal_TimeZoneRec("Europe/Belgrade",1,data13),
+ Cal_TimeZoneRec("Europe/Paris",1,data13),
+ Cal_TimeZoneRec("ECT",1,data13),
+ Cal_TimeZoneRec("Africa/Bujumbura",2),
+ Cal_TimeZoneRec("Africa/Gaborone",2),
+ Cal_TimeZoneRec("Africa/Lubumbashi",2),
+ Cal_TimeZoneRec("Africa/Maseru",2),
+ Cal_TimeZoneRec("Africa/Blantyre",2),
+ Cal_TimeZoneRec("Africa/Maputo",2),
+ Cal_TimeZoneRec("Africa/Kigali",2),
+ Cal_TimeZoneRec("Africa/Khartoum",2),
+ Cal_TimeZoneRec("Africa/Mbabane",2),
+ Cal_TimeZoneRec("Africa/Lusaka",2),
+ Cal_TimeZoneRec("Africa/Harare",2),
+ Cal_TimeZoneRec("CAT",2),
+ Cal_TimeZoneRec("Africa/Johannesburg",2),
+ Cal_TimeZoneRec("Europe/Sofia",2,data11),
+ Cal_TimeZoneRec("Europe/Minsk",2,data17),
+ Cal_TimeZoneRec("Asia/Nicosia",2,data18),
+ Cal_TimeZoneRec("Europe/Tallinn",2,data17),
+ Cal_TimeZoneRec("Africa/Cairo",2,data19),
+ Cal_TimeZoneRec("ART",2,data19),
+ Cal_TimeZoneRec("Europe/Helsinki",2,data20),
+ Cal_TimeZoneRec("Europe/Athens",2,data20),
+ Cal_TimeZoneRec("Asia/Jerusalem",2,data21),
+ Cal_TimeZoneRec("Asia/Amman",2,data22),
+ Cal_TimeZoneRec("Asia/Beirut",2,data18),
+ Cal_TimeZoneRec("Europe/Vilnius",2,data17),
+ Cal_TimeZoneRec("Europe/Riga",2,data23),
+ Cal_TimeZoneRec("Europe/Chisinau",2,data11),
+ Cal_TimeZoneRec("Europe/Bucharest",2,data11),
+ Cal_TimeZoneRec("Europe/Kaliningrad",2,data17),
+ Cal_TimeZoneRec("Asia/Damascus",2,data24),
+ Cal_TimeZoneRec("Europe/Kiev",2,data20),
+ Cal_TimeZoneRec("Europe/Istanbul",2,data20),
+ Cal_TimeZoneRec("EET",2,data20),
+ Cal_TimeZoneRec("Asia/Bahrain",3),
+ Cal_TimeZoneRec("Africa/Djibouti",3),
+ Cal_TimeZoneRec("Africa/Asmera",3),
+ Cal_TimeZoneRec("Africa/Addis_Ababa",3),
+ Cal_TimeZoneRec("EAT",3),
+ Cal_TimeZoneRec("Africa/Nairobi",3),
+ Cal_TimeZoneRec("Indian/Comoro",3),
+ Cal_TimeZoneRec("Asia/Kuwait",3),
+ Cal_TimeZoneRec("Indian/Antananarivo",3),
+ Cal_TimeZoneRec("Asia/Qatar",3),
+ Cal_TimeZoneRec("Africa/Mogadishu",3),
+ Cal_TimeZoneRec("Africa/Dar_es_Salaam",3),
+ Cal_TimeZoneRec("Africa/Kampala",3),
+ Cal_TimeZoneRec("Asia/Aden",3),
+ Cal_TimeZoneRec("Indian/Mayotte",3),
+ Cal_TimeZoneRec("Asia/Riyadh",3),
+ Cal_TimeZoneRec("Asia/Baghdad",3,data25),
+ Cal_TimeZoneRec("Europe/Simferopol",3,data20),
+ Cal_TimeZoneRec("Europe/Moscow",3,data17),
+ Cal_TimeZoneRec("Asia/Tehran",3.5,data26),
+ Cal_TimeZoneRec("MET",3.5,data26),
+ Cal_TimeZoneRec("Asia/Dubai",4),
+ Cal_TimeZoneRec("Indian/Mauritius",4),
+ Cal_TimeZoneRec("Asia/Muscat",4),
+ Cal_TimeZoneRec("Indian/Reunion",4),
+ Cal_TimeZoneRec("Indian/Mahe",4),
+ Cal_TimeZoneRec("Asia/Yerevan",4),
+ Cal_TimeZoneRec("NET",4),
+ Cal_TimeZoneRec("Asia/Baku",4,data27),
+ Cal_TimeZoneRec("Asia/Aqtau",4,data11),
+ Cal_TimeZoneRec("Europe/Samara",4,data17),
+ Cal_TimeZoneRec("Asia/Kabul",4.5),
+ Cal_TimeZoneRec("Indian/Kerguelen",5),
+ Cal_TimeZoneRec("Asia/Tbilisi",5),
+ Cal_TimeZoneRec("Indian/Chagos",5),
+ Cal_TimeZoneRec("Indian/Maldives",5),
+ Cal_TimeZoneRec("Asia/Dushanbe",5),
+ Cal_TimeZoneRec("Asia/Ashkhabad",5),
+ Cal_TimeZoneRec("Asia/Tashkent",5),
+ Cal_TimeZoneRec("Asia/Karachi",5),
+ Cal_TimeZoneRec("PLT",5),
+ Cal_TimeZoneRec("Asia/Bishkek",5,data28),
+ Cal_TimeZoneRec("Asia/Aqtobe",5,data11),
+ Cal_TimeZoneRec("Asia/Yekaterinburg",5,data17),
+ Cal_TimeZoneRec("Asia/Calcutta",5.5),
+ Cal_TimeZoneRec("IST",5.5),
+ Cal_TimeZoneRec("Asia/Katmandu",5.75),
+ Cal_TimeZoneRec("Antarctica/Mawson",6),
+ Cal_TimeZoneRec("Asia/Thimbu",6),
+ Cal_TimeZoneRec("Asia/Colombo",6),
+ Cal_TimeZoneRec("Asia/Dacca",6),
+ Cal_TimeZoneRec("BST",6),
+ Cal_TimeZoneRec("Asia/Alma-Ata",6,data11),
+ Cal_TimeZoneRec("Asia/Novosibirsk",6,data17),
+ Cal_TimeZoneRec("Indian/Cocos",6.5),
+ Cal_TimeZoneRec("Asia/Rangoon",6.5),
+ Cal_TimeZoneRec("Indian/Christmas",7),
+ Cal_TimeZoneRec("Asia/Jakarta",7),
+ Cal_TimeZoneRec("Asia/Phnom_Penh",7),
+ Cal_TimeZoneRec("Asia/Vientiane",7),
+ Cal_TimeZoneRec("Asia/Saigon",7),
+ Cal_TimeZoneRec("VST",7),
+ Cal_TimeZoneRec("Asia/Bangkok",7),
+ Cal_TimeZoneRec("Asia/Krasnoyarsk",7,data17),
+ Cal_TimeZoneRec("Antarctica/Casey",8),
+ Cal_TimeZoneRec("Australia/Perth",8),
+ Cal_TimeZoneRec("Asia/Brunei",8),
+ Cal_TimeZoneRec("Asia/Hong_Kong",8),
+ Cal_TimeZoneRec("Asia/Ujung_Pandang",8),
+ Cal_TimeZoneRec("Asia/Ishigaki",8),
+ Cal_TimeZoneRec("Asia/Macao",8),
+ Cal_TimeZoneRec("Asia/Kuala_Lumpur",8),
+ Cal_TimeZoneRec("Asia/Manila",8),
+ Cal_TimeZoneRec("Asia/Singapore",8),
+ Cal_TimeZoneRec("Asia/Taipei",8),
+ Cal_TimeZoneRec("Asia/Shanghai",8),
+ Cal_TimeZoneRec("CTT",8),
+ Cal_TimeZoneRec("Asia/Ulan_Bator",8,data18),
+ Cal_TimeZoneRec("Asia/Irkutsk",8,data17),
+ Cal_TimeZoneRec("Asia/Jayapura",9),
+ Cal_TimeZoneRec("Asia/Pyongyang",9),
+ Cal_TimeZoneRec("Asia/Seoul",9),
+ Cal_TimeZoneRec("Pacific/Palau",9),
+ Cal_TimeZoneRec("Asia/Tokyo",9),
+ Cal_TimeZoneRec("JST",9),
+ Cal_TimeZoneRec("Asia/Yakutsk",9,data17),
+ Cal_TimeZoneRec("Australia/Darwin",9.5),
+ Cal_TimeZoneRec("ACT",9.5),
+ Cal_TimeZoneRec("Australia/Adelaide",9.5,data29),
+ Cal_TimeZoneRec("Antarctica/DumontDUrville",10),
+ Cal_TimeZoneRec("Pacific/Truk",10),
+ Cal_TimeZoneRec("Pacific/Guam",10),
+ Cal_TimeZoneRec("Pacific/Saipan",10),
+ Cal_TimeZoneRec("Pacific/Port_Moresby",10),
+ Cal_TimeZoneRec("Australia/Brisbane",10),
+ Cal_TimeZoneRec("Asia/Vladivostok",10,data17),
+ Cal_TimeZoneRec("Australia/Sydney",10,data29),
+ Cal_TimeZoneRec("AET",10,data29),
+ Cal_TimeZoneRec("Australia/Lord_Howe",10.5,data30),
+ Cal_TimeZoneRec("Pacific/Ponape",11),
+ Cal_TimeZoneRec("Pacific/Efate",11),
+ Cal_TimeZoneRec("Pacific/Guadalcanal",11),
+ Cal_TimeZoneRec("SST",11),
+ Cal_TimeZoneRec("Pacific/Noumea",11,data31),
+ Cal_TimeZoneRec("Asia/Magadan",11,data17),
+ Cal_TimeZoneRec("Pacific/Norfolk",11.5),
+ Cal_TimeZoneRec("Pacific/Kosrae",12),
+ Cal_TimeZoneRec("Pacific/Tarawa",12),
+ Cal_TimeZoneRec("Pacific/Majuro",12),
+ Cal_TimeZoneRec("Pacific/Nauru",12),
+ Cal_TimeZoneRec("Pacific/Funafuti",12),
+ Cal_TimeZoneRec("Pacific/Wake",12),
+ Cal_TimeZoneRec("Pacific/Wallis",12),
+ Cal_TimeZoneRec("Pacific/Fiji",12),
+ Cal_TimeZoneRec("Antarctica/McMurdo",12,data32),
+ Cal_TimeZoneRec("Asia/Kamchatka",12,data17),
+ Cal_TimeZoneRec("Pacific/Auckland",12,data32),
+ Cal_TimeZoneRec("NST",12,data32),
+ Cal_TimeZoneRec("Pacific/Chatham",12.75,data33),
+ Cal_TimeZoneRec("Pacific/Enderbury",13),
+ Cal_TimeZoneRec("Pacific/Tongatapu",13),
+ Cal_TimeZoneRec("Asia/Anadyr",13,data17),
+ Cal_TimeZoneRec("Pacific/Kiritimati",14)]
+end