############################################################################
#
# File: calendar.icn
#
# Subject: Procedures for data and time calculation and conversion
#
# Author: Robert J. Alexander
#
# Date: June 23, 2000
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# Procedures in this file supercede 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
This page produced by UniDoc on 2021/04/15 @ 23:59:44.