diff --git a/.gitattributes b/.gitattributes index 6861ae761f53c9f43cf7312b098d3b3032952890..1c09c76b30be830269963076040424b27f584f25 100644 --- a/.gitattributes +++ b/.gitattributes @@ -44,6 +44,7 @@ testfont binary /lib/modules/Cache.pmod/Storage.pmod/Memory.pike foreign_ident /lib/modules/Cache.pmod/Storage.pmod/Yabu.pike foreign_ident /lib/modules/Cache.pmod/cache.pike foreign_ident +/lib/modules/Calendar.pmod/mkrules.pike foreign_ident /lib/modules/Crypto/_rsa.pike foreign_ident /lib/modules/Crypto/des3.pike foreign_ident /lib/modules/Crypto/des3_cbc.pike foreign_ident diff --git a/lib/modules/Calendar.pmod/CHANGES b/lib/modules/Calendar.pmod/CHANGES new file mode 100644 index 0000000000000000000000000000000000000000..10afe847fb5f8b14ff0ebc0daa96bc815fe79066 --- /dev/null +++ b/lib/modules/Calendar.pmod/CHANGES @@ -0,0 +1,176 @@ +Calendar -> Calendar II +changes and backwards issues +================================================================ + +a-b => b->range(a)/a + + a-b does no longer give the number of a's between a and b. + Correct use to get the number of something in a time period + is to create the period using + + b->range(a) + or, depending on context + b->distance(a) + + and then divide by the type that you wish to count, + + b->xxx(a)/a + + so the old use of + + day2-day1 + + will now be + + day1->distance(day2)/day1 + + with more units allowed, so for instance + + day1->distance(day2)/Month() + + will count the number of months. + + a-b + + will now return a stepped back b time, + + day2-day1 + + therefore means "the day before day2", + which might be quite not what you want in your old code. + +---------------------------------------------------------------- + +a->days(), a->months(), etc + + x->units() no longer gives the possible arguments + to x->unit(), but the timerange objects themselves: + + Week()->days() + => ({day,day,day,...,day}) + + instead of + => ({0,1,2,3,...,6}) + + which is quite more useful. But + + map(x->days(),x->day) + + no longer works! + + Also note that ->units() and ->unit() works on + *all* overlapping timeranges of that unit - + this means that + + year->week(1) + or + year->weeks()[0] + + not always is week 1, but some times week 53 + of the previous year. + +---------------------------------------------------------------- + +iso_name and other quick string formats + + The methods to conjure formats has changed name; + since all units are interchangable, the old method + names "iso_name" and "iso_short_name" are too non- + descript and are now represented by some new methods, + named "format_xxx" - depending on what unit you wish to print: + + format_... + iso_ymd_full "2000-06-02 (Jun) -W22-5 (Fri)" [2] + ymd "2000-06-02" + ymd_short "20000602" + ymd_xshort "000602" [1] + iso_week "2000-W22" + iso_week_short "2000W22" + week "2000-w22" [2] + week_short "2000w22" [2] + month "2000-06" + month_short "200006" [1] + iso_time_full "2000-06-02 (Jun) -W22-5 (Fri) 20:53:14 UTC+1" [2] + ctime "Fri Jun 2 20:53:14 2000\n" [2] [3] + http "Fri, 02 Jun 2000 20:53:14 GMT" [4] + time "2000-06-02 20:53:14" + time_short "20000602 20:53:14" + time_xshort "000602 20:53:14" + mtime "2000-06-02 20:53" + xtime "2000-06-02 20:53:14.123456" + tod "20:53:14" + tod_short "205314" + todz "20:53:14 CET" + todz_iso "20:53:14 UTC+1" + xtod "20:53:14.123456" + mod "20:53" + + [1] note conflict (think 1 February 2003) + [2] language dependent + [3] as from the libc function ctime() + [4] as specified by the HTTP standard; + not language or timezone dependant + +Note + iso_name and iso_short_name are backwards compatible + in the Day and Second objects. + +---------------------------------------------------------------- + +(int), (string), number() and name() + + For the same reason, these doesn't exist either. + Instead, there are the "datetime" method, + that returns a convinient mapping from any object: + + ([ "year": int // year number (2000 AD=2000, 1 BC==0) + "month": int(1..) // month of year + "day": int(1..) // day of month + "yearday": int(1..) // day of year + "week": int(1..) // week of year + "week_day": int(1..) // day of week (depending on calendar) + + "hour": int(0..) // hour of day, including dst + "minute": int(0..59) // minute of hour + "second": int(0..59) // second of minute + "fraction": float // fraction of second + "timezone": int // offset to utc, including dst + + "unix": int // unix time + "julian": int|float // julian day + ]); + + and a number of query methods, + + int month_day() + int month_no() + int week_day() + int week_no() - iso week number + int year_day() - day of year, 1... + int year_no() - year number, 1AD=1, 1BC=0, 2BC=-1 + + timezone dependant: + float fraction_no() + int hour_no() + int minute_no() + int second_no() + + string tzname() - CET, CEST, etc + string tzname_iso() - UTC+1 - always UTC something + int utc_offset() - seconds to utc + + language dependant: + string month_name() - "February" + string month_shortname() - "Feb" + string week_day_name() - "Monday" + string week_day_shortname() - "Mon" + string week_name() - "w42", "v42" + string year_name() - "2000", "437 BC" + + int leap_year() - 1 if year is leap year + + int|float julian_day() - julian day + int unix_time() - unix time + + which should solve the problem better. + diff --git a/lib/modules/Calendar.pmod/Calendar.pike b/lib/modules/Calendar.pmod/Calendar.pike new file mode 100644 index 0000000000000000000000000000000000000000..adbdb9854d492d72e7bb47f819b944868309412f --- /dev/null +++ b/lib/modules/Calendar.pmod/Calendar.pike @@ -0,0 +1,12 @@ +import "."; + +//! module Calendar +//! class Calendar +//! This is the base class of the calendars. + +//! method TimeRange now() +//! Give the zero-length time period of the +//! current time. + +TimeRanges.TimeRange now(); + diff --git a/lib/modules/Calendar.pmod/Coptic.pmod b/lib/modules/Calendar.pmod/Coptic.pmod new file mode 100644 index 0000000000000000000000000000000000000000..968e48c21d3b5f8179fbbb142effa3ee3041ea0e --- /dev/null +++ b/lib/modules/Calendar.pmod/Coptic.pmod @@ -0,0 +1,98 @@ +//! +//! module Calendar +//! submodule Coptic +//! +//! This is the Coptic Orthodox Church calendar, +//! that starts the 11th or 12th September and has +//! 13 months. +//! +//! note: +//! The (default) names of the months +//! are different then other the emacs calendar; +//! I do not know which ones are used - the difference +//! seem to be only the transcription of the phonetic sounds +//! (B <-> P, etc). +//! +//! I do not know for how long back the calendar is valid, +//! either. My sources claim that the calendar is synchronized +//! with the <ref>Gregorian</ref> calendar, which is odd. +//! + +import "."; +// inherit some rules from Gregorian, like week numbering +inherit Gregorian:Gregorian; + +string calendar_name() { return "Coptic"; } + +private static mixed __initstuff=lambda() +{ + f_week_day_shortname_from_number="gregorian_week_day_shortname_from_number"; + f_week_day_name_from_number="gregorian_week_day_name_from_number"; + f_week_day_number_from_name="gregorian_week_day_number_from_name"; + + f_year_name_from_number="coptic_year_name_from_number"; + f_month_name_from_number="coptic_month_name_from_number"; + f_month_shortname_from_number="coptic_month_shortname_from_number"; + f_month_number_from_name="coptic_month_number_from_name"; + f_week_name_from_number="week_name_from_number"; +}(); + +static constant year_offset=-284; +static constant start=1720949; + +static array year_from_julian_day(int jd) +{ + int d=jd-start; + + int century=(4*d+3)/146097; + int century_jd=(century*146097)/4; + int century_day=d-century_jd; + int century_year=(100*century_day+75)/36525; + + return + ({ + century*100+century_year+year_offset, + start+century_year*365+century_year/4+century_jd, + }); +} + +static int julian_day_from_year(int y) +{ + y-=year_offset; + return start+y*365+y/4-y/100+y/400; +} + +static int year_leap_year(int y) +{ + y-=year_offset; + werror("%O\n",y); + return (!(((y)%4) || (!((y)%100) && ((y)%400)))); +} + +static array(int) year_month_from_month(int y,int m) +{ +// [y,m,ndays,myd] + + y+=(m-1)/13; + m=1+(m-1)%13; + + return ({y,m,m==13?year_leap_year(y)+5:30,1+30*(m-1)}); +} + +static array(int) month_from_yday(int y,int yd) +{ +// [month,day-of-month,ndays,month-year-day] + int m=(yd-1)/30+1; + int myd=1+30*(m-1); + return ({m,1+yd-myd,m==13?year_leap_year(y)+5:30,myd}); +} + +class cYear +{ + inherit Gregorian::cYear; + + int number_of_months() + { + return 13*n; + } +} diff --git a/lib/modules/Calendar.pmod/Discordian.pmod b/lib/modules/Calendar.pmod/Discordian.pmod new file mode 100644 index 0000000000000000000000000000000000000000..3c2b08db8cbede7ee623bd5dddd2eefdb2857393 --- /dev/null +++ b/lib/modules/Calendar.pmod/Discordian.pmod @@ -0,0 +1,254 @@ +//! +//! module Calendar +//! submodule Discordian +//! The Discordian calendar, as described on page 34 +//! in the fourth edition of Principia Discordia. +//! +//! Chaotic enough, it's quite simpler then the Gregorian calendar; +//! weeks are 5 days, and evens up on a year. Months are 73 days. +//! +//! The leap day is inserted at the 60th day of the first month +//! (Chaos), giving the first month 74 days. The description of +//! the calendar is a "perpetual date converter from the gregorian +//! to the POEE calendar", so the leap years are the same as +//! the gregorians. +//! +//! The Principia calls months "seasons", but for simplicity I +//! call them months in this calendar. +//! +//! If anyone know more about how to treat the leap day - now it is +//! inserted in the month and week where it lands, rather then being +//! separated from month and weeks, I'm interested to know. +//! +//! - Mirar, Pope of POEE. +//! + +// the discordian calendar follows the gregorian years, very practical ;) + +import "."; +inherit Gregorian:Gregorian; + +string calendar_name() { return "Discordian"; } + +private static mixed __initstuff=lambda() +{ +// language setup + f_week_day_shortname_from_number= + "discordian_week_day_shortname_from_number"; + f_week_day_name_from_number="discordian_week_day_name_from_number"; + f_year_name_from_number="discordian_year_name_from_number"; + f_month_name_from_number="discordian_month_name_from_number"; + f_month_shortname_from_number="discordian_month_shortname_from_number"; + f_month_number_from_name="discordian_month_number_from_name"; + f_week_name_from_number="discordian_week_name_from_number"; + f_week_day_number_from_name="discordian_week_day_number_from_name"; +}(); + +static int compat_week_day(int n) +{ + return n; // N/A +} + +// almost as gregorian +static array year_from_julian_day(int jd) +{ + array a=::year_from_julian_day(jd); + return ({a[0]+1166,a[1]}); +} + +static int julian_day_from_year(int y) +{ + return ::julian_day_from_year(y-1166); +} + +static int year_leap_year(int y) +{ + return ::year_leap_year(y-1166); +} + +static array(int) year_month_from_month(int y,int m) +{ +// [y,m,ndays,myd] + + y+=(m-1)/5; + m=1+(m-1)%5; + + switch (m) + { + case 1: return ({y,m,73+year_leap_year(y),1}); + case 2..5: return ({y,m,73,1+73*(m-1)+year_leap_year(y)}); + } + + error("month out of range\n"); +} + +static array(int) month_from_yday(int y,int yd) +{ +// [month,day-of-month,ndays,month-year-day] + int l=year_leap_year(y); + + if (yd<=73+l) return ({1,yd,73+l,1}); + yd-=l; + int m=(yd+72)/73; + return ({m,yd-(m-1)*73,73,(m-1)*73+l+1}); +} + +static array(int) week_from_julian_day(int jd) +{ +// [year,week,day-of-week,ndays,week-julian-day] + + [int y,int yjd]=year_from_julian_day(jd); + int yday=jd-yjd+1; + int l=year_leap_year(y); + + if (l) + if (yday==60) + return ({y,12,6,6,yjd+55}); + else if (yday>55 && yday<62) + return ({y,12,(yday==61)?5:yday-55,6,yjd+55}); + else if (yday>60) + yday--; + else + l=0; + + int w=(yday+4)/5; + return ({y,w,(yday-1)%5+1,5,yjd+(w-1)*5+l}); +} + +static array(int) week_from_week(int y,int w) +{ +// [year,week,1 (wd),ndays,week-julian-day] + y+=(w-1)/73; + w=1+(w-1)%73; + int yjd=julian_day_from_year(y); + + int l=year_leap_year(y); + if (!l||w<12) return ({y,w,1,5,yjd+(w-1)*5}); + return week_from_julian_day(yjd+(w-1)*5+(l&&w>12)); +} + +static int year_remaining_days(int y,int yday) +{ + return 365+year_leap_year(y)-yday; +} + +class cYear +{ + inherit Gregorian::cYear; + + int number_of_weeks() + { + return 73*n; + } + + TimeRange place(TimeRange what) + { + if (what->is_day) + { + int yd=what->yd; + if (yd>=59) + switch (year_leap_year(what->y)*10+year_leap_year(y)) + { + case 00: + case 11: + break; + case 10: /* from leap to non-leap */ + if (yd==59) return 0; // not this year + yd--; + break; + case 01: /* from non-leap to leap */ + yd++; + break; + } + return Day("ymd_yd",rules,y,yjd,yjd+yd-1,yd,what->n); + } + + return ::place(what); + } + + int year_no() { return y+1166; } +} + +class cDay +{ + inherit Gregorian::cDay; + + string nice_print() + { + mixed err=catch + { + if (m==CALUNKNOWN) make_month(); + if (wd==CALUNKNOWN) make_week(); + return + sprintf("%s %d of %s %s", + week_day_shortname(), + md,month_shortname(), + year_name()); + }; + return "error"; + } + + int year_no() { return y+1166; } +} + +class cMonth +{ + inherit Gregorian::cMonth; + + void create(mixed ...args) + { + ::create(@args); + if (yjd+yd-1!=jd) error("yjd=%O yday=%O jd=%O != %O\n", + yjd,yd,jd,jd+yd-1); + + } + + TimeRange place(TimeRange what,int|void force) + { + if (what->is_day) + { + int wmd=what->month_day(); + if (md==CALUNKNOWN) make_month(); + if (what->m==1 && m==1 && wmd>=60) + { + int l1=year_leap_year(what->y); + int l2=year_leap_year(y); + if (l1||l2) + { + if (l1 && wmd==60) + if (l2) wmd=60; + else { if (!force) return 0; } + else + { + if (l1 && wmd>60) wmd--; + if (l2 && wmd>60) wmd++; + } + } + } + if (!force && wmd>number_of_days()) return 0; + return Day("ymd_yd",rules,y,yjd,jd+wmd-1,yd+wmd-1,what->n); + } + + return ::place(what); + } + + int year_no() { return y+1166; } +} + +class cWeek +{ + inherit Gregorian::cWeek; + + static int weeks_to_week(int y2,int w2) + { + return (y2-y)*73+w2-w; + } + + int number_of_days() + { + [int y2,int w2,int wd2,int nd2,int jd2]=week_from_week(y,w+n); + return jd2-jd; + } + + int year_no() { return y+1166; } +} diff --git a/lib/modules/Calendar.pmod/Event.pmod b/lib/modules/Calendar.pmod/Event.pmod new file mode 100644 index 0000000000000000000000000000000000000000..ecd8edb15e1fdca40384bc53fa50eae3eab57323 --- /dev/null +++ b/lib/modules/Calendar.pmod/Event.pmod @@ -0,0 +1,1103 @@ +import "."; +constant TimeRange=TimeRanges.TimeRange; + +constant M_YD=({0,0,31,59,90,120,151,181,212,243,273,304,334}); +constant M_ED=({({0,31,59,90,120,151,181,212,243,273,304,334,365}), + ({0,31,60,91,121,152,182,213,244,274,305,335,366}), + ({0,31,60,90,120,151,181,212,243,273,304,334,365}) }); +constant M_NAME="---JanFebMarAprMayJunJulAugSepOctNovDec"/3; +constant WD_NAME="---MonTueWedThuFriSatSun"/3; + +// ---------------------------------------------------------------- +// base classes +// ---------------------------------------------------------------- + +//! module Calendar +//! submodule Event +//! subclass Event +//! <ref>Event</ref> is a base class, defining what +//! methods an Event need to have. + +//! method array(TimeRange) scan(TimeRange in) +//! This calculates the eventual events that +//! is contained or overlapped by the given timerange. +//! +//! Example: +//! <tt>Event.christmas_eve->scan(Year(2000))</tt> +//! => <tt>({ Day(Sun 24 Dec 2000) })</tt> +//! +//! <ref>scan</ref> uses <ref>next</ref> if not overloaded. +//! +//! note: +//! <ref>scan</ref> can return an array of overlapping timeranges. +//! +//! This method must use <tt>in->calendar_object-></tt><i>type</i> +//! to create the returned timeranges, and must keep the ruleset. + +//! method TimeRange next(TimeRange from,void|int(0..1) including) +//! method TimeRange previous(TimeRange from,void|int(0..1) including) +//! This calculates the next or previous occurance of the event, +//! from the given timerange's <b>start</b>, +//! including any event occuring at the start if that flag is set. +//! +//! It returns zero if there is no next event. +//! +//! This method is virtual in the base class. + +class Event +{ + string name; + + constant is_event=1; + + TimeRange next(TimeRange from,void|int(0..1) including); + TimeRange previous(TimeRange from,void|int(0..1) including); + +// what events in this period? + array(TimeRange) scan(TimeRange in) + { + array res=({}); + TimeRange t=next(in,1); + for (;;) + { + if (!t || !t->overlaps(in)) return res; + res+=({t}); + t=next(t); + } + } + + mapping(TimeRange:Event) scan_events(TimeRange in) + { + array r=scan(in); + return mkmapping(r,allocate(sizeof(r),this_object())); + } + + Event `|(Event ... with) + { + with-=({0}); + with|=({this_object()}); + if (sizeof(with)==1) return with[0]; + return SuperEvent(with); + } + Event ``|(Event with) { return `|(with); } + + string _sprintf(int t) + { + return (t!='O')?0:sprintf("Event(%s)",name); + } + + array(Event) cast(string to) + { + if (to[..4]=="array") + return ({this_object()}); + else + error("Can't cast to %O\n",to); + } + + string describe() + { + return "Unknown event"; + } +} + +class NullEvent +{ + inherit Event; + + void create(mixed ...args) {} + + TimeRange next(TimeRange from,void|int(0..1) including) + { + return 0; + } + + TimeRange previous(TimeRange from,void|int(0..1) including) + { + return 0; + } +} + +//! module Calendar +//! submodule Event +//! subclass Day_Event +//! <ref>Day_Event</ref> is a base class, extending <ref>Event</ref> +//! for events that are single days, using julian day numbers +//! for the calculations. +//! +//! method array(TimeRange) scan(TimeRange in) +//! method TimeRange next(TimeRange from) +//! method TimeRange next(TimeRange from,int(0..1) including) +//! These methods are implemented, using the +//! virtual method <ref>scan_jd</ref>. +//! see also: Event +//! +//! method int scan_jd(Calendar realm,int jd,int(-1..-1)||int(1..1) direction) +//! These methods has to be defined, and is what +//! really does some work. It should return the next or previos +//! julian day (><i>jd</i>) when the event occurs, +//! or the constant <tt>NODAY</tt> if it doesn't. +//! +//! <i>direction</I> <tt>1</tt> is forward (next), +//! <tt>-1</tt> is backward (previous). + +class Day_Event +{ + inherit Event; + + constant is_day_event=1; + constant NODAY=-1; + + int nd=1; + +// find the next (or same) jd with the event + int scan_jd(Calendar realm,int jd,int(1..1)|int(-1..-1) direction); + +// find + TimeRange next(TimeRange from,void|int(0..1) including) + { + int jd=(int)(from->julian_day())+!including; + jd=scan_jd(from->calendar(),jd,1); + if (jd==NODAY) return 0; + return (from->calendar()->Day)("julian_r",jd,from->ruleset())*nd; + } + + TimeRange previous(TimeRange from,void|int(0..1) including) + { + float|int jd=from->julian_day(); + if (floatp(jd)) jd=(int)ceil(jd); + if (!including) jd--; + jd=scan_jd(from->calendar(),jd,-1); + if (jd==NODAY) return 0; + return (from->calendar()->Day)("julian_r",jd,from->ruleset())*nd; + } +} + + +//! module Calendar +//! submodule Event +//! subclass Nameday +//! This is created by the <ref>Namedays</ref> classes +//! to represent an event for a name. + +class Nameday +{ + inherit Day_Event; + + constant is_nameday=1; + + int jd; + + void create(string _name,int _jd) + { + name=_name; + jd=_jd; + } + + int scan_jd(Calendar realm,int sjd,int(1..1)|int(-1..-1) direction) + { + if (direction==1) return sjd<=jd?jd:NODAY; + else return sjd>=jd?jd:NODAY; + } + + string _sprintf(int t) + { + return t=='O'?sprintf("Nameday(%s)",name):0; + } +} + +//! module Calendar +//! submodule Event +//! subclass Namedays +//! This contains a ruleset about namedays. It +//! is a virtual base class. +//! inherits Event + +class Namedays +{ + inherit Event; + constant is_namedays=1; + +//! method array(string) names(TimeRange t) +//! Gives back an array of names that occur during +//! the time period, in no particular order. + + array(string) names(TimeRange t) + { +// optimize this? + return predef::`|(({}),@values(namedays(t))); + } + +//! method mapping(TimeRange:array(string)) namedays(TimeRange t) +//! Gives back an table of days with names that occur during +//! the time period. Note that days without names will not +//! appear in the returned mapping. + + mapping(TimeRange:array(string)) namedays(TimeRange t) + { + int jd=t->julian_day(); + mapping res=([]); + function(mixed...:TimeRange) day=t->calendar()->Day; + Ruleset rules=t->ruleset(); + [int y,int yjd,int leap]=gregorian_yjd(jd); + int ld; + array(string) names=namedays_year(y); + if (y<2000) ld=55-1; // 24 feb + else ld=60-1; // 29 feb + + for (;;) + { + TimeRange td=day("julian_r",jd,rules); + if (!td->overlaps(t)) return res; + + if (jd>=yjd+365+leap) // next year + { + [y,yjd,leap]=gregorian_yjd(jd); + names=namedays_year(y); + if (y<2000) ld=55-1; // 24 feb + else ld=60-1; // 29 feb + } + + if (!names) + { + jd=yjd+365+leap; // next year, please + } + else + { + string n; + int d=jd-yjd; + if (leap) + { + if (d<ld) n=names[d]; + else if (d>ld) n=names[d-1]; + else n=names[-1]; + } + else + n=names[d]; + + if (n) res[td]=n/","; + jd++; + } + } + } + +//! method TimeRange next_name(TimeRange from,string name,int inclusive) +//! method TimeRange previous_name(TimeRange from,string name,int inclusive) +//! Gives back the next or previous day where the name +//! occurs, inclusive the start of the given timerange if +//! that flag is non-zero. + +//! method array(string) namedays_year(int y) +//! Static virtual function that should give back the array +//! of namedays that year, or zero if there +//! are no named days for that year. +//! +//! The array is arranged as day 1..365 +//! a non-leap year, followed by the leap day. +//! If a day doesn't contain names, it should be zero, +//! not a string. If a day has more then one name, +//! it should be separated by a comma (in the string!). + + static array(string) namedays_year(int y); + +//! method int nameday_lookup(int y,string name) +//! Static virtual function that gives back the +//! day (1..) of the year for the given name - +//! if the year is a non-leap year (!), -1 +//! if the name is on the leap day, or zero if +//! the name doesn't exist that year. + + static int nameday_lookup(int y,string s); + +//! method mapping make_lookup(array(string) names) +//! Help function to make a lookup mapping +//! of the names feeded to it. +//! note: +//! This function is <tt>static</tt>. + + static mapping make_lookup(array(string) a) + { + mapping m=([]); + int i; + foreach (a,string z) + { + if (i++==365) i=-1; // leap day last + if (z) foreach (z/",",string s) + m[lower_case(s)]=i; + } + } + + mapping(TimeRange:Event) scan_events(TimeRange in) + { + mapping res=([]); + foreach ((array)namedays(in),[TimeRange t,array(string) s]) + res[t]=predef::`|(@map(s,Nameday,t->julian_day())); + return res; + } + + array(TimeRange) scan(TimeRange in) + { + return indices(namedays(in)); + } + +//! method TimeRange previous(TimeRange from,void|int(0..1) including) +//! method TimeRange next(TimeRange from,void|int(0..1) including) +//! known bugs: +//! Just returns the argument converted to a day. + + TimeRange next(TimeRange from,void|int(0..1) including) + { + return from->calendar() + ->Day("julian_r",(int)(from->julian_day()),from->ruleset()); + } + + TimeRange previous(TimeRange from,void|int(0..1) including) + { + return from->calendar() + ->Day("julian_r",(int)(from->julian_day()),from->ruleset()); + } + + string _sprintf(int t) + { + return t=='O'?sprintf("Namedays(%s)",name):0; + } + + string describe() + { + return "Namedays"; + } +} + + +// ---------------------------------------------------------------- +// simple Gregorian date events +// ---------------------------------------------------------------- + +static array gregorian_yjd(int jd) +{ + int d=jd-1721426; + + int century=(4*d+3)/146097; + int century_jd=(century*146097)/4; + int century_day=d-century_jd; + int century_year=(100*century_day+75)/36525; + + int y=century*100+century_year+1; + + return + ({ + y, + 1721426+century_year*365+century_year/4+century_jd, + (!(((y)%4) || (!((y)%100) && ((y)%400)))) + }); +} + +static array gregorian_year(int y) +{ + return + ({ + y, + 1721426+(y-1)*365+(y-1)/4-(y-1)/100+(y-1)/400, + (!(((y)%4) || (!((y)%100) && ((y)%400)))) + }); +} + +static array julian_yjd(int jd) +{ + int d=jd-1721058; + + int quad=d/1461; + int quad_year=max( (d%1461-1)/365, 0); + + int y=quad*4+quad_year; + + return + ({ + y, + 1721424+(y-1)*365+(y-1)/4, + !(y%4), + }); +} + +static array julian_year(int y) +{ + return + ({ + y, + 1721424+(y-1)*365+(y-1)/4, + !(y%4), + }); +} + +// a set date of year, counting leap day in february - +// used for the gregorian fixed events in the events list +class Gregorian_Fixed +{ + inherit Day_Event; + + constant is_fixed=1; + + int md,mn; + int yd; + + void create(string _name,int(1..31) _md,int(1..12) _mn,int ... _n) + { + name=_name; + md=_md; + mn=_mn; + + yd=M_YD[mn]+md; +// if (sizeof(_n)) nd=_n[0]; + nd=1; + } + + int scan_jd(Calendar realm,int jd,int(-1..1) direction) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + int njd; + + if (leap && yd>59) + njd=yjd+yd; + else + njd=yjd+yd-1; // yd start with 1 + + if (direction==1) + { + if (njd>=jd) return njd; + return scan_jd(realm,yjd+365+leap,1); + } + if (njd<=jd) return njd; + return scan_jd(realm,yjd-1,-1); + } + + string describe() + { + return sprintf("%s %2d",M_NAME[mn],md); + } +} + +// same, but julian +class Julian_Fixed +{ + inherit Gregorian_Fixed; + + int scan_jd(Calendar realm,int jd,int(-1..1) direction) + { + [int y,int yjd,int leap]=julian_yjd(jd); + int njd; + + for (;;) + { + if (leap && yd>59) + njd=yjd+yd; + else + njd=yjd+yd-1; // yd start with 1 + + if (direction==1) + { + if (njd>=jd) return njd; + [y,yjd,leap]=julian_year(y+1); + } + else + { + if (njd<=jd) return njd; + [y,yjd,leap]=julian_year(y-1); + } + } + } + + string describe() + { + return sprintf("%s %2d julian",M_NAME[mn],md); + } +} + +//! module Calendar +//! submodule Event +//! subclass Date +//! This class represents the event of a given gregorian date. +//! For instance, +//! <tt>Event.Date(12,10)->next(Day())</tt> +//! finds the next 12 of October. +//! +//! method void create(int month_day,int month) +//! The event is created by a given month day and +//! a month number (1=January, 12=December). + +class Date +{ + inherit Day_Event; + + int md,mn; + + int yd; + + void create(int _md,int _mn) + { + md=_md; + mn=_mn; + name=M_NAME[mn]+" "+md; + + yd=M_YD[mn]+md; + } + + int scan_jd(Calendar realm,int jd,int(-1..1) direction) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + for (;;) + { + int njd; + + if (leap && yd>60) + njd=yjd+yd; + else + njd=yjd+yd-1; // yd start with 1 + + if (((direction==1)?njd>=jd:(njd<=jd)) && + njd-yjd<M_ED[leap][mn]) return njd; + + if (yd>M_ED[2][mn]) return NODAY; // will never happen + + if (direction==1) + [y,yjd,leap]=gregorian_yjd(yjd+365+leap); + else + [y,yjd,leap]=gregorian_yjd(yjd-1); + } + } +} + +//! module Calendar +//! submodule Event +//! subclass Date_Weekday +//! This class represents the event that a given gregorian date appears +//! a given weekday. +//! For instance, +//! <tt>Event.Date_Weekday(12,10,5)->next(Day())</tt> +//! finds the next 12 of October that is a friday. +//! +//! method void create(int month_day,int month,int weekday) +//! The event is created by a given month day, +//! a month number (1=January, 12=December), and a +//! weekday number (1=Monday, 7=Sunday). +//! +//! note: +//! The week day numbers used +//! are the same as the day of week in the <ref>ISO</ref> calendar - +//! the <ref>Gregorian</ref> calendar has 1=Sunday, 7=Saturday. + +class Date_Weekday +{ + inherit Day_Event; + + int md,mn; + + int yd; + int jd_wd; + + void create(int _md,int _mn,int wd) + { + md=_md; + mn=_mn; + name=M_NAME[mn]+" "+md+" "+WD_NAME[wd]; + + yd=M_YD[mn]+md; + jd_wd=(wd+6)%7; + } + + int scan_jd(Calendar realm,int jd,int(-1..1) direction) + { + if (md<1) return 0; + [int y,int yjd,int leap]=gregorian_yjd(jd); + for (;;) + { + int njd; + + if (leap && yd>60) + njd=yjd+yd; + else + njd=yjd+yd-1; // yd start with 1 + + if (jd_wd==njd%7 && + ((direction==1)?njd>=jd:(njd<=jd)) && + njd-yjd<M_ED[leap][mn]) return njd; + + if (yd>M_ED[2][mn]) return NODAY; // will never happen + + if (direction==1) + [y,yjd,leap]=gregorian_yjd(yjd+365+leap); + else + [y,yjd,leap]=gregorian_yjd(yjd-1); + } + } +} + +//! module Calendar +//! submodule Event +//! subclass Monthday_Weekday +//! This class represents the event that a given gregorian +//! day of month appears a given weekday. +//! For instance, +//! <tt>Event.Date_Weekday(13,5)->next(Day())</tt> +//! finds the next friday the 13th. +//! +//! method void create(int month_day,int weekday) +//! The event is created by a given month day, +//! and a weekday number (1=Monday, 7=Sunday). +//! +//! note: +//! The week day numbers used +//! are the same as the day of week in the <ref>ISO</ref> calendar - +//! the <ref>Gregorian</ref> calendar has 1=Sunday, 7=Saturday. + +class Monthday_Weekday +{ + inherit Day_Event; + + int md; + int jd_wd; + + void create(int _md,int wd) + { + md=_md; + name=md+","+WD_NAME[wd]; + jd_wd=(wd+6)%7; + } + + int scan_jd(Calendar realm,int jd,int(-1..1) direction) + { + if (md>31 || md<1) return 0; + [int y,int yjd,int leap]=gregorian_yjd(jd); + for (;;) + { + array z,w; + + if (!leap) + z=({0,31,59,90,120,151,181,212,243,273,304,334}); + else + z=({0,31,60,91,121,152,182,213,244,274,305,335}); + + z=map(z,`+,yjd,md,-1); + w=map(z,`%,7); + + if (direction==1) + { + foreach (enumerate(12),int i) + if (w[i]==jd_wd && z[i]>=jd && + z[i]-yjd<M_ED[leap][i+1]) return z[i]; + [y,yjd,leap]=gregorian_yjd(yjd+365+leap); + } + else + { + foreach (enumerate(12),int i) + if (w[i]==jd_wd && z[i]<=jd && + z[i]-yjd<M_ED[leap][i+1]) return z[i]; + [y,yjd,leap]=gregorian_yjd(yjd-1); + } + } + } +} + +//! module Calendar +//! submodule Event +//! subclass Weekday +//! This class represents any given weekday. +//! For instance, +//! <tt>Event.Weekday(5)->next(Day())</tt> +//! finds the next friday. +//! +//! These are also available as the pre-defined events +//! "monday", "tuesday", "wednesday", "thursday", +//! "friday", "saturday" and "sunday". +//! +//! method void create(int month_day,int weekday) +//! The event is created by a given month day, +//! and a weekday number (1=Monday, 7=Sunday). +//! +//! note: +//! The week day numbers used +//! are the same as the day of week in the <ref>ISO</ref> calendar - +//! not the <ref>Gregorian</ref> or <ref>Julian</ref> +//! calendar that has 1=Sunday, 7=Saturday. + +class Weekday +{ + inherit Day_Event; + constant is_weekday=1; + + int jd_wd; + + void create(int wd) + { + jd_wd=(wd+6)%7; // convert to julian day numbering + name=WD_NAME[wd]; + } + + int scan_jd(Calendar realm,int jd,int(-1..1) direction) + { + if (direction==-1) return jd-(jd-jd_wd)%7; + return jd+(7-(jd-jd_wd))%7; + } +} + + +// Easter + +class Easter +{ + inherit Day_Event; + +// shift is the year to shift from old to new style + + int shift=1582; + + void create(void|int _shift) + { + if (_shift) shift=_shift; + } + + int new_style(int y) + { + int century=y/100; + int solar=century-century/4; + int lunar=(century-15-(century-17)/25)/3; + int epact=(13+11*(y%19)-solar+lunar)%30; +// if (epact<0) epact+=30; // not neccesary for pike + int new_moon=31-epact; +// werror("epact: %O\n",epact); +// werror("new_moon: %O\n",new_moon); + if (new_moon<8) + if (epact==24 || epact==25 && (y%19)>10) + new_moon+=29; + else + new_moon+=30; + int full_moon=new_moon+13; + int week_day=(2+y+y/4-solar+full_moon)%7; + return full_moon+7-week_day; + } + + int old_style(int y) + { +#if 1 + int new_moon=23-11*(y%19); + while (new_moon<8) new_moon+=30; + int full_moon=new_moon+13; + int week_day=(y+y/4+full_moon)%7; + return full_moon+7-week_day; +#else + int g=y%19; + int i=(19*g+15)%30; + int j=(y+y/4+i)%7; + int l=i-j; + int m=3+(l+40)/44; + int d=l+28-31*(m/4); +// werror("y=%d m=%d d=%d l=%d\n",y,m,d,l); + return l+28; +#endif + } + + int easter_yd(int y,int yjd,int leap) + { + int z=(y<shift)?old_style(y):new_style(y); + return `+(yjd,z,58,leap); + } + + array(int) my_year(int y) + { + if (y<shift) return julian_year(y); + return gregorian_year(y); + } + + int scan_jd(Calendar realm,int jd,int(-1..1) direction) + { + int y,yjd,leap,ejd; + +// werror("scan %O %O\n",jd,direction); + + [y,yjd,leap]=gregorian_yjd(jd); + if (y<shift) + [y,yjd,leap]=julian_yjd(jd); + + for (;;) + { + ejd=easter_yd(y,yjd,leap); + +// werror("[%O %O %O] %O (%O)\n",y,yjd,leap,ejd,ejd-yjd+1); + + if (direction==1) + { + if (ejd>=jd) return ejd; + [y,yjd,leap]=my_year(y+1); + } + else + { + if (ejd<=jd) return ejd; + [y,yjd,leap]=my_year(y-1); + } + } + } +} + +// Easter relative + +class Easter_Relative +{ + inherit Easter; + + constant is_easter_relative=1; + + int offset; + + void create(string _name,void|int _offset) + { + name=_name; + offset=_offset; + } + + int scan_jd(Calendar realm,int jd,int(-1..1) direction) + { + return offset+::scan_jd(realm,jd-direction*offset,direction); + } + + string describe() + { + return sprintf("%seaster %+2d, %s", + shift>2000?"orthodox ":"", + offset,WD_NAME[(offset-1)%7+1]); + } +} + +// Orthodox Easter relative +// simple set shift year very high + +class Orthodox_Easter_Relative +{ + inherit Easter_Relative; + + constant is_easter_relative=1; + + int offset; + + void create(string _name,void|int _offset) + { + ::create(_name,_offset); + shift=9999999; + } +} + +// Monthday Weekday relative, +// n:th special weekday, +// "fourth sunday before 24 dec" => md=24,mn=12,wd=7,n=-4 + +class Monthday_Weekday_Relative +{ + inherit Gregorian_Fixed; + + constant is_fixed=0; + + int offset; + int wd; + + int n,inclusive; + + void create(string name,int(1..31) md,int(1..12) mn, + int(1..7) _wd,int _n,void|int(0..1) _inclusive) + { + ::create(name,md,mn); + + n=_n; + inclusive=_inclusive; + +// offset is the offset to the last possible day + if (n<0) + offset=(n+1)*7-!inclusive; + else if (n>0) + offset=n*7-!!inclusive; + else + offset=3; + + wd=_wd; + } + + int scan_jd(Calendar realm,int jd,int(-1..1) direction) + { + [int y,int yjd,int leap]=gregorian_yjd(jd-offset); + for (;;) + { + int njd; + + int d=yd+offset; + if (leap && d>59) + njd=(yjd+((d)-1)+leap-( (yjd+leap+((d)+(8-wd)-1)) % 7)); + else + njd=(yjd+((d)-1)-( (yjd+((d)+(8-wd)-1)) % 7)); + + if (direction==1) + { + if (njd>=jd) return njd; + [y,yjd,leap]=gregorian_year(y+1); + } + else + { + if (njd<=jd) return njd; + [y,yjd,leap]=gregorian_year(y-1); + } + } + } + + string describe() + { + return sprintf("%s %2d %s %+2d %s [<=%+d]", + M_NAME[mn],md,WD_NAME[wd],n, + inclusive?"incl":"",offset); + } +} + +//! module Calendar +//! submodule Event +//! subclass SuperEvent +//! This class holds any number of events, +//! and adds the functionality of event flags. +//! +//! note: +//! Scanning (scan_events,next,etc) will drop flag information. +//! Dig out what you need with -><ref>holidays</ref> et al first. + +class SuperEvent +{ + inherit Event; + + constant is_superevent=1; + string name="SuperEvent"; + + mapping(Event:multiset(string)) flags=([]); + + array(Event) events=({}); + + array(Event) day_events=({}); + array(Namedays) namedays=({}); + array(Event) other_events=({}); + + mapping year_cache=([]); + + static void create(array(Event) _events, + void|mapping(Event:multiset(string)) _flags) + { + if (_flags) flags=_flags; + + foreach (_events,Event e) + if (e->is_superevent) + { + events|=e->events; + if (flags[e] && flags[e]!=(<>)) + foreach (e->events,Event e2) + flags[e2]=flags[e]|(e->flags[e2]||(<>)); + else + flags|=e->flags; + + m_delete(flags,e); + } + else events|=({e}); + + foreach (events,Event e) + if (e->is_day_event) day_events+=({e}); + else if (e->is_namedays) namedays+=({e}); + else other_events+=({e}); + } + +//! method SuperEvent filter_flag(string flag) +//! method SuperEvent holidays() +//! method SuperEvent flagdays() +//! Filter out the events that has a certain flag set. +//! Holidays (flag "h") are the days that are marked +//! red in the calendar (non-working days), +//! Flagdays (flag "f") are the days that the flag +//! should be visible in (only some countries). + + SuperEvent filter_flag(string flag) + { + array res=({}); + multiset m; + foreach (events,Event e) + if ((m=flags[e]) && m[flag]) res+=({e}); + return SuperEvent(res,flags&res); + } + + SuperEvent holidays() { return filter_flag("h"); } + SuperEvent flagdays() { return filter_flag("f"); } + + mapping(TimeRange:Event) scan_events(TimeRange in) + { + mapping res=([]); + foreach (events,Event e) + { + mapping er=e->scan_events(in); + foreach ((array)er,[TimeRange t,Event e]) + if (res[t]) res[t]|=e; // join + else res[t]=e; + } + return res; + } + + array(TimeRange) scan(TimeRange in) + { + return indices(scan_events(in)); + } + + TimeRange next(TimeRange from,void|int(0..1) including) + { + TimeRange best=0; + foreach (events,Event e) + { + TimeRange y=e->next(from,including); + if (!best || y->preceeds(best)) best=y; + else if (y->starts_with(best)) best|=y; + } + return best; + } + + TimeRange previous(TimeRange from,void|int(0..1) including) + { + TimeRange best=0; + foreach (events,Event e) + { + TimeRange y=e->previous(from,including); + if (!best || best->preceeds(y)) best=y; + else if (y->ends_with(best)) best|=y; + } + return best; + } + + Event `|(Event ... with) + { + with-=({0}); + return SuperEvent(events|with,flags); + } + Event ``|(Event with) { return `|(with); } + + Event `-(Event ...subtract) + { + array(Event) res=events-subtract; + if (res==events) return this_object(); + return SuperEvent(res,flags&res); + } + + array(Event) cast(string to) + { + if (to[..4]=="array") + return events; + else + error("Can't cast to %O\n",to); + } + + string _sprintf(int t) + { + return (t!='O')?0: + (sizeof(events)>5 + ? sprintf("SuperEvent(%O,%O..%O [%d])", + events[0],events[1],events[-1], + sizeof(events)) + : sprintf("SuperEvent(%s)", + map(events,lambda(Event e) { return sprintf("%O",e); })* + ",")); + } +} + diff --git a/lib/modules/Calendar.pmod/Events.pmod b/lib/modules/Calendar.pmod/Events.pmod new file mode 100644 index 0000000000000000000000000000000000000000..0c82ee6a2eebbebe2c3c81daaf599adbb932445e --- /dev/null +++ b/lib/modules/Calendar.pmod/Events.pmod @@ -0,0 +1,5416 @@ +import "."; +import Event; + +program|Event `[](string s) +{ + return ::`[](s) || magic_event(s); +} +function `-> = `[]; + +Event|Namedays|Magic_Index magic_event(string s) +{ + s=replace(s,"_"," "); + Event e; + if ( (e=made_events[s]) ) return e; + array a=events[s]; + if (a) + return made_events[s]=a[0](@a[1..]); + + if (sizeof(glob(s+"/*",indices(events)))) + return made_events[s]=Magic_Index(s); + return ([])[0]; +} + +mapping made_events=([]); + +class Magic_Index +{ + string base; + void create(string s) { base=s+"/"; } + Event|Namedays|Magic_Index `[](string s) { return magic_event(base+s); } + Event|Namedays|Magic_Index `->(string s) { return `[](s); } + + array(string) _indices() + { + return map(glob(base+"*",indices(events)), + lambda(string s) { return array_sscanf(s,base+"%[^/]")[0]; }); + } + + array(Event|Namedays|Magic_Index) _values() + { + return map(_indices(),`[]); + } + + string _sprintf(int t) + { return (t!='O')?0:sprintf("Event index(%O)",base); } +} + +#if 1 + +mapping(string:SuperEvent) made_countries=([]); + +Event country(string name) +{ + if (made_countries[name]) return made_countries[name]; + + array z=country_events[name]; + if (!z) return 0; + + array(Event) ze=({}); + mapping(Event:multiset(string)) zf=([]); +// reuse those multisets + mapping(string:multiset) flags=(["":0,"h":(<"h">),"f":(<"f">)]); + flags->hf=flags->fh=(<"h","f">); + + foreach (z,string id) + if (id[0]=='+') + { + Event e=country(id[1..]); + if (!e) werror("internal error: Missing country %O, can't inherit\n", + id[1..]); + else + ze=e->events|ze, zf=e->flags|zf; + } + else if (id[0]=='-') + { + Event e=magic_event(id[1..]); + if (!zf[e]) + werror("internal error: Missing event %O, can't remove\n",id[1..]); + m_delete(zf,e); + ze-=({e}); + } + else + { + string fs=""; + sscanf(id,"%s|%s",id,fs); + Event e=magic_event(id); + if (!e) werror("internal error: Missing event %O\n",id); + else ze|=({e}); + if (fs!="") zf[e]=flags[fs]||mkmultiset( (array)fs ); + } + return made_countries[name]=SuperEvent(ze,zf); +} +#endif + +// ---------------------------------------------------------------- +// event definitions +// ---------------------------------------------------------------- + +#define FIXED(NAME,MD,MN) \ + ({Gregorian_Fixed,NAME,MD,MN}) +#define FIX_M(NAME,MD,MN,N) \ + ({Gregorian_Fixed,NAME,MD,MN,N}) + +// relative week day (n: 1=first following, 2=2nd, -1=previous, -2=2nd prev) +#define DWDR(NAME,MD,MN,WD,N) \ + ({Monthday_Weekday_Relative,NAME,MD,MN,WD,N}) + +// relative week day, inclusive +#define DWDRI(NAME,MD,MN,WD,N) \ + ({Monthday_Weekday_Relative,NAME,MD,MN,WD,N,1}) + +#define EASTER_REL(NAME,OFFSET) \ + ({Easter_Relative,NAME,OFFSET}) + +#define ORTH_EASTER_REL(NAME,OFFSET) \ + ({Orthodox_Easter_Relative,NAME,OFFSET}) + +#define J_FIXED(NAME,MD,MN) \ + ({Julian_Fixed,NAME,MD,MN}) +#define J_FIX_M(NAME,MD,MN,N) \ + ({Julian_Fixed,NAME,MD,MN,N}) + +constant events=([ +// ---------------------------------------------------------------- +// standard + "monday": ({Weekday,1}), + "tuesday": ({Weekday,2}), + "wednesday": ({Weekday,3}), + "thursday": ({Weekday,4}), + "friday": ({Weekday,5}), + "saturday": ({Weekday,6}), + "sunday": ({Weekday,7}), + +// ---------------------------------------------------------------------- +// global events +// ---------------------------------------------------------------------- + + "new year": FIXED("New Year's Day", 1, 1), + "unity": FIXED("Unity Day", 22, 2), + "womens": FIXED("Int. Women's Day", 8, 3), + "arab league": FIXED("Arab League Day", 22, 3), + "anzac": FIXED("ANZAC Day", 25, 4), + "labor": FIXED("Labor Day", 1, 5), + "may day": FIXED("May Day", 1, 5), + "africa": FIXED("Africa Day", 25, 5), + "perseid meteor shower":FIXED("Perseid Meteor Shower",11,8), + "columbus": FIXED("Columbus Day", 12,10), + "un": FIXED("UN Day", 24,10), + "halloween": FIXED("Halloween", 31,10), + "armistice": FIXED("Armistice Day", 11,11), + "family": FIXED("Family Day", 25,12), + "kwanzaa": FIXED("Kwanzaa", 26,12), + "new years eve": FIXED("New Year's Eve", 31,12), + + "mardi gras": EASTER_REL("Mardi Gras",-47), + + "mothers": DWDRI("Mother's Day", 1,5,7,2), + "fathers": DWDRI("Father's Day", 1,6,7,3), + +// ---------------------------------------------------------------------- +// religious events +// ---------------------------------------------------------------------- + +// common (catholic) christianity + + "c/circumcision": FIXED("Feast of the Circumcision",1,1), + "c/epiphany": FIXED("Epiphany", 6, 1), + "c/presentation": FIXED("Presentation", 2, 2), + "c/candlemas": FIXED("Candlemas", 2, 2), + "c/annunciation": FIXED("Annunciation", 25, 3), + "c/transfiguration": FIXED("Transfiguration", 6, 8), + "c/assumption": FIXED("Assumption Day", 15, 8), + "c/nativity of mary":FIXED("Nativity of Mary",8, 9), + "c/all saints": FIXED("All Saints Day", 1,11), + "c/all souls": FIXED("All Souls Day", 2,11), + "c/immaculate conception":FIXED("Immaculate Conception",8,12), + "c/christmas eve": FIXED("Christmas Eve", 24,12), + "c/christmas": FIXED("Christmas Day", 25,12), + "c/christmas2d": FIX_M("Christmas", 25,12,2), + "c/boxing": FIXED("Boxing Day", 26,12), + "c/childermas": FIXED("Childermas", 28,12), + + "c/shrove sunday": EASTER_REL("Shrove Sunday", -49), + "c/shrove monday": EASTER_REL("Shrove Monday", -48), + "c/rose monday": EASTER_REL("Rose Monday", -48), // aka + "c/shrove tuesday": EASTER_REL("Shrove Tuesday", -47), + "c/fat tuesday": EASTER_REL("Fat Tuesday", -47), // aka + "c/ash wednesday": EASTER_REL("Ash wednesday", -46), + "c/palm sunday": EASTER_REL("Palm Sunday", -7), + "c/holy thursday": EASTER_REL("Holy Thursday", -3), + "c/maundy thursday": EASTER_REL("Maundy Thursday", -3), // aka + "c/holy friday": EASTER_REL("Holy Friday", -2), + "c/good friday": EASTER_REL("Good Friday", -2), // aka + "c/holy saturday": EASTER_REL("Holy Saturday", -1), + "c/easter eve": EASTER_REL("Easter Eve", -1), // aka + "c/easter": EASTER_REL("Easter", 0), + "c/easter monday": EASTER_REL("Easter Monday", 1), + "c/rogation sunday": EASTER_REL("Rogation Sunday", 35), + "c/ascension": EASTER_REL("Ascension", 39), + "c/pentecost eve": EASTER_REL("Pentecost Eve", 48), + "c/pentecost": EASTER_REL("Pentecost", 49), + "c/whitsunday": EASTER_REL("Whitsunday", 49), // aka + "c/pentecost monday":EASTER_REL("Pentecost Monday",50), + "c/whitmonday": EASTER_REL("Whitmonday", 50), // aka + "c/trinity": EASTER_REL("Trinity", 56), + "c/corpus christi": EASTER_REL("Corpus Christi", 60), + + "c/advent 1": DWDR ("Advent 1",24,12,7,-4), + "c/advent 2": DWDR ("Advent 2",24,12,7,-3), + "c/advent 3": DWDR ("Advent 3",24,12,7,-2), + "c/advent 4": DWDR ("Advent 4",24,12,7,-1), + +// other + + "catholic church/baptism of christ": + FIXED("Feast of the Baptism of Christ",13,1), + "catholic church/christ the king": + DWDRI("Feast of Christ the King",1,10,7,-1), + "catholic church/gaurdian angles": + FIXED("Feast of the Gaurdian Angles",2,10), + "catholic church/transfiguration":FIXED("Transfiguration",6,8), + +// orthodox + +// I don't know which of these are/will be needed: + "orhodox/circumcision": J_FIXED("Feast of the Circumcision",1,1), + "orthodox/epiphany": J_FIXED("Epiphany", 6, 1), + "orthodox/presentation": J_FIXED("Presentation", 2, 2), + "orthodox/candlemas": J_FIXED("Candlemas", 2, 2), + "orthodox/annunciation": J_FIXED("Annunciation", 25, 3), + "orthodox/transfiguration": J_FIXED("Transfiguration", 6, 8), + "orthodox/assumption": J_FIXED("Assumption Day", 15, 8), + "orthodox/nativity of mary": J_FIXED("Nativity of Mary",8, 9), + "orthodox/immaculate conception":J_FIXED("Immaculate Conception",8,12), + "orthodox/christmas eve": J_FIXED("Christmas Eve", 24,12), + "orthodox/christmas": J_FIXED("Christmas Day", 25,12), + "orthodox/christmas2d": J_FIX_M("Christmas", 25,12,2), + "orthodox/boxing": J_FIXED("Boxing Day", 26,12), + "orthodox/childermas": J_FIXED("Childermas", 28,12), + + "orthodox/triodon": ORTH_EASTER_REL("Triodon",-70), + "orthodox/sat. of souls": ORTH_EASTER_REL("Sat. of Souls",-57), + "orthodox/meat fare": ORTH_EASTER_REL("Meat Fare",-56), + "orthodox/2nd sat. of souls":ORTH_EASTER_REL("2nd Sat. of Souls",-50), + "orthodox/lent begins": ORTH_EASTER_REL("Lent Begins",-48), + "orthodox/saints/theodore": ORTH_EASTER_REL("St. Theodore",-43), + "orthodox/orthodoxy": ORTH_EASTER_REL("Sunday of Orthodoxy",-42), + "orthodox/lazarus": ORTH_EASTER_REL("Saturday of Lazarus",-8), + "orthodox/palm sunday": ORTH_EASTER_REL("Palm Sunday",-7), + "orthodox/good friday": ORTH_EASTER_REL("Good Friday",-2), + "orthodox/holy saturday": ORTH_EASTER_REL("Holy Saturday",-1), + "orthodox/easter": ORTH_EASTER_REL("Easter",0), + "orthodox/easter monday": ORTH_EASTER_REL("Easter Monday",1), + "orthodox/ascension": ORTH_EASTER_REL("Ascension",39), + "orthodox/sat. of souls": ORTH_EASTER_REL("Sat. of Souls",48), + "orthodox/pentecost": ORTH_EASTER_REL("Pentecost",49), + "orthodox/pentecost monday": ORTH_EASTER_REL("Pentecost Monday",50), + "orthodox/all saints": ORTH_EASTER_REL("All Saints",56), + + "bahai/ascension of abdul-baha":FIXED("Ascension of 'Abdu'l-Baha",28,11), + "bahai/ascension of bahaullah":FIXED("Ascension of Baha'u'llah",29,5), + "bahai/birth of bab": FIXED("Birth of Bab",20,10), + "bahai/birth of bahaullah": FIXED("Birth of Baha'u'llah",12,11), + "bahai/day of the covenant": FIXED("Day of the Covenant",27,11), + "bahai/declaration of bab": FIXED("Declaration of B\341b",23,5), + "bahai/festival of ridvan": FIXED("Festival of Ridv\341n",21,4), + "bahai/martyrdom of bab": FIXED("Martyrdom of Bab",9,7), + "bahai/naw-ruz": FIXED("Naw-R\372z",21,3), + +// temporary + "saints/basil": FIXED("St. Basil",1,1), + "saints/devote": FIXED("St. Devote",27,1), + "saints/blaise": FIXED("St. Blaise",3,2), + "saints/valentine": FIXED("St. Valentine",14,2), + "saints/john the baptist": FIXED("St. John the Baptist",24,6), + "saints/peter": FIXED("St. Peter",29,6), + "saints/paul": FIXED("St. Paul",29,6), + "saints/demetrios": FIXED("St. Demetrios",26,10), + "saints/lucy": FIXED("St. Lucy",13,12), + "saints/stephen": FIXED("St. Stephen",26,12), // aka boxing day + "saints/patrick": FIXED("St. Patrick",17,3), + "saints/david": FIXED("St. David",1,3), + +// --------------------------------------------------------------------- +// historic and political +// --------------------------------------------------------------------- + +#if 0 +// this should be the julian dates... + "roman festivals/agonalia": FIXED("Agonalia",9,1), + "roman festivals/ambarvalia": FIXED("Ambarvalia",29,5), + "roman festivals/carmentalia":FIX_M("Carmentalia",11,1,5), + "roman festivals/cerealia": FIXED("Cerealia",19,4), + "roman festivals/equiria": FIXED("Equiria",14,3), + "roman festivals/faunalia": FIXED("Faunalia",13,2), + "roman festivals/feralia": FIXED("Feralia",18,2), + "roman festivals/festival of anna perenna": + FIXED("festival of Anna Perenna",15,3), + "roman festivals/festival of the lares pr\346stites": + FIXED("festival of the Lares Pr\346stites",1,5), + "roman festivals/floria": FIXED("Floria",28,4), + "roman festivals/fools": FIXED("Feast of Fools",17,2), + "roman festivals/fordicidia": FIXED("Fordicidia",15,4), +// "roman festivals/fornicalia": February, + "roman festivals/lemuria": FIX_M("Lemuria",9,5,5), + "roman festivals/liberalia": FIXED("Liberalia",17,3), + "roman festivals/ludi apollinares":FIXED("Ludi Apollinares",5,7), + "roman festivals/ludi consualia":FIXED("Ludi Consualia",21,8), + "roman festivals/ludi martiales":FIXED("Ludi Martiales",12,5), + "roman festivals/ludi merceruy":FIXED("Ludi Merceruy",15,5), + "roman festivals/lupercalia": FIXED("Lupercalia",15,2), + "roman festivals/magalesia": FIX_M("Magalesia",4,4,7), + "roman festivals/matralia": FIXED("Matralia",11,6), + "roman festivals/matronalia": FIXED("Matronalia",1,3), + "roman festivals/nemoralia": FIXED("Nemoralia",13,8), + "roman festivals/neptunalia": FIXED("Neptunalia",23,7), + "roman festivals/paganalia": FIX_M("Paganalia",24,1,3), + "roman festivals/parentalia": FIX_M("Parentalia",13,2,9), + "roman festivals/parilia": FIXED("Parilia",21,4), + "roman festivals/portunalia": FIXED("Portunalia",17,8), + "roman festivals/quinquatrus minusculoe": + FIXED("Quinquatrus Minusculoe",13,6), + "roman festivals/quinquatrus[quinquatria?]": + FIX_M("Quinquatrus[Quinquatria?]",19,3,3), + "roman festivals/quirinalia": FIXED("Quirinalia",17,2), + "roman festivals/regifugium": FIXED("Regifugium",24,2), + "roman festivals/robigalia": FIXED("Robigalia",25,4), +// "roman festivals/semo sanctus":occurred in June, + "roman festivals/terminalia": FIXED("Terminalia",23,2), + "roman festivals/the vestalia":FIXED("The Vestalia",9,6), + "roman festivals/tubilustrium":FIXED("Tubilustrium",23,3), + "roman festivals/vinalia": FIXED("Vinalia",23,4), + "roman festivals/vinalia rustica":FIXED("Vinalia Rustica",19,8), + "roman festivals/volcanalia": FIXED("Volcanalia",23,8), +#endif + + "british commonwealth/august bank holiday": + DWDRI("August Bank Holiday",1,8,1,1), + "british commonwealth/empire":FIXED("Empire Day",24,5), + "british commonwealth/prince of wales": + FIXED("Prince of Wales' Birthday",14,11), + "british commonwealth/queens":FIXED("Queen's Birthday",4,6), + + "caribbean/caricom": DWDRI("CARICOM Day",1,7,1,1), + "caribbean/emancipation": DWDRI("Emancipation Day",1,8,1,1), + "caribbean/schoelcher": FIXED("Schoelcher Day",21,7), + +// ---------------------------------------------------------------- +// verified +// ---------------------------------------------------------------- + + "argentina/revolution": FIXED("Revolution Anniversary",25,5), + "argentina/soberanys": FIXED("Soberany's Day",10,6), + "argentina/flag": FIXED("Flag's Day",20,6), + "argentina/independence": FIXED("Independence Day",9,7), + "argentina/gral san martin": FIXED("Gral San Martín decease",17,8), + "argentina/race": FIXED("Race's Day",12,10), + "argentina/malvinas": FIXED("Malvinas Day",2,4), + + "sweden/kings birthday": FIXED("King's Birthday",30,4), + "sweden/kings nameday 2": FIXED("King's Nameday",28,1), + "sweden/crown princess nameday": FIXED("Crown Princess' Nameday",12,3), + "sweden/crown princess birthtday":FIXED("Crown Princess' Birthday",14,7), + "sweden/flag": FIXED("Sweden's Flag Day",6,6), + "sweden/kings nameday": FIXED("King's Nameday",6,11), + "sweden/nobel": FIXED("Nobel Day",10,12), + "sweden/queens birthday": FIXED("Queen's Birthday",23,12), + "sweden/queens nameday": FIXED("Queen's Nameday",8,8), + "sweden/valborg eve": FIXED("Valborgsmässoafton",30,4), + "sweden/waffle": FIXED("Waffle Day",25,3), + "sweden/all saints": DWDRI("Alla helgons dag",1,11,6,1), + "sweden/midsummers eve": DWDRI("Midsummer's Eve",20,6,5,1), + "sweden/midsummer": DWDRI("Midsummer's Day",21,6,6,1), + "sweden/mothers": DWDR ("Mother's Day", 1,6,7,-1), + "sweden/fathers": DWDRI("Father's Day", 1,11,7,2), + + "russia/state sovereignity": FIXED("State Sovereignity Day",12,6), + "russia/victory": FIXED("Victory Day",9,5), + "russia/valpurgis": FIXED("Valpurgis Night",1,5), + "russia/warriors": FIXED("Warriors Day",23,2), + "russia/teachers": FIXED("Teachers Day",1,10), + +// ---------------------------------------------------------------- +// not verified +// ---------------------------------------------------------------- + + "afghanistan/afghan new year":FIXED("Afghan New Year",21,3), + "afghanistan/childrens": FIXED("Children's Day",30,8), + "afghanistan/independence": FIXED("Independence Day",27,5), +// "afghanistan/jeshyn-afghans": August [28-31?], + "afghanistan/mothers": FIXED("Mother's Day",14,6), + "afghanistan/national assembly":DWDRI("National Assembly Day",1,9,3,2), + "afghanistan/revolution": FIXED("Revolution Day",27,4), + "afghanistan/workers": FIXED("Workers' Day",1,5), + + "albania/army": FIXED("Army Day",10,7), + "albania/independence": FIXED("Independence Day",28,11), + "albania/liberation": FIXED("Liberation Day",29,11), + "albania/proclamation of the republic": + FIXED("Proclamation of the Republic Day",11,1), + + "algeria/independence": FIXED("Independence Day",3,7), + "algeria/national": FIXED("National Day",19,6), + "algeria/revolution": FIXED("Revolution Day",1,11), + + "american baptist/roger williams":FIXED("Roger Williams Day",5,2), + + "american samoa/flag": FIXED("Flag Day",17,4), + + "andorra/national feast": FIXED("National Feast Day",8,9), + + "anglican church/name of jesus":FIXED("Feast of the Name of Jesus",7,8), + + "angola/armed forces": FIXED("Armed Forces Day",1,8), + "angola/independence": FIXED("Independence Day",11,11), + "angola/mpla foundation": FIXED("MPLA Foundation Day",10,12), + "angola/national heros": FIXED("National Hero's Day",17,9), + "angola/national holiday": FIXED("National Holiday",4,2), + "angola/pioneers": FIXED("Pioneers' Day",1,12), + "angola/victory": FIXED("Victory Day",27,3), + "angola/workers": FIXED("Workers' Day",1,5), + "angola/youth": FIXED("Youth Day",14,4), + + "anguilla/anguilla": FIXED("Anguilla Day",1,6), + + "antigua and barbuda/independence":FIXED("Independence Day",1,11), + + "armenia/christmas": FIXED("Christmas",6,1), + "armenia/martyrs": FIXED("Martyrs' Day",24,4), + "armenia/republic": FIXED("Republic Day",28,5), + + "aruba/aruba flag": FIXED("Aruba Flag Day",18,3), + + "australia/australia": FIXED("Australia Day",26,1), + "australia/eight hour": FIXED("Eight Hour Day",11,10), + "australia/foundation": FIXED("Foundation Day",7,6), + "australia/hobert regatta": FIXED("Hobert Regatta Day",9,2), + "australia/proclamation": FIXED("Proclamation Day",28,12), + "australia/recreation": FIXED("Recreation Day",1,11), + "australia/second new years": FIXED("Second New Year's Day",2,1), + "australia/show": DWDRI("Show Day",1,11,2,1), + "australia/summer bank holiday":DWDRI("Bank Holiday",1,8,1,4), // ? + "australia/spring bank holiday":DWDRI("Bank Holiday",1,3,1,4), // ? + + "austria/national": FIXED("National Day",15,5), + "austria/national holiday": FIXED("National Holiday",26,10), + "austria/national holiday of austria": + FIXED("National Holiday of Austria",26,10), + "austria/republic": FIXED("Republic Day",12,11), + "austria/second republic": FIXED("Second Republic Day",27,4), + + "bahamas/fox hill": DWDRI("Fox Hill Day",1,8,2,2), + "bahamas/independence": FIXED("Independence Day",10,7), + "bahamas/labor": DWDRI("Labour Day",1,6,5,1), + + "bahrain/national of bahrain":FIXED("National Day of Bahrain",16,12), + + "bangladesh/bengali new year":FIXED("Bengali New Year",14,4), + "bangladesh/independence": FIXED("Independence Day",26,3), + "bangladesh/national mourning":FIXED("National Mourning Day",21,2), + "bangladesh/revolution": FIXED("Revolution Day",7,11), + "bangladesh/victory": FIXED("Victory Day",16,12), + + "barbados/errol barrow": FIXED("Errol Barrow Day",21,1), + "barbados/independence": FIXED("Independence Day",30,11), + "barbados/united nations": FIXED("United Nations Day",7,10), + + "belgium/dynasty": FIXED("Dynasty Day",15,11), + "belgium/independence": FIX_M("Independence Day",21,7,2), + "belgium/kings": FIXED("King's Birthday",15,11), + + "belize/baron bliss": FIXED("Baron Bliss Day",9,3), + "belize/commonwealth": FIXED("Commonwealth Day",24,5), + "belize/garifuna": FIXED("Garifuna Day",19,11), + "belize/independence": FIXED("Independence Day",21,9), + "belize/national": FIXED("National Day",10,9), + "belize/pan american": FIXED("Pan American Day",12,10), + "belize/saint georges cay": FIXED("St. George's Cay Day",10,9), + + "benin/armed forces": FIXED("Armed Forces Day",26,10), + "benin/harvest": FIXED("Harvest Day",31,12), + "benin/martyrs": FIXED("Martyrs' Day",16,1), + "benin/national": FIXED("National Day",30,11), + "benin/workers": FIXED("Workers' Day",1,5), + "benin/youth": FIXED("Youth Day",1,4), + + "bermuda/bermuda": FIXED("Bermuda Day",24,5), + "bermuda/peppercorn": FIXED("Peppercorn Day",23,4), + "bermuda/remembrance": FIXED("Remembrance Day",11,11), + "bermuda/somers": FIXED("Somers Day",28,7), + + "bhutan/kings": FIXED("King's Birthday",11,11), + "bhutan/national of bhutan": FIXED("National Day of Bhutan",17,12), + +// "bolivia/alacitas": occurs in January, + "bolivia/independence": FIXED("Independence Day",6,8), + "bolivia/la paz": FIXED("La Paz Day",16,7), + "bolivia/martyrs": FIXED("Martyrs' Day",21,7), + "bolivia/memorial": FIXED("Memorial Day",23,3), + "bolivia/national": FIXED("National Day",9,4), + + "bosnia and herzegovina/labors":FIX_M("Labor Days",1,5,2), + + "botswana/botswana": FIXED("Botswana Day",30,9), + "botswana/presidents": FIXED("President's Day",24,5), + + "brazil/brasilia": FIXED("Brasilia Day",21,4), + "brazil/discovery": FIXED("Discovery Day",22,4), + "brazil/independence": FIXED("Independence Day",7,9), + "brazil/proclamation of the republic": + FIXED("Proclamation of the Republic Day",15,11), + "brazil/republic": FIXED("Republic Day",15,11), + "brazil/sao paulo": FIXED("Sao Paulo Anniversary",25,1), + "brazil/tiradentes": FIXED("Tiradentes Day",21,4), + +// "british virgin islands/sovereigns observance":occurs in June, + "british virgin islands/territory":FIXED("Territory Day",1,7), + + "brunei/national": FIXED("National Day",23,2), + "brunei/royal brunei armed forces": + FIXED("Royal Brunei Armed Forces Day",1,6), + "brunei/sultans": FIXED("Sultan's Birthday",15,7), + + "bulgaria/babin den": FIXED("Babin Den",20,1), + "bulgaria/botev": FIXED("Botev Day",20,5), + "bulgaria/education": FIXED("Education Day",24,5), + "bulgaria/liberation": FIXED("Liberation Day",3,3), + "bulgaria/national": FIXED("National Day",3,3), + "bulgaria/national holiday": FIX_M("National Holiday",9,9,2), + "bulgaria/viticulturists": FIXED("Viticulturists' Day",14,2), + + "burkina faso/anniversary of 1966 coup": + FIXED("Anniversary of 1966 Coup",3,1), + "burkina faso/labor": FIXED("Labour Day",1,5), + "burkina faso/national": FIXED("National Day",4,8), + "burkina faso/republic": FIXED("Republic Day",11,12), + "burkina faso/youth": FIXED("Youth Day",30,11), + + "burundi/anniversary of the revolution": + FIXED("Anniversary of the Revolution",30,11), + "burundi/independence": FIXED("Independence Day",1,7), + "burundi/murder of the hero": FIXED("Murder of the Hero Day",13,10), + "burundi/victory of uprona": FIXED("Victory of Uprona Day",18,9), + + "cambodia/ancestors": FIXED("Feast of the Ancestors",22,9), +// "cambodia/chaul chhnam": occurs in April, + "cambodia/day of hatred": FIXED("Day of Hatred",20,5), + "cambodia/independence": FIXED("Independence Day",17,4), + "cambodia/khmer republic constitution": + FIXED("Khmer Republic Constitution Day",12,5), + "cambodia/memorial": FIXED("Memorial Day",28,6), + "cambodia/national": FIXED("National Day",7,1), +// "cambodia/visak bauchea": Vesak Day, + + "cameroon/commemoration of national institutions": + FIXED("Commemoration of National Institutions Day",10,5), + "cameroon/constitution": FIXED("Constitution Day",20,5), + "cameroon/human rights": FIXED("Human Rights Day",10,12), + "cameroon/independence": FIXED("Independence Day",1,1), + "cameroon/unification": FIXED("Unification Day",1,10), + "cameroon/youth": FIXED("Youth Day",11,2), + + "canada/civic holiday": DWDRI("Civic Holiday",1,8,1,1), + "canada/discovery": DWDRI("Discovery Day",24,6,1,0), + "canada/dominion": FIXED("Dominion Day",1,7), + "canada/klondike gold discovery": + DWDR("Klondike Gold Discovery Day",18,8,5,-1), + "canada/labor": DWDRI("Labor Day",1,9,1,1), + "canada/remembrance": FIXED("Remembrance Day",11,11), +// "canada/thanksgiving": +// usually in early October, and determined by annual proclamation, + "canada/victoria": FIXED("Victoria Day",24,5), + + "cape verde/independence": FIXED("Independence Day",5,7), + "cape verde/national": FIXED("National Day",12,9), + "cape verde/national heroes": FIXED("National Heroes' Day",20,1), + + "caribbean/caricom": DWDRI("CARICOM Day",1,7,1,1), + "caribbean/emancipation": DWDRI("Emancipation Day",1,8,1,1), + "caribbean/schoelcher": FIXED("Schoelcher Day",21,7), + + "central african republic/first government": + FIXED("anniversary of first government",15,5), + "central african republic/republic": + FIXED("Anniversary of the Proclamation of the Republic",1,12), + "central african republic/day after republic": + FIXED("Day after Republic Day",2,12), + "central african republic/boganda":FIXED("Boganda Day",29,3), + "central african republic/independence":FIXED("Independence Day",13,8), + "central african republic/national holiday":FIXED("national holiday",11,11), + "central african republic/the after republic": + FIXED("the day after Republic Day",2,12), + + "central america/independence":FIXED("Independence Day",15,9), + + "chad/creation of the union of central african states": + FIXED("Creation of the Union of Central African States Day",2,4), + "chad/independence": FIXED("Independence Day",11,8), + "chad/national": FIXED("National Day",11,1), + "chad/republic": FIXED("Republic Day",28,11), + "chad/traditional independence []": + FIXED("Traditional Independence Day []",11,8), + + "chile/armed forces": FIXED("Armed Forces Day",19,9), + "chile/independence": FIXED("Independence Day",18,9), + "chile/independence2": FIX_M("Independence Day",18,9,2), + "chile/national holiday": FIXED("National Holiday",11,9), + "chile/navy": FIXED("Navy Day",21,5), + +// "china/army": +// or <i>National Liberation Army Festival,</i> August 1, 1927, + "china/ccps": FIXED("The CCP's Birthday",1,7), + "china/childrens": FIXED("Children's Day",1,6), + "china/national": FIXED("National Day",1,10), + "china/teachers": FIXED("Teacher's Day",1,9), + "china/tree planting": FIXED("Tree Planting Day",1,4), + "china/youth": FIXED("Youth Day",4,5), + + "columbia/battle of boyaca": FIXED("Battle of Boyaca Day",7,8), + "columbia/cartagena independence":FIXED("Cartagena Independence Day",11,11), + "columbia/independence": FIXED("Independence Day",20,7), + "columbia/thanksgiving": FIXED("Thanksgiving Day",5,6), + + "comoros/anniversary of president abdallahs assassination": + FIXED("Anniversary of President Abdallah's Assassination",27,11), + "comoros/independence": FIXED("Independence Day",6,7), + + "congo/day before army": FIXED("day before Army Day",16,11), + "congo/day before independence":FIXED("day before Independence Day",29,6), + "congo/day before national": FIXED("day before national day",23,11), + "congo/independence": FIXED("Independence Day",15,8), + "congo/martyr of independence":FIXED("Martyr of Independence Day",4,1), + + "corsica/napoleons": FIXED("Napoleon's Day",15,8), + + "costa rica/battle of rivas": FIXED("Battle of Rivas Day",11,4), +// "costa rica/guanacaste": , + "costa rica/independence": FIXED("Independence Day",15,9), + + "croatia/national holiday": FIXED("National Holiday",22,6), + "croatia/republic": FIXED("Republic Day",30,5), + +// "cuba/beginning of independence wars":commemorates Fidel Castro's guerrilla, + "cuba/independence": FIXED("Independence Day",20,5), + "cuba/liberation": FIXED("Liberation Day",1,1), + "cuba/revolution": FIXED("Revolution Day",26,7), + "cuba/wars of independence": FIXED("Wars of Independence Day",10,10), + + "cyprus/green monday": EASTER_REL("Green Monday",-41), + "cyprus/kataklysmos": FIXED("Kataklysmos",7,6), + "cyprus/peace and freedom": FIXED("Peace and Freedom Day",20,7), + "cyprus/submersion of the holy cross": + FIXED("Feast of the Submersion of the Holy Cross",6,1), + "cyprus/communal resistance": FIXED("Communal Resistance Day",1,8), + "cyprus/greek national": FIXED("Greek National Day",28,10), + "cyprus/name day": FIXED("Name Day",19,1), + + "czech republic/death of jan hus":FIXED("Death of Jan Hus",6,7), + "czech republic/introduction of christianity": + FIXED("Introduction of Christianity",5,7), + + "czechoslovakia/resistance movement":FIXED("Resistance Movement Day",11,4), +// "czechoslovakia/teachers": , + + "denmark/birthday of queen margrethe ii": + FIXED("Birthday of Queen Margrethe II",16,4), + "denmark/common prayer": EASTER_REL("Common Prayer Day",26), + "denmark/constitution": FIXED("Constitution Day",5,6), + "denmark/fjortende februar": FIXED("Fjortende Februar",14,2), + "denmark/liberation": FIXED("Liberation Day",5,5), +// "denmark/public holidays": , + "denmark/valdemars": FIXED("Valdemar's Day",15,6), + + "djibouti/independence feast":FIXED("Independence Feast Day",27,6), + "djibouti/workers": FIXED("Workers' Day",1,5), + + "dominica/community service": FIXED("Community Service Day",4,11), + "dominica/emancipation": DWDRI("Emancipation Day",1,8,1,1), + "dominica/independence": FIXED("Independence Day",3,11), + + "ecuador/battle of pichincha ":FIXED("Battle of Pichincha Day",24,5), +// "ecuador/cuenca independence": +// commemorates the declaration of independence for, + "ecuador/guayaquils independence": + FIXED("Guayaquil's Independence Day",9,10), +// "ecuador/independence": : August 10, 1809, + "ecuador/simon bolivars": FIXED("Simon Bolivar's Birthday",24,7), + + "egypt/armed forces": FIXED("Armed Forces Day",6,10), + "egypt/evacuation": FIXED("Evacuation Day",18,6), + "egypt/leylet en-nuktah": FIXED("Leylet en-Nuktah",17,6), + "egypt/revolution": FIXED("Revolution Day",23,7), + "egypt/sham al-naseem": FIXED("Sham al-Naseem",21,3), + "egypt/sinai liberation": FIXED("Sinai Liberation Day",25,4), + "egypt/suez": FIXED("Suez Day",24,10), + "egypt/victory": FIXED("Victory Day",23,12), + + "el salvador/first call for independence": + FIXED("First Call for Independence Day",5,11), + "el salvador/independence": FIXED("Independence Day",15,9), + "el salvador/san salvador festival":FIX_M("San Salvador Festival",4,8,3), + "el salvador/schoolteachers": FIXED("Schoolteachers Day",22,6), + + "equatorial guinea/armed forces":FIXED("Armed Forces Day",3,8), + "equatorial guinea/constitution":FIXED("Constitution Day",15,8), + "equatorial guinea/independence":FIXED("Independence Day",12,10), + "equatorial guinea/oau": FIXED("OAU DAy",25,5), + "equatorial guinea/presidents":FIXED("President's Birthday",5,6), + + "estonia/midsummer": FIXED("Midsummer Day",24,6), + "estonia/victory": FIXED("Victory Day",23,6), + + "ethiopia/battle of aduwa": FIXED("Battle of Aduwa Day",2,3), + "ethiopia/buhe": FIXED("Buhe",19,8), + "ethiopia/epiphany": FIXED("Epiphany",19,1), + "ethiopia/ethiopian new year":FIXED("Ethiopian New Year",11,9), + "ethiopia/genna": FIXED("Genna",7,1), + "ethiopia/liberation": FIXED("Liberation Day",5,5), + "ethiopia/martyrs": FIXED("Martyrs' Day",19,2), + "ethiopia/meskel": FIXED("Meskel",28,9), + "ethiopia/patriots victory": FIXED("Patriots' Victory Day",6,4), + "ethiopia/popular revolution commemoration": + FIXED("Popular Revolution Commemoration Day",12,9), + "ethiopia/revolution": FIXED("Revolution Day",12,9), + "ethiopia/victory of adowa": FIXED("Victory of Adowa",2,3), + + "falkland islands/anniversary of the battle of the falkland islands": + FIXED("Anniversary of the Battle of the Falkland Islands",8,12), + "falkland islands/liberation":FIXED("Liberation Day",14,6), + + "fiji/bank holiday": DWDRI("Bank Holiday",1,8,1,1), +// "fiji/deed of cession": occurs near October 7, +// "fiji/fiji2" on or near October 10, + "fiji/fiji": DWDRI("Fiji Day",1,8,1,2), + "fiji/prince charles": DWDRI("Prince Charles Day",1,11,1,3), + "fiji/queens": DWDRI("Queen's Birthday",1,6,1,2), + + "finland/alexis kivi": FIXED("Alexis Kivi Day",10,10), + "finland/flag": FIXED("Flag Day",4,6), + "finland/flag of the army": FIXED("Flag Day of the Army",19,5), +// "finland/helsinki": , + "finland/independence": FIXED("Independence Day",6,12), + "finland/kalevala": FIXED("Kalevala Day",28,2), +// "finland/midsummers eve": WDREL("Midsummer's Eve","midsummers",5,-1), + "finland/runebergs": FIXED("Runeberg's Day",5,2), + "finland/snellman": FIXED("Snellman Day",12,5), + "finland/vappu": FIXED("Vappu Day",1,5), + "finland/all saints": DWDRI("All Saints Day",1,11,6,1), + "finland/midsummers eve": DWDRI("Midsummer's Eve",24,6,5,0), + "finland/midsummer": DWDRI("Midsummer's Day",25,6,6,0), + + "france/ascension": FIXED("Ascension Day",12,5), + "france/bastille": FIXED("Bastille Day",14,7), + "france/d-day observance": FIXED("D-Day Observance",6,6), + "france/fathers": DWDRI("Father's Day",1,6,7,2), + "france/fete des saintes-maries":FIXED("F\352te des Saintes-Maries",24,5), + "france/fete nationale": FIXED("F\352te Nationale",22,9), + "france/liberation": FIXED("Liberation Day",8,5), + "france/marseillaise": FIXED("Marseillaise Day",30,7), + "france/night watch": FIXED("Night Watch",13,7), + + + "french polynesia/armistice": FIXED("Armistice Day",8,5), + "french polynesia/chinese new year":FIXED("Chinese New Year",6,2), + "french polynesia/missionaries arrival commemoration": + FIXED("Missionaries Arrival Commemoration",5,3), + + "gabon/constitution": FIXED("Constitution Day",19,2), + "gabon/independence": FIXED("Independence Day",17,8), + "gabon/renovation": FIXED("Renovation Day",12,3), + + "germany/day of repentance": FIXED("Day of Repentance",18,11), + "germany/day of the workers": FIXED("Day of the Workers",1,5), + "germany/foundation": FIXED("Foundation Day",7,10), + "germany/national": FIXED("National Day",23,5), +// "germany/oktoberfest": occurs in Munich in September/October, + "germany/unity": FIXED("Unity Day",3,10), + "germany/waldchestag": EASTER_REL("Waldchestag",53), + +// "ghana/aboakyer": occurs in April or May, + "ghana/homowo": FIXED("Homowo",1,8), + "ghana/independence": FIXED("Independence Day",6,3), + "ghana/liberation": FIXED("Liberation Day",24,2), + "ghana/republic": FIXED("Republic Day",1,7), + "ghana/revolution": FIXED("Revolution Day",31,12), + "ghana/third republic": FIXED("Third Republic Day",24,9), + "ghana/uprising": FIXED("Uprising Day",4,6), + + "gibraltar/commonwealth": FIXED("Commonwealth Day",13,3), +// "gibraltar/late summer bank holiday":occurs in the end of August, + "gibraltar/spring bank holiday":FIXED("Spring Bank Holiday",25,6), + + "greece/clean monday": EASTER_REL("Clean Monday",-41), +// "greece/dumb week": the week preceding Holy Week, + "greece/independence": FIXED("Independence Day",25,3), + "greece/flower festival": + FIXED("Flower Festival",1,5), + "greece/midwifes": FIXED("Midwife's Day",8,1), + "greece/ochi": FIXED("Ochi Day",28,10), + "greece/saint basils": FIXED("Saint Basil's Day",1,1), + "greece/dodecanese accession":FIXED("Dodecanese Accession Day",7,3), + "greece/liberation of xanthi":FIXED("Liberation of Xanthi",4,10), + + "gregorian calendar /gregorian calendar": + FIXED("Gregorian Calendar Day",24,2), + + "grenada/independence": FIXED("Independence Day",7,2), + "grenada/national holiday": FIXED("National Holiday",13,3), + "grenada/thanksgiving": FIXED("Thanksgiving Day",25,10), + + "guadeloupe/ascension": FIXED("Ascension Day",12,5), + + "guam/discovery": FIXED("Discovery Day",6,3), + "guam/guam discovery": DWDRI("Guam Discovery Day",1,3,1,1), + "guam/liberation": FIXED("Liberation Day",21,7), + + "guatemala/army": FIXED("Army Day",30,6), + "guatemala/bank employees": FIXED("Bank Employees' Day",1,7), + "guatemala/independence": FIXED("Independence Day",15,9), + "guatemala/revolution": FIXED("Revolution Day",30,6), + + "guinea/anniversary of cmrn": FIXED("Anniversary of CMRN",3,4), + "guinea/anniversary of womens revolt": + FIXED("Anniversary of Women's Revolt",27,8), + "guinea/day of 1970 invasion":FIXED("Day of 1970 Invasion",22,11), + "guinea/independence": FIXED("Independence Day",2,10), + "guinea/referendum": FIXED("Referendum Day",28,9), + + "guinea-bissau/colonization martyrs":FIXED("Colonization Martyr's Day",3,8), + "guinea-bissau/independence": FIXED("Independence Day",24,9), + "guinea-bissau/mocidade": FIXED("Mocidade Day",1,12), + "guinea-bissau/national": FIXED("National Day",12,9), + "guinea-bissau/national heroes":FIXED("National Heroes Day",20,1), + "guinea-bissau/readjustment movement": + FIXED("Readjustment Movement Day",14,11), + + "guyana/freedom": FIXED("Freedom Day",1,8), + "guyana/independence": FIXED("Independence Day",26,5), + "guyana/republic": FIXED("Republic Day",23,2), + + "haiti/discovery": FIXED("Discovery Day",5,12), + "haiti/vertieres": FIXED("Verti\350res Day",18,11), + + "honduras/armed forces": FIXED("Armed Forces Day",21,10), + "honduras/independence": FIXED("Independence Day",15,9), + "honduras/morazan": FIXED("Moraz\341n Day",3,10), + "honduras/pan american": FIXED("Pan American Day",14,4), + "honduras/thanksgiving": FIXED("Thanksgiving Day",15,3), + + "hong kong/birthday of confucious":FIXED("Birthday of Confucious",22,9), + "hong kong/birthday of pak tai":FIXED("Birthday of Pak Tai",3,4), +// "hong kong/chung yeung festival":[9th day of 9th month], + "hong kong/half-year": FIXED("Half-Year Day",1,7), + "hong kong/liberation": DWDR("Liberation Day",1,9,1,-1), + + "hungary/constitution": FIXED("Constitution Day",20,8), + "hungary/revolution1848": FIXED("1848 Revolution Day",15,3), + "hungary/revolution56": FIXED("'56 Revolution Day",23,10), + "hungary/labor": FIXED("Holiday of Labor",1,5), + + "iceland/independence": FIXED("Independence Day",17,6), + + "india/indian independence": FIXED("Indian Independence Day",15,8), + "india/mahatma gandhi jayanti":FIXED("Mahatma Gandhi Jayanti",2,10), + "india/mahatma gandhi martyrdom":FIXED("Mahatma Gandhi Martyrdom Day",30,1), + "india/republic": FIXED("Republic Day",26,1), + +// "indonesia/balinese new year":held every 210 days, + "indonesia/independence": FIXED("Independence Day",17,8), + "indonesia/kartini": FIXED("Kartini Day",21,4), + + "iran/constitution": FIXED("Constitution Day",5,8), + "iran/islamic republic": FIXED("Islamic Republic Day",1,4), + "iran/martyrdom of imam ali": FIXED("Martyrdom of Imam Ali",14,7), + "iran/no ruz": FIXED("No Ruz",21,3), + "iran/oil nationalization": FIXED("Oil Nationalization Day",20,3), + "iran/revolution": FIXED("Revolution Day",11,2), + "iran/revolution2": FIXED("Revolution Day",2,4), + + "iraq/14 ramadan revolution": FIXED("14 Ramadan Revolution Day",8,2), + "iraq/army": FIXED("Army Day",6,1), + "iraq/july revolution": FIXED("July Revolution Day",17,7), + "iraq/republic": FIXED("Republic Day",14,7), + + "ireland/sheelahs": FIXED("Sheelah's Day",18,3), + + "israel/balfour declaration": FIXED("Balfour Declaration Day",2,11), +// "israel/hebrew university": occurs near April 1, +// "israel/holocaust memorial": Nisan 27, +// "israel/independence": Iyar 5, + "israel/jerusalem reunification":FIXED("Jerusalem Reunification Day",12,5), +// "israel/national": occurs in May, + + "italy/anniversary of the republic": + FIXED("Anniversary of the Republic",2,6), + "italy/befana": FIXED("Befana Day",6,1), + "italy/day of conciliation": FIXED("Day of Conciliation",11,2), + "italy/festa del redentore": DWDRI("Festa del Redentore",1,7,7,3), + "italy/joust of the quintana":DWDRI("Joust of the Quintana",1,8,7,1), + "italy/liberation": FIXED("Liberation Day",25,4), + "italy/natale di roma": FIXED("Natale di Roma",21,4), + "italy/palio del golfo": DWDRI("Palio Del Golfo",1,8,7,2), +// "italy/saint marks": occurs in April, + "italy/santo stefano": FIXED("Santo Stefano",26,12), + + "ivory coast/independence": FIXED("Independence Day",7,12), + "ivory coast/national holiday of the ivory coast": + FIXED("National Holiday of the Ivory Coast",7,12), + +// "jainism/jain payushan": began on 9/2/94 and 8/23/95, +// "jainism/mahavir jayanti": Vaisakha 13, + + "jamaica/heroes": DWDRI("Heroes' Day",1,10,1,3), + "jamaica/independence": DWDRI("Independence Day",1,8,1,1), + "jamaica/labor": FIXED("Labour Day",23,5), + + "japan/adults": FIXED("Adults Day",15,1), +// "japan/autumnal equinox": [sep 22nd or 23rd], + "japan/bean-throwing festival":FIXED("Bean-Throwing Festival",4,2), +// "japan/black ship": near July 15, +// "japan/bon": occurs between July 13 and 15, + "japan/childrens": FIXED("Children's Day",5,5), + "japan/childrens protection": FIXED("Children's Protection Day",17,4), + "japan/constitution": FIXED("Constitution Day",3,5), + "japan/culture": FIXED("Culture Day",3,11), + "japan/emperors": FIXED("Emperor's Birthday",23,12), + "japan/empire": FIXED("Empire Day",11,2), + "japan/gion matsuri": FIX_M("Gion Matsuri",16,2,9), + "japan/greenery": FIXED("Greenery Day",29,4), +// "japan/health": <i>Sports Day,</i> October 10, + "japan/hina matsuri": FIXED("Hina Matsuri",3,3), + "japan/hiroshima peace festival":FIXED("Hiroshima Peace Festival",6,8), + "japan/hollyhock festival": FIXED("Hollyhock Festival",15,5), + "japan/jidai matsuri": FIXED("Jidai Matsuri",22,10), + "japan/kakizome": FIXED("Kakizome",2,1), + "japan/kambutsue": FIXED("Kambutsue",8,4), + "japan/kite battles of hamamatsu":FIX_M("Kite Battles of Hamamatsu",3,5,3), + "japan/labor thanksgiving": FIXED("Labor Thanksgiving Day",23,11), + "japan/martyr": FIXED("Martyr Day",5,2), +// "japan/memorial": , + "japan/memorial to broken dolls":FIXED("Memorial to Broken Dolls Day",3,6), + "japan/national foundation": FIXED("National Foundation Day",11,2), +// "japan/peoples holiday": [near may 4?], + "japan/respect for the aged": FIXED("Respect for the Aged Day",15,9), + "japan/sanno matsuri": FIXED("Sanno Matsuri",15,6), +// "japan/shichigosan": The name means "seven-five-three", + "japan/shigoto hajime": FIXED("Shigoto Hajime",2,1), + "japan/tanabata": FIXED("Tanabata",7,7), + "japan/tango-no-sekku": FIXED("Tango-no-sekku",5,5), +// "japan/vernal equinox": [mar 20 or mar 21st], + + "jordan/arbor": FIXED("Arbor Day",15,1), + "jordan/coronation": FIXED("Coronation Day",11,8), + "jordan/independence": FIXED("Independence Day",25,5), + "jordan/king hussein": FIXED("King Hussein Day",14,11), + + "kenya/independence": FIXED("Independence Day",12,12), + "kenya/kenyatta": FIXED("Kenyatta Day",20,10), + "kenya/madaraka": FIXED("Madaraka Day",1,6), + + "kiribati/independence": FIXED("Independence Day",12,7), + "kiribati/youth": FIXED("Youth Day",4,8), + + "korea/independence movement":FIXED("Independence Movement Day",1,3), + + "kuwait/independence": FIXED("Independence Day",19,6), + "kuwait/national": FIXED("National Day",25,2), + +// "laos/army": occurs around March 24, + "laos/constitution": FIXED("Constitution Day",11,5), + "laos/independence": FIXED("Independence Day",19,7), + "laos/memorial": FIXED("Memorial Day",15,8), + "laos/pathet lao": FIXED("Pathet Lao Day",6,1), + "laos/republic": FIXED("Republic Day",2,12), + + "latvia/independence": FIXED("Independence Day",18,11), + "latvia/midsummer festival": FIX_M("Midsummer Festival",23,6,2), + + "lebanon/evacuation": FIXED("Evacuation Day",31,12), + "lebanon/independence": FIXED("Independence Day",22,11), + "lebanon/martyrs": FIXED("Martyrs' Day",6,5), + "lebanon/saint maron": FIXED("Saint Maron Day",9,2), + + "lesotho/family": DWDRI("Family Day",1,7,1,1), + "lesotho/independence": FIXED("Independence Day",4,10), + "lesotho/kings": FIXED("King's Birthday",2,5), + "lesotho/moshoeshoes": FIXED("Moshoeshoe's Day",12,3), + "lesotho/national holiday": FIXED("National Holiday",28,1), + "lesotho/national sports": FIXED("National Sports Day",6,10), + "lesotho/national tree planting":FIXED("National Tree Planting Day",21,3), + + "liberia/armed forces": FIXED("Armed Forces Day",11,2), + "liberia/decoration": FIXED("Decoration Day",13,3), + "liberia/fast and prayer": FIXED("Fast and Prayer Day",11,4), + "liberia/flag": FIXED("Flag Day",24,8), + "liberia/independence": FIXED("Independence Day",26,7), + "liberia/j j roberts": FIXED("J. J. Robert's Birthday",15,3), + "liberia/literacy": FIXED("Literacy Day",14,2), + "liberia/matilda newport": FIXED("Matilda Newport Day",1,12), + "liberia/memorial": FIXED("Memorial Day",12,11), + "liberia/national redemption":FIXED("National Redemption Day",12,4), + "liberia/pioneers": FIXED("Pioneers' Day",7,1), + "liberia/president tubmans": FIXED("President Tubman's Birthday",29,11), + "liberia/thanksgiving": DWDRI("Thanksgiving Day",1,11,4,1), + "liberia/unification and integration": + FIXED("Unification and Integration Day",14,5), + + "libya/evacuation": FIXED("Evacuation Day",28,3), + "libya/expulsion of the fascist settlers": + FIXED("Expulsion of the Fascist Settlers Day",7,10), + "libya/kings": FIXED("King's Birthday",12,3), + "libya/national": FIXED("National Day",1,9), + "libya/revolution": FIXED("Revolution Day",1,9), + "libya/sanusi army": FIXED("Sanusi Army Day",9,8), +// "libya/troop withdrawal": near June 30, + + "liechtenstein/birthday of prince franz-josef ii": + FIXED("Birthday of Prince Franz-Josef II",16,8), + "liechtenstein/national": FIXED("National Day",15,8), + + "lithuania/coronation": FIXED("Coronation Day",6,7), + "lithuania/independence": FIXED("Independence Day",16,2), + "lithuania/mourning": FIXED("Mourning",1,11), + + "luxembourg/burgsonndeg": FIXED("Burgsonndeg",28,2), + "luxembourg/grand duchess": FIXED("Grand Duchess' Birthday",23,1), + "luxembourg/liberation": FIXED("Liberation Day",9,9), + "luxembourg/national": FIXED("National Day",23,6), + + "macao/anniversary of the portugese revolution": + FIXED("Anniversary of the Portugese Revolution",25,4), + "macao/battle of july 13": FIXED("Feast of the Battle of July 13",13,7), +// "macao/hungry ghosts": occurs in August, + "macao/procession of our lady of fatima": + FIXED("Procession of Our Lady of Fatima",13,5), + "macao/republic": FIXED("Republic Day",5,10), + + "madagascar/commemoration": FIXED("Commemoration Day",29,3), + "madagascar/independence": FIXED("Independence Day",26,6), + "madagascar/republic": FIXED("Republic Day",30,12), + + "malawi/august holiday": FIXED("August Holiday",6,8), + "malawi/kamuzu": FIXED("Kamuzu Day",14,5), + "malawi/martyrs": FIXED("Martyrs' Day",3,3), + "malawi/mothers": FIXED("Mother's Day",17,10), + "malawi/national tree-planting":FIXED("National Tree-Planting Day",21,12), + "malawi/republic": FIXED("Republic Day",6,7), + +// "malaysia/additional public holiday in kuala lumpur":City Day (Feb 1), + "malaysia/kings": FIXED("King's Birthday",3,6), + "malaysia/malaysia": FIXED("Malaysia Day",31,8), + + "maldives/fisheries": FIXED("Fisheries Day",10,12), + "maldives/independence": FIXED("Independence Day",26,7), + "maldives/national": FIXED("National Day",7,1), + "maldives/republic": FIXED("Republic Day",11,11), + "maldives/victory": FIXED("Victory Day",3,11), + + "mali/army": FIXED("Army Day",20,1), + "mali/independence": FIXED("Independence Day",22,9), + "mali/liberation": FIXED("Liberation Day",19,11), + + "malta/freedom": FIXED("Freedom Day",31,3), + "malta/independence": FIXED("Independence Day",21,9), + "malta/memorial of 1919 riot":FIXED("Memorial of 1919 riot",7,6), + "malta/republic": FIXED("Republic Day",13,12), + + "marshall islands/proclamation of the republic of marshall islands": + FIXED("Proclamation of the Republic of Marshall Islands",1,5), + + "martinique/ascension": FIXED("Ascension Day",12,5), + + "mauritania/independence": FIXED("Independence Day",28,11), + + "mauritius/independence": FIXED("Independence Day",12,3), + + "mexico/birthday of benito juarez": + FIXED("Birthday of Benito Ju\341rez",21,3), + "mexico/cinco de mayo": FIXED("Cinco de Mayo",5,5), + "mexico/constitution": FIXED("Constitution Day",5,2), + "mexico/day of mourning": FIXED("Day of Mourning",17,7), + "mexico/dia de la raza": FIXED("Dia de la Raza",12,10), + "mexico/holy cross": FIXED("Holy Cross Day",3,5), + "mexico/independence": FIXED("Independence Day",16,9), + "mexico/night of the radishes":FIXED("Night of the Radishes",23,12), + "mexico/our lady of guadalupe": + FIXED("Feast of Our Lady of Guadalupe",12,12), + "mexico/posadass": FIX_M("Posadas Days",16,12,9), + "mexico/presidential message":FIXED("Presidential Message Day",1,9), + "mexico/revolution": FIXED("Revolution Day",20,11), + "mexico/san marc\363s": FIXED("San Marc\363s Day",25,4), + +// "micronesia/national holiday":, + + "monaco/monaco national festival":FIXED("Monaco National Festival",19,11), + + "mongolia/national": FIXED("National Day",11,7), + "mongolia/republic": FIXED("Republic Day",26,11), + + "montserrat/festival": FIXED("Festival Day",31,12), + "montserrat/liberation": FIXED("Liberation Day",23,11), + + "mormonism/founding of the mormon church": + FIXED("Founding of the Mormon Church",6,4), + + "morocco/green march": FIXED("Green March",6,11), + "morocco/independence": FIXED("Independence Day",2,3), + "morocco/oued ed-dahab": FIXED("Oued ed-Dahab Day",14,8), + "morocco/throne": FIXED("Throne Day",3,3), + + "mozambique/armed forces": FIXED("Armed Forces Day",25,9), + "mozambique/heroes": FIXED("Heroes' Day",3,2), + "mozambique/independence": FIXED("Independence Day",25,6), + "mozambique/lusaka agreement":FIXED("Lusaka Agreement Day",7,9), + "mozambique/universal fraternity":FIXED("Universal Fraternity Day",1,1), + "mozambique/womens": FIXED("Women's Day",7,4), + "mozambique/workers": FIXED("Workers' Day",1,5), + + "myanmar/armed forces": FIXED("Armed Forces Day",27,3), +// "myanmar/burmese new year": near April 17, + "myanmar/independence": FIXED("Independence Day",4,1), + "myanmar/martyrs": FIXED("Martyrs' Day",19,7), + "myanmar/national": FIXED("National Day",10,12), + "myanmar/peasants": FIXED("Peasants' Day",2,3), + "myanmar/resistance": FIXED("Resistance Day",27,3), + "myanmar/union": FIXED("Union Day",12,2), + + "namibia/casinga": FIXED("Casinga Day",4,5), + "namibia/day of goodwill": FIXED("Day of Goodwill",7,10), + "namibia/family": FIXED("Family Day",26,12), + "namibia/heroes": FIXED("Heroes' Day",26,8), + "namibia/independence": FIXED("Independence Day",21,3), + "namibia/workers": FIXED("Workers' Day",1,5), + + "nauru/angam": FIXED("Angam Day",27,10), + "nauru/independence": FIXED("Independence Day",31,1), + + "nepal/birthday of king birendra":FIXED("Birthday of King Birendra",28,12), +// "nepal/buddha jayanti": occurs in May, + "nepal/constitution": FIXED("Constitution Day",16,12), + "nepal/democracy": FIXED("Democracy Day",18,2), + "nepal/independence": FIXED("Independence Day",21,12), + "nepal/kings": FIXED("King's Birthday",28,12), + "nepal/national unity": FIXED("National Unity Day",11,1), + "nepal/queens": FIXED("Queen's Birthday",8,11), + "nepal/tij": FIXED("Tij Day",8,8), + + "netherlands/beggars": FIXED("Beggar's Day",11,11), + "netherlands/independence": FIXED("Independence Day",25,7), + "netherlands/liberation": FIXED("Liberation Day",5,5), + "netherlands/queens": FIXED("Queen's Day",30,4), + "netherlands/sinterklaas": FIXED("Sinterklaas",6,12), + + "netherlands antilles/bonaire":FIXED("Bonaire Day",6,9), + "netherlands antilles/cura\347ao":FIXED("Cura\347ao Day",2,7), + "netherlands antilles/queens":FIXED("Queen's Birthday",30,4), + "netherlands antilles/saba": FIXED("Saba Day",6,12), + "netherlands antilles/saint eustatius":FIXED("St Eustatius Day",16,11), + "netherlands antilles/saint maarten":FIXED("St Maarten Day",11,11), + + "new zealand/labor": DWDR("Labor Day",1,11,1,-1), + "new zealand/queens": FIXED("Queen's Birthday",4,6), + "new zealand/waitangi": FIXED("Waitangi Day",6,2), + + "nicaragua/air force": FIXED("Air Force Day",1,2), + "nicaragua/army": FIXED("Army Day",27,5), + "nicaragua/fiesta": FIXED("Fiesta Day",1,8), + "nicaragua/independence": FIXED("Independence Day",15,9), + "nicaragua/revolution": FIXED("Revolution Day",19,7), + "nicaragua/san jacinto": FIXED("San Jacinto Day",14,9), + + "niger/independence": FIXED("Independence Day",3,8), + "niger/national": FIXED("National Day",15,4), + "niger/republic": FIXED("Republic Day",18,12), + + "nigeria/childrens": FIXED("Children's Day",27,5), + "nigeria/harvest festival": FIXED("Harvest Festival",12,10), + "nigeria/national": FIXED("National Day",1,10), +// "nigeria/odum titun": occurs in the winter, +// "nigeria/odun kekere": occurs at the end of Ramadan, + + "northern mariana islands/commonwealth":FIXED("Commonwealth Day",3,1), + "northern mariana islands/presidents":FIXED("Presidents Day",13,2), + + "norway/constitution": FIXED("Constitution Day",17,5), + "norway/olsok eve festival": FIXED("Olsok Eve Festival",29,7), + "norway/tyvendedagen": FIXED("Tyvendedagen",13,1), + + "oman/national": FIXED("National Day",23,7), + "oman/national of oman": FIXED("National Day of Oman",18,11), + "oman/national2": FIXED("National Day",18,11), + "oman/sultans": FIXED("Sultan's Birthday",19,11), + + "pakistan/birthday of quaid-i-azam":FIXED("Birthday of Quaid-i-Azam",25,12), + "pakistan/defense": FIXED("Defense Day",6,9), + "pakistan/independence": FIXED("Independence Day",14,8), + "pakistan/iqbal": FIXED("Iqbal Day",9,11), + "pakistan/jinnah": FIXED("Jinnah Day",11,9), + "pakistan/pakistan": FIXED("Pakistan Day",23,3), + + "panama/constitution": FIXED("Constitution Day",1,3), + "panama/day of mourning": FIXED("Day of Mourning",9,1), + "panama/festival of the black christ": + FIXED("Festival of the Black Christ",21,10), + "panama/flag": FIXED("Flag Day",4,11), + "panama/foundation of panama city":FIXED("Foundation of Panama City",15,8), + "panama/independence": FIXED("Independence Day",3,11), + "panama/independence from spain":FIXED("Independence from Spain",28,11), + "panama/mothers": FIXED("Mothers' Day",8,12), + "panama/national anthem": FIXED("National Anthem Day",1,11), + "panama/revolution": FIXED("Revolution Anniversary Day",11,10), + "panama/uprising of los santos":FIXED("Uprising of Los Santos",10,11), + + "papua new guinea/independence":FIXED("Independence Day",16,9), + "papua new guinea/remembrance":FIXED("Remembrance Day",23,7), + + "paraguay/battle of boquer\363n":FIXED("Battle of Boquer\363n Day",29,9), + "paraguay/constitution": FIXED("Constitution Day",25,8), + "paraguay/day of the race": FIXED("Day of the Race",12,10), + "paraguay/founding of the city of asunci\363n": + FIXED("Founding of the City of Asunci\363n",15,8), + "paraguay/heroes": FIXED("Heroes' Day",1,3), + "paraguay/independence": FIX_M("Independence Day",14,5,2), + "paraguay/peace of chaco": FIXED("Peace of Chaco Day",12,6), + "paraguay/virgin of caacupe": FIXED("Virgin of Caacupe",8,12), + + "peru/combat of angamos": FIXED("Combat of Angamos",8,10), + "peru/independence": FIX_M("Independence Day",28,7,2), + "peru/inti raymi fiesta": FIXED("Inti Raymi Fiesta",24,6), + "peru/santa rosa de lima": FIXED("Santa Rosa de Lima",30,8), + + "philippines/araw ng kagitingan":FIXED("Araw ng Kagitingan",6,5), + "philippines/barangay": FIXED("Barangay Day",11,9), + "philippines/bataan": FIXED("Bataan Day",9,4), + "philippines/bonifacio": FIXED("Bonifacio Day",30,11), + "philippines/christ the king":FIXED("Feast of Christ the King",24,10), + "philippines/constitution": FIXED("Constitution Day",17,1), + "philippines/freedom": FIXED("Freedom Day",25,2), + "philippines/independence": FIXED("Independence Day",12,6), + "philippines/misa de gallo": FIX_M("Misa de Gallo",16,12,9), + "philippines/national heroes":FIXED("National Heroes' Day",27,8), + "philippines/philippine-american friendship": + FIXED("Philippine-American Friendship Day",4,7), + "philippines/rizal": FIXED("Rizal Day",30,12), + "philippines/thanksgiving": FIXED("Thanksgiving Day",21,9), + + "portugal/cam\365es memorial":FIXED("Cam\365es Memorial Day",10,6), + "portugal/christmas lisbon also observes the st anthony": + FIXED("Christmas. Lisbon also observes the feast of St Anthony",13,6), + "portugal/day of the dead": FIXED("Day of the Dead",2,11), + "portugal/liberty": FIXED("Liberty Day",25,4), + "portugal/portugal": FIXED("Portugal Day",10,6), + "portugal/republic": FIXED("Republic Day",5,10), + "portugal/restoration of the independence": + FIXED("Restoration of the Independence",1,12), + + "puerto rico/barbosa": FIXED("Barbosa Day",27,7), + "puerto rico/birthday of eugenio maria de hostos": + FIXED("Birthday of Eugenio Maria de Hostos",11,1), + "puerto rico/constitution": FIXED("Constitution Day",25,7), + "puerto rico/de diego": FIXED("De Diego Day",16,4), + "puerto rico/discovery": FIXED("Discovery Day",19,11), + "puerto rico/emancipation": FIXED("Emancipation Day",22,3), + "puerto rico/memorial": FIXED("Memorial Day",28,5), + "puerto rico/mu\361oz rivera":FIXED("Mu\361oz Rivera Day",17,7), + "puerto rico/ponce de leon": FIXED("Ponce de Leon Day",12,8), + "puerto rico/saint johns": FIXED("St John's Day",24,6), + "puerto rico/san juan": FIXED("San Juan Day",24,6), + + "qatar/anniversary of the amirs accession": + FIXED("Anniversary of the Amir's Accession",22,2), + "qatar/independence": FIXED("Independence Day",3,9), + + "romania/liberation": FIXED("Liberation Day",23,8), + "romania/national": FIXED("National Day",1,12), + "romania/public holiday": FIX_M("Public Holiday",23,8,2), + + "rwanda/armed forces": FIXED("Armed Forces Day",26,10), + "rwanda/democracy": FIXED("Democracy Day",28,1), + "rwanda/independence": FIXED("Independence Day",1,7), + "rwanda/kamarampaka": FIXED("Kamarampaka Day",25,9), + "rwanda/peace and unity": FIXED("Peace and Unity Day",5,7), + + "saint kitts and nevis/carnival":FIXED("Carnival",31,12), + "saint kitts and nevis/independence":FIXED("Independence Day",19,9), + "saint kitts and nevis/prince of wales": + FIXED("Prince of Wales' Birthday",14,11), + + "saint lucia/discovery": FIXED("Discovery Day",13,12), + "saint lucia/independence": FIXED("Independence Day",22,2), + "saint lucia/thanksgiving": DWDRI("Thanksgiving Day",1,10,1,1), + + "saint vincent and the grenadines/independence": + FIXED("Independence Day",27,10), + "saint vincent and the grenadines/saint vincent and the grenadines": + FIXED("Saint Vincent and the Grenadines Day",22,1), + + "san marino/anniversary of the arengo": + FIXED("Anniversary of the Arengo",25,3), + "san marino/fall of fascism": FIXED("Fall of Fascism Day",28,7), + "san marino/investiture of the new captains regent": + FIXED("Investiture of the New Captains Regent",1,4), + "san marino/investiture of the new captains-regent": + FIXED("Investiture of the New Captains-Regent",1,10), + "san marino/liberation": FIXED("Liberation Day",5,2), + "san marino/national": FIXED("National Day",1,4), + "san marino/san marino": FIXED("San Marino Day",3,9), + + "sao tome and principe/farmers":FIXED("Farmers' Day",30,9), + "sao tome and principe/independence":FIXED("Independence Day",12,7), + "sao tome and principe/martyrs":FIXED("Martyrs' Day",4,2), + "sao tome and principe/transitional government": + FIXED("Transitional Government Day",21,12), + + "saudi arabia/national": FIXED("National Day",12,9), + "saudi arabia/national of saudi arabia": + FIXED("National Day of Saudi Arabia",23,9), + + "senegal/african community": FIXED("African Community Day",14,7), + "senegal/independence": FIXED("Independence Day",4,4), + + "seychelles/independence": FIXED("Independence Day",29,6), + "seychelles/liberation": FIXED("Liberation Day",5,6), + + "sierra leone/independence": FIXED("Independence Day",27,4), + "sierra leone/republic": FIXED("Republic Day",19,4), + +// "singapore/birthday of the monkey god": +// occurs in February and September/October, +// "singapore/birthday of the saint of the poor":occurs in March, + "singapore/independence": FIXED("Independence Day",16,9), + "singapore/labor": FIXED("Labour Day",1,5), +// "singapore/mooncake festival":occurs in September, + "singapore/national holiday": FIXED("National Holiday",9,8), +// "singapore/vesak": occurs in May, + + "slovakia/day of the slav apostles":FIXED("Day of the Slav Apostles",5,7), + "slovakia/liberation": FIXED("Liberation Day",8,5), + "slovakia/reconciliation": FIXED("Reconciliation Day",1,11), + "slovakia/slovak national uprising": + FIXED("Slovak National Uprising Day",29,8), + + "solomon islands/independence":FIXED("Independence Day",7,7), + + "somalia/foundation of the republic": + FIXED("Foundation of the Republic Day",1,7), + "somalia/independence": FIXED("Independence Day",26,6), + "somalia/revolution": FIX_M("Revolution Anniversary",21,10,2), + + "south africa/day of the vow":FIXED("Day of the Vow",16,12), + "south africa/family": DWDRI("Family Day",1,7,1,2), + "south africa/kruger": FIXED("Kruger Day",10,10), + "south africa/republic": FIXED("Republic Day",31,5), + "south africa/settlers": DWDRI("Settlers' Day",1,9,1,1), + "south africa/van riebeeck": FIXED("Van Riebeeck Day",6,4), + "south africa/workers": FIXED("Workers' Day",1,5), + + "soviet union/anniversary of the october socialist revolution": + FIX_M("Anniversary of the October Socialist Revolution",7,11,2), + "soviet union/victory": FIXED("Victory Day",9,5), + + "spain/constitution": FIXED("Constitution Day",6,12), + "spain/fiesta de san fermin": FIXED("Fiesta de San Fermin",7,7), + "spain/fiesta del arbol": FIXED("Fiesta del Arbol",26,3), + "spain/grenada": FIXED("Grenada Day",2,1), + "spain/hispanidad": FIXED("Hispanidad Day",12,10), + "spain/king juan carlos saints":FIXED("King Juan Carlos' Saint's Day",24,6), + "spain/labor": FIXED("Labor Day",18,7), + "spain/national": FIXED("National Day",12,10), + "spain/national holiday of spain":FIXED("National Holiday of Spain",12,10), + "spain/queen isabella": FIXED("Queen Isabella Day",22,4), + "spain/saint james": FIXED("St James Day",25,7), + "spain/saint joseph the workman":FIXED("St Joseph the Workman",1,5), +// "spain/tomatina": late August, + +// "sri lanka/bandaranaike memorial":[9/26/96], +// "sri lanka/hadji festival": [4/29/96], + "sri lanka/independence": FIXED("Independence Day",4,2), +// "sri lanka/kandy perahera": occurs on a new moon in July, + "sri lanka/national heroes": FIXED("National Heroes Day",22,5), + "sri lanka/republic": FIXED("Republic Day",22,5), + "sri lanka/sinhala and tamil new year": + FIXED("Sinhala and Tamil New Year",14,4), +// "sri lanka/thai pongal": occurs in January, +// "sri lanka/vesak festival": occurs in May, + + "sudan/decentralization": FIXED("Decentralization Day",1,7), + "sudan/independence": FIXED("Independence Day",1,1), + "sudan/national": FIXED("National Day",25,5), + "sudan/unity": FIXED("Unity Day",3,3), + "sudan/uprising": FIXED("Uprising Day",6,4), + + "suriname/independence": FIXED("Independence Day",25,11), + "suriname/national union": FIXED("National Union Day",1,7), + "suriname/revolution": FIXED("Revolution Day",25,2), + + "swaziland/commonwealth": DWDRI("Commonwealth Day",1,3,1,2), + "swaziland/flag": FIXED("Flag Day",25,4), +// "swaziland/incwala": December or January, + "swaziland/kings": FIXED("King's Birthday",22,7), + "swaziland/reed dance": DWDRI("Reed Dance Day",1,7,1,2), + "swaziland/somhlolo": FIXED("Somhlolo Day",6,9), + + "switzerland/berchtolds": FIXED("Berchtold's Day",2,1), + "switzerland/glarus festival":DWDRI("Glarus Festival",1,4,4,1), + "switzerland/homstrom": DWDRI("Homstrom",1,2,7,1), + "switzerland/independence": FIXED("Independence Day",1,8), + "switzerland/may eve": FIXED("May Day Eve",30,4), + + "syria/beginning of october war":FIXED("Beginning of October War",6,10), + "syria/evacuation": FIXED("Evacuation Day",17,4), + "syria/national": FIXED("National Day",16,11), + "syria/revolution": FIXED("Revolution Day",8,3), + "syria/union": FIXED("Union Day",1,9), + + "taiwan/birthday of confucious":FIXED("Birthday of Confucious",28,9), +// "taiwan/birthday of matsu": occurs in April or May, + "taiwan/buddha bathing festival":FIXED("Buddha Bathing Festival",8,4), + "taiwan/chiang kai-shek": FIXED("Chiang Kai-shek Day",1,11), + "taiwan/childrens": FIXED("Children's Day",4,4), + "taiwan/constitution": FIXED("Constitution Day",25,12), + "taiwan/dragon boat festival":FIXED("Dragon Boat Festival",8,6), + "taiwan/founding of the republic of china": + FIX_M("Founding of the Republic of China",1,1,2), +// "taiwan/lantern festival": occurs on the fifteenth day of the first moon, + "taiwan/martyrs": FIXED("Martyrs' Day",29,3), + "taiwan/national": FIXED("National Day",10,10), + "taiwan/restoration": FIXED("Restoration Day",25,10), + "taiwan/sun yat-sen": FIXED("Sun Yat-sen Day",12,11), + "taiwan/youth": FIXED("Youth Day",29,3), + + "tanzania/chama cha mapinduzi":FIXED("Chama Cha Mapinduzi Day",5,2), + "tanzania/heroes": FIXED("Heroes' Day",1,9), + "tanzania/independence": FIXED("Independence Day",9,12), + "tanzania/naming": FIXED("Naming Day",29,10), + "tanzania/saba saba": FIXED("Saba Saba Day",7,7), + "tanzania/sultans": FIXED("Sultan's Birthday",26,8), + "tanzania/union": FIXED("Union Day",26,4), + "tanzania/zanzibar revolution":FIXED("Zanzibar Revolution Day",12,1), + + "thailand/asalapha bupha": FIXED("Asalapha Bupha Day",28,7), + "thailand/chakri": FIXED("Chakri Day",6,4), + "thailand/chulalongkorn": FIXED("Chulalongkorn Day",23,10), + "thailand/constitution": FIXED("Constitution Day",10,12), + "thailand/coronation": FIXED("Coronation Day",5,5), + "thailand/harvest festival": FIXED("Harvest Festival Day",11,5), + "thailand/kings": FIXED("King's Birthday",5,12), +// "thailand/loy krathong festival":occurs in November, +// "thailand/makha bucha": full moon in first lunar month, + "thailand/queens": FIXED("Queen's Birthday",12,8), + "thailand/songkran": FIX_M("Songkran",13,4,3), +// "thailand/state ploughing ceremony":occurs in May [7th?], +// "thailand/visakha bucha": full moon of the sixth lunar month, + + "gambia/independence": FIXED("Independence Day",18,2), + "gambia/moslem new year": FIXED("Moslem New Year",7,10), + + "togo/anniversary of the failed attack on lome": + FIXED("Anniversary of the failed attack on Lom\351",24,9), + "togo/economic liberation": FIXED("Economic Liberation Day",24,1), + "togo/independence": FIXED("Independence Day",27,4), + "togo/liberation": FIXED("Liberation Day",13,1), + "togo/martyrs of pya": FIXED("Martyrs of Pya",21,6), + "togo/victory": FIXED("Victory Day",24,4), + + "tonga/constitution": FIXED("Constitution Day",4,11), + "tonga/emancipation": FIXED("Emancipation Day",4,6), + "tonga/king tupou": FIXED("King Tupou Day",4,12), + "tonga/kings": FIXED("King's Birthday",4,7), + "tonga/princes": FIXED("Prince's Birthday",4,5), + + "trinidad and tobago/discovery":FIXED("Discovery Day",1,8), + "trinidad and tobago/emancipation":FIXED("Emancipation Day",1,8), + "trinidad and tobago/independence":FIXED("Independence Day",31,8), + "trinidad and tobago/labor": FIXED("Labor Day",19,6), + "trinidad and tobago/republic":FIXED("Republic Day",24,9), + + "tunisia/accession": FIXED("Accession Day",7,11), + "tunisia/bourguibas": FIXED("Bourguiba's Day",3,8), + "tunisia/evacuation": FIXED("Evacuation Day",15,10), + "tunisia/independence": FIXED("Independence Day",20,3), + "tunisia/independence recognition": + FIXED("Independence Recognition Day",20,7), + "tunisia/martyrs": FIXED("Martyrs' Day",9,4), + "tunisia/memorial": FIXED("Memorial Day",3,9), + "tunisia/national holiday of tunisia": + FIXED("National Holiday of Tunisia",1,6), + "tunisia/national revolution":FIXED("National Revolution Day",18,1), + "tunisia/republic": FIXED("Republic Day",25,7), + "tunisia/tree festival": FIXED("Tree Festival Day",9,11), + "tunisia/womens": FIXED("Women's Day",13,8), + "tunisia/youth": FIXED("Youth Day",21,3), + + "turkey/freedom and constitution": + FIXED("Freedom and Constitution Day",27,5), + "turkey/hidrellez": FIXED("Hidrellez",6,5), + "turkey/independence": FIXED("Independence Day",29,10), + "turkey/youth and sports": FIXED("Youth and Sports Day",19,5), + "turkey/ataturk commemoration": FIXED("Atatürk Commemoration",19,5), // ? + "turkey/national sovereignty":FIXED("National Sovereignty",23,4), + "turkey/childrens": FIXED("Children's day",23,4), + "turkey/navy and merchant marine":FIXED("Navy and Merchant Marine Day",1,7), + "turkey/rumis": FIXED("Rumi's Birthday",17,12), + "turkey/spring": FIXED("Spring Day",1,5), + "turkey/victory": FIXED("Victory Day",30,8), + + "turks and caicos islands/columbus":FIXED("Columbus Day",10,10), + "turks and caicos islands/emancipation":FIXED("Emancipation Day",1,8), + "turks and caicos islands/human rights": + FIXED("International Human Rights Day",24,10), + "turks and caicos islands/jags mccartney memorial": + FIXED("J.A.G.S. McCartney Memorial Day",6,6), + + "tuvalu/tuvalu": FIX_M("Tuvalu Day",1,10,2), + + "uganda/heroes": FIXED("Heroes Day",9,6), + "uganda/independence": FIXED("Independence Day",9,10), + "uganda/martyrs": FIXED("Martyr's Day",3,6), + "uganda/nrm/nra victorys": FIXED("NRM/NRA Victory Celebrations",26,1), + "uganda/republic": FIXED("Republic Day",8,9), + + "ukraine/taras shevchenko": FIXED("Taras Shevchenko Day",9,3), + "ukraine/ukrainian": FIXED("Ukrainian Day",22,1), + "ukraine/ukrainian independence":FIXED("Ukrainian Independence Day",24,8), + "ukraine/victory": FIXED("Victory Day",9,3), + + "united arab emirates/accession of the ruler of abu dhabi": + FIXED("Accession of the Ruler of Abu Dhabi",6,8), + "united arab emirates/national":FIXED("National Day",2,12), + + "uruguay/artigas": FIXED("Artigas Day",19,6), + "uruguay/battle of las piedras":FIXED("Battle of Las Piedras",18,5), + "uruguay/blessing of the waters":FIXED("Blessing of the Waters",8,12), + "uruguay/constitution": FIXED("Constitution Day",18,7), + "uruguay/independence": FIXED("Independence Day",25,8), + "uruguay/landing of the 33 patriots": + FIXED("Landing of the 33 Patriots Day",19,4), + + "united kingdom/bannockburn": FIXED("Bannockburn Day",24,6), + "united kingdom/battle of britain":FIXED("Battle of Britain Day",15,9), + "united kingdom/burns": FIXED("Burns Day",25,1), + "united kingdom/day after": FIXED("The Day After",2,1), + "united kingdom/guy fawkes": FIXED("Guy Fawkes Day",5,11), + "united kingdom/handsel monday":DWDRI("Handsel Monday",1,1,1,1), + "united kingdom/highland games":DWDR("Highland Games",1,10,6,-1), + "united kingdom/lammas": FIXED("Lammas Day",1,8), + "united kingdom/lord mayors": FIXED("Lord Mayor's Day",9,11), + "united kingdom/mothering sunday":EASTER_REL("Mothering Sunday",-21), // ? + "united kingdom/new year": FIX_M("New Year's Day",1,1,2), + "united kingdom/oak apple": FIXED("Oak Apple Day",29,5), + "united kingdom/orangemans": FIXED("Orangeman's Day",12,7), + "united kingdom/pancake tuesday": EASTER_REL("Fat Tuesday",-47), + "united kingdom/queens": DWDRI("Queen's Birthday",1,6,4,2), + "united kingdom/woman peerage":FIXED("Woman Peerage Day",30,1), + "united kingdom/spring bank holiday":DWDRI("Spring Bank Holiday",1,5,1,4), + "united kingdom/late summer bank holiday": + DWDRI("Late Summer Bank Holiday",1,8,1,4), + "united kingdom/orangeman": FIXED("Orangeman's Day",12,7), + "united kingdom/scottish new year":FIXED("Scottish New Year",2,1), + "united kingdom/victoria":DWDRI("Victoria Day",1,5,1,3), + "united kingdom/autumn holiday":DWDRI("Autumn Holiday",1,9,1,3), + + + "us/appomattox": FIXED("Appomattox Day",9,4), + "us/armed forces": DWDRI("Armed Forces Day",1,5,6,3), + "us/bill of rights": FIXED("Bill of Rights Day",15,12), + "us/carnation": FIXED("Carnation Day",29,1), + "us/citizenship": FIXED("Citizenship Day",17,9), + "us/columbus": DWDRI("Columbus Day",1,10,1,2), + "us/election": DWDRI("Election Day",1,11,1,1), + "us/flag": FIXED("Flag Day",14,6), + "us/forefathers": FIXED("Forefathers' Day",21,12), + "us/inauguration": FIXED("Inauguration Day",20,1), + "us/independence": FIXED("Independence Day",4,7), + "us/iwo jima": FIXED("Iwo Jima Day",23,2), + "us/jefferson davis": FIXED("Jefferson Davis Day",3,6), + "us/kosciuszko": FIXED("Kosciuszko Day",4,2), + "us/labor": DWDRI("Labor Day",1,9,1,1), + "us/lincolns": FIXED("Lincoln's Birthday",12,2), + "us/martin luther king": FIXED("Martin Luther King Day",15,1), + "us/memorial": DWDRI("Memorial Day",30,5,1,-1), + "us/national freedom": FIXED("National Freedom Day",1,2), + "us/navy": FIXED("Navy Day",27,10), + "us/patriots": DWDRI("Patriot's Day",1,4,1,3), + "us/robert e lee": FIXED("Robert E. Lee Day",19,1), + "us/thomas jeffersons": FIXED("Thomas Jefferson's Birthday",13,4), + "us/veterans": FIXED("Veteran's Day",11,11), + "us/vietnam": FIXED("Vietnam Day",27,1), + "us/washingtons": DWDRI("Washington's Birthday",1,2,1,3), + "us/washington": DWDRI("Washington Day",1,2,1,3), + "us/washington-lincoln": DWDRI("Washington-Lincoln Day",1,2,1,3), + "us/presidents": DWDRI("Presidents Day",1,2,1,3), + "us/womens equality": FIXED("Women's Equality Day",26,8), + "us/thanksgiving": DWDRI("Thanksgiving Day",1,11,4,4), + "us/day after thanksgiving": DWDRI("Day after Thanksgiving Day",2,11,5,4), + + "us/alabama/alabama admission": FIXED("Alabama Admission Day",14,12), + "us/alabama/confederate memorial":DWDR("Confederate Memorial Day",1,5,1,-1), + "us/alabama/jefferson davis": DWDRI("Jefferson Davis Day",1,6,1,1), + "us/alabama/robert e lee": DWDRI("Robert E. Lee Day",1,1,1,3), + + "us/alaska/alaska": DWDRI("Alaska Day",1,10,1,3), + "us/alaska/alaska admission": FIXED("Alaska Admission Day",3,1), + "us/alaska/flag": FIXED("Flag Day",4,7), + "us/alaska/sewards": FIXED("Seward's Day",30,3), + + "us/arizona/american family": DWDRI("American Family Day",1,8,7,1), + "us/arizona/arborn": FIXED("Arbor Day (northern Arizona)",1,1), + "us/arizona/arbors": DWDR ("Arbor Day (southern Arizona)",1,2,5,1), + "us/arizona/arizona admission": FIXED("Arizona Admission Day",14,2), + "us/arizona/lincoln": DWDRI("Lincoln Day",1,2,1,2), + + "us/arkansas/arkansas admission":FIXED("Arkansas Admission Day",15,6), + "us/arkansas/general douglas macarthur": + FIXED("General Douglas MacArthur Day",26,1), +// "us/arkansas/jefferson davis": , + "us/arkansas/world war ii memorial":FIXED("World War II Memorial Day",14,8), + + "us/california/arbor": FIXED("Arbor Day",7,3), + "us/california/california admission":FIXED("California Admission Day",9,9), + + "us/colorado/arbor": DWDRI("Arbor Day",1,4,5,3), + "us/colorado/colorado": DWDRI("Colorado Day",1,8,1,1), + + "us/connecticut/connecticut ratification": + FIXED("Connecticut Ratification Day",9,1), + "us/delaware/arbor": FIXED("Arbor Day",22,4), + "us/delaware/delaware": FIXED("Delaware Day",7,12), + "us/delaware/lincolns": DWDRI("Lincoln's Birthday",1,2,1,1), + "us/delaware/memorial": FIXED("Memorial Day",30,5), + "us/delaware/separation": FIXED("Separation Day",15,6), + "us/delaware/swedish colonial": FIXED("Swedish Colonial Day",29,3), + + "us/florida/arbor": DWDRI("Arbor Day",1,1,5,3), + "us/florida/confederate memorial":FIXED("Confederate Memorial Day",26,4), + "us/florida/farmers": DWDRI("Farmer's Day",1,10,1,2), + "us/florida/florida admission": FIXED("Florida Admission Day",3,3), + "us/florida/pascua florida": FIXED("Pascua Florida Day",2,4), + "us/florida/susan b anthony": FIXED("Susan B. Anthony Day",15,2), + + "us/georgia/confederate memorial":FIXED("Confederate Memorial Day",26,4), + "us/georgia/georgia": FIXED("Georgia Day",12,2), + + "us/hawaii/flag": FIXED("Flag Day",4,7), + "us/hawaii/hawaii statehood": DWDRI("Hawaii Statehood Day",1,8,5,3), + "us/hawaii/kamehameha": FIXED("Kamehameha Day",11,6), + "us/hawaii/kuhio": FIXED("Kuhio Day",26,3), + "us/hawaii/lei": FIXED("Lei Day",1,5), + "us/hawaii/wesak flower festival":DWDRI("Wesak Flower Festival",1,4,7,1), + + "us/idaho/idaho admission": FIXED("Idaho Admission Day",3,7), + "us/idaho/idaho pioneer": FIXED("Idaho Pioneer Day",15,6), + + "us/illinois/illinois admission":FIXED("Illinois Admission Day",3,12), + "us/illinois/memorial": FIXED("Memorial Day",30,5), + + "us/indiana/indiana admission": FIXED("Indiana Admission Day",11,12), + "us/indiana/primary election": DWDRI("Primary Election Day",2,5,2,1), + "us/indiana/vincennes": FIXED("Vincennes Day",24,2), + + "us/iowa/bird": FIXED("Bird Day",21,3), + "us/iowa/independence sunday": DWDR ("Independence Sunday",4,7,7,-1), + "us/iowa/iowa admission": FIXED("Iowa Admission Day",28,12), + + "us/kansas/kansas": FIXED("Kansas Day",29,1), + + "us/kentucky/franklin d roosevelt":FIXED("Franklin D. Roosevelt Day",30,1), + "us/kentucky/kentucky statehood":FIXED("Kentucky Statehood Day",1,6), + + "us/louisiana/huey p long": FIXED("Huey P. Long Day",30,8), + "us/louisiana/jackson": FIXED("Jackson Day",8,1), + "us/louisiana/louisiana admission":FIXED("Louisiana Admission Day",30,4), + + "us/maine/battleship": FIXED("Battleship Day",15,2), + "us/maine/maine admission": FIXED("Maine Admission Day",3,3), + + "us/maryland/defenders": FIXED("Defenders' Day",12,9), + "us/maryland/john hanson": FIXED("John Hanson Day",14,4), + "us/maryland/maryland": FIXED("Maryland Day",25,3), + "us/maryland/maryland admission":FIXED("Maryland Admission Day",28,4), + "us/maryland/maryland ratification":FIXED("Maryland Ratification Day",14,1), + "us/maryland/memorial": FIXED("Memorial Day",30,5), + "us/maryland/national anthem": FIXED("National Anthem Day",14,9), + "us/maryland/repudiation": FIXED("Repudiation Day",23,11), + + "us/massachusetts/bunker hill": FIXED("Bunker Hill Day",17,6), + "us/massachusetts/childrens": DWDRI("Children's Day",1,6,7,2), + "us/massachusetts/evacuation": FIXED("Evacuation Day",17,3), + "us/massachusetts/john f kennedy":DWDR("John F. Kennedy Day",1,12,7,-1), + "us/massachusetts/lafayette": FIXED("Lafayette Day",20,5), + "us/massachusetts/liberty tree": FIXED("Liberty Tree Day",14,8), + "us/massachusetts/massachusetts ratification": + FIXED("Massachusetts Ratification Day",6,2), + "us/massachusetts/spanish-american war memorial": + FIXED("Spanish-American War Memorial Day",15,2), + "us/massachusetts/student government":DWDRI("Student Government Day",1,4,5,1), + "us/massachusetts/susan b anthony":FIXED("Susan B. Anthony Day",26,8), + "us/massachusetts/teachers": DWDRI("Teacher's Day",1,6,7,1), + + "us/michigan/memorial": DWDRI("Memorial Day",1,5,1,3), + "us/michigan/michigan": FIXED("Michigan Day",26,1), + + "us/minnesota/american family": DWDRI("American Family Day",1,8,7,1), + "us/minnesota/minnesota": FIXED("Minnesota Day",11,5), + + "us/mississippi/confederate memorial": + DWDRI("Confederate Memorial Day",30,4,1,-1), + "us/mississippi/jefferson davis":DWDRI("Jefferson Davis Day",1,6,1,1), + "us/mississippi/robert elee": DWDRI("Robert E.Lee Day",1,1,1,3), + + "us/missouri/missouri admission":FIXED("Missouri Admission Day",10,8), + "us/missouri/truman": FIXED("Truman Day",8,5), + + "us/montana/election": DWDRI("Election Day",1,11,2,1), + + "us/nebraska/arbor": FIXED("Arbor Day",22,4), + "us/nebraska/nebraska state": FIXED("Nebraska State Day",1,3), + + "us/nevada/nevada": FIXED("Nevada Day",31,10), + + "us/new hampshire/fast": DWDRI("Fast Day",1,4,1,4), + "us/new hampshire/memorial": FIXED("Memorial Day",30,5), + "us/new hampshire/new hampshire admission": + FIXED("New Hampshire Admission Day",21,6), + + "us/new jersey/new jersey admission": + FIXED("New Jersey Admission Day",18,12), + + "us/new mexico/arbor": DWDRI("Arbor Day",1,3,5,2), + "us/new mexico/memorial": FIXED("Memorial Day",25,5), + + "us/new york/audubon": DWDRI("Audubon Day",1,4,5,2), + "us/new york/flag": DWDRI("Flag Day",1,6,7,2), + "us/new york/martin luther king":DWDRI("Martin Luther King Day",1,1,7,3), + "us/new york/new york ratification":FIXED("New York Ratification Day",26,7), + "us/new york/verrazano": FIXED("Verrazano Day",17,4), + + "us/north carolina/confederate memorial": + FIXED("Confederate Memorial Day",10,5), + "us/north carolina/halifax resolutions": + FIXED("Halifax Resolutions Day",12,4), + "us/north carolina/mecklenburg": FIXED("Mecklenburg Day",20,5), + + "us/north dakota/north dakota admission": + FIXED("North Dakota Admission Day",2,11), + + "us/ohio/martin luther king": DWDRI("Martin Luther King Day",1,1,1,3), + "us/ohio/ohio admission": FIXED("Ohio Admission Day",1,3), + + "us/oklahoma/bird": FIXED("Bird Day",1,5), + "us/oklahoma/cherokee strip": FIXED("Cherokee Strip Day",16,9), + "us/oklahoma/indian": FIXED("Indian Day",12,8), + "us/oklahoma/oklahoma": FIXED("Oklahoma Day",22,4), +// "oklahoma/oklahoma heritage week":week of November 16, + "us/oklahoma/oklahoma historical":FIXED("Oklahoma Historical Day",10,10), + "us/oklahoma/oklahoma statehood":FIXED("Oklahoma Statehood Day",16,11), + "us/oklahoma/senior citizens": FIXED("Senior Citizens Day",9,6), + "us/oklahoma/will rogers": FIXED("Will Rogers Day",4,11), +// "oklahoma/youth": on first day of Spring, + + "us/oregon/lincolns": DWDRI("Lincoln's Birthday",1,2,1,1), + "us/oregon/oregon statehood": FIXED("Oregon Statehood Day",14,2), + + "us/pennsylvania/barry": FIXED("Barry Day",13,9), + "us/pennsylvania/charter": FIXED("Charter Day",4,3), + "us/pennsylvania/pennsylvania admission": + FIXED("Pennsylvania Admission Day",12,12), + + "us/rhode island/arbor": DWDRI("Arbor Day",1,5,5,2), + "us/rhode island/rhode island admission": + FIXED("Rhode Island Admission Day",29,5), + "us/rhode island/rhode island independence": + FIXED("Rhode Island Independence Day",4,5), + "us/rhode island/victory": DWDRI("Victory Day",1,8,1,2), + + "us/south carolina/confederate memorial": + FIXED("Confederate Memorial Day",10,5), + "us/south carolina/south carolina admission": + FIXED("South Carolina Admission Day",23,5), + + "us/south dakota/memorial": FIXED("Memorial Day",30,5), + "us/south dakota/pioneers": DWDRI("Pioneers' Day",1,10,1,2), + "us/south dakota/south dakota admission": + FIXED("South Dakota Admission Day",2,11), + + "us/tennessee/confederate memorial":FIXED("Confederate Memorial Day",3,6), + "us/tennessee/tennesse statehood":FIXED("Tennesse Statehood Day",1,6), + + "us/texas/alamo": FIXED("Alamo Day",6,3), + "us/texas/austin": FIXED("Austin Day",3,11), + "us/texas/confederate heroes": FIXED("Confederate Heroes Day",19,1), + "us/texas/juneteenth": FIXED("Juneteenth",19,6), + "us/texas/lyndon b johnsons": FIXED("Lyndon B. Johnson's Birthday",27,8), + "us/texas/san jacinto": FIXED("San Jacinto Day",21,4), + "us/texas/texas admission": FIXED("Texas Admission Day",29,12), + "us/texas/texas independence": FIXED("Texas Independence Day",2,3), + "us/texas/texas pioneers": FIXED("Texas Pioneers' Day",12,8), + + "us/utah/arbor": DWDR("Arbor Day",1,5,5,-1), + "us/utah/pioneer": FIXED("Pioneer Day",24,7), + "us/utah/utah admission": FIXED("Utah Admission Day",4,1), + + "us/vermont/bennington battle": FIXED("Bennington Battle Day",16,8), + "us/vermont/memorial": FIXED("Memorial Day",30,5), + "us/vermont/town meeting": DWDRI("Town Meeting Day",1,3,2,1), + "us/vermont/vermont": FIXED("Vermont Day",4,3), + + "us/virginia/cape henry": FIXED("Cape Henry Day",26,4), + "us/virginia/confederate memorial":FIXED("Confederate Memorial Day",30,5), + "us/virginia/crater": FIXED("Crater Day",30,7), +// "virginia/jack jouett": occurs in June, + "us/virginia/jamestown": FIXED("Jamestown Day",13,5), + "us/virginia/lee-jackson": DWDRI("Lee-Jackson Day",1,1,1,3), + "us/virginia/royalist fast": FIXED("Royalist Fast Day",30,1), + "us/virginia/virginia ratification":FIXED("Virginia Ratification Day",25,6), + + "us/washington/washington admission":FIXED("Washington Admission Day",11,11), + + "us/washington dc/arbor": DWDRI("Arbor Day",1,4,5,3), + + "us/west virginia/west virginia":FIXED("West Virginia Day",20,6), + + "us/wisconsin/primary election": DWDRI("Primary Election Day",1,9,2,1), + "us/wisconsin/wisconsin": FIXED("Wisconsin Day",29,5), + + "us/wyoming/arbor": DWDR("Arbor Day",1,5,1,-1), + "us/wyoming/primary election": DWDRI("Primary Election Day",1,9,2,2), + "us/wyoming/wyoming": FIXED("Wyoming Day",10,12), + "us/wyoming/wyoming statehood": FIXED("Wyoming Statehood Day",10,7), + + "vanuatu/constitution": FIXED("Constitution Day",5,10), + "vanuatu/independence": FIXED("Independence Day",30,7), + + "vatican city/anniversary of the beginning of the john paul ii pontificate": + FIXED("Anniversary of the Beginning of the John Paul II Pontificate",22,10), + "vatican city/john paul ii namesday":FIXED("John Paul II Namesday",4,11), + + "venezuela/battle of carabobo":FIXED("Battle of Carabobo Day",24,6), + "venezuela/bolivars": FIXED("Bolivar's Birthday",24,7), + "venezuela/civil servants": FIXED("Civil Servants' Day",4,9), + "venezuela/declaration of independence": + FIXED("Declaration of Independence",19,4), + "venezuela/independence": FIXED("Independence Day",5,7), + "venezuela/teachers": FIXED("Teacher's Day",15,1), + + "vietnam/day of the nation": FIXED("Day of the Nation",2,9), + "vietnam/emperor-founder hung vuongs": + FIXED("Emperor-Founder Hung Vuong's Day",7,4), + "vietnam/founding of the communist party": + FIXED("Founding of the Communist Party",3,2), + "vietnam/independence": FIXED("Independence Day",14,6), + "vietnam/liberation of saigon":FIXED("Liberation of Saigon",30,4), +// "vietnam/tet nguyen dan": occurs in January of February, +// "vietnam/thanh minh": between April 5 and 20, + + "virgin islands/danish west indies emancipation": + FIXED("Danish West Indies Emancipation Day",3,7), + "virgin islands/hurricane supplication": + DWDRI("Hurricane Supplication Day",1,7,1,4), + "virgin islands/hurricane thanksgiving": + DWDRI("Hurricane Thanksgiving Day",1,10,1,3), + "virgin islands/liberty": DWDRI("Liberty Day",1,11,1,1), + "virgin islands/nicole robin":FIXED("Nicole Robin Day",4,8), + "virgin islands/organic act": DWDRI("Organic Act Day",1,6,1,3), + "virgin islands/transfer": DWDR("Transfer Day",1,4,1,-1), + + "western samoa/arbor": DWDRI("Arbor Day",1,11,5,1), + "western samoa/independence": FIXED("Independence Celebration Day",1,6), + "western samoa/independence2":FIX_M("Independence Celebration",1,6,3), + "western samoa/white sunday": DWDRI("White Sunday",1,10,7,2), + + "yemen/corrective movement": FIXED("Corrective Movement Anniversary",13,6), + "yemen/national": FIXED("National Day",14,10), + + "zaire/armed forces": FIXED("Armed Forces Day",17,11), + "zaire/constitution": FIXED("Constitution Day",24,6), + "zaire/day of the martyrs for independence": + FIXED("Day of the Martyrs for Independence",4,1), + "zaire/independence": FIXED("Independence Day",30,6), + "zaire/mpr": FIXED("MPR Day",20,5), + "zaire/naming": FIXED("Naming Day",27,10), + "zaire/new regime": FIXED("New Regime Day",24,11), + "zaire/parents": FIXED("Parent's Day",1,8), + "zaire/presidents": FIXED("President's Day",14,10), + "zaire/youth/presidents": FIXED("Youth Day/President's Birthday",14,10), + + "zambia/farmers": DWDRI("Farmers' Day",1,8,1,1), + "zambia/heroes": DWDRI("Heroes' Day",1,7,1,1), + "zambia/independence": FIXED("Independence Day",24,10), + "zambia/unity": DWDRI("Unity Day",1,7,2,1), + "zambia/youth": DWDRI("Youth Day",1,8,1,2), + "zambia/youth2": DWDRI("Youth Day",1,3,6,2), + + "zimbabwe/heroess": FIX_M("Heroes' Days",11,8,2), + "zimbabwe/independence": FIXED("Independence Day",18,4), + "zimbabwe/workers": FIXED("Workers' Day",1,5), + +// ---------------------------------------------------------------- +// namedays +// ---------------------------------------------------------------- + + "namedays/sweden":({.Namedays.Sweden}), + "namedays/hungary":({.Namedays.Hungary}), +]); + +// ---------------------------------------------------------------------- +// country information +// ---------------------------------------------------------------------- + +mapping country_events= +([ +// ---------------------------------------------------------------------- +// verified +// ---------------------------------------------------------------------- + + "sweden": + ({ + "halloween", + "labor|hf", + "new years eve", + "new year|hf", + "un|f", + "womens", + + "c/all saints", + "c/annunciation", + "c/ascension|h", + "c/christmas eve", + "c/christmas|hf", + "c/easter monday|h", + "c/easter eve", + "c/easter|hf", + "c/epiphany|h", + "c/fat tuesday", + "c/good friday|h", + "c/palm sunday|h", + "c/pentecost monday|h", + "c/pentecost eve", + "c/pentecost|hf", + "c/candlemas", + "c/advent 1|h", + "c/advent 2|h", + "c/advent 3|h", + "c/advent 4|h", + + "saints/stephen|h", // annandag jul + "saints/john the baptist", + "saints/lucy", + "saints/valentine", + + "sweden/all saints|h", + "sweden/crown princess birthtday|f", + "sweden/crown princess nameday|f", + "sweden/flag|f", + "sweden/nobel|f", + "sweden/kings birthday|f", + "sweden/kings nameday 2|f", + "sweden/kings nameday|f", + "sweden/midsummers eve", + "sweden/midsummer|hf", + "sweden/queens birthday|f", + "sweden/queens nameday|f", + "sweden/valborg eve", + "sweden/waffle", + "sweden/mothers", + "sweden/fathers", + + "namedays/sweden", + "sunday|h", + }), + +// argentina +// source: Julio César Gázquez + + "argentina": + // "argentina/race" ? + // "carnival [shrove tuesday?]" ? + // "death of general san martin" ? + ({ + "new year|h", + "labor|h", + + "argentina/revolution|h", + "argentina/soberanys|h", + "argentina/flag|h", + "argentina/independence|h", + "argentina/gral san martin|h", + "argentina/race|h", + "argentina/malvinas|h", // ? + + "c/epiphany", + "c/good friday|h", + "c/easter|h", + "c/christmas|h", + "c/immaculate conception|h", + "c/assumption", + "c/all saints", + "c/corpus christi", + "c/holy thursday", + "c/holy saturday", + + "sunday|h", + }), + +// hungary +// source: Csongor Fagyal <concept@conceptonline.hu> + + "hungary": + ({ + "new year|h", + "hungary/revolution1848|h", + "hungary/labor|h", + "hungary/constitution|h", + "hungary/revolution56|h", + "c/christmas2d|h", + "c/easter|h", + "c/easter monday|h", + "c/pentecost|h", + "c/pentecost monday|h", + "sunday|h", + "namedays/hungary", + }), + +// russia +// source: Michael Schvryev + + "russia": + ({ "orthodox/christmas|h", + "labor|h", + "new year|h", + "orthodox/easter|h", + "russia/state sovereignity|h", + "russia/victory|h", + "russia/valpurgis|h", + "russia/warriors|h", + "russia/teachers|h", + "womens|h" }), + +// ---------------------------------------------------------------------- +// not verified +// ---------------------------------------------------------------------- + + "afghanistan": + // "afghanistan/jeshyn-afghans" ? + // "deliverance" ? + // "eid al-qorban" ? + // "first of ramadan the sabbath is on friday" ? + // "independence festival" ? + // "national holidays are eid al-fetr" ? + // "prophets" ? + // "pushtunistan" ? + // "sunday are normal works" ? + // "with work ceasing on noon thursday saturday" ? + // "yom ashura" ? + ({ "afghanistan/afghan new year", + "afghanistan/childrens", + "afghanistan/independence", + "afghanistan/mothers", + "afghanistan/national assembly", + "afghanistan/revolution", + "afghanistan/workers" }), + + "albania": + ({ "albania/army", + "albania/independence", + "albania/liberation", + "albania/proclamation of the republic", + "new year", + "womens" }), + + "algeria": + // "ashora" ? + // "first of ramadan" ? + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + // "mouloud" ? + ({ "algeria/independence", + "algeria/national", + "algeria/revolution", + "labor", + "new year" }), + + "american baptist": + ({ "american baptist/roger williams" }), + + "american samoa": + ({ "+us", + "american samoa/flag", + "c/christmas", + "labor", + "new year" }), + + "andorra": + ({ "andorra/national feast", + "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "new year" }), + + "anglican church": + ({ "anglican church/name of jesus" }), + + "angola": + // "yet are generally treated as public holidays these are youth" ? + ({ "angola/armed forces", + "angola/independence", + "angola/mpla foundation", + "angola/national heros", + "angola/national holiday", + "angola/pioneers", + "angola/victory", + "angola/workers", + "angola/youth", + "family", + "new year" }), + + "anguilla": + // "august monday" ? + // "august thursday" ? + // "constitution" ? + // "queens official" ? + // "separation" ? + // "spring bank holiday" ? + ({ "anguilla/anguilla", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "labor", + "new year" }), + + "antigua and barbuda": + // "carnival" ? + ({ "antigua and barbuda/independence", + "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "caribbean/caricom", + "labor", + "new year" }), + + "armenia": + // "armenia/Easter (Orthodox)" ? + ({ "armenia/christmas", + "armenia/martyrs", + "armenia/republic" }), + + "aruba": + // "lenten carnival" ? + ({ "aruba/aruba flag", + "british commonwealth/queens", + "c/ascension", + "c/christmas", + "c/easter", + "c/whitmonday", + "labor", + "new year" }), + + "australia": + ({ "australia/australia|h", + "australia/eight hour", + "new year|h", + "c/good friday|h", + "c/easter monday|h", + "c/easter|h", + "anzac|h", + "united kingdom/queens|h", + "c/christmas|h", + "c/boxing|h" }), + + "australia/new south wales": + ({ "+australia", + "australia/summer bank holiday|h"}), + "australia/northern territory": + ({ "+australia", + "labor|h" }), + "australia/queensland": + ({ "+australia", +// "australia/labor_oct|h", + "australia/summer bank holiday|h"}), + "australia/south australia": + ({ "+australia", + "australia/proclamation|h", + "labor|h", }), + "australia/tasmania": + ({ "+australia", + "australia/recreation", + "australia/hobert regatta|h", +// "australia/labor_mar|h", + "australia/spring bank holiday|h" }), + "australia/victoria": + ({ "+australia", + "australia/show|h", + "australia/second new years", +// "australia/labor_mar|h", +// "australia/cup|h", + "australia/spring bank holiday|h"}), + "australia/western australia": + ({ "+australia", + "australia/foundation|h", + "australia/show|h", +// "australia/labor_mar|h", + "australia/spring bank holiday|h" }), + + "austria": + ({ "c/all saints", + "austria/national", + "austria/national holiday", + "austria/national holiday of austria", + "austria/republic", + "austria/second republic", + "c/ascension", + "c/assumption", + "c/christmas", + "c/corpus christi", + "c/easter monday", + "c/immaculate conception", + "c/whitmonday", + "c/epiphany", + "labor", + "new year" }), + + "bahamas": + ({ "bahamas/fox hill", + "bahamas/independence", + "bahamas/labor", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "caribbean/emancipation", + "columbus", + "labor", + "new year" }), + + "bahrain": + // "ashoura" ? + // "first of muharram" ? + // "first of ramadan" ? + // "id al-adha" ? + // "id al-fitr" ? + // "leilat al-meiraj" ? + // "mouloud" ? + // "national" ? + ({ "bahrain/national of bahrain", + "new year" }), + + "bangladesh": + // "buddha purnima" ? + // "durga puja" ? + // "eid-ul-azha" ? + // "eid-ul-fitr" ? + // "jamaat-ul-bida" ? + // "janmastami" ? + // "martyrs" ? + // "shab-e-barat" ? + // "shab-e-qudr" ? + // "yom ashura" ? + ({ "bangladesh/bengali new year", + "bangladesh/independence", + "bangladesh/national mourning", + "bangladesh/revolution", + "bangladesh/victory", + "c/christmas", + "may day" }), + + "barbados": + // "kadooment" ? + ({ "barbados/errol barrow", + "barbados/independence", + "barbados/united nations", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "labor", + "new year" }), + + "belgium": + ({ "c/all saints", + "armistice", + "belgium/dynasty", + "belgium/independence", + "belgium/kings", + "c/all souls", + "c/ascension", + "c/assumption", + "c/boxing", + "c/christmas", + "c/easter monday", + "c/whitmonday", + "labor", + "new year" }), + + "belize": + ({ "belize/baron bliss", + "belize/commonwealth", + "belize/garifuna", + "belize/independence", + "belize/national", + "belize/pan american", + "belize/saint georges cay", + "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/holy saturday", + "labor", + "new year" }), + + "benin": + // "id al-adha" ? + // "id al-fitr" ? + ({ "c/all saints", + "benin/armed forces", + "benin/harvest", + "benin/martyrs", + "benin/national", + "benin/workers", + "benin/youth", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "new year" }), + + "bermuda": + // "bermuda/Labor Day (Sep)" ? + // "cup match" ? + // "queens official" ? + ({ "bermuda/bermuda", + "bermuda/peppercorn", + "bermuda/remembrance", + "bermuda/somers", + "c/christmas", + "c/good friday", + "new year" }), + + "bhutan": + // "buddhist holidays" ? + // "dussehra" ? + ({ "bhutan/kings", + "bhutan/national of bhutan" }), + + "bolivia": + // "also regional public holidays" ? + // "bolivia/alacitas" ? + // "bolivia/la paz" ? + // "carnival " ? + // "christmas there" ? + // "shrove tue)" ? + ({ "bolivia/independence", + "bolivia/martyrs", + "bolivia/memorial", + "bolivia/national", + "c/all souls", + "c/corpus christi", + "c/good friday", + "labor", + "new year" }), + + "bosnia and herzegovina": + // "july 27" ? + // "november 25" ? + ({ "bosnia and herzegovina/labors", + "new year" }), + + "botswana": + // "christmas multiples" ? + // "given for most of these holidays" ? + // "national holidays" ? + ({ "botswana/botswana", + "botswana/presidents", + "c/ascension", + "c/easter", + "new year" }), + + "brazil": + // "carnival" ? + // "christmas sao paulo has the additional regional public holiday sao paulo" ? + // "national holidays" ? + // "saint sebastians feast" ? + ({ "brazil/brasilia", + "brazil/discovery", + "brazil/independence", + "brazil/proclamation of the republic", + "brazil/republic", + "brazil/sao paulo", + "brazil/tiradentes", + "c/all souls", + "c/corpus christi", + "c/good friday", + "labor", + "new year" }), + + "british virgin islands": + // "august holiday " ? + // "british virgin islands/sovereigns observance" ? + // "commonwealth" ? + // "queens official" ? + // "saint ursulas" ? + // "tue" ? + // "wed)" ? + ({ "british commonwealth/prince of wales", + "british virgin islands/territory", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "new year" }), + + "brunei": + // "beginning of ramadan" ? + // "brunei/Hari Raya Haji (Feast of the Sacrifice)" ? + // "brunei/Hari Raya Puasa (end of Ramadan)" ? + // "brunei/Hizrah (Islamic New Year)" ? + // "brunei/Isra Mera (Leilat al-Meiraj)" ? + // "brunei/Memperingati Nuzul Al-Quran (Revelation of the Koran)" ? + // "chinese new year" ? + // "hari mouloud" ? + ({ "brunei/national", + "brunei/royal brunei armed forces", + "brunei/sultans", + "c/christmas", + "new year" }), + + "bulgaria": + // "national holidays" ? + ({ "bulgaria/babin den", + "bulgaria/botev", + "bulgaria/education", + "bulgaria/liberation", + "bulgaria/national", + "bulgaria/national holiday", + "bulgaria/viticulturists", + "c/christmas", + "labor", + "new year" }), + + "burkina faso": + // "id al-adha" ? + // "id al-fitr" ? + // "mouloud" ? + ({ "c/all saints", + "burkina faso/anniversary of 1966 coup", + "burkina faso/labor", + "burkina faso/national", + "burkina faso/republic", + "burkina faso/youth", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/whitmonday", + "new year" }), + + "burundi": + // "umugamuro" ? + ({ "c/all saints", + "burundi/anniversary of the revolution", + "burundi/independence", + "burundi/murder of the hero", + "burundi/victory of uprona", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter monday", + "labor", + "new year" }), + + "cambodia": + // "cambodia/chaul chhnam" ? + // "cambodia/visak bauchea" ? + // "chaul chhnam" ? + ({ "cambodia/ancestors", + "cambodia/day of hatred", + "cambodia/independence", + "cambodia/khmer republic constitution", + "cambodia/memorial", + "cambodia/national", + "labor" }), + + "cameroon": + ({ "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/pentecost monday", + "cameroon/commemoration of national institutions", + "cameroon/constitution", + "cameroon/human rights", + "cameroon/independence", + "cameroon/unification", + "cameroon/youth", + "labor" }), + + "canada": + // "also public holidays specific to each province" ? + // "canada/Labor Day (Sep.)" ? + // "canada/discovery" ? + // "canada/thanksgiving" ? + // "christmas there" ? + // "thanksgiving" ? + ({ "c/easter monday", + "c/good friday", + "canada/civic holiday", + "canada/dominion", + "canada/klondike gold discovery", + "canada/labor", + "canada/remembrance", + "canada/victoria", + "new year" }), + + "cape verde": + ({ "c/all saints", + "c/assumption", + "c/christmas", + "cape verde/independence", + "cape verde/national", + "cape verde/national heroes", + "labor", + "new year" }), + + "caribbean": + ({ "caribbean/caricom", + "caribbean/emancipation", + "caribbean/schoelcher" }), + + "cayman islands": + // "constitution" ? + // "discovery" ? + // "queens official" ? + // "remembrance" ? + ({ "c/ash wednesday", + "c/christmas", + "c/easter monday", + "c/good friday", + "new year" }), + + "central african republic": + // "national holidays" ? + ({ "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/pentecost", + "central african republic/first government", + "central african republic/republic", + "central african republic/boganda", + "central african republic/day after republic", + "central african republic/independence", + "central african republic/national holiday", + "labor", + "new year" }), + + "central america": + ({ "central america/independence" }), + + "chad": + // "aid el kebir" ? + // "aid el sequir" ? + // "mouloud el nebi" ? + ({ "africa", + "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/pentecost", + "chad/creation of the union of central african states", + "chad/independence", + "chad/national", + "chad/republic", + "chad/traditional independence []", + "labor", + "new year" }), + + "chile": + ({ "saints/paul", + "saints/peter", + "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/corpus christi", + "c/good friday", + "c/immaculate conception", + "chile/armed forces", + "chile/independence", + "chile/independence2", + "chile/national holiday", + "chile/navy", + "columbus", + "labor", + "new year" }), + + "china": + // "army" ? + // "china/army" ? + // "chinese new year" ? + // "dragon boat festival" ? + // "lantern festival" ? + // "mid-autumn festival" ? + // "qing ming" ? + // "seventh eve" ? + ({ "china/ccps", + "china/childrens", + "china/national", + "china/teachers", + "china/tree planting", + "china/youth", + "labor", + "new year", + "womens" }), + + "columbia": + // "battle of boyacaday" ? + // "national holidays" ? + // "sacred heart" ? + // "saint josephs" ? + ({ "saints/paul", + "saints/peter", + "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/corpus christi", + "c/good friday", + "c/holy thursday", + "c/immaculate conception", + "columbia/battle of boyaca", + "columbia/cartagena independence", + "columbia/independence", + "columbia/thanksgiving", + "columbus", + "c/epiphany", + "labor", + "new year" }), + + "comoros": + // "ashoura" ? + // "beginning of ramadan" ? + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + // "mouloud" ? + ({ "comoros/anniversary of president abdallahs assassination", + "comoros/independence" }), + + "congo": + // "national holidays" ? + ({ "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/pentecost", + "congo/day before army", + "congo/day before independence", + "congo/day before national", + "congo/independence", + "congo/martyr of independence", + "new year" }), + + "corsica": + ({ "corsica/napoleons" }), + + "costa rica": + // "costa rica/guanacaste" ? + ({ "costa rica/battle of rivas", + "costa rica/independence" }), + + "croatia": + ({ "c/assumption", + "c/christmas", + "croatia/national holiday", + "croatia/republic", + "c/epiphany", + "labor", + "new year" }), + + "cuba": + // "cuba/beginning of independence wars" ? + ({ "cuba/independence", + "cuba/liberation", + "cuba/revolution", + "cuba/wars of independence", + "labor" }), + + "cyprus/greece": + ({ "new year", + "c/epiphany", + "cyprus/name day", + "cyprus/green monday", + "greece/independence", + "c/good friday", + "c/holy saturday", + "c/easter monday", + "cyprus/greek national", + "c/christmas", + "c/boxing", + "cyprus/kataklysmos", + "cyprus/submersion of the holy cross" }), + + "cyprus/turkey": +// "id al-fitr" +// "id al-adha" +// "birth of the prophet" + ({ "new year", + "turkey/national sovereignty", + "turkey/childrens", + "labor", + "turkey/youth and sports", + "cyprus/communal resistance", + "turkey/victory", + "turkey/independence", + "cyprus/kataklysmos", + "cyprus/peace and freedom", + "cyprus/submersion of the holy cross" }), + + "czech republic": + ({ "c/christmas", + "saints/stephen", + "c/christmas eve", + "c/easter monday", + "czech republic/death of jan hus", + "czech republic/introduction of christianity", + "labor", + "new year" }), + + "czechoslovakia": + // "czechoslovakia/teachers" ? + ({ "czechoslovakia/resistance movement" }), + + "denmark": + // "denmark/public holidays" ? + ({ "denmark/birthday of queen margrethe ii", + "denmark/common prayer", + "denmark/constitution", + "denmark/fjortende februar", + "denmark/liberation", + "denmark/valdemars" }), + + "djibouti": + // "id al-adha" ? + // "id al-fitr" ? + // "independence" ? + // "mawloud" ? + // "muharram" ? + ({ "c/christmas", + "djibouti/independence feast", + "djibouti/workers", + "new year" }), + + "dominica": + // "carnival" ? + ({ "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "dominica/community service", + "dominica/emancipation", + "dominica/independence", + "labor", + "new year" }), + + "ecuador": + // "battle of pichincha" ? + // "carnival" ? + // "cuenca independence" ? + // "ecuador/cuenca independence" ? + // "ecuador/independence" ? + // "founding of quito" ? + // "guayaquil independence" ? + // "independence" ? + // "simsn bolmvars" ? + ({ "c/all saints", + "c/all souls", + "c/christmas", + "c/good friday", + "c/holy thursday", + "columbus", + "ecuador/battle of pichincha ", + "ecuador/guayaquils independence", + "ecuador/simon bolivars", + "c/epiphany", + "labor", + "new year" }), + + "egypt": + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + // "mouled al nabi" ? + ({ "egypt/armed forces", + "egypt/evacuation", + "egypt/leylet en-nuktah", + "egypt/revolution", + "egypt/sham al-naseem", + "egypt/sinai liberation", + "egypt/suez", + "egypt/victory", + "labor", + "new year", + "unity" }), + + "el salvador": + // "el salvador/Discovery of America (Columbus Day)" ? + ({ "c/all souls", + "c/christmas", + "c/corpus christi", + "c/easter", + "el salvador/first call for independence", + "el salvador/independence", + "el salvador/san salvador festival", + "el salvador/schoolteachers", + "labor", + "new year" }), + + "equatorial guinea": + ({ "c/christmas", + "c/easter", + "c/good friday", + "equatorial guinea/armed forces", + "equatorial guinea/constitution", + "equatorial guinea/independence", + "equatorial guinea/oau", + "equatorial guinea/presidents", + "labor", + "new year" }), + + "estonia": + // "independence" ? + ({ "c/christmas", + "c/good friday", + "estonia/midsummer", + "estonia/victory", + "labor", + "new year" }), + + "ethiopia": + // "birthday of mohammed" ? + // "id al-adha" ? + // "id al-fitr" ? + ({ "c/good friday", + "ethiopia/battle of aduwa", + "ethiopia/buhe", + "ethiopia/epiphany", + "ethiopia/ethiopian new year", + "ethiopia/genna", + "ethiopia/liberation", + "ethiopia/martyrs", + "ethiopia/meskel", + "ethiopia/patriots victory", + "ethiopia/popular revolution commemoration", + "ethiopia/revolution", + "ethiopia/victory of adowa", + "labor" }), + + "falkland islands": + // "bank holiday" ? + ({ "british commonwealth/queens", + "c/christmas", + "c/good friday", + "falkland islands/anniversary of the battle of the falkland islands", + "falkland islands/liberation", + "new year" }), + + "fiji": + // "diwali" ? + // "fiji/deed of cession" ? + // "fiji/fiji2" ? + // "prophets" ? + ({ "c/boxing", + "c/christmas", + "c/easter", + "c/easter eve", + "c/easter monday", + "c/good friday", + "fiji/bank holiday", + "fiji/fiji", + "fiji/prince charles", + "fiji/queens", + "new year" }), + + "finland": + // "finland/helsinki" ? + ({ "c/boxing", + "c/christmas", + "c/christmas eve", + "c/easter monday", + "c/good friday", + "c/epiphany", + "c/pentecost eve", + "finland/alexis kivi", + "finland/flag", + "finland/flag of the army", + "finland/independence", + "finland/kalevala", + "finland/midsummers eve", + "finland/runebergs", + "finland/snellman", + "finland/vappu", + "finland/all saints", + "finland/midsummer", + "may day", + "new year" }), + + "france": + ({ "c/all saints", + "armistice", + "c/all souls", + "c/ash wednesday", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/pentecost", + "france/ascension", + "france/bastille", + "france/d-day observance", + "france/fathers", + "france/fete des saintes-maries", + "france/fete nationale", + "france/liberation", + "france/marseillaise", + "france/night watch", + "new year" }), + + "french guiana": + // "bastille" ? + ({ "c/all saints", + "armistice", + "c/all souls", + "c/ascension", + "c/ash wednesday", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/pentecost", + "new year" }), + + "french polynesia": + ({ "french polynesia/armistice", + "french polynesia/chinese new year", + "french polynesia/missionaries arrival commemoration", + "may day" }), + + "gabon": + // "id al-adha" ? + // "id al-fitr" ? + // "mouloud" ? + ({ "c/all saints", + "c/christmas", + "c/easter monday", + "c/whitmonday", + "gabon/constitution", + "gabon/independence", + "gabon/renovation", + "labor", + "new year" }), + + "gambia": + // "id al-fitr" ? + // "id al-kabir" ? + // "mouloud" ? + ({ "c/assumption", + "c/christmas", + "gambia/independence", + "gambia/moslem new year", + "labor", + "new year" }), + + "germany": + // "christmas the following religious holidays" ? + // "germany/oktoberfest" ? + // "observed in certain l\344nder only epiphany" ? + ({ "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/corpus christi", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "germany/day of repentance", + "germany/day of the workers", + "germany/foundation", + "germany/national", + "germany/unity", + "germany/waldchestag", + "labor", + "new year", + "unity" }), + + "ghana": + // "ghana/aboakyer" ? + ({ "c/boxing", + "c/easter eve", + "c/easter monday", + "c/good friday", + "ghana/homowo", + "ghana/independence", + "ghana/liberation", + "ghana/republic", + "ghana/revolution", + "ghana/third republic", + "ghana/uprising", + "labor", + "new year" }), + + "gibraltar": + // "gibraltar/late summer bank holiday" ? + // "late summer bank holiday" ? + // "queens official" ? + ({ "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "gibraltar/commonwealth", + "gibraltar/spring bank holiday", + "may day", + "new year" }), + + "greece": + // "greece/dumb week" ? + ({ "orthodox/assumption", + "orthodox/easter", + "orthodox/easter monday", + "orthodox/good friday", + "orthodox/holy saturday", + "orthodox/epiphany", + "orthodox/christmas", + "greece/clean monday", + "greece/independence", + "greece/flower festival", + "greece/midwifes", + "greece/ochi", + "greece/dodecanese accession", // rhodes + "saints/demetrios", // thessaloniki + "greece/liberation of xanthi", // xanthi + "saints/basil", + "labor", + "new year" }), + + "gregorian calendar ": + ({ "gregorian calendar /gregorian calendar" }), + + "grenada": + ({ "c/boxing", + "c/christmas", + "c/corpus christi", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "caribbean/emancipation", + "grenada/independence", + "grenada/national holiday", + "grenada/thanksgiving", + "labor", + "new year" }), + + "guadeloupe": + // "bastille" ? + // "schoelcher" ? + ({ "c/all saints", + "armistice", + "c/all souls", + "c/ash wednesday", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/pentecost", + "caribbean/schoelcher", + "guadeloupe/ascension", + "new year" }), + + "guam": + // "george washingtons" ? + // "memorial" ? + // "thanksgiving" ? + // "us independence" ? + ({ "c/christmas", + "guam/discovery", + "guam/guam discovery", + "guam/liberation", + "labor", + "new year" }), + + "guatemala": + ({ "c/all saints", + "c/assumption", + "c/christmas", + "c/holy friday", + "c/holy saturday", + "c/holy thursday", + "guatemala/army", + "guatemala/bank employees", + "guatemala/independence", + "guatemala/revolution", + "labor", + "new year" }), + + "guinea": + // "id al-fitr" ? + // "mouloud" ? + ({ "c/all saints", + "c/christmas", + "c/easter", + "guinea/anniversary of cmrn", + "guinea/anniversary of womens revolt", + "guinea/day of 1970 invasion", + "guinea/independence", + "guinea/referendum", + "labor", + "new year" }), + + "guinea-bissau": + // "guinea-bissau/Korit\351(Id al-Fitr)" ? + // "guinea-bissau/Tabaski (Id al-Adha)" ? + ({ "c/christmas", + "guinea-bissau/colonization martyrs", + "guinea-bissau/independence", + "guinea-bissau/mocidade", + "guinea-bissau/national", + "guinea-bissau/national heroes", + "guinea-bissau/readjustment movement", + "labor", + "new year" }), + + "guyana": + // "diwali" ? + // "guyana/Carribean Day (June)" ? + // "guyana/Indian Heritage Day (May)" ? + // "guyana/Youman Nabi (Mouloud)" ? + // "holi" ? + // "id al-adha" ? + // "id al-fitr" ? + ({ "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "guyana/freedom", + "guyana/independence", + "guyana/republic", + "labor", + "new year" }), + + "haiti": + ({ "haiti/discovery", + "haiti/vertieres" }), + + "honduras": + ({ "c/christmas", + "c/good friday", + "c/holy thursday", + "columbus", + "honduras/armed forces", + "honduras/independence", + "honduras/morazan", + "honduras/thanksgiving", + "labor", + "new year", + "honduras/pan american" }), + + "hong kong": + // "hong kong/chung yeung festival" ? + ({ "hong kong/birthday of confucious", + "hong kong/birthday of pak tai", + "hong kong/half-year", + "hong kong/liberation" }), + + "iceland": + ({ "iceland/independence" }), + + "india": + ({ "india/indian independence", + "india/mahatma gandhi jayanti", + "india/mahatma gandhi martyrdom", + "india/republic" }), + + "indonesia": + // "id al-adha" ? + // "id al-fitr" ? + // "indonesia/balinese new year" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + // "mouloud" ? + ({ "c/ascension", + "c/christmas", + "c/good friday", + "indonesia/independence", + "indonesia/kartini", + "new year" }), + + "iran": + // "ashoura" ? + // "id al-adha" ? + // "id al-fitr" ? + // "leilat al-meiraj" ? + // "mouloud" ? + ({ "iran/constitution", + "iran/islamic republic", + "iran/martyrdom of imam ali", + "iran/no ruz", + "iran/oil nationalization", + "iran/revolution", + "iran/revolution2" }), + + "iraq": + // "ashoura" ? + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + // "mouloud" ? + ({ "iraq/14 ramadan revolution", + "iraq/army", + "iraq/july revolution", + "iraq/republic", + "new year" }), + + "ireland": + // "august" ? + // "bank holidays on mondays in june" ? + // "october" ? + // "saint patricks" ? + ({ "c/christmas", + "saints/stephen", + "c/easter monday", + "c/good friday", + "ireland/sheelahs", + "new year" }), + + "israel": + // "holocaust memorial" ? + // "independence" ? + // "israel/hebrew university" ? + // "israel/holocaust memorial" ? + // "israel/independence" ? + // "israel/national" ? + // "lasts)" ? + // "passover " ? + // "rosh hashanah" ? + // "shavuot" ? + // "simhat torah" ? + // "succot" ? + // "yom kippur" ? + ({ "israel/balfour declaration", + "israel/jerusalem reunification" }), + + "italy": + // "italy/saint marks" ? + ({ "c/christmas", + "italy/anniversary of the republic", + "italy/befana", + "italy/day of conciliation", + "italy/festa del redentore", + "italy/joust of the quintana", + "italy/liberation", + "italy/natale di roma", + "italy/palio del golfo", + "italy/santo stefano" }), + + "ivory coast": + // "id al-adha" ? + // "id al-fitr" ? + ({ "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "ivory coast/independence", + "ivory coast/national holiday of the ivory coast", + "labor", + "new year" }), + + "jamaica": + ({ "c/ash wednesday", + "c/christmas", + "c/easter monday", + "c/good friday", + "jamaica/heroes", + "jamaica/independence", + "jamaica/labor", + "labor", + "new year" }), + + "japan": + // "autumn equinox" ? + // "health sports" ? + // "japan/autumnal equinox" ? + // "japan/black ship" ? + // "japan/bon" ? + // "japan/health" ? + // "japan/memorial" ? + // "japan/peoples holiday" ? + // "japan/shichigosan" ? + // "japan/vernal equinox" ? + // "vernal equinox" ? + ({ "japan/adults", + "japan/bean-throwing festival", + "japan/childrens", + "japan/childrens protection", + "japan/constitution", + "japan/culture", + "japan/emperors", + "japan/empire", + "japan/gion matsuri", + "japan/greenery", + "japan/hina matsuri", + "japan/hiroshima peace festival", + "japan/hollyhock festival", + "japan/jidai matsuri", + "japan/kakizome", + "japan/kambutsue", + "japan/kite battles of hamamatsu", + "japan/labor thanksgiving", + "japan/martyr", + "japan/memorial to broken dolls", + "japan/national foundation", + "japan/respect for the aged", + "japan/sanno matsuri", + "japan/shigoto hajime", + "japan/tanabata", + "japan/tango-no-sekku", + "new year" }), + + "jordan": + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + // "mouloud" ? + ({ "arab league", + "jordan/arbor", + "jordan/coronation", + "jordan/independence", + "jordan/king hussein" }), + + "kenya": + // "id al-fitr" ? + ({ "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "kenya/independence", + "kenya/kenyatta", + "kenya/madaraka", + "labor", + "new year" }), + + "kiribati": + ({ "c/christmas", + "c/easter", + "kiribati/independence", + "kiribati/youth", + "new year" }), + + "korea": + ({ "korea/independence movement" }), + + "kuwait": + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + // "mouloud" ? + // "start of ramadan" ? + ({ "kuwait/independence", + "kuwait/national", + "new year" }), + + "laos": + // "chinese new year" ? + // "laos/army" ? + ({ "labor", + "laos/constitution", + "laos/independence", + "laos/memorial", + "laos/pathet lao", + "laos/republic" }), + + "latvia": + // "indpendence" ? + ({ "c/christmas", + "c/good friday", + "latvia/independence", + "latvia/midsummer festival", + "new year", + "new years eve" }), + + "lebanon": + // "ashoura" ? + // "chrismas" ? + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + // "mouloud" ? + // "orthodox easter" ? + ({ "c/all saints", + "arab league", + "c/ascension", + "c/assumption", + "c/easter", + "lebanon/evacuation", + "lebanon/independence", + "lebanon/martyrs", + "lebanon/saint maron", + "new year" }), + + "lesotho": + ({ "c/ascension", + "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "family", + "lesotho/family", + "lesotho/independence", + "lesotho/kings", + "lesotho/moshoeshoes", + "lesotho/national holiday", + "lesotho/national sports", + "lesotho/national tree planting", + "new year" }), + + "liberia": + // "fast" ? + // "integration" ? + // "prayer" ? + // "unification" ? + ({ "c/christmas", + "c/good friday", + "liberia/armed forces", + "liberia/decoration", + "liberia/fast and prayer", + "liberia/flag", + "liberia/independence", + "liberia/j j roberts", + "liberia/literacy", + "liberia/matilda newport", + "liberia/memorial", + "liberia/national redemption", + "liberia/pioneers", + "liberia/president tubmans", + "liberia/thanksgiving", + "liberia/unification and integration", + "new year" }), + + "libya": + // "ashoura" ? + // "expulsion of fascist settlers" ? + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + // "libya/troop withdrawal" ? + // "mouloud" ? + ({ "libya/evacuation", + "libya/expulsion of the fascist settlers", + "libya/kings", + "libya/national", + "libya/revolution", + "libya/sanusi army" }), + + "liechtenstein": + // "saint josephs" ? + ({ "c/all saints", + "saints/stephen", + "c/ascension", + "c/assumption", + "c/christmas", + "c/corpus christi", + "c/easter", + "c/good friday", + "c/immaculate conception", + "c/nativity of mary", + "c/whitmonday", + "c/epiphany", + "labor", + "liechtenstein/birthday of prince franz-josef ii", + "liechtenstein/national", + "new year" }), + + "lithuania": + // "national of hope" ? + ({ "c/christmas", + "lithuania/coronation", + "lithuania/independence", + "lithuania/mourning", + "new year" }), + + "luxembourg": + ({ "c/all saints", + "c/boxing", + "c/christmas", + "c/easter monday", + "luxembourg/burgsonndeg", + "luxembourg/grand duchess", + "luxembourg/liberation", + "luxembourg/national", + "new year" }), + + "macao": + // "chinese mid-autumn festival" ? + // "chinese new year" ? + // "ching ming" ? + // "dragon boat festival" ? + // "festival of ancestors" ? + // "macao/hungry ghosts" ? + // "national of china" ? + // "portugal" ? + // "portuguese republic" ? + // "restoration of the independence" ? + // "saint johns" ? + // "winter solstice" ? + ({ "c/all souls", + "c/christmas", + "c/good friday", + "c/immaculate conception", + "labor", + "macao/anniversary of the portugese revolution", + "macao/battle of july 13", + "macao/procession of our lady of fatima", + "macao/republic", + "new year" }), + + "madagascar": + ({ "c/all saints", + "c/ascension", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitsunday", + "labor", + "madagascar/commemoration", + "madagascar/independence", + "madagascar/republic", + "new year" }), + + "malawi": + // "but usually jul 5-7)" ? + ({ "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "malawi/august holiday", + "malawi/kamuzu", + "malawi/martyrs", + "malawi/mothers", + "malawi/national tree-planting", + "malawi/republic", + "mothers", + "new year" }), + + "malaysia": + // "chinese new year" ? + // "diwali " ? + // "each state has its own public holidays" ? + // "malaysia/Hari Raya Haji (Id al-Adha)" ? + // "malaysia/Hari Raya Puasa (Id al-Fitr)" ? + // "malaysia/additional public holiday in kuala lumpur" ? + // "mouloud in addition" ? + // "sarawak)" ? + // "vesak" ? + ({ "c/christmas", + "labor", + "malaysia/kings", + "malaysia/malaysia" }), + + "maldives": + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "mouloud" ? + ({ "maldives/fisheries", + "maldives/independence", + "maldives/national", + "maldives/republic", + "maldives/victory" }), + + "mali": + // "mali/Korit\351(Id al-Fitr)" ? + // "mali/Tabaski (Id al-Adha)" ? + // "mouloud" ? + ({ "africa", + "c/christmas", + "c/easter monday", + "labor", + "mali/army", + "mali/independence", + "mali/liberation", + "new year" }), + + "malta": + // "malta/Feast of Our Lady of Victories (Nativity of Mary)" ? + // "saint josephs" ? + // "saint pauls shipwreck" ? + ({ "saints/paul", + "saints/peter", + "c/assumption", + "c/christmas", + "c/good friday", + "c/immaculate conception", + "labor", + "malta/freedom", + "malta/independence", + "malta/memorial of 1919 riot", + "malta/republic", + "new year" }), + + "marshall islands": + ({ "marshall islands/proclamation of the republic of marshall islands" }), + + "martinique": + // "bastille" ? + // "lundi-gras" ? + // "mardi-gras" ? + ({ "c/all saints", + "armistice", + "c/all souls", + "c/ash wednesday", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/pentecost", + "martinique/ascension", + "new year" }), + + "mauritania": + // "islamic new year" ? + // "leilat al-meiraj" ? + // "mauritania/Korit\351(Id al-Fitr)" ? + // "mauritania/Tabaski (Id al-Adha)" ? + // "mouloud" ? + ({ "africa", + "labor", + "mauritania/independence", + "new year" }), + + "mauritius": + // "diwali" ? + // "ganesh chaturi" ? + // "id al-fitr" ? + // "maha shivaratree" ? + // "mauritius/Chinese Spring Festival (Chinese New Year)" ? + // "mauritius/Ougadi (Hindu)" ? + // "thaipusam" ? + ({ "c/all saints", + "c/christmas", + "c/good friday", + "labor", + "mauritius/independence", + "new year" }), + + "mexico": + // "birthday of benito juarez easter" ? + // "but not public holidays" ? + // "christmas in addition" ? + // "mexico/Day of the Dead (All Souls' Day)" ? + // "widely celebrated" ? + ({ "c/christmas", + "labor", + "mexico/birthday of benito juarez", + "mexico/cinco de mayo", + "mexico/constitution", + "mexico/day of mourning", + "mexico/dia de la raza", + "mexico/holy cross", + "mexico/independence", + "mexico/night of the radishes", + "mexico/our lady of guadalupe", + "mexico/posadass", + "mexico/presidential message", + "mexico/revolution", + "mexico/san marc\363s", + "new year" }), + + "micronesia": + // "micronesia/national holiday" ? + ({ }), + + "monaco": + // "monaco/F\352te du Travail (Labor Day)" ? + ({ "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/immaculate conception", + "c/whitmonday", + "monaco/monaco national festival", + "new year", + "saints/devote" }), + + "mongolia": + // "mongolia/Tsagaan Sar (lunar new year)" ? + ({ "mongolia/national", + "mongolia/republic", + "new year", + "womens" }), + + "montserrat": + // "august monday" ? + // "queens official" ? + // "saint patricks" ? + ({ "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "labor", + "montserrat/festival", + "montserrat/liberation", + "new year" }), + + "mormonism": + ({ "mormonism/founding of the mormon church" }), + + "morocco": + // "ashoura" ? + // "first of ramadan" ? + // "islamic new year" ? + // "morocco/Eid el Kebir (Id al-Adha)" ? + // "morocco/Eid el Seghir (Id al-Fitr)" ? + // "mouloud" ? + ({ "labor", + "morocco/green march", + "morocco/independence", + "morocco/oued ed-dahab", + "morocco/throne", + "new year" }), + + "mozambique": + ({ "family", + "mozambique/armed forces", + "mozambique/heroes", + "mozambique/independence", + "mozambique/lusaka agreement", + "mozambique/universal fraternity", + "mozambique/womens", + "mozambique/workers", + "new year" }), + + "myanmar": + // "burmese new year" ? + // "diwali" ? + // "full moon of kason" ? + // "full moon of tabaung" ? + // "full moon of thadingyut" ? + // "full moon of waso" ? + // "id al-adha" ? + // "karen new year" ? + // "myanmar/Water Festival (Maha Thingyan)" ? + // "myanmar/burmese new year" ? + // "tazaundaing festival" ? + ({ "c/christmas", + "labor", + "myanmar/armed forces", + "myanmar/independence", + "myanmar/martyrs", + "myanmar/national", + "myanmar/peasants", + "myanmar/resistance", + "myanmar/union" }), + + "namibia": + // "human rights" ? + ({ "africa", + "c/ascension", + "c/christmas", + "c/easter", + "family", + "namibia/casinga", + "namibia/day of goodwill", + "namibia/family", + "namibia/heroes", + "namibia/independence", + "namibia/workers", + "new year" }), + + "nauru": + ({ "c/christmas", + "c/easter", + "nauru/angam", + "nauru/independence", + "new year" }), + + "nepal": + // "diwali" ? + // "holi" ? + // "indra jatra" ? + // "nepal/Baishakh Purnima (Buddha's birthday)" ? + // "nepal/Dasain (Durga Puja)" ? + // "nepal/Martyrs' Day (near Jan 30)" ? + // "nepal/Navabarsha (Baisakhi)" ? + // "nepal/buddha jayanti" ? + // "ramnavami" ? + // "shiva ratri" ? + // "united nations" ? + ({ "nepal/birthday of king birendra", + "nepal/constitution", + "nepal/democracy", + "nepal/independence", + "nepal/kings", + "nepal/national unity", + "nepal/queens", + "nepal/tij", + "womens" }), + + "netherlands": + ({ "c/ascension", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "netherlands/beggars", + "netherlands/independence", + "netherlands/liberation", + "netherlands/queens", + "netherlands/sinterklaas", + "new year" }), + + "netherlands antilles": + // "christmas additional public holidays: lenten carnival in cura\347ao" ? + // "whitmonday in st maarten" ? + ({ "c/ascension", + "c/easter monday", + "c/good friday", + "labor", + "netherlands antilles/bonaire", + "netherlands antilles/cura\347ao", + "netherlands antilles/queens", + "netherlands antilles/saba", + "netherlands antilles/saint eustatius", + "netherlands antilles/saint maarten", + "new year" }), + + "new caledonia": + // "bastille" ? + // "liberation" ? + ({ "armistice", + "c/ascension", + "c/christmas", + "c/easter monday", + "c/whitmonday", + "labor", + "new year" }), + + "new zealand": + ({ "anzac", + "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "labor", + "new year", + "new zealand/labor", + "new zealand/queens", + "new zealand/waitangi" }), + + "nicaragua": + ({ "c/all souls", + "c/christmas", + "c/easter", + "c/holy friday", + "c/holy thursday", + "labor", + "new year", + "nicaragua/air force", + "nicaragua/army", + "nicaragua/fiesta", + "nicaragua/independence", + "nicaragua/revolution", + "nicaragua/san jacinto" }), + + "niger": + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "mouloud" ? + ({ "c/christmas", + "c/easter monday", + "labor", + "new year", + "niger/independence", + "niger/national", + "niger/republic" }), + + "nigeria": + // "id al-fitr" ? + // "mouloud" ? + // "nigeria/Id al-Kabir (Id al-Adha)" ? + // "nigeria/odum titun" ? + // "nigeria/odun kekere" ? + ({ "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "new year", + "nigeria/childrens", + "nigeria/harvest festival", + "nigeria/national" }), + + "northern mariana islands": + // "memorial" ? + // "thanksgiving" ? + // "us independence" ? + ({ "c/christmas", + "labor", + "new year", + "northern mariana islands/commonwealth", + "northern mariana islands/presidents" }), + + "norway": + ({ "c/ascension", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/holy thursday", + "c/whitmonday", + "may day", + "new year", + "norway/constitution", + "norway/olsok eve festival", + "norway/tyvendedagen" }), + + "oman": + // "ashoura" ? + // "first of ramadan" ? + // "id al-adha" ? + // "id al-adha" ? + // "id al-fitr" ? + // "id al-fitr" ? + // "islamic new year" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + // "mouloud" ? + // "prophets" ? + ({ "oman/national", + "oman/national of oman", + "oman/national2", + "oman/sultans" }), + + "pakistan": + // "ashoura" ? + // "first of ramadan" ? + // "id al-adha optional holidays for christians" ? + // "id al-fitr" ? + // "islamic new year" ? + // "pakistan/Eid-i-Milad-un-Nabi (Mouloud)" ? + ({ "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "labor", + "pakistan/birthday of quaid-i-azam", + "pakistan/defense", + "pakistan/independence", + "pakistan/iqbal", + "pakistan/jinnah", + "pakistan/pakistan" }), + + "panama": + // "christmas in panama city" ? + // "panama/Carnival (Shrove Tuesday)" ? + ({ "c/all souls", + "c/good friday", + "labor", + "mothers", + "new year", + "panama/constitution", + "panama/day of mourning", + "panama/festival of the black christ", + "panama/flag", + "panama/foundation of panama city", + "panama/independence", + "panama/independence from spain", + "panama/mothers", + "panama/national anthem", + "panama/revolution", + "panama/uprising of los santos" }), + + "papua new guinea": + ({ "british commonwealth/queens", + "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "new year", + "papua new guinea/independence", + "papua new guinea/remembrance" }), + + "paraguay": + ({ "c/all saints", + "c/ascension", + "c/christmas", + "c/corpus christi", + "c/good friday", + "c/holy thursday", + "labor", + "new year", + "paraguay/battle of boquer\363n", + "paraguay/constitution", + "paraguay/day of the race", + "paraguay/founding of the city of asunci\363n", + "paraguay/heroes", + "paraguay/independence", + "paraguay/peace of chaco", + "paraguay/virgin of caacupe", + "saints/blaise" }), + + "peru": + // "peasants" ? + ({ "saints/paul", + "saints/peter", + "c/all saints", + "c/christmas", + "c/good friday", + "c/holy thursday", + "c/immaculate conception", + "labor", + "new year", + "peru/combat of angamos", + "peru/independence", + "peru/inti raymi fiesta", + "peru/santa rosa de lima" }), + + "philippines": + ({ "c/all saints", + "c/christmas", + "c/good friday", + "c/maundy thursday", + "labor", + "new year", + "new years eve", + "philippines/araw ng kagitingan", + "philippines/barangay", + "philippines/bataan", + "philippines/bonifacio", + "philippines/christ the king", + "philippines/constitution", + "philippines/freedom", + "philippines/independence", + "philippines/misa de gallo", + "philippines/national heroes", + "philippines/philippine-american friendship", + "philippines/rizal", + "philippines/thanksgiving" }), + + "portugal": + // "porto observes the st john the baptist" ? + // "portugal/Carnival (Shrove Tuesday)" ? + ({ "c/all saints", + "c/assumption", + "c/corpus christi", + "c/good friday", + "c/immaculate conception", + "labor", + "new year", + "portugal/cam\365es memorial", + "portugal/christmas lisbon also observes the st anthony", + "portugal/day of the dead", + "portugal/liberty", + "portugal/portugal", + "portugal/republic", + "portugal/restoration of the independence" }), + + "puerto rico": + // "martin luther king" ? + // "us independence" ? + // "us thanksgiving" ? + // "veterans" ? + // "washington-lincoln" ? + ({ "c/christmas", + "c/good friday", + "columbus", + "c/epiphany", + "labor", + "new year", + "puerto rico/barbosa", + "puerto rico/birthday of eugenio maria de hostos", + "puerto rico/constitution", + "puerto rico/de diego", + "puerto rico/discovery", + "puerto rico/emancipation", + "puerto rico/memorial", + "puerto rico/mu\361oz rivera", + "puerto rico/ponce de leon", + "puerto rico/saint johns", + "puerto rico/san juan" }), + + "qatar": + // "first of ramadan" ? + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + ({ "qatar/anniversary of the amirs accession", + "qatar/independence" }), + + "romania": + ({ "c/christmas", + "c/easter monday", + "c/good friday", + "labor", + "new year", + "romania/liberation", + "romania/national", + "romania/public holiday" }), + + "rwanda": + // "peace" ? + ({ "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/whitmonday", + "labor", + "new year", + "rwanda/armed forces", + "rwanda/democracy", + "rwanda/independence", + "rwanda/kamarampaka", + "rwanda/peace and unity", + "unity" }), + + "saint kitts and nevis": + // "august monday" ? + ({ "british commonwealth/queens", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "labor", + "saint kitts and nevis/carnival", + "saint kitts and nevis/independence", + "saint kitts and nevis/prince of wales" }), + + "saint lucia": + // "carnival" ? + ({ "british commonwealth/august bank holiday", + "british commonwealth/queens", + "c/boxing", + "c/christmas", + "c/corpus christi", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "labor", + "new year", + "saint lucia/discovery", + "saint lucia/independence", + "saint lucia/thanksgiving" }), + + "saint vincent and the grenadines": + // "carnival" ? + // "grenadines" ? + // "saint vincent" ? + ({ "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "caribbean/caricom", + "caribbean/emancipation", + "labor", + "new year", + "saint vincent and the grenadines/independence", + "saint vincent and the grenadines/saint vincent and the grenadines" }), + + "san marino": + ({ "c/all saints", + "saints/stephen", + "c/all souls", + "c/assumption", + "c/christmas", + "c/corpus christi", + "c/easter monday", + "c/immaculate conception", + "c/epiphany", + "labor", + "new year", + "san marino/anniversary of the arengo", + "san marino/fall of fascism", + "san marino/investiture of the new captains regent", + "san marino/investiture of the new captains-regent", + "san marino/liberation", + "san marino/national", + "san marino/san marino" }), + + "sao tome and principe": + // "sao tomeand principe/Armed Forces Day (1st week in Sep)" ? + ({ "family", + "sao tome and principe/farmers", + "sao tome and principe/independence", + "sao tome and principe/martyrs", + "sao tome and principe/transitional government" }), + + "saudi arabia": + // "ashoura" ? + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "leilat al-meirag" ? + // "mouloud" ? + ({ "saudi arabia/national", + "saudi arabia/national of saudi arabia" }), + + "senegal": + // "mouloud" ? + // "senegal/Korit\351 (Id al-Fitr)" ? + // "senegal/Tabaski (Id al-Adha)" ? + ({ "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "labor", + "new year", + "senegal/african community", + "senegal/independence" }), + + "seychelles": + ({ "c/all saints", + "c/assumption", + "c/christmas", + "c/corpus christi", + "c/easter", + "c/immaculate conception", + "labor", + "new year", + "seychelles/independence", + "seychelles/liberation" }), + + "sierra leone": + // "id al-adha" ? + // "id al-fitr" ? + // "mouloud" ? + ({ "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "new year", + "sierra leone/independence", + "sierra leone/republic" }), + + "singapore": + // "chinese new year" ? + // "singapore/Deepavali (Diwali)" ? + // "singapore/Hari Raya Haji (Id al-Adha)" ? + // "singapore/Hari Raya Puasa (Id al-Fitr)" ? + // "singapore/birthday of the monkey god" ? + // "singapore/birthday of the saint of the poor" ? + // "singapore/mooncake festival" ? + // "singapore/vesak" ? + // "vesak" ? + ({ "c/christmas", + "c/good friday", + "new year", + "singapore/independence", + "singapore/labor", + "singapore/national holiday" }), + + "slovakia": + ({ "c/christmas", + "c/easter monday", + "may day", + "new year", + "slovakia/day of the slav apostles", + "slovakia/liberation", + "slovakia/reconciliation", + "slovakia/slovak national uprising" }), + + "slovenia": + ({ }), + + "solomon islands": + ({ "british commonwealth/queens", + "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/holy saturday", + "c/whitmonday", + "new year", + "solomon islands/independence" }), + + "somalia": + // "ashoura" ? + // "id al-adha" ? + // "id al-fitr" ? + // "mouloud" ? + ({ "labor", + "new year", + "somalia/foundation of the republic", + "somalia/independence", + "somalia/revolution" }), + + "south africa": + ({ "c/ascension", + "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "new year", + "south africa/day of the vow", + "south africa/family", + "south africa/kruger", + "south africa/republic", + "south africa/settlers", + "south africa/van riebeeck", + "south africa/workers" }), + + "soviet union": + ({ "soviet union/anniversary of the october socialist revolution", + "soviet union/victory" }), + + + "spain": + // "also observed" ? + // "madrid only)" ? + // "palma de mallorca)" ? + // "palma de mallorca) local holidays" ? + // "saint isidros " ? + // "spain/tomatina" ? + ({ "c/all saints", + "c/assumption", + "c/boxing", + "c/christmas", + "c/corpus christi", + "c/easter monday", + "c/good friday", + "c/immaculate conception", + "c/maundy thursday", + "c/epiphany", + "new year", + "spain/constitution", + "spain/fiesta de san fermin", + "spain/fiesta del arbol", + "spain/grenada", + "spain/hispanidad", + "spain/king juan carlos saints", + "spain/labor", + "spain/national", + "spain/national holiday of spain", + "spain/queen isabella", + "spain/saint james", + "spain/saint joseph the workman" }), + + "sri lanka": + // "there is a monthy full moon" ? + // "diwali" ? + // "holy prophets" ? + // "sinhala" ? + // "sri lanka/bandaranaike memorial" ? + // "sri lanka/hadji festival" ? + // "sri lanka/kandy perahera" ? + // "sri lanka/thai pongal" ? + // "sri lanka/vesak festival" ? + // "tamil new year" ? + // "tamil thai pongal" ? + ({ "c/good friday", + "c/christmas", + "may day", + "new year", + "sri lanka/independence", + "sri lanka/national heroes", + "sri lanka/republic", + "sri lanka/sinhala and tamil new year" }), + + "sudan": + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "mououd" ? + // "sudan/Sham an-Nassim (Coptic Easter Monday)" ? + ({ "c/christmas", + "new year", + "sudan/decentralization", + "sudan/independence", + "sudan/national", + "sudan/unity", + "sudan/uprising" }), + + "suriname": + // "id al-fitr" ? + // "suriname/Phagwa (Holi)" ? + ({ "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "labor", + "new year", + "suriname/independence", + "suriname/national union", + "suriname/revolution" }), + + "swaziland": + // "incwala" ? + // "national flag" ? + // "swaziland/incwala" ? + // "united nations" ? + ({ "c/ascension", + "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "new year", + "swaziland/commonwealth", + "swaziland/flag", + "swaziland/kings", + "swaziland/reed dance", + "swaziland/somhlolo" }), + + "switzerland": + ({ "c/ascension", + "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "c/whitmonday", + "labor", + "new year", + "switzerland/berchtolds", + "switzerland/glarus festival", + "switzerland/homstrom", + "switzerland/independence", + "switzerland/may eve" }), + + "syria": + // "egypts revolution" ? + // "greek orthodox easter" ? + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + // "mouloud" ? + ({ "c/christmas", + "new year", + "syria/beginning of october war", + "syria/evacuation", + "syria/national", + "syria/revolution", + "syria/union", + "unity" }), + + "taiwan": + // "chinese new year" ? + // "ching ming festival" ? + // "taiwan/birthday of matsu" ? + // "taiwan/lantern festival" ? + ({ "taiwan/birthday of confucious", + "taiwan/buddha bathing festival", + "taiwan/chiang kai-shek", + "taiwan/childrens", + "taiwan/constitution", + "taiwan/dragon boat festival", + "taiwan/founding of the republic of china", + "taiwan/martyrs", + "taiwan/national", + "taiwan/restoration", + "taiwan/sun yat-sen", + "taiwan/youth" }), + + "tanzania": + // "id al-fitr" ? + // "mouloud" ? + // "tanzania/Id al-Hajj (Id al-Adha)" ? + ({ "c/christmas", + "c/easter monday", + "c/good friday", + "labor", + "tanzania/chama cha mapinduzi", + "tanzania/heroes", + "tanzania/independence", + "tanzania/naming", + "tanzania/saba saba", + "tanzania/sultans", + "tanzania/union", + "tanzania/zanzibar revolution" }), + + "thailand": + // "buddhist lent" ? + // "makha bucha" ? + // "thailand/loy krathong festival" ? + // "thailand/makha bucha" ? + // "thailand/state ploughing ceremony" ? + // "thailand/visakha bucha" ? + // "visakha bucha" ? + ({ "new year", + "new years eve", + "thailand/asalapha bupha", + "thailand/chakri", + "thailand/chulalongkorn", + "thailand/constitution", + "thailand/coronation", + "thailand/harvest festival", + "thailand/kings", + "thailand/queens", + "thailand/songkran" }), + + "togo": + // "id al-fitr" ? + // "national liberation" ? + // "togo/Tabaski (Id al-Adha)" ? + ({ "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter monday", + "c/whitmonday", + "labor", + "new year", + "togo/anniversary of the failed attack on lome", + "togo/economic liberation", + "togo/independence", + "togo/liberation", + "togo/martyrs of pya", + "togo/victory" }), + + "tonga": + ({ "anzac", + "c/boxing", + "c/christmas", + "c/easter monday", + "c/good friday", + "new year", + "tonga/constitution", + "tonga/emancipation", + "tonga/king tupou", + "tonga/kings", + "tonga/princes" }), + + "trinidad and tobago": + // "carnival" ? + // "diwali" ? + ({ "c/christmas", + "c/corpus christi", + "c/easter", + "c/whitmonday", + "new year", + "trinidad and tobago/discovery", + "trinidad and tobago/emancipation", + "trinidad and tobago/independence", + "trinidad and tobago/labor", + "trinidad and tobago/republic" }), + + "tunisia": + // "evacuaton" ? + // "tunisia/Aid El Kebir (Id al-Adha)" ? + // "tunisia/Aid El Seghir (Id al-Fitr)" ? + ({ "labor", + "new year", + "tunisia/accession", + "tunisia/bourguibas", + "tunisia/evacuation", + "tunisia/independence", + "tunisia/independence recognition", + "tunisia/martyrs", + "tunisia/memorial", + "tunisia/national holiday of tunisia", + "tunisia/national revolution", + "tunisia/republic", + "tunisia/tree festival", + "tunisia/womens", + "tunisia/youth", + "womens" }), + + "turkey": + // "ataturk memorial" ? + // "childrens" ? + // "national sovereignty" ? + // "turkey/Kurban Bayram (Id al-Adha)" ? + // "turkey/Seker Bayram (Id al-Fitr)" ? + // "youth & sports" ? + ({ "new year", + "turkey/ataturk commemoration", + "turkey/youth and sports", + "turkey/freedom and constitution", + "turkey/hidrellez", + "turkey/independence", + "turkey/childrens", + "turkey/national sovereignty", + "turkey/navy and merchant marine", + "turkey/rumis", + "turkey/spring", + "turkey/victory" }), + + "turks and caicos islands": + // "commonwealth" ? + // "national heroes" ? + // "national youth" ? + // "queens official" ? + ({ "c/christmas", + "c/easter monday", + "c/good friday", + "new year", + "turks and caicos islands/columbus", + "turks and caicos islands/emancipation", + "turks and caicos islands/human rights", + "turks and caicos islands/jags mccartney memorial" }), + + "tuvalu": + // "commonwealth" ? + // "national childrens" ? + ({ "british commonwealth/prince of wales", + "british commonwealth/queens", + "c/boxing", + "c/christmas", + "c/easter", + "new year", + "tuvalu/tuvalu" }), + + "uganda": + // "id al-adha" ? + // "id al-fitr" ? + ({ "c/christmas", + "c/easter", + "c/good friday", + "labor", + "new year", + "uganda/heroes", + "uganda/independence", + "uganda/martyrs", + "uganda/nrm/nra victorys", + "uganda/republic" }), + + "ukraine": + ({ "c/christmas", + "labor", + "new year", + "orthodox/christmas", + "ukraine/taras shevchenko", + "ukraine/ukrainian", + "ukraine/ukrainian independence", + "ukraine/victory", + "womens" }), + + "united arab emirates": + // "id al-adha" ? + // "id al-fitr" ? + // "islamic new year" ? + // "leilat al-meiraj" ? + // "mouloud" ? + // "ramadan 1" ? + ({ "c/christmas", + "new year", + "united arab emirates/accession of the ruler of abu dhabi", + "united arab emirates/national" }), + + "uruguay": + ({ "c/all souls", + "c/christmas", + "columbus", + "c/epiphany", + "labor", + "new year", + "uruguay/artigas", + "uruguay/battle of las piedras", + "uruguay/blessing of the waters", + "uruguay/constitution", + "uruguay/independence", + "uruguay/landing of the 33 patriots" }), + + "united kingdom": + ({ "new year|h", + "c/good friday|h", + "c/easter monday|h", + "c/christmas|h", + "c/boxing|h", + "may day|h", + "united kingdom/spring bank holiday|h", + "united kingdom/late summer bank holiday|h", + "united kingdom/lammas", + "united kingdom/queens", + "united kingdom/burns", }), + + "united kingdom/england": + ({ "+united kingdom", + "united kingdom/guy fawkes", + "united kingdom/oak apple", + "united kingdom/battle of britain", + "united kingdom/lord mayors", + "united kingdom/mothering sunday", + "united kingdom/woman peerage", + "united kingdom/pancake tuesday" }), + + "united kingdom/scotland": + ({ "+united kingdom", + "united kingdom/bannockburn", + "united kingdom/day after", + "united kingdom/handsel monday", + "united kingdom/highland games", + "united kingdom/scottish new year|h", + "united kingdom/victoria|h", + "united kingdom/autumn holiday|h" }), + + "united kingdom/wales": + ({ "+united kingdom", + "saints/david|h" }), + + "united kingdom/northern ireland": + ({ "+united kingdom", + "united kingdom/orangeman|h", + "saints/patrick" }), + + "us": + ({ "new year|h", + "c/christmas", + "us/columbus|h", + "mardi gras", + "us/appomattox", + "us/armed forces", + "us/bill of rights", + "us/carnation", + "us/citizenship", + "us/election", + "us/flag|f", + "us/forefathers", + "us/inauguration", + "us/independence|h", + "us/iwo jima", + "us/jefferson davis", + "us/kosciuszko", + "us/labor|h", + "us/lincolns", + "us/martin luther king", + "us/memorial", + "us/national freedom", + "us/navy", + "us/patriots", + "us/robert e lee", + "us/thanksgiving", + "us/thomas jeffersons", + "us/veterans|h", + "us/vietnam", + "us/washingtons|h", + "us/womens equality" }), + + "us/alabama": + ({ "+us", + "us/alabama/alabama admission|h", + "us/alabama/confederate memorial|h", + "us/alabama/jefferson davis|h", + "us/alabama/robert e lee|h", + "columbus|h", + "mardi gras|h", + "us/thomas jeffersons|h" }), + + "us/alaska": + ({ "+us", + "us/alaska/alaska|h", + "us/alaska/alaska admission|h", + "-us/independence", + "us/alaska/flag|fh", + "us/alaska/sewards|h", + "us/lincolns|h", + "us/memorial|h" }), + + "us/arizona": + ({ "+us", + "us/arizona/american family|h", + "us/arizona/arbors|h", + "us/arizona/arborn|h", + "us/arizona/arizona admission|h", + "us/arizona/lincoln|h", + "us/columbus|h", + "fathers|h", + "mothers|h", + "us/memorial|h", + "-us/washingtons", + "us/washington|h" }), + + "us/arkansas": + ({ "+us", + "us/arkansas/arkansas admission|h", + "us/arkansas/general douglas macarthur|h", + "us/arkansas/world war ii memorial|h", + "us/columbus|h", + "us/election|h", + "us/jefferson davis|h", + "us/memorial|h", + "us/robert e lee|h" }), + + "us/california": + ({ "+us", + "us/california/california admission|h", + "us/columbus|h", + "us/california/arbor|h", + "us/election|h", + "us/lincolns|h", + "us/memorial|h", }), + + "us/colorado": + ({ "+us", + "us/colorado/arbor|h", + "us/colorado/colorado|h", + "columbus|h", + "us/election|h", + "us/lincolns|h", + "us/memorial|h", }), + + "us/connecticut": + ({ "+us", + "c/good friday|h", + "us/columbus|h", + "us/connecticut/connecticut ratification|h", + "us/lincolns|h", + "us/martin luther king|h", + "us/memorial|h", }), + + "us/delaware": + ({ "+us", + "c/good friday|h", + "us/columbus|h", + "us/delaware/arbor|h", + "us/delaware/delaware|h", + "us/delaware/lincolns|h", + "us/delaware/memorial|h", + "us/delaware/separation|h", + "us/delaware/swedish colonial|h", + "us/election|h" }), + + "us/florida": + ({ "+us", + "c/christmas|h", + "c/good friday|h", + "us/columbus|h", + "us/florida/arbor|h", + "us/florida/confederate memorial|h", + "us/florida/farmers|h", + "us/florida/florida admission|h", + "us/florida/pascua florida|h", + "us/florida/susan b anthony|h", + "us/election|h", + "us/jefferson davis|h", + "us/lincolns|h", + "us/martin luther king|h", + "us/memorial|h", + "us/robert e lee|h",}), + + "us/georgia": + // "us/robert elee" ? + ({ "+us", + "us/columbus|h", + "us/georgia/confederate memorial|h", + "us/georgia/georgia|h", + "us/jefferson davis|h", + "us/memorial|h" }), + + "us/hawaii": + // "us/hawaii/Discoverers' Day (Us/Columbus Day)" ? + ({ "+us", + "c/good friday|h", + "us/hawaii/flag|fh", + "us/hawaii/hawaii statehood|h", + "us/hawaii/kamehameha|h", + "us/hawaii/kuhio|h", + "us/hawaii/lei|h", + "us/hawaii/wesak flower festival|h", + "us/election|h", + "us/memorial|h", + "us/presidents|h" }), + + "us/idaho": + ({ "+us", + "us/columbus|h", + "us/idaho/idaho admission|h", + "us/idaho/idaho pioneer|h", + "us/election|h", + "us/memorial|h" }), + + "us/illinois": + ({ "+us", + "us/columbus|h", + "us/day after thanksgiving|h", + "us/illinois/illinois admission|h", + "us/illinois/memorial|h", + "us/election|h", + "us/lincolns|h", + "us/martin luther king|h" }), + + "us/indiana": + ({ "+us", + "c/good friday|h", + "us/columbus|h", + "us/indiana/indiana admission|h", + "us/indiana/primary election|h", + "us/indiana/vincennes|h", + "us/election|h", + "us/lincolns|h", + "us/memorial|h" }), + + "us/iowa": + ({ "+us", + "us/iowa/bird|h", + "us/iowa/independence sunday|h", + "us/iowa/iowa admission|h", + "us/lincolns|h", + "us/memorial|h" }), + + "us/kansas": + ({ "+us", + "us/columbus|h", + "us/kansas/kansas|h", + "us/lincolns|h", + "us/memorial|h" }), + + "us/kentucky": + ({ "+us", + "us/columbus|h", + "us/kentucky/franklin d roosevelt|h", + "us/kentucky/kentucky statehood|h", + "us/election|h", + "us/jefferson davis|h", + "us/lincolns|h", + "us/martin luther king|h", + "us/memorial|h", + "us/robert e lee|h" }), + + "us/louisiana": + ({ "+us", + "c/all saints|h", + "c/good friday|h", + "us/columbus|h", + "us/louisiana/huey p long|h", + "us/louisiana/jackson|h", + "us/louisiana/louisiana admission|h", + "mardi gras|h", + "new year|h", + "us/election|h", + "us/jefferson davis|h", + "us/martin luther king|h", + "us/memorial|h", + "us/robert e lee|h" }), + + "us/maine": + ({ "+us", + "us/columbus|h", + "us/maine/battleship|h", + "us/maine/maine admission|h", + "us/memorial|h", + "us/patriots|h" }), + + "us/maryland": + ({ "+us", + "c/good friday|h", + "us/columbus|h", + "us/maryland/defenders|h", + "us/maryland/john hanson|h", + "us/maryland/maryland|h", + "us/maryland/maryland admission|h", + "us/maryland/maryland ratification|h", + "us/maryland/memorial|h", + "us/maryland/national anthem|h", + "us/maryland/repudiation|h", + "us/election|h", + "us/lincolns|h", + "us/martin luther king|h" }), + + "us/massachusetts": + ({ "+us", + "us/columbus|h", + "us/massachusetts/bunker hill|h", + "us/massachusetts/childrens|h", + "us/massachusetts/evacuation|h", + "us/massachusetts/john f kennedy|h", + "us/massachusetts/lafayette|h", + "us/massachusetts/liberty tree|h", + "us/massachusetts/massachusetts ratification|h", + "us/massachusetts/spanish-american war memorial|h", + "us/massachusetts/student government|h", + "us/massachusetts/susan b anthony|h", + "us/massachusetts/teachers|h", + "us/martin luther king|h", + "us/memorial|h", + "us/patriots|h" }), + + "us/michigan": + ({ "+us", + "us/michigan/memorial|h", + "us/michigan/michigan|h", + "us/martin luther king|h" }), + + "us/minnesota": + ({ "+us", + "us/columbus|h", + "us/minnesota/american family|h", + "us/minnesota/minnesota|h", + "us/memorial|h" }), + + "us/mississippi": + ({ "+us", + "us/mississippi/confederate memorial|h", + "us/mississippi/jefferson davis|h", + "us/mississippi/robert elee|h" }), + + "us/missouri": + ({ "+us", + "us/columbus|h", + "us/missouri/missouri admission|h", + "us/missouri/truman|h", + "us/election|h", + "us/lincolns|h", + "us/memorial|h" }), + + "us/montana": + ({ "+us", + "us/columbus|h", + "us/montana/election|h", + "us/lincolns|h", + "us/memorial|h" }), + + "us/nebraska": + ({ "+us", + "us/columbus|h", + "us/day after thanksgiving|h", + "us/nebraska/arbor|h", + "us/nebraska/nebraska state|h", + "us/memorial|h", + "us/presidents|h" }), + + "us/nevada": + ({ "+us", + "us/nevada/nevada|h", + "us/memorial|h" }), + + "us/new hampshire": + ({ "+us", + "us/columbus|h", + "us/day after thanksgiving|h", + "us/new hampshire/fast|h", + "us/new hampshire/memorial|h", + "us/new hampshire/new hampshire admission|h", + "us/election|h" }), + + "us/new jersey": + ({ "+us", + "c/good friday|h", + "us/columbus|h", + "us/new jersey/new jersey admission|h", + "us/election|h", + "us/lincolns|h", + "us/martin luther king|h", + "us/memorial|h" }), + + "us/new mexico": + ({ "+us", + "us/columbus|h", + "us/new mexico/arbor|h", + "us/new mexico/memorial|h", + "us/lincolns|h" }), + + "us/new york": + ({ "+us", + "us/columbus|h", + "us/new york/audubon|h", + "us/new york/flag|fh", + "us/new york/martin luther king|h", + "us/new york/new york ratification|h", + "us/new york/verrazano|h", + "us/election|h", + "us/lincolns|h", + "us/memorial|h" }), + + "us/north carolina": + ({ "+us", + "c/easter monday|h", + "us/north carolina/confederate memorial|h", + "us/north carolina/halifax resolutions|h", + "us/north carolina/mecklenburg|h", + "us/memorial|h", + "us/robert e lee|h" }), + + "us/north dakota": + ({ "+us", + "c/good friday|h", + "us/north dakota/north dakota admission|h", + "us/memorial|h" }), + + "us/ohio": + ({ "+us", + "us/columbus|h", + "us/ohio/martin luther king|h", + "us/ohio/ohio admission|h", + "us/memorial|h", + "-us/washingtons", + "us/washington-lincoln|h" }), + + "us/oklahoma": + // "us/oklahoma/oklahoma heritage week" ? + // "us/oklahoma/youth" ? + ({ "+us", + "us/columbus|h", + "mothers|h", + "us/oklahoma/bird|h", + "us/oklahoma/cherokee strip|h", + "us/oklahoma/indian|h", + "us/oklahoma/oklahoma|h", + "us/oklahoma/oklahoma historical|h", + "us/oklahoma/oklahoma statehood|h", + "us/oklahoma/senior citizens|h", + "us/oklahoma/will rogers|h", + "us/election|h", + "us/memorial|h", + "us/thomas jeffersons|h" }), + + "us/oregon": + ({ "+us", + "us/oregon/lincolns|h", + "us/oregon/oregon statehood|h", + "us/memorial|h" }), + + "us/pennsylvania": + ({ "+us", + "c/good friday|h", + "us/columbus|h", + "us/pennsylvania/barry|h", + "us/pennsylvania/charter|h", + "us/pennsylvania/pennsylvania admission|h", + "us/election|h", + "us/flag|fh", + "us/martin luther king|h", + "us/memorial|h", + "us/presidents|h" }), + + "us/rhode island": + ({ "+us", + "us/columbus|h", + "us/rhode island/arbor|h", + "us/rhode island/rhode island admission|h", + "us/rhode island/rhode island independence|h", + "us/rhode island/victory|h", + "us/election|h", + "us/memorial|h" }), + + "us/south carolina": + ({ "+us", + "us/south carolina/confederate memorial|h", + "us/south carolina/south carolina admission|h", + "us/election|h", + "us/jefferson davis|h", + "us/martin luther king|h", + "us/robert e lee|h" }), + + "us/south dakota": + ({ "+us", + "us/south dakota/memorial|h", + "us/south dakota/pioneers|h", + "us/south dakota/south dakota admission|h", + "us/presidents|h" }), + + "us/tennessee": + ({ "+us", + "c/good friday|h", + "us/columbus|h", + "us/tennessee/confederate memorial|h", + "us/tennessee/tennesse statehood|h", + "us/election|h", + "us/memorial|h" }), + + "us/texas": + ({ "+us", + "us/columbus|h", + "us/texas/alamo|h", + "us/texas/austin|h", + "us/texas/confederate heroes|h", + "us/texas/juneteenth|h", + "us/texas/lyndon b johnsons|h", + "us/texas/san jacinto|h", + "us/texas/texas admission|h", + "us/texas/texas independence|h", + "us/texas/texas pioneers|h", + "us/election|h", + "us/memorial|h" }), + + "us/utah": + ({ "+us", + "us/columbus|h", + "us/lincolns|h", + "us/memorial|h", + "us/utah/arbor|h", + "us/utah/pioneer|h", + "us/utah/utah admission|h" }), + + "us/vermont": + ({ "+us", + "us/columbus|h", + "us/lincolns|h", + "us/vermont/bennington battle|h", + "us/vermont/memorial|h", + "us/vermont/town meeting|h", + "us/vermont/vermont|h" }), + + "us/virginia": + // "us/virginia/jack jouett" ? + ({ "+us", + "us/columbus|h", + "us/election|h", + "us/memorial|h", + "us/virginia/cape henry|h", + "us/virginia/confederate memorial|h", + "us/virginia/crater|h", + "us/virginia/jamestown|h", + "us/virginia/lee-jackson|h", + "us/virginia/royalist fast|h", + "us/virginia/virginia ratification|h" }), + + "us/washington": + ({ "+us", + "us/lincolns|h", + "us/memorial|h", + "us/washington/washington admission|h" }), + +// ? + "us/washington dc": + ({ "+us", + "us/columbus|h", + "us/election|h", + "us/memorial|h", + "us/washington dc/arbor|h" }), + + "us/west virginia": + ({ "+us", + "us/columbus|h", + "us/election|h", + "us/lincolns|h", + "us/memorial|h", + "-us/washingtons", + "us/washington|h", + "us/west virginia/west virginia|h" }), + + "us/wisconsin": + ({ "+us", + "c/good friday|h", + "us/columbus|h", + "us/election|h", + "us/memorial|h", + "-us/washingtons", + "us/washington-lincoln|h", + "us/wisconsin/primary election|h", + "us/wisconsin/wisconsin|h" }), + + "us/wyoming": + // "us/nellie tayloe ross" ? + ({ "+us", + "us/columbus|h", + "us/election|h", + "us/memorial|h", + "-us/washingtons", + "us/washington-lincoln|h", + "us/wyoming/arbor|h", + "us/wyoming/primary election|h", + "us/wyoming/wyoming|h", + "us/wyoming/wyoming statehood" }), + + "vanuatu": + ({ "c/ascension", + "c/assumption", + "c/christmas", + "c/easter", + "labor", + "new year", + "unity", + "vanuatu/constitution", + "vanuatu/independence" }), + + "vatican city": + ({ "vatican city/anniversary of the beginning of the john paul ii pontificate", + "vatican city/john paul ii namesday" }), + + "venezuela": + // "carnival" ? + // "additional bank holidays" ? + // "saint josephs" ? + ({ "saints/paul", + "saints/peter", + "c/all saints", + "c/ascension", + "c/assumption", + "c/christmas", + "c/easter", + "c/immaculate conception", + "columbus", + "c/epiphany", + "labor", + "new year", + "new years eve", + "venezuela/battle of carabobo", + "venezuela/bolivars", + "venezuela/civil servants", + "venezuela/declaration of independence", + "venezuela/independence", + "venezuela/teachers" }), + + "vietnam": + // "tet nguyen dan" ? + // "vietnam/tet nguyen dan" ? + // "vietnam/thanh minh" ? + ({ "labor", + "new year", + "vietnam/day of the nation", + "vietnam/emperor-founder hung vuongs", + "vietnam/founding of the communist party", + "vietnam/independence", + "vietnam/liberation of saigon" }), + + "virgin islands": + // "martin luther king" ? + // "memorial" ? + // "presidents" ? + // "three kings" ? + // "us independence" ? + // "us thanksgiving" ? + // "veterans" ? + ({ "c/christmas", + "c/easter", + "columbus", + "labor", + "new year", + "virgin islands/danish west indies emancipation", + "virgin islands/hurricane supplication", + "virgin islands/hurricane thanksgiving", + "virgin islands/liberty", + "virgin islands/nicole robin", + "virgin islands/organic act", + "virgin islands/transfer" }), + + "western samoa": + // "national womens" ? + ({ "anzac", + "c/boxing", + "c/christmas", + "c/easter", + "c/whitmonday", + "new year", + "western samoa/arbor", + "western samoa/independence", + "western samoa/independence2", + "western samoa/white sunday" }), + + "yemen": + // "ashoura" ? + // "first of ramadan" ? + // "id al-adha" ? + // "id al-fitr" ? + // "leilat al-meiraj" ? + // "mouloud" ? + // "muharram" ? + ({ "labor", + "new year", + "womens", + "yemen/corrective movement", + "yemen/national" }), + + "zaire": + ({ "c/christmas", + "labor", + "new year", + "zaire/armed forces", + "zaire/constitution", + "zaire/day of the martyrs for independence", + "zaire/independence", + "zaire/mpr", + "zaire/naming", + "zaire/new regime", + "zaire/parents", + "zaire/presidents", + "zaire/youth/presidents" }), + + "zambia": + ({ "africa", + "c/christmas", + "c/easter", + "labor", + "new year", + "unity", + "zambia/farmers", + "zambia/heroes", + "zambia/independence", + "zambia/unity", + "zambia/youth", + "zambia/youth2" }), + + "zimbabwe": + ({ "africa", + "c/christmas", + "c/easter", + "new year", + "zimbabwe/heroess", + "zimbabwe/independence", + "zimbabwe/workers" }), +]); diff --git a/lib/modules/Calendar.pmod/FILES b/lib/modules/Calendar.pmod/FILES new file mode 100644 index 0000000000000000000000000000000000000000..8275dd215f8a8e404128194f8934985a2ed01cb1 --- /dev/null +++ b/lib/modules/Calendar.pmod/FILES @@ -0,0 +1,152 @@ +CHANGES +FILES + +Calendar.pike + This is the virtual base class for any Calendar. + It might be used as type for variables + containing a random calendar object. + +TimeRanges.pmod + This contains the base classes for timerange objects: + TimeRange + The TimeRange is the virtual base class for any + timerange object. It defines everything that needs to + be possible to do with it, and has a lot of + non-virtual functions that calls back to the virtual + functions to ease implementations of new timerange + classes. + SuperTimeRange + The SuperTimeRange is a class that is used to + contain more then one timerange. This object + is created by methods and operators such as subtract, + `| or `^. + +Time.pmod + This contains the base classes for calendars that uses + time-of-day with hours, minutes and seconds: + Hour + Minute + Second + The normal time-of-day units. They are defined + to contain n*3600, n*60 and n seconds respectively, + and to start on those positions of the day. + They autopromote upwards (second->minute->hour). + Fraction + A fraction is a partial second. It can start + and end on non-even seconds - it has an integer + for nanosecond precision. It autopromotes upwards + to second (etc). + This module can not be used standalone, but must have + some virtual functions filled in. + It extends the TimeRanges module. + +YMD.pmod + This contains the base classes of any traditional calendar: + Year + The Year class, which contains the largest timerange + unit used. + Month + The month, which divides the year into non-equal + - most of the calendards, anyway - long day sequences, + and which is aligned to the year. + Week + The week, which is a equally long day sequence, + and isn't aligned to the year. + Day + The Day, which is the smallest unit before + time-of-day, and which is the base unit of time-of-day. + None of these four units autopromote. + The YMD module also extends the Time module, + so it contains those classes as well. + +Gregorian.pmod + This is the base module for Julian style calendars; + despite the name. Most calendars of today are in sync + with the Gregorian calendar. +ISO.pmod + This inherits the Gregorian calendar to tweak it to + conform to the ISO standards. Most affected are weeks, + which starts on Monday in the ISO calendar. + This is also the default calendar. +Discordian.pmod + The Discordian calendar as described in Principia Discordia + is in sync with the Gregorian calendar (although some claim + that it should be the Julian - I go with what I can read + from my Principia Discordia). The module inherits and + tweaks the Gregorian module. +Coptic.pmod + The Coptic calendar is by some sources ("St. Marks' + Coptic Orthodox Church" web pages) is for now on in sync with + the Gregorian Calendar, so this module too inherits + and tweaks the Gregorian module. It needs to be + adjusted for historical use. +Julian.pmod + This is the Julian calendar, with the small changes + to the Gregorian calendar (leap years). + +Islamic.pmod + This is the Islamic calendar, using the 'Calendrical + Calculations' rules for new moon. It is based + directly on the YMD module. +Stardate.pmod + This is the (TNG) Stardate calendar, which consists + of one time unit only, the Tick (1000 Tick is one earth year). + It is based directly on TimeRanges. + +Ruleset.pike + Each time unit keeps track of what rules are in affect now; + the rules contain two things for now, language to use and + timezone to use. It will be extended to contain geographical + position and possible other needed stuff later. + Any TimeRange object returning a new TimeRange object + will transfer the rules in the creation of the object. +Language.pmod + This module keeps the base classes of languages. +Timezone.pmod + This module keeps the base classes of timezones, + inheriting the DST rules and including the timezone + definitions that are created by the mkrules.pike + program. +TZrules.pmod + This module has the DST rules (127). +TZs.h + This file keeps the Timezone definitions (440). +TZnames.pmod + This is a convinience module that keeps the names + of all possible timezones in a convinient mapping. +mkrules.pike + This is the program that take timezone definition + files (as used by most unix systems) and create the + three files listed above. It is not a base class, + it's a complete program. + +Event.pmod + This module defines the base classes used for event + definitions: + Event + The virtual base class. + Date + Date_Weekday + Monthday_Weekday + Weekday + Open classes for self-created events. + Day_Event + Gregorian_Fixed + Easter + Easter_Relative + Monthday_Weekday_Relative + Classes for event definitions in Events.pmod. + +Namedays.pmod + This module defines the namedays used in some + countries and the saints days. +Events.pmod + This module defines a number of events, used + all over the world. It also keeps tracks + of holidays and events used in countries and + regions. + +module.pmod + This is only used to make "Calendar.Day" equal + "Calendar.ISO.Day" but still keep "Calendar.Stardate" + intact. diff --git a/lib/modules/Calendar.pmod/Gregorian.pmod b/lib/modules/Calendar.pmod/Gregorian.pmod index c4d170c5d23fd7cd6dbb59dca476abaa2b68b502..a26b244be0edea63c8494a298ae4aee6d7b70277 100644 --- a/lib/modules/Calendar.pmod/Gregorian.pmod +++ b/lib/modules/Calendar.pmod/Gregorian.pmod @@ -1,1543 +1,298 @@ -// by Mirar - +//! //! module Calendar //! submodule Gregorian -//! time units: -//! <ref>Year</ref>, <ref>Month</ref>, <ref>Week</ref>, <ref>Day</ref> //! -//! class - -array(string) month_names= - ({"January","February","March","April","May","June","July","August", - "September","October","November","December"}); - -array(string) week_day_names= - ({"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}); +//! This is the standard conservative christian calendar, +//! used regularly in some countries - USA, for instance - and +//! which derivate - <ref>the ISO calendar</ref> - is used +//! in most of europe. +//! -/* calculated on need */ +import "."; +inherit YMD:YMD; -mapping week_day_mapping,month_mapping; +string calendar_name() { return "Gregorian"; } -class _TimeUnit +private static mixed __initstuff=lambda() { - inherit Calendar._TimeUnit; - - program vYear=function_object(object_program(this_object()))->Year; - program vDay=function_object(object_program(this_object()))->Day; - program vMonth=function_object(object_program(this_object()))->Month; - program vWeek=function_object(object_program(this_object()))->Week; - program vHour=function_object(object_program(this_object()))->Hour; - program vMinute=function_object(object_program(this_object()))->Minute; - program vSecond=function_object(object_program(this_object()))->Second; + f_week_day_shortname_from_number="gregorian_week_day_shortname_from_number"; + f_week_day_name_from_number="gregorian_week_day_name_from_number"; + f_year_name_from_number="gregorian_year_name_from_number"; + f_week_day_number_from_name="gregorian_week_day_number_from_name"; + + f_month_day_name_from_number="month_day_name_from_number"; + f_month_name_from_number="month_name_from_number"; + f_month_shortname_from_number="month_shortname_from_number"; + f_month_number_from_name="month_number_from_name"; + f_week_name_from_number="week_name_from_number"; + f_year_number_from_name="year_number_from_name"; +}(); + +static int year_leap_year(int y) +{ + return (!(((y)%4) || (!((y)%100) && ((y)%400)))); } -//== Year ==================================================================== - -class Year +// [y,yjd] +static array year_from_julian_day(int jd) { -//! class Year -//! A <ref>Calendar.time_unit</ref>. -//! -//! Lesser units: <ref>Month</ref>, <ref>Week</ref>, <ref>Day</ref> -//! Greater units: none -//! -//! - inherit _TimeUnit; - -//-- variables ------------------------------------------------------ + int d=jd-1721426; - int y; + int century=(4*d+3)/146097; + int century_jd=(century*146097)/4; + int century_day=d-century_jd; + int century_year=(100*century_day+75)/36525; - array days_per_month; - array month_start_day; + return + ({ + century*100+century_year+1, + 1721426+century_year*365+century_year/4+century_jd, + }); +} -//-- standard methods ----------------------------------------------- +static int julian_day_from_year(int y) +{ + y--; + return 1721426+y*365+y/4-y/100+y/400; +} - string is() - { - return "year"; - } +static int compat_week_day(int n) +{ + return n-1; +} - array(string) lesser() - { - return ({"month","week","day"}); - } +static array(int) year_month_from_month(int y,int m) +{ +// [y,m,ndays,myd] - array(string) greater() - { - return ({}); - } + y+=(m-1)/12; + m=1+(m-1)%12; - void create(int ... arg) + switch (m) { - if (!sizeof(arg)) - { - object yp=vDay()->year(); - y=yp->y; - } - else - y=arg[0]; - - int l=this->leap(); - days_per_month= - ({-17, 31,28+l,31,30,31,30,31,31,30,31,30,31}); - - month_start_day=allocate(sizeof(days_per_month)); - - for (int i=1,l=0; i<sizeof(days_per_month); i++) - month_start_day[i]=l,l+=days_per_month[i]; + case 1: return ({y,m,31,1}); + case 2: return ({y,m,28+year_leap_year(y),32}); + case 3: return ({y,m,31,60+year_leap_year(y)}); + case 4: return ({y,m,30,91+year_leap_year(y)}); + case 5: return ({y,m,31,121+year_leap_year(y)}); + case 6: return ({y,m,30,152+year_leap_year(y)}); + case 7: return ({y,m,31,182+year_leap_year(y)}); + case 8: return ({y,m,31,213+year_leap_year(y)}); + case 9: return ({y,m,30,244+year_leap_year(y)}); + case 10: return ({y,m,31,274+year_leap_year(y)}); + case 11: return ({y,m,30,305+year_leap_year(y)}); + case 12: return ({y,m,31,335+year_leap_year(y)}); } - int `<(object x) - { - return y<(int)x; - } + error("month out of range\n"); +} - int `==(object x) - { - return - object_program(x)==object_program(this) && - (int)x==y; - } +static array(int) month_from_yday(int y,int yd) +{ +// [month,day-of-month,ndays,month-year-day] + int l=year_leap_year(y); + if (yd<32) return ({1,yd,31,1}); + yd-=l; + switch (yd) + { + case 0..59: return ({2,yd-31+l,28+l,32}); + case 60..90: return ({3,yd-59,31 ,60+year_leap_year(y)}); + case 91..120: return ({4,yd-90,30 ,91+year_leap_year(y)}); + case 121..151: return ({5,yd-120,31 ,121+year_leap_year(y)}); + case 152..181: return ({6,yd-151,30 ,152+year_leap_year(y)}); + case 182..212: return ({7,yd-181,31 ,182+year_leap_year(y)}); + case 213..243: return ({8,yd-212,31 ,213+year_leap_year(y)}); + case 244..273: return ({9,yd-243,30 ,244+year_leap_year(y)}); + case 274..304: return ({10,yd-273,31,274+year_leap_year(y)}); + case 305..334: return ({11,yd-304,30,305+year_leap_year(y)}); + case 335..365: return ({12,yd-334,31,335+year_leap_year(y)}); + } + error("yday out of range\n"); +} - int hash() { return y*113; } +static array(int) week_from_julian_day(int jd) +{ +// [year,week,day-of-week,ndays,week-julian-day] - int `>(object x) - { - return y>(int)x; - } + [int y,int yjd]=year_from_julian_day(jd); + int yday=jd-yjd+1; - object next() - { - return vYear(y+1); - } + int k=4+(yjd-4)%7; + int w=(yday+k)/7; + int wjd=jd-(jd+1)%7; - object prev() + if (!w) { - return vYear(y-1); +// handle the case that the day is in the previous year; +// years previous to years staring on saturday, +// ... and leap years starting on sunday + y--; + w=52+( (k==4) || ( (k==5) && year_leap_year(y) ) ); } - - object `+(int n) + else if (w==53 && k>=6-year_leap_year(y) && k<10-year_leap_year(y)) { - return vYear(y+n); +// handle the case that the week is in the next year + y++; + w=1; } - int|object `-(int|object n) - { - if (objectp(n) && object_program(n)==vYear) return y-n->y; - return this+-n; - } + return ({y,w,1+(yjd+yday)%7,7,wjd}); +} -//-- nonstandard methods -------------------------------------------- +static array(int) week_from_week(int y,int w) +{ +// [year,week,1 (wd),ndays,week-julian-day] - int julian_day(int d) // jd%7 gives weekday, mon=0, sun=6 - { - int a; - a = (y-1)/100; - return 1721426 + d - a + (a/4) + (36525*(y-1))/100; - } + int yjd=julian_day_from_year(y); + int wjd=-5+yjd-(yjd+3)%7; - int leap() - { - if (!(y%400)) return 1; - if (!(y%100)) return 0; - return !(y%4); - } + if (w<1 || w>52) // may or may not be out of this year + return week_from_julian_day(wjd+w*7); - int leap_day() - { - return 31+24-1; // 24 Feb - } + return ({y,w,1,7,wjd+w*7}); +// fixme +} - int number_of_weeks() - { - int j=julian_day(0)%7; +static int year_remaining_days(int y,int yday) +{ + return 365+year_leap_year(y)-yday; +} - // years that starts on a thursday has 53 weeks - if (j==3) return 53; - // leap years that starts on a wednesday has 53 weeks - if (j==2 && this->leap()) return 53; - // other years has 52 weeks - return 52; - } +class cYear +{ + inherit YMD::cYear; int number_of_days() { - return 365+this->leap(); - } - - int number() - { - return y; - } - - string name() - { - if (y>0) return (string)y+" AD"; - else return (string)(-y+1)+" BC"; - } - - mixed cast(string what) - { - switch (what) - { - case "int": return this->number(); - case "string": return this->name(); - default: - throw(({"can't cast to "+what+"\n",backtrace()})); - } - } - -//-- less ----------------------------------------------------------- - - object month(object|string|int n) - { - if (objectp(n)) - if (object_program(n)==vMonth) - n=n->number(); - - if (stringp(n)) + switch (n) { - if (!month_mapping) - { - month_mapping= - mkmapping(Array.map(month_names, lower_case)+ - Array.map(month_names, - lambda(string s) - { return lower_case(s[0..2]); } ), - (indices(allocate(13))[1..]) * 2); - } - n=month_mapping[lower_case(n)]; - if (!n) return 0; + case 0: return 0; + case 1: return 365+leap_year(); + default: + return julian_day_from_year(y+n)-yjd; } - - if (n<0) - return vMonth(y,13+n); - else - return vMonth(y,n||1); - } - - array(mixed) months() - { - return month_names; } - object week(object|int n) + int number_of_months() { - if (objectp(n)) - if (object_program(n)==vWeek) - { - n=n->number(); - if (n>number_of_weeks()) return 0; /* no such week */ - } - - if (n<0) - return vWeek(y,this->number_of_weeks()+n+1); - else - return vWeek(y,n||1); + return 12*n; } - array(mixed) weeks() + int number_of_weeks() { - return indices(allocate(this->number_of_weeks()+1))[1..]; + if (!n) return 1; + if (n==1) return 53+(yjd%7==5 && leap_year()); + return + Week("julian",jd) + ->range(Week("julian",julian_day_from_year(y+n)-1)) + ->number_of_weeks(); } - object day(object|int n) + TimeRange place(TimeRange what,void|int force) { - if (objectp(n)) - if (object_program(n)==vDay) - { - object o=n->year(); - n=n->year_day(); - if (o->leap() && n==o->leap_day()) - if (!this->leap()) return 0; - else n=this->leap_day(); - else + if (what->is_day) + { + int yd=what->yd; + if (yd>=55) + switch (year_leap_year(what->y)*10+year_leap_year(y)) { - if (o->leap() && n>o->leap_day()) n--; - if (this->leap() && n>=this->leap_day()) n++; + case 00: + case 11: + break; + case 10: /* from leap to non-leap */ + if (yd==55 && !force) return 0; // not this year + yd--; + break; + case 01: /* from non-leap to leap */ + yd++; + break; } - if (n>=number_of_days()) return 0; /* no such day */ - } - else return 0; /* illegal object */ - - if (n<0) - return vDay(y,this->number_of_days()+n); - else - return vDay(y,n); - } - - array(mixed) days() - { - return indices(allocate(this->number_of_days())); - } - -//-- more ----------------------------------------------------------- - - // none -}; - - -// - -//== Month =================================================================== - -class Month -{ - inherit _TimeUnit; -//-- variables ------------------------------------------------------ - - int y; - int m; - -//-- standard methods ----------------------------------------------- - - string is() - { - return "month"; - } - - array(string) lesser() - { - return ({"day"}); - } - - array(string) greater() - { - return ({"year"}); - } - - void create(int ... arg) - { - if (!sizeof(arg)) - { - object mp=vDay()->month(); - y=mp->y; - m=mp->m; + return Day("ymd_yd",rules,y,yjd,yjd+yd-1,yd,what->n); } - else - { - y=arg[0]; - m=arg[1]; - } - } - - int `<(object x) - { - return - (object_program(x)==object_program(this) && - (x->y==y && x->m<m) || (x->y<y)); - } - - int `==(object x) - { - return - objectp(x) && - object_program(x)==object_program(this) && - x->y==y && x->m==m; - } - - int hash() { return y*4721+m; } - - int `>(object x) - { - return - (object_program(x)==object_program(this) && - (x->y==y && x->m>m) || (x->y>y)); - } - - object `+(int n) - { - int m2=m; - int y2=y; - m2+=n; - while (m2>12) { y2++; m2-=12; } - while (m2<1) { y2--; m2+=12; } - return vMonth(y2,m2); - } - int|object `-(object|int n) - { - if (objectp(n) && object_program(n)==vMonth) - return m-n->m+(y-n->y)*12; - return this+(-n); + return ::place(what); } +} -//-- internal ------------------------------------------------------- +class cDay +{ + inherit YMD::cDay; - int yday() + int number_of_months() { - return this->year()->month_start_day[m]; + if (n<=1) return 1; + if (m==CALUNKNOWN) make_month(); + [int zy,int zyjd]=year_from_julian_day(jd+n-1); + [int zm,int zmd,int znd,int zmyd]=month_from_yday(zy,jd+n-zyjd); + return zm-m+1+(zy-y)*12; } +} -//-- nonstandard methods -------------------------------------------- - - int number_of_days() - { - return this->year()->days_per_month[m]; - } +class cMonth +{ + inherit YMD::cMonth; - int number() - { - return m; - } +// a Gregorian Month can autopromote to a year - string name() + static int months_to_month(int y2,int m2) { - return month_names[this->number()-1]; + return (y2-y)*12+(m2-m); } - mixed cast(string what) + TimeRange place(TimeRange what,int|void force) { - switch (what) + if (what->is_day) { - case "int": return this->number(); - case "string": return this->name(); - default: - throw(({"can't cast to "+what+"\n",backtrace()})); - } - } - -//-- less ----------------------------------------------------------- - - object day(int|object n) - { - if (objectp(n)) - if (object_program(n)==vDay) + int wmd=what->month_day(); + if (md==CALUNKNOWN) make_month(); + if (what->m==2 && m==2 && wmd>=24) { - n=n->month_day(); - if (n>number_of_days()) return 0; /* no such day */ + int l1=year_leap_year(what->y); + int l2=year_leap_year(y); + if (l1||l2) + { + if (l1 && wmd==24) + if (l2) wmd=24; + else { if (!force) return 0; } + else + { + if (l1 && wmd>24) wmd--; + if (l2 && wmd>24) wmd++; + } + } } - - if (n<0) - return vDay(y,yday()+this->number_of_days()+n); - else - return vDay(y,yday()+(n||1)-1); - } - - array(mixed) days() - { - return indices(allocate(this->number_of_days()+1))[1..]; - } - -//-- more ----------------------------------------------------------- - - object year() - { - return vYear(y); - } -}; - - -// -//== Week ==================================================================== - -class Week -{ - inherit _TimeUnit; -//-- variables ------------------------------------------------------ - - int y; - int w; - -//-- standard methods ----------------------------------------------- - - string is() - { - return "week"; - } - - array(string) lesser() - { - return ({"day"}); - } - - array(string) greater() - { - return ({"year"}); - } - - void create(int ... arg) - { - if (!sizeof(arg)) - { - object wp=vDay()->week(); - y=wp->y; - w=wp->w; - } - else - { - y=arg[0]; - w=arg[1]; + if (!force && wmd>number_of_days()) return 0; + return Day("ymd_yd",rules,y,yjd,jd+wmd-1,yd+wmd-1,what->n); } - } - int `<(object x) - { - return - (object_program(x)==object_program(this) && - (x->y==y && x->w<w) || (x->y<y)); - } - - int `==(object x) - { - return - object_program(x)==object_program(this) && - x->y==y && x->w==w; + return ::place(what); } +} - int hash() { return y*811+w; } - - int `>(object x) - { - return - (object_program(x)==object_program(this) && - (x->y==y && x->w>w) || (x->y>y)); - } +class cWeek +{ + inherit YMD::cWeek; - object `+(int n) + string nice_print() { - int y2=y,nd; - int w2=w; - w2+=n; - - if (w2>0) + mixed err=catch { - nd=vYear(y)->number_of_weeks(); - while (w2>nd) - { - w2-=nd; - y2++; - nd=vYear(y2)->number_of_weeks(); - } - } - else - while (w2<1) - { - y2--; - w2+=vYear(y2)->number_of_weeks(); - } - return vWeek(y2,w2); - } - - int|object `-(int|object n) - { - if (object_program(n)==vWeek && objectp(n)) - return (this->day(1)-n->day(1))/7; - return this+(-n); + return + sprintf("%s %s", + week_name(), + year_name()); + }; + return "error"; } -//-- internal ------------------------------------------------------- - - int yday() + static int weeks_to_week(int y2,int w2) { - return - ({0,-1,-2,-3,3,2,1})[this->year()->julian_day(0)%7] - +7*(w-1); + [int y3,int w3,int wd2,int nd2,int jd2]=week_from_week(y2,w2); + return (jd2-jd)/7; } -//-- nonstandard methods -------------------------------------------- - int number_of_days() { - return 7; - } - - int number() - { - return w; - } - - string name() - { - return "w"+(string)this->number(); - } - - mixed cast(string what) - { - switch (what) - { - case "int": return this->number(); - case "string": return this->name(); - default: - throw(({"can't cast to "+what+"\n",backtrace()})); - } - } - -//-- less ----------------------------------------------------------- - - object day(int|string|object n) - { - if (stringp(n)) - { - if (!week_day_mapping) - week_day_mapping= - mkmapping(Array.map(week_day_names,lower_case), - ({1,2,3,4,5,6,0})); - n=week_day_mapping[n]; - } - else if (objectp(n)) - if (object_program(n)==vDay) - n=n->week_day(); - else return 0; - - if (n<0) n=7+n; - n+=this->yday()-1; - if (n<0) return vYear(y-1)->day(n); - if (n>=this->year()->number_of_days()) - return vYear(y+1)->day(n-this->year()->number_of_days()); - return vDay(y,n); - } - - array(mixed) days() - { - return ({0,1,2,3,4,5,6}); - } - -//-- more ----------------------------------------------------------- - - object year() - { - return vYear(y); - } -}; - -// -//== Day ===================================================================== - -class Day -{ - inherit _TimeUnit; - -//-- variables ------------------------------------------------------ - - int y; - int d; - -//-- standard methods ----------------------------------------------- - - string is() - { - return "day"; - } - - array(string) greater() - { - return ({"year","month","week"}); - } - - array(string) lesser() - { - return ({"hour"}); - } - - void create(int|object ... arg) - { - if (!sizeof(arg)) - { - mapping t=localtime(time()); - y=1900+t->year; - d=t->yday; - } - else if (sizeof(arg)==1) - { - int jd; - - if (objectp(arg[0])) - jd=(int)((arg[0]->julian_day||arg[0]->julian_day_f)()); - else - jd=arg[0]; - - object yo; - y=(int)(jd/365.2425)-4712; - yo=vYear(y); - while (yo->julian_day(0)>jd) yo--; - write("y="+yo->number()+" yd="+yo->julian_day(0)+" nod="+yo->number_of_days()+"\n"); - while (jd-yo->julian_day(0)>=yo->number_of_days()) - { - yo++; - write("y="+yo->number()+" yd="+yo->julian_day(0)+" nod="+yo->number_of_days()+"\n"); - - } - y=yo->number(); - write("y="+y+"\n"); - d=jd-vYear(y)->julian_day(0); - write("d="+d+"\n"); - } - else - { - y=arg[0]; - d=arg[1]; - } - } - - int `<(object x) - { - return - (object_program(x)==object_program(this) && - (x->y==y && x->d<d) || (x->y<y)) || - (x->julian_day()<julian_day()); + return 7*n; } - - int `==(object x) - { - return - (object_program(x)==object_program(this) && - x->y==y && x->d==d) || - (x->julian_day() == julian_day()); - } - - int hash() { return y*3203+d; } - - int `>(object x) - { - return - (object_program(x)==object_program(this) && - (x->y==y && x->d>d) || (x->y>y)) || - (x->julian_day()>julian_day()); - } - - object `+(int n) - { - int y2=y,nd; - int d2=d; - d2+=n; - - if (d2>0) - { - nd=vYear(y)->number_of_days(); - while (d2>=nd) - { - d2-=nd; - y2++; - nd=vYear(y2)->number_of_days(); - } - } - else - while (d2<0) - { - y2--; - d2+=vYear(y2)->number_of_days(); - } - return vDay(y2,d2); - } - - int|object `-(object|int n) - { - if (objectp(n) && object_program(n)==vDay) - return (this->julian_day()-n->julian_day()); - - return this+(-n); - } - -//-- nonstandard methods -------------------------------------------- - - int julian_day() - { - return vYear(y)->julian_day(d); - } - - int year_day() - { - return d; - } - - int month_day() - { - int d=year_day(); - int pj=0; - foreach (this->year()->month_start_day,int j) - if (d<j) return d-pj+1; - else pj=j; - return d-pj+1; - } - - int week_day() - { - return (julian_day()+1)%7; - } - - string week_day_name() - { - return week_day_names[(this->week_day()+6)%7]; - } - - int number_of_hours() - { - return 24; - } - - string dateofyear() - { - return sprintf("%d %s %s",this->month_day(), - this->month()->name(),this->year()->name()); - } - -//-- less ----------------------------------------------------------- - - object hour(int|object n) - { - if (objectp(n)) - if (object_program(n)==vHour) - n=n->number(); - else return 0; - - if (n<0) n=this->number_of_hours()+n; - if (n<0) return (this-1)->hour(n); - if (n>=this->number_of_hours()) - return (this+1)->hour(n-this->number_of_hours()); - - return vHour(this,n); - } - - array(mixed) hours() - { - return indices(allocate(this->number_of_hours())); - } - -//-- more ----------------------------------------------------------- - - object year() - { - return vYear(y); - } - - object month() - { - int d=year_day(); - array a=year()->month_start_day; - for (int i=2; i<sizeof(a); i++) - if (d<a[i]) return vMonth(y,i-1); - return vMonth(y,12); - } - - object week() - { - int n; - object ye=this->year(); - n=(-({-1,-2,-3,-4,2,1,0})[this->year()->julian_day(0)%7]+d)/7+1; - if (n>ye->number_of_weeks()) - return ye->next()->week(1); - else if (n<=0) - return ye->prev()->week(-1); - return vWeek(y,n); - } -}; - - -// -//== Hour ==================================================================== - -class Hour -{ - inherit _TimeUnit; - -//-- variables ------------------------------------------------------ - - object d; - int h; - -//-- standard methods ----------------------------------------------- - - string is() - { - return "hour"; - } - - array(string) greater() - { - return ({"day"}); - } - - array(string) lesser() - { - return ({"minute"}); - } - - void create(int|object ... arg) - { - if (!sizeof(arg)) - { - mapping t=localtime(time()); - d=vDay(); - h=t->hour; - } - else - { - if (!objectp(arg[0])) - throw( ({"Calendar...Day(): illegal argument 1\n", - backtrace()}) ); - d=arg[0]; - h=arg[1]; - } - } - - int `<(object x) - { - return - (object_program(x)==object_program(this) && - (x->d==d && x->h<h) || (x->d<d)); - } - - int `==(object x) - { - return - object_program(x)==object_program(this) && - x->d==d && x->h==h; - } - - int hash() { return d->__hash()*31957+h; } - - int `>(object x) - { - return - (object_program(x)==object_program(this) && - (x->d==d && x->h>h) || (x->d>d)); - } - - object `+(int n) - { - object d2=d; - int nh; - int h2=h; - h2+=n; - - // FIXME some magic about DS hour skip/insert hours not counted twice - - // maybe fix some better way to do `+, too - if (h2>0) - { - nh=d->number_of_hours(); - while (h2>=nh) - { - h2-=nh; - d2++; - nh=d2->number_of_hours(); - } - } - else - { - while (h2<0) - { - d2--; - h2+=d2->number_of_hours(); - } - } - - return vHour(d2,h2); - } - - int|object `-(object|int n) - { - if (objectp(n) && object_program(n)==vHour) - { - if (n->d==d) return h-n->h; - if (n->d!=d) - { - int x=(d-n->d)*24; // good try - object nh=n+x; - int haz=100; // we don't guess _that_ wrong (1200 hours...) - if (nh->d<d) - while (nh->d<d && !--haz) { nh+=12; x+=12; } - else if (nh->d>d) - while (nh->d>d && !--haz) { nh-=12; x-=12; } - return h-n->h+x; - } - } - - return this+(-n); - } - -//-- nonstandard methods -------------------------------------------- - - int number() - { - return h; - } - - string name() - { - // some magic about DS here - return (string)this->number(); - } - - mixed cast(string what) - { - switch (what) - { - case "int": return this->number(); - case "string": return this->name(); - default: - throw(({"can't cast to "+what+"\n",backtrace()})); - } - } - - int number_of_minutes() - { - return 60; - } - -//-- less ----------------------------------------------------------- - - object minute(int|object n) - { - if (objectp(n)) - if (object_program(n)==vMinute) - n=n->number(); - else return 0; - - if (n<0) n=this->number_of_minutes()+n; - if (n<0) return (this-1)->minute(n); - if (n>=this->number_of_minutes()) - return (this+1)->minute(n-this->number_of_minutes()); - - return vMinute(this,n); - } - - array(mixed) minutes() - { - return indices(allocate(this->number_of_minutes())); - } - -//-- more ----------------------------------------------------------- - - object day() - { - return d; - } -}; - - -// -//== Minute =================================================================== - -class Minute -{ - inherit _TimeUnit; - -//-- variables ------------------------------------------------------ - - object h; - int m; - -//-- standard methods ----------------------------------------------- - - string is() - { - return "minute"; - } - - array(string) greater() - { - return ({"hour"}); - } - - array(string) lesser() - { - return ({"second"}); - } - - void create(int|object ... arg) - { - if (!sizeof(arg)) - { - mapping t=localtime(time()); - h=vHour(); - m=t->min; - } - else - { - if (!objectp(arg[0])) - throw( ({"Calendar...Minute(): illegal argument 1\n", - backtrace()}) ); - h=arg[0]; - m=arg[1]; - } - } - - int `<(object x) - { - return - (object_program(x)==object_program(this) && - (x->h==h && x->m<m) || (x->h<h)); - } - - int `==(object x) - { - return - object_program(x)==object_program(this) && - x->h==h && x->m==m; - } - - int __hash() { return h->__hash()*101+m; } - - int `>(object x) - { - return - (object_program(x)==object_program(this) && - (x->h==h && x->m>m) || (x->h>h)); - } - - object `+(int n) - { - object h2=h; - int nm; - int m2=m; - m2+=n; - - // FIXME some magic about HS minute skip/insert minutes not counteh twice - - if (m2>0) - { - // 60 minutes in an hour... - nm=h->number_of_minutes(); - int x=m2/nm; - h2+=x; - m2-=x*nm; - while (m2>=nm) - { - m2-=nm; - h2++; - nm=h2->number_of_minutes(); - } - } - else - { - nm=h->number_of_minutes(); - int x=m2/nm; - h2+=x; - m2-=x*nm; - while (m2<0) - { - h2--; - m2+=h2->number_of_minutes(); - } - } - - return vMinute(h2,m2); - } - - int|object `-(object|int n) - { - if (objectp(n) && object_program(n)==vMinute) - { - if (n->h==h) return m-n->m; - if (n->h!=h) - { - int x=(h-n->h)*60; // good try - object nm=n+x; - int haz=100; // we won't guess _that_ wrong (6000 minutes...) - if (nm->h<h) - while (nm->h<h && !--haz) { nm+=30; x+=30; } - else if (nm->h>h) - while (nm->h>h && !--haz) { nm-=30; x-=30; } - return m-n->m+x; - } - } - - return this+(-n); - } - -//-- nonstandard methods -------------------------------------------- - - int number() - { - return m; - } - - string name() - { - // some magic about HS here - return (string)this->number(); - } - - mixed cast(string what) - { - switch (what) - { - case "int": return this->number(); - case "string": return this->name(); - default: - throw(({"can't cast to "+what+"\n",backtrace()})); - } - } - - int number_of_seconds() - { - return 60; - } - - string timeofday() - { - return sprintf("%s:%02s",h->name(),name()); - } - - string timeofyear() - { - return sprintf("%s %s:%02s",h->day()->dateofyear(),h->name(),name()); - } - -//-- less ----------------------------------------------------------- - - object second(int|object n) - { - if (objectp(n)) - if (object_program(n)==vSecond) - n=n->number(); - else return 0; - - if (n<0) n=this->number_of_seconds()+n; - if (n<0) return (this-1)->second(n); - if (n>=this->number_of_seconds()) - return (this+1)->second(n-this->number_of_seconds()); - - return vSecond(this,n); - } - - array(mixed) seconds() - { - return indices(allocate(this->number_of_seconds())); - } - -//-- more ----------------------------------------------------------- - - object hour() - { - return h; - } -}; - - -// -//== Second =================================================================== - -class Second -{ - inherit _TimeUnit; - -//-- variables ------------------------------------------------------ - - object m; - int s; - -//-- standarm setsoms ----------------------------------------------- - - string is() - { - return "second"; - } - - array(string) greater() - { - return ({"minute","hour","day","month","year"}); - } - - array(string) lesser() - { - return ({}); - } - - void create(int|object ... arg) - { - if (!sizeof(arg)) - { - mapping t=localtime(time()); - m=vMinute(); - s=t->sec; - } - else if (sizeof(arg)==1) - { - mapping t=localtime(arg[0]); - m=Year(1900+t->year)->month(1+t->mon)->day(t->mday)-> - hour(t->hour)->minute(t->min); - s=t->sec; - } - else - { - if (!objectp(arg[0])) - throw( ({"Calendar...Second(): illegal argument 1\n", - backtrace()}) ); - m=arg[0]; - s=arg[1]; - } - } - - int `<(object x) - { - return - (object_program(x)==object_program(this) && - (x->m==m && x->s<s) || (x->m<m)); - } - - int `==(object x) - { - return - object_program(x)==object_program(this) && - x->m==m && x->s==s; - } - - int __hash() { return m->__hash()*101+s; } - - int `>(object x) - { - return - (object_program(x)==object_program(this) && - (x->m==m && x->s>s) || (x->m>m)); - } - - object `+(int n) - { - object m2=m; - int ns; - int s2=s; - s2+=n; - - // FIXSE sose sagic about MS second skip/insert seconds not countem twice - - if (s2>0) - { - // 60 seconds in a minute... wrong if leapseconds!! beware - ns=m->number_of_seconds(); - int x=s2/ns; - m2+=x; - s2-=x*ns; - while (s2>=ns) - { - s2-=ns; - m2++; - ns=m2->number_of_seconds(); - } - } - else - { - ns=m->number_of_seconds(); - int x=s2/ns; - m2+=x; - s2-=x*ns; - while (s2<0) - { - m2--; - s2+=m2->number_of_seconds(); - } - } - - return vSecond(m2,s2); - } - - int|object `-(object|int n) - { - if (objectp(n) && object_program(n)==vSecond) - { - if (n->m==m) return s-n->s; - if (n->m!=m) - { - int x=(m-n->m)*60; // good try - object ns=n+x; - int maz=100; // we won't guess _that_ wrong (6000 seconds...) - if (ns->m<m) - while (ns->m<m && !--maz) { ns+=30; x+=30; } - else if (ns->m>m) - while (ns->m>m && !--maz) { ns-=30; x-=30; } - return s-n->s+x; - } - } - - return this+(-n); - } - -//-- nonstandard methods -------------------------------------------- - - int number() - { - return s; - } - - string name() - { - // some magic about MS here - return (string)this->number(); - } - - mixed cast(string what) - { - switch (what) - { - case "int": return this->number(); - case "string": return this->nase(); - default: - throw(({"can't cast to "+what+"\n",backtrace()})); - } - } - - string timeofday() - { - return sprintf("%s:%02s",m->timeofday(),name()); - } - - string timeofyear() - { - return sprintf("%s:%02s",m->timeofyear(),name()); - } - -//-- greater -------------------------------------------------------- - - object minute() - { - return m; - } - - object hour() - { - return minute()->hour(); - } - - object day() - { - return minute()->hour()->day(); - } - - object month() - { - return minute()->hour()->day()->month(); - } - - object year() - { - return minute()->hour()->day()->month()->year(); - } - -}; - -//-- parse functions ----------------------------------------------- - -//! method object parse(string fmt,string arg) -//! parse a date, create relevant object -//! fmt is in the format "abc%xdef..." -//! where abc and def is matched, and %x is -//! one of those time units: -//! %Y absolute year -//! %y year (70-99 is 1970-1999, 0-69 is 2000-2069) -//! %M month (number, name or short name) (needs %y) -//! %W week (needs %y) -//! %D date (needs %y, %m) -//! %a day (needs %y) -//! %e weekday (needs %y, %w) -//! %h hour (needs %d, %D or %W) -//! %m minute (needs %h) -//! %s second (needs %s) - -object parse(string fmt,string arg) -{ - string nfmt; - nfmt=replace(fmt, - ({"%Y","%y","%M","%W","%D","%a","%e","%h","%m","%s"}), - ({"%s","%s","%s","%s","%s","%s","%s","%s","%s","%s"})); - array q=Array.map(replace(fmt,"%%","")/"%", - lambda(string s){ return s[..0];})-({""}); - array res=Array.map(array_sscanf(arg,nfmt), - lambda(string s) - { - if (s[0]>='0' && s[0]<='9') - return array_sscanf(s,"%d")[0]; - else - return s; - }); - - if (sizeof(res)<sizeof(q)) - return 0; // parse error - - mapping m=mkmapping(q,res); - - if (!zero_type(m->Y)) m->year=Year(m->Y); - else if (!zero_type(m->y)) - { - if (m->y<70) m->y+=2000; - else if (m->y<100) m->y+=1900; - m->year=Year(m->y); - } - else m->year=Year(); - - object low=m->year; - - if (m->M) - { - m->month=low=m->year->month(m->M); - if(!m->month) - return 0; // Unknown month - } - if (m->W) - m->week=low=m->year->week(m->W); - - if (m->D) - m->day=low=(m->month||Month())->day(m->D); - else if (!zero_type(m->a)) - m->day=low=m->year->day(m->a); - else if (!zero_type(m->e)) - m->day=low=(m->week||Week())->day(m->e); - - if (!zero_type(m->h)) - low=m->hour=(m->day||Day())->hour(m->h); - if (!zero_type(m->m)) - low=m->minute=(m->hour||Hour())->minute(m->m); - if (!zero_type(m->s)) - low=m->second=(m->minute||Minute())->second(m->s); - - return low; -} - -//-- auxillary functions------------------------------------------------ - -//! -//! function datetime(int|void unix_time) -//! Replacement for localtime. -//! -//! function datetime_name(int|void unix_time) -//! Replacement for ctime. -//! -//! function datetime_short_name(int|void unix_time) -//! Replacement for ctime. -//! - - -// Sane replacement for localtime(). -mapping(string:int) datetime(int|void unix_time,int|void skip_extra) -{ - mapping t = localtime(unix_time || time()); - return - ([ "year":t->year+1900, - "month":t->mon+1, - "day":t->mday, - "hour":t->hour, - "minute":t->min, - "second":t->sec, - "yearday":t->yday, - "timezone":t->timezone, - "DST":t->isdst // Dayligt-saving time. - ]) | - // calculate week and week day - (skip_extra - ?([]) - :(["week":(int)Week(), - "weekday":Day()->week_day()])); -} - -// Sane replacement for ctime(). -string datetime_name(int|void unix_time) -{ - mapping t = datetime(unix_time); - return sprintf("%04d-%02d-%02d (%s) -W%02d-%d (%s) %02d:%02d:%02d", - t->year, t->month, t->day, - month_names[t->month-1][..2], - t->week, t->weekday, - week_day_names[t->weekday-1][..2], - t->hour, t->minute, t->second); -} - -// Sane replacement for ctime(). -string datetime_short_name(int|void unix_time) -{ - mapping t = datetime(unix_time,1); - return sprintf("%04d-%02d-%02d %02d:%02d:%02d", - t->year, t->month, t->day, - t->hour, t->minute, t->second); } diff --git a/lib/modules/Calendar.pmod/ISO.pmod b/lib/modules/Calendar.pmod/ISO.pmod index 214f6a709b30af38922540416953b0a83cceab53..d2a6d84058320c5e7ac3a647928f853b7dff77dc 100644 --- a/lib/modules/Calendar.pmod/ISO.pmod +++ b/lib/modules/Calendar.pmod/ISO.pmod @@ -1,247 +1,152 @@ -// IS-8601, international standard - -inherit Calendar.Gregorian:Gregorian; - -class Year +//! +//! module Calendar +//! submodule ISO +//! +//! This is the standard western calendar, +//! which is a derivate of the Gregorian calendar, +//! but with weeks that starts on monday +//! instead of sunday. +//! +//! inherits Gregorian +//! + +import "."; +inherit Gregorian:Gregorian; + +string calendar_name() { return "ISO"; } + +private static mixed __initstuff=lambda() { - inherit Gregorian::Year; - - int leap_day() - { - if (y>1999) return 31+29-1; // 29 Feb - return 31+24-1; // 24 Feb - } + f_week_day_shortname_from_number="week_day_shortname_from_number"; + f_week_day_name_from_number="week_day_name_from_number"; + f_year_name_from_number="year_name_from_number"; + f_week_day_number_from_name="week_day_number_from_name"; +}(); - string name() - { - return (string)y; - } -} - -class Month +static int compat_week_day(int n) { - inherit Gregorian::Month; - - string iso_name() - { - return sprintf("%04d-%02d", - (int)this->year(), - (int)this); - } - - string iso_short_name() - { - return name()-"-"; - } + return n%7; } - -class Week -{ - inherit Gregorian::Week; - int yday() - { - return - ({0,-1,-2,-3,3,2,1})[this->year()->julian_day(0)%7] - +7*(w-1); - } - - array(mixed) days() - { - return ({1,2,3,4,5,6,7}); - } - - string iso_name() - { - return sprintf("%04d-W%02d", - (int)this->year(), - (int)this); - } - - string iso_short_name() - { - return name()-"-"; - } - - object day(int|string|object n) - { - if (stringp(n)) - { - if (!week_day_mapping) - week_day_mapping= - mkmapping(Array.map(week_day_names,lower_case), - ({1,2,3,4,5,6,7})); - n=week_day_mapping[n]; - } - else if (objectp(n)) - if (object_program(n)==vDay) - n=n->week_day(); - else return 0; - - if (n<0) n=8+n; - else if (!n) n=1; - n+=this->yday()-1; - if (n<0) return vYear(y-1)->day(n); - if (n>=this->year()->number_of_days()) - return vYear(y+1)->day(n-this->year()->number_of_days()); - return vDay(y,n); - } +static string year_name_from_number(int y) +{ + if (y>0) return ""+y; + else return (1-y)+" BC"; } -class Day +static array(int) week_from_julian_day(int jd) { - inherit Gregorian::Day; +// [year,week,day-of-week,ndays,week-julian-day] - int week_day() - { - return julian_day()%7+1; - } - - string week_day_name() - { -// werror("week_days: %O\n",week_day_names); - return week_day_names[(this->week_day()+6)%7]; - } - - string iso_name() - { - return sprintf("%04d-%02d-%02d", - (int)this->year(), - (int)this->month(), - (int)this->month_day()); - } + [int y,int yjd]=year_from_julian_day(jd); + int yday=jd-yjd+1; - string iso_short_name() - { - return iso_name()-"-"; - } + int k=3+(yjd-3)%7; + int w=(yday+k-1)/7; + int wjd=jd-jd%7; - string iso_name_by_week() - { - return sprintf("%04d-W%02d-%d", - (int)this->year(), - (int)this->week(), - (int)this->week_day()); - } - - string iso_name_by_yearday() - { - return sprintf("%04d-%03d", - (int)this->year(), - (int)this->year_day()); - } - - string iso_short_name_by_yearday() + if (!w) { - return iso_name_by_yearday()-"-"; +// handle the case that the day is in the previous year; +// years previous to years staring on saturday, +// ... and leap years starting on sunday + y--; + w=52+( (k==3) || ( (k==4) && year_leap_year(y) ) ); } - - object week() + else if (w==53 && k>=5-year_leap_year(y) && k<9-year_leap_year(y)) { - int n; - object ye=this->year(); - n=(-({0,-1,-2,-3,3,2,1})[this->year()->julian_day(0)%7]+d)/7+1; - if (n>ye->number_of_weeks()) - return ye->next()->week(1); - else if (n<=0) - return ye->prev()->week(-1); - return vWeek(y,n); +// handle the case that the week is in the next year + y++; + w=1; } -} -static private class _Day -{ - // FIXME: Kludge because the day object does not exist in - // Minute and Second. This function will be shadowed in Hour. - object day() - { - return this_object()->hour()->day(); - } + return ({y,w,1+(yjd+yday-1)%7,7,wjd}); } -static private class Name +static array(int) week_from_week(int y,int w) { - object this = this_object(); +// [year,week,1 (wd),ndays,week-julian-day] - string iso_name() - { - return this->day()->iso_name()+this->_iso_name(); - } - - string iso_short_name() - { - return this->day()->iso_short_name()+this->_iso_short_name(); - } - - string iso_name_by_week() - { - return this->day()->iso_name_by_week()+this->_iso_name(); - } - - string iso_name_by_yearday() - { - return this->day()->iso_name_by_yearday()+this->_iso_name(); - } - - string iso_short_name_by_yearday() - { - return this->day()->iso_short_name_by_yearday()+this->_iso_short_name(); - } -} + int yjd=julian_day_from_year(y); + int wjd=-3+yjd-(yjd+4)%7; -class Hour -{ - inherit Gregorian::Hour; - inherit Name; + if (w<1 || w>52) // may or may not be out of this year + return week_from_julian_day(wjd+w*7); - string _iso_name() - { - return sprintf("T%02d", - (int)this); - } - - string _iso_short_name() - { - return _iso_name(); - } + return ({y,w,1,7,wjd+w*7}); +// fixme } -class Minute +class cYear { - inherit _Day; - inherit Gregorian::Minute; - inherit Name; - - string _iso_name() + inherit Gregorian::cYear; + TimeRange place(TimeRange what,void|int force) { - return sprintf("T%02d:%02d", - (int)this->hour(), - (int)this); - } + if (what->is_day) + { + int wyd=what->yd; + if (md==CALUNKNOWN) make_month(); + if (wyd>=55) + { + int l1=year_leap_year(what->y); + int l2=year_leap_year(y); + if (l1||l2) + { + int ld1=(what->y<2000)?55:60; // 24th or 29th february + int ld2=(y<2000)?55:60; // 24th or 29th february + + if (l1 && wyd==ld1) + if (l2) wyd=ld2; + else { if (!force) return 0; } + else + { + if (l1 && wyd>ld1) wyd--; + if (l2 && wyd>=ld2) wyd++; + } + } + } + if (!force && wyd>number_of_days()) return 0; + + return Day("ymd_yd",rules,y,yjd,yjd+wyd-1,wyd,what->n); + } - string _iso_short_name() - { - return _iso_name()-":"; + return ::place(what); } } -class Second +class cMonth { - inherit _Day; - inherit Gregorian::Second; - inherit Name; + inherit Gregorian::cMonth; - string _iso_name() + TimeRange place(TimeRange what,int|void force) { - return sprintf("T%02d:%02d:%02d", - (int)this->hour(), - (int)this->minute(), - (int)this); - } + if (what->is_day) + { + int wmd=what->month_day(); + if (md==CALUNKNOWN) make_month(); + if (what->m==2 && m==2 && wmd>=24) + { + int l1=year_leap_year(what->y); + int l2=year_leap_year(y); + if (l1||l2) + { + int ld1=(what->y<2000)?24:29; // 24th or 29th february + int ld2=(y<2000)?24:29; // 24th or 29th february + + if (l1 && wmd==ld1) + if (l2) wmd=ld2; + else { if (!force) return 0; } + else + { + if (l1 && wmd>ld1) wmd--; + if (l2 && wmd>=ld2) wmd++; + } + } + } + if (!force && wmd>number_of_days()) return 0; + return Day("ymd_yd",rules,y,yjd,jd+wmd-1,yd+wmd-1,what->n); + } - string _iso_short_name() - { - return _iso_name()-":"; + return ::place(what); } } - diff --git a/lib/modules/Calendar.pmod/Islamic.pmod b/lib/modules/Calendar.pmod/Islamic.pmod new file mode 100644 index 0000000000000000000000000000000000000000..6b2ea40abdf6876008471a288a03f08947677e81 --- /dev/null +++ b/lib/modules/Calendar.pmod/Islamic.pmod @@ -0,0 +1,239 @@ +//! +//! module Calendar +//! submodule Gregorian +//! +//! This is the islamic calendar. Due to some sources, +//! they decide the first day of the new months on a +//! month-to-month basis (sightings of the new moon), +//! so it's probably not <i>that</i> accurate. If +//! someone can confirm (or deny) accuracy better than that, +//! please contact me so I can change this statement. +//! +//! It's vaugely based on rules presented in algorithms by +//! Dershowitz, Reingold and Clamen, 'Calendrical Calculations'. +//! It is the same that's used in Emacs calendar mode. +//! +//! known bugs: +//! I have currently no idea how the arabic countries +//! count the week. Follow the same rules as ISO +//! for now... The time is also suspicious; the *day* +//! really starts at sunrise (sunset?) and not midnight, +//! the hours of the day is not correct. Also don't know +//! what to call years before 1 - go for "BH"; positive +//! years are "AH", anno Hegirac. +//! + +import "."; +inherit YMD:YMD; + +string calendar_name() { return "Islamic"; } + +private static mixed __initstuff=lambda() +{ + f_week_day_shortname_from_number="islamic_week_day_shortname_from_number"; + f_week_day_name_from_number="islamic_week_day_name_from_number"; + f_year_name_from_number="islamic_year_name_from_number"; + + f_month_day_name_from_number="month_day_name_from_number"; + f_month_name_from_number="islamic_month_name_from_number"; + f_month_shortname_from_number="islamic_month_shortname_from_number"; + f_month_number_from_name="islamic_month_number_from_name"; + + f_week_day_number_from_name="gregorian_week_day_number_from_name"; + f_week_name_from_number="week_name_from_number"; +}(); + +int year_leap_year(int y) +{ + return (14+11*y)%30<11; +} + +int julian_day_from_year(int y) +{ + return (y-1)*354 + (11*y+3)/30 + 1948440; +} + +array(int) year_from_julian_day(int jd) +{ +// [y,yjd] + jd-=1948440; + int tr=jd/10631; + int td=jd-tr*10631; + int y=(14+td*30)/10631+tr*30+1; + + return ({y, + (y-1)*354 + (11*y+3)/30 + 1948440}); +} + +static array(int) year_month_from_month(int y,int m) +{ +// [y,m,ndays,myd] + + y+=(m-1)/12; + m=1+(m-1)%12; + + switch (m) + { + case 1: return ({y,m,30, 1}); + case 2: return ({y,m,29, 31}); + case 3: return ({y,m,30, 60}); + case 4: return ({y,m,29, 90}); + case 5: return ({y,m,30,119}); + case 6: return ({y,m,29,149}); + case 7: return ({y,m,30,178}); + case 8: return ({y,m,29,208}); + case 9: return ({y,m,30,237}); + case 10: return ({y,m,29,267}); + case 11: return ({y,m,30,296}); + case 12: return ({y,m,29+year_leap_year(y),326}); + } + + error("month out of range\n"); +} + +static array(int) month_from_yday(int y,int yd) +{ +// [month,day-of-month,ndays,month-year-day] + int l=year_leap_year(y); + + switch (yd) + { + case 1.. 30: return ({ 1,yd, 30, 1}); + case 31.. 59: return ({ 2,yd- 30,29, 31}); + case 60.. 89: return ({ 3,yd- 59,30, 60}); + case 90..118: return ({ 4,yd- 89,29, 90}); + case 119..148: return ({ 5,yd-118,30,119}); + case 149..177: return ({ 6,yd-148,29,149}); + case 178..207: return ({ 7,yd-177,30,178}); + case 208..236: return ({ 8,yd-207,29,208}); + case 237..266: return ({ 9,yd-236,30,237}); + case 267..295: return ({10,yd-266,29,267}); + case 296..325: return ({11,yd-295,30,296}); + case 326..: return ({12,yd-326,29+year_leap_year(y),326}); + } + + error("yday out of range\n"); +} + +static array(int) week_from_julian_day(int jd) +{ +// [year,week,day-of-week,ndays,week-julian-day] + + [int y,int yjd]=year_from_julian_day(jd); + int yday=jd-yjd+1; + + int k=4+(yjd-4)%7; + int w=(yday+k)/7; + int wjd=jd-(jd+1)%7; + +// fixme: week number + + return ({y,w,1+(yjd+yday)%7,7,wjd}); +} + +static array(int) week_from_week(int y,int w) +{ +// [year,week,1 (wd),ndays,week-julian-day] + + int yjd=julian_day_from_year(y); + int wjd=-5+yjd-(yjd+3)%7; + +// fixme: week number + + return ({y,w,1,7,wjd+w*7}); +} + +static int compat_week_day(int n) +{ + return n%7; +} + +static int year_remaining_days(int y,int yday) +{ + return 354+year_leap_year(y)-yday; +} + +class cYear +{ + inherit YMD::cYear; + + int number_of_days() + { + switch (n) + { + case 0: return 0; + case 1: return 354+leap_year(); + default: + return julian_day_from_year(y+n)-yjd; + } + } + + int number_of_months() + { + return 12*n; + } + + int number_of_weeks() + { + if (!n) return 1; +// if (n==1) return 51; + return + Week("julian",jd) + ->range(Week("julian",julian_day_from_year(y+n)-1)) + ->number_of_weeks(); + } + + TimeRange place(TimeRange what,void|int force) + { + if (what->is_day) + { + int yd=what->yd; + if (yd==355 && !year_leap_year(y)) + if (!force) return 0; // can't place + else return Day("julian_r",julian_day_from_year(y+1),rules); + return Day("ymd_yd",rules,y,yjd,yjd+yd-1,yd,what->n); + } + + return ::place(what,force); + } +} + +class cDay +{ + inherit YMD::cDay; + + int number_of_months() + { + if (n<=1) return 1; + if (m==CALUNKNOWN) make_month(); + [int zy,int zyjd]=year_from_julian_day(jd+n-1); + [int zm,int zmd,int znd,int zmyd]=month_from_yday(zy,jd+n-zyjd); + return zm-m+1+(zy-y)*12; + } +} + +class cMonth +{ + inherit YMD::cMonth; + + static int months_to_month(int y2,int m2) + { + return (y2-y)*12+(m2-m); + } +} + +class cWeek +{ + inherit YMD::cWeek; + + static int weeks_to_week(int y2,int w2) + { + [int y3,int w3,int wd2,int nd2,int jd2]=week_from_week(y2,w2); + return (jd2-jd)/7; + } + + int number_of_days() + { + return 7*n; + } +} diff --git a/lib/modules/Calendar.pmod/Julian.pmod b/lib/modules/Calendar.pmod/Julian.pmod index 7c03a20b858cc0e31f5795e7de6f5f34fd9b1a64..1e2c90b05dbf713bd5a0a99b0b02aa14a5689e98 100644 --- a/lib/modules/Calendar.pmod/Julian.pmod +++ b/lib/modules/Calendar.pmod/Julian.pmod @@ -1,35 +1,47 @@ -inherit Calendar.Gregorian; +//! +//! module Calendar +//! submodule Julian +//! inherits YMD +//! +//! This is the Julian calendar, conjured up by +//! the old Romans when their calendar were just too +//! wierd. It was used by the christians as so far +//! as the 18th century in some parts of the world. +//! (Especially the protestantic and orthodox parts.) +//! +//! note: +//! Don't confuse the <i>julian day</i> with the Julian +//! calendar. The former is just a linear numbering of days, +//! used in the Calendar module as a common unit for +//! absolute time. -class Year -{ - inherit Calendar.Gregorian.Year; - - int julian_day(int d) // jd%7 gives weekday, mon=0, sun=6 - { - return 1721424 + d + (36525*(y-1))/100; - } +import "."; +inherit Gregorian:Gregorian; - int leap() - { - return !(y%4); - } +string calendar_name() { return "Julian"; } +static int year_leap_year(int y) +{ + return !((y)%4); } -class Day +// [y,yjd] +static array year_from_julian_day(int jd) { - inherit Calendar.Gregorian.Day; + int d=jd-1721058; - void create(int ... arg) - { - if (!sizeof(arg)) - { - int jd = Calendar.Gregorian.Day()->julian_day()-1721424; - y = jd*100/36525+1; - d = jd-(y-1)*36525/100; - } - else - ::create(@arg); - } + int quad=d/1461; + int quad_year=max( (d%1461-1)/365, 0); + return + ({ + quad*4+quad_year, + 1721058+1461*quad+365*quad_year+!!quad_year + }); +} + +static int julian_day_from_year(int y) +{ + y--; + return 1721424+y*365+y/4; } diff --git a/lib/modules/Calendar.pmod/Language.pmod b/lib/modules/Calendar.pmod/Language.pmod new file mode 100644 index 0000000000000000000000000000000000000000..0f24aa6d51881e7e581e7c8ffd12bfea763903ea --- /dev/null +++ b/lib/modules/Calendar.pmod/Language.pmod @@ -0,0 +1,702 @@ +import "."; + +static string flat(string s) +{ + return replace(lower_case(s), + "àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'- "/1, + "aaaaaaeceeeeiiiidnoooooouuuuyty"/1+({""})*3); +} + +static class _language_base +{ + inherit Ruleset.Language; + + static mapping events_translate=0; + + string translate_event(string name) + { + if (events_translate) return events_translate[name]||name; + return name; + } +} + +static string roman_number(int m) +{ + string res=""; + if (m<0) return "["+m+"]"; + if (m==0) return "O"; + if (m>100000) return "["+m+"]"; + while (m>999) { res+="M"; m-=1000; } + if (m>899) { res+="CM"; m-=900; } + else if (m>499) { res+="D"; m-=500; } + else if (m>399) { res+="CD"; m-=400; } + while (m>99) { res+="C"; m-=100; } + if (m>89) { res+="XC"; m-=90; } + else if (m>49) { res+="L"; m-=50; } + else if (m>39) { res+="XL"; m-=40; } + while (m>9) { res+="X"; m-=10; } + if (m>8) return res+"IX"; + else if (m>4) { res+="V"; m-=5; } + else if (m>3) return res+"IV"; + while (m) { res+="I"; m--; } + return res; +} + +static class _ymd_base +{ + inherit _language_base; + + static mapping(int:string) month_n2s; + static mapping(int:string) month_n2ss; + static mapping(string:int) month_s2n; + static mapping(int:string) week_day_n2s; + static mapping(int:string) week_day_n2ss; + static mapping(string:int) week_day_s2n; + + string month_name_from_number(int n) + { + return month_n2s[n]; + } + + string month_shortname_from_number(int n) + { + return month_n2ss[n]; + } + + int month_number_from_name(string name) + { + int j=(month_s2n[lower_case(name)]); + if (!j) error("no such month of year: %O\n",name); + return j; + } + + string week_day_name_from_number(int n) + { + return week_day_n2s[n]; + } + + string week_day_shortname_from_number(int n) + { + return week_day_n2ss[n]; + } + + int week_day_number_from_name(string name) + { + int j=(week_day_s2n[lower_case(name)]); + if (!j) error("no such day of week: %O\n",name); + return j; + } + + string week_name_from_number(int n) + { + return sprintf("w%d",n); + } + + int week_number_from_name(string s) + { + int w; + if (sscanf(s,"w%d",w)) return w; + if (sscanf(s,"%d",w)) return w; + return 0; + } + + string year_name_from_number(int y) + { + if (y<1) return sprintf("%d BC",1-y); + return (string)y; + } + + int year_number_from_name(string name) + { + int y; + string x; + if (sscanf(name,"%d%s",y,x)==1 || + x=="") + return y>=0?y:y+1; // "-1" == integer year 0 + switch (x) + { + case "AD": case " AD": return y; + case "BC": case " BC": return -y+1; + default: + error("Can't understand year.\n"); + } + } + + string month_day_name_from_number(int d,int mnd) + { + return (string)d; + } + +// gregorian defaults + + string gregorian_week_day_name_from_number(int n) + { + return week_day_n2s[(n+5)%7+1]; + } + + string gregorian_week_day_shortname_from_number(int n) + { + return week_day_n2ss[(n+5)%7+1]; + } + + int gregorian_week_day_number_from_name(string name) + { + int j=(week_day_s2n[lower_case(name)]); + if (!j) error("no such day of week: %O\n",name); + return j%7+1; + } + + string gregorian_year_name_from_number(int y) + { + if (y<1) return sprintf("%d BC",1-y); + return sprintf("%d AD",y); + } + + +// discordian defaults + + string discordian_month_name_from_number(int n) + { + return ({0,"Chaos","Discord","Confusion","Bureaucracy","The Aftermath"})[n]; + } + + string discordian_month_shortname_from_number(int n) + { + return ({0,"Chs","Dsc","Cfn","Bcy","Afm"})[n]; + } + + int discordian_month_number_from_name(string name) + { + return (["chaos":1,"discord":2,"confusion":3, + "bureaucracy":4,"the aftermath":5, + "chs":1,"dsc":2,"cfn":3,"bcy":4,"afm":5]) + [lower_case(name)]; + } + + string discordian_week_day_shortname_from_number(int n) + { + return ({0,"SM","BT","PD","PP","SO","ST"})[n]; + } + + string discordian_week_day_name_from_number(int n) + { + return ({0,"Sweetmorn","Boomtime","Pungenday","Prickle-Prickle", + "Setting Orange","St. Tib's day"})[n]; + } + + int discordian_week_day_number_from_name(string name) + { + return (["sweetmorn":1,"boomtime":2,"pungenday":3,"prickle-prickle":4, + "setting orange":5,"st. tib's day":6, + "prickleprickle":4,"setting":5,"orange":5,"tib":6,"tibs":6, + "sttib":6,"sttibs":6,"saint tib's day":6, + "sm":1,"bt":2,"pd":3,"pp":4,"so":5,"st":6]) + [lower_case(name)]; + } + + string discordian_week_name_from_number(int n) + { + return "w"+n; + } + + string discordian_year_name_from_number(int y) + { + return (string)y; + } + +// coptic defaults + + string coptic_month_name_from_number(int n) + { + return ({0,"Tout","Baba","Hator","Kiahk","Toba", + "Amshir","Baramhat","Baramouda","Pakho", + "Paona","Epep","Mesra","Nasie"})[n]; + } + + string coptic_month_shortname_from_number(int n) + { + return ({0,"Tou","Bab","Hat","Kia","Tob", + "Ams","Bar","Bar","Pak", + "Pao","Epe","Mes","Nas"})[n]; + } + + int coptic_month_number_from_name(string name) + { + return (["tout":1,"baba":2,"hator":3,"kiahk":4,"toba":5, + "amshir":6,"baramhat":7,"baramouda":8,"pakho":9, + "paona":10,"epep":11,"mesra":12,"nasie":13, + "tou":1,"bab":2,"hat":3,"kia":4,"tob":5, + "ams":6,"bar":7,"bar":8,"pak":9, + "pao":10,"epe":11,"mes":12,"nas":13]) + [lower_case(name)]; + } + + string coptic_year_name_from_number(int y) + { + return (string)y; + } + + int x; + +// islamic defaults + + array(string) islamic_months= + ",Muharram,Safar,Rebîu'l-awwal,Rebîul-âchir," + "Djumâda'l-ûla,Djumâda'l-âchira,Redjeb,Shaabân,Ramadân," + "Schawwâl,Dhu'l-káada,Dhu'l-Hiddja"/","; + array(string) islamic_shortmonths= // help! :) + ",Muharram,Safar,Rebîu'l-awwal,Rebîul-âchir," + "Djumâda'l-ûla,Djumâda'l-âchira,Redjeb,Shaabân,Ramadân," + "Schawwâl,Dhu'l-káada,Dhu'l-Hiddja"/","; + mapping islamic_backmonth=0; + array(string) islamic_shortweekdays= + ",aha,ith,thu,arb,kha,dsc,sab"/","; + array(string) islamic_weekdays= + ",ahad,ithnain,thulâthâ,arbiâ,khamîs,dschuma,sabt"/","; + mapping islamic_backweekday=0; + + string islamic_month_name_from_number(int n) + { + return islamic_months[n]; + } + + string islamic_month_shortname_from_number(int n) + { + return islamic_shortmonths[n]; + } + + int islamic_month_number_from_name(string name) + { + if (!islamic_backmonth) + { + islamic_backmonth= + mkmapping(map(islamic_months[1..],flat), + enumerate(12,1,1))| + mkmapping(map(islamic_months[1..],flat), + enumerate(12,1,1))| + (["rabi1":2, + "rabi2":3, + "djumada1":4, + "djumada2":5]); + } + + return islamic_backmonth[`-(flat(name),"-","'"," ")]; + } + + string islamic_week_day_name_from_number(int n) + { + return "jaum el "+islamic_weekdays[n]; + } + + string islamic_week_day_shortname_from_number(int n) + { + return islamic_shortweekdays[n]; + } + + int islamic_week_day_number_from_name(string name) + { + if (!islamic_backweekday) + { + islamic_backweekday= + mkmapping(map(map(islamic_weekdays[1..],flat),`-,"'","-"), + enumerate(7,1,1))| + mkmapping(map(map(islamic_weekdays[1..],flat),`-,"'","-"), + enumerate(7,1,1)); + } + + sscanf(name,"jaum el %s",name); + return islamic_backweekday[`-(flat(name),"-","'")]; + } + + + string islamic_week_name_from_number(int n) + { + return "w"+n; + } + + string islamic_year_name_from_number(int y) + { + if (y<1) return sprintf("%d BH",1-y); + return sprintf("%d AH",y); + } +} + +// ---------------------------------------------------------------- + +// this sets up the mappings from the arrays + +#define SETUPSTUFF \ + month_n2s=mkmapping(enumerate(12,1,1),month_names); \ + month_n2ss= \ + mkmapping(enumerate(12,1,1),map(month_names,predef::`[],0,2)); \ + month_s2n= \ + mkmapping(map(map(month_names,predef::`[],0,2),flat), \ + enumerate(12,1,1)) \ + | mkmapping(map(month_names,flat),enumerate(12,1,1)); \ + week_day_n2s= mkmapping(enumerate(7,1,1),week_day_names); \ + week_day_n2ss= mkmapping(enumerate(7,1,1), \ + map(week_day_names,predef::`[],0,2)); \ + week_day_s2n= \ + mkmapping(map(map(week_day_names,predef::`[],0,2),flat), \ + enumerate(7,1,1)) \ + | mkmapping(map(week_day_names,flat),enumerate(7,1,1)) + +// ---------------------------------------------------------------- +// now the real classes: + +// this should probably be called UK_en or something: + +constant cENGLISH=cISO; +class cISO +{ + inherit _ymd_base; + + constant month_names= + ({"January","February","March","April","May","June","July","August", + "September","October","November","December"}); + + constant week_day_names= + ({"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}); + + void create() + { + SETUPSTUFF; + } + + string week_name_from_number(int n) + { + return sprintf("w%d",n); + } + + int week_number_from_name(string s) + { + int w; + if (sscanf(s,"w%d",w)) return w; + if (sscanf(s,"%d",w)) return w; + return 0; + } + + string year_name_from_number(int y) + { + if (y<1) return sprintf("%d BC",1-y); + return (string)y; + } +}; + +// swedish (note: all name as cLANG where LANG is in caps) + +constant cSE_SV=cSWEDISH; +class cSWEDISH +{ + inherit _ymd_base; + + static private constant month_names= + ({"januari","februari","mars","april","maj","juni","juli","augusti", + "september","oktober","november","december"}); + + static private constant week_day_names= + ({"måndag","tisdag","onsdag","torsdag", + "fredag","lördag","söndag"}); + + static mapping events_translate= + ([ + "New Year's Day": "Nyårsdagen", + "Epiphany": "Trettondag jul", + "King's Nameday": "H K M Konungens namnsdag", + "Candlemas": "Kyndelsmässodagen", + "St. Valentine": "Alla hjärtans dag", + "Int. Women's Day": "Internationella kvinnodagen", + "Crown Princess' Nameday":"H K M Kronprinsessans namnsdag", + "Waffle Day": "Våffeldagen", + "Annunciation": "Marie bebådelsedag", + "Labor Day": "Första maj", + "Sweden's Flag Day": "Svenska flaggans dag", + "St. John the Baptist": "Johannes Döpares dag", + "Crown Princess' Birthday":"H K M Kronprinsessans födelsedag", + "Queen's Nameday": "H K M Drottningens namnsdag", + "UN Day": "FN-dagen", + "All saints Day": "Allhelgonadagen", + "King's Nameday": "H K M Konungens namnsdag", + "King's Birthday": "H K M Konungens födelsedag", + "St. Lucy": "Luciadagen", + "Queen's Birthday": "H K M Drottningens födelsedag", + "Christmas Eve": "Julafton", + "Christmas Day": "Juldagen", + "St. Stephen": "Annandagen", + "New Year's Eve": "Nyårsafton", + "Midsummer's Eve": "Midsommarafton", + "Midsummer's Day": "Midsommardagen", + "All Saints Day": "Allhelgonadagen", + + "Fat Tuesday": "Fettisdagen", + "Palm Sunday": "Palmsöndagen", + "Good Friday": "Långfredagen", + "Easter Eve": "Påskafton", + "Easter": "Påskdagen", + "Easter Monday": "Annandag påsk", + "Ascension": "Kristi himmelsfärd", + "Pentecost Eve": "Pingstafton", + "Pentecost": "Pingst", + "Pentecost Monday": "Annandag pingst", + "Advent 1": "Första advent", + "Advent 2": "Andra advent", + "Advent 3": "Tredje advent", + "Advent 4": "Fjärde advent", + "Mother's Day": "Mors dag", + "Father's Day": "Fars dag", + + "Summer Solstice": "Sommarsolstånd", + "Winter Solstice": "Vintersolstånd", + "Spring Equinox": "Vårdagjämning", + "Autumn Equinox": "Höstdagjämning", + +// not translated: +// "Halloween" +// "Alla helgons dag" +// "Valborgsmässoafton" + ]); + + void create() + { + SETUPSTUFF; + } + + string week_name_from_number(int n) + { + return sprintf("v%d",n); + } + + int week_number_from_name(string s) + { + if (sscanf(s,"v%d",int w)) return w; + return ::week_number_from_name(s); + } + + string year_name_from_number(int y) + { + if (y<1) return sprintf("%d fk",1-y); + return (string)y; + } +} + +// austrian +// Martin Baehr <mbaehr@email.archlab.tuwien.ac.at> + +class cAUSTRIAN +{ + inherit _ymd_base; + + static private constant month_names= + ({"jänner","feber","märz","april","mai","juni","juli","august", + "september","oktober","november","dezember"}); + + static private constant week_day_names= + ({"montag","dienstag","mittwoch","donnerstag", + "freitag","samstag","sonntag"}); + + void create() + { + SETUPSTUFF; + } +} + +// Welsh + +class cWELSH +{ + inherit _ymd_base; + + static private constant month_names= + ({"ionawr","chwefror","mawrth","ebrill","mai","mehefin", + "gorffenaf","awst","medi","hydref","tachwedd","rhagfyr"}); + + static private constant week_day_names= + ({"Llun","Mawrth","Mercher","Iau","Gwener","Sadwrn","Sul"}); + + string week_day_name_from_number(int n) + { + return "dydd "+::week_day_name_from_number(n); + } + + int week_day_number_from_name(string name) + { + sscanf(name,"dydd %s",name); + return week_day_number_from_name(name); + } + + void create() + { + SETUPSTUFF; + } +} + +// Spanish +// Julio César Gázquez <jgazquez@dld.net> + +class cSPANISH +{ + inherit _ymd_base; + + static private constant month_names= + ({"enero","febrero","marzo","abril","mayo","junio", + "julio","agosto","setiembre","octubre","noviembre","diciembre"}); + + static private constant week_day_names= + ({"lunes","martes","miércoles","jueves", + "viernes","sábado","domingo"}); + +// contains argentina for now + static mapping events_translate= + ([ + "Epiphany":"Día de Reyes", // Epifania + "Malvinas Day":"Día de las Malvinas", + "Labor Day":"Aniversario de la Revolución", + "Soberany's Day":"Día de la soberania", + "Flag's Day":"Día de la bandera", + "Independence Day":"Día de la independencia", + "Assumption Day":"Día de la asunción", // ? + "Gral San Martín decease": + "Aniversario del fallecimiento del Gral. San Martin", + "Race's Day":"Día de la Raza", + "All Saints Day":"Día de todos los santos", + "Immaculate Conception":"Inmaculada Concepción", + "Christmas Day":"Natividad del Señor", + "New Year's Day":"Año Nuevo", + "Holy Thursday":"Jueves Santo", + "Good Friday":"Viernes Santo", + "Holy Saturday":"Sãbado de gloria", + "Easter":"Domingo de resurrección", + "Corpus Christi":"Corpus Christi" + ]); + + void create() + { + SETUPSTUFF; + } +} + +// Hungarian +// Csongor Fagyal <concept@conceptonline.hu> + +class cHUNGARIAN +{ + inherit _ymd_base; + + static private constant month_names= + ({"Január","Február","Március","Április","Május","Június", + "Július","August","September","October","November","December"}); + + static private constant week_day_names= + ({"Hétfo","Kedd","Szerda","Csütörtkök","Péntek","Szombat","Vasárnap"}); + +// contains argentina for now + static mapping events_translate= + ([ + "New Year's Day":"Úb év ünnepe", + "1848 Revolution Day":"Az 'Az 1848-as Forradalom Napja", + "Holiday of Labor":"A munka ünnepe", + "Constitution Day":"Az alkotmány ünnepe", + "'56 Revolution Day":"Az '56-os Forradalom ünnepe", + "Easter":"Húsvét", + "Easter monday":"Húsvét", + "Whitsunday":"Pünkösd", + "Whitmonday":"Pünkösd", + "Christmas":"Christmas", + ]); + + void create() + { + SETUPSTUFF; + } +} + +// Modern Latin + +class cLATIN +{ + inherit _ymd_base; + + static array(string) month_names= + ({"Ianuarius", "Februarius", "Martius", "Aprilis", "Maius", "Iunius", + "Iulius", "Augustus", "September", "October", "November", "December" }); + + static private constant week_day_names= + ({"lunae","Martis","Mercurii","Jovis","Veneris","Saturni","solis"}); + + string week_day_name_from_number(int n) + { + return ::week_day_name_from_number(n)+" dies"; + } + + int week_day_number_from_name(string name) + { + sscanf(name,"%s dies",name); + return week_day_number_from_name(name); + } + + string gregorian_year_name_from_number(int y) + { + return year_name_from_number(y); + } + + string year_name_from_number(int y) + { + if (y<1) return sprintf("%d BC",1-y); // ? + return sprintf("anno ab Incarnatione Domini %s",roman_number(y)); + } + + void create() + { + SETUPSTUFF; + } +} + +// Roman latin + +class cROMAN +{ + inherit cLATIN; + + static array(string) month_names= + ({"Ianuarius", "Februarius", "Martius", "Aprilis", "Maius", "Iunius", + "Quintilis", // Iulius + "Sextilis", // Augustus + "September", "October", "November", "December" + }); + + string year_name_from_number(int y) + { + return sprintf("%s ab urbe condita",roman_number(y+752)); + } + + string month_day_name_from_number(int d,int mnd) + { +// this is not really correct, I've seen but +// i can't find it - they did something like 4 from the start of the +// months, 19 from the end of the month. + return roman_number(d); + } +} + + + + +// ---------------------------------------------------------------- + +// find & compile language + +static mapping _cache=([]); + +Ruleset.Language `[](string lang) +{ + lang=upper_case(lang); + Ruleset.Language l=_cache[lang]; + if (l) return l; + program cl=::`[]("c"+lang); + + if (!cl) { return ([])[0]; } + + l=_cache[lang]=cl(); + + return l; +} diff --git a/lib/modules/Calendar.pmod/Namedays.pmod b/lib/modules/Calendar.pmod/Namedays.pmod new file mode 100644 index 0000000000000000000000000000000000000000..42be2a93469709ae294e40d045f0b3e3d9212dce --- /dev/null +++ b/lib/modules/Calendar.pmod/Namedays.pmod @@ -0,0 +1,745 @@ +import "."; +inherit Event; + +// ---------------------------------------------------------------- +// special nameday objects +// ---------------------------------------------------------------- + +class Sweden +{ + inherit Namedays; + + mapping lookup_pre1986=0; + mapping lookup_1986=0; + mapping lookup_1993=0; + + void create() + { + name="Sweden"; + } + + static array(string) namedays_year(int y) + { + if (y<1986) return swedish_namedays_pre1986; + if (y<1993) return swedish_namedays_1986; + return swedish_namedays_1993; + } + + static int nameday_lookup(int y,string s) + { + if (y<1986) + return (lookup_pre1986|| + (lookup_pre1986=make_lookup(swedish_namedays_pre1986))) + [lower_case(s)]; + if (y<1993) + return (lookup_1986|| + (lookup_1986=make_lookup(swedish_namedays_1986))) + [lower_case(s)]; + return (lookup_1993|| + (lookup_1993=make_lookup(swedish_namedays_1993))) + [lower_case(s)]; + } + + constant swedish_namedays_pre1986= + ({ 0, "Svea", "Alfred", "Rut", "Hanna", 0 /* trettondag */, + "August", "Erland", "Gunnar", "Sigurd", "Hugo", "Frideborg", + "Knut", "Felix", "Laura", "Hjalmar", "Anton", "Hilda", "Henrik", + "Fabian", "Agnes", "Vincent", "Emilia", "Erika", "Paulus", + "Botolda", "Göte", "Karl", "Valter", "Gunhild", "Ivar", "Max", + 0/*kyndels*/, "Disa", "Ansgar", "Agata", "Dorotea", "Rikard", + "Berta", "Fanny", "Eugenia", "Yngve", "Evelina", "Agne", + "Valentin", "Sigfrid", "Julia", "Alexandra", "Frida", + "Gabriella", "Hulda", "Hilding", "Martina", "Torsten", + "Mattias", "Sigvard", "Torgny", "Lage", "Maria", "Albin", + "Ernst", "Gunborg", "Adrian", "Tora", "Ebba", "Ottilia", + "Filippa", "Torbjörn", "Edla", "Edvin", "Viktoria", "Greger", + "Matilda", "Kristofer", "Herbert", "Gertrud", "Edvard", "Josef", + "Joakim", "Bengt", "Viktor", "Gerda", "Gabriel", "Mary", + "Emanuel", "Rudolf", "Malkolm", "Jonas", "Holger", "Ester", + "Harald", "Gudmund", "Ferdinand", "Ambrosius", "Nanna", + "Vilhelm", "Ingemund", "Hemming", "Otto", "Ingvar", "Ulf", + "Julius", "Artur", "Tiburtius", "Olivia", "Patrik", "Elias", + "Valdemar", "Olavus Petri", "Amalia", "Anselm", "Albertina", + "Georg", "Vega", "Markus", "Teresia", "Engelbrekt", "Ture", + "Tyko", "Mariana", "Valborg", "Filip", "Göta", "Monika", + "Gotthard", "Sigmund", "Gustava", "Åke", "Jonathan", "Esbjörn", + "Märta", "Charlotta", "Linnea", "Halvard", "Sofia", "Hilma", + "Rebecka", "Erik", "Alrik", "Karolina", "Konstantin", "Henning", + "Desideria", "Ragnvald", "Urban", "Vilhelmina", "Blenda", + "Ingeborg", "Baltsar", "Fritjof", "Isabella", "Nikodemus", + "Rutger", "Ingemar", "Holmfrid", "Bo", "Gustav", "Robert", + "Salomon", "Börje", "Svante", "Bertil", "Eskil", "Aina", + "Håkan", "Justina", "Axel", "Torborg", "Björn", "Germund", + "Flora", "Alf", "Paulina", "Adolf", "Johan", "David", "Rakel", + "Selma", "Leo", "Petrus", "Elof", "Aron", "Rosa", "Aurora", + "Ulrika", "Melker", "Esaias", "Klas", "Kjell", "Götilda", + "Anund", "Eleonora", "Herman", "Joel", "Folke", "Ragnhild", + "Reinhold", "Alexis", "Fredrik", "Sara", "Margareta", "Johanna", + "Magdalena", "Emma", "Kristina", "Jakob", "Jesper", "Marta", + "Botvid", "Olof", "Algot", "Elin", "Per", "Karin", "Tage", + "Arne", "Ulrik", "Sixten", "Arnold", "Sylvia", "Roland", "Lars", + "Susanna", "Klara", "Hillevi", "Ebbe", "Stella", "Brynolf", + "Verner", "Helena", "Magnus", "Bernhard", "Josefina", + "Henrietta", "Signe", "Bartolomeus", "Lovisa", "Östen", "Rolf", + "Augustin", "Hans", "Albert", "Arvid", "Samuel", "Justus", + "Alfhild", "Moses", "Adela", "Sakarias", "Regina", "Alma", + "Augusta", "Tord", "Dagny", "Tyra", "Ambjörn", "Ida", "Sigrid", + "Eufemia", "Hildegard", "Alvar", "Fredrika", "Agda", "Matteus", + "Maurits", "Tekla", "Gerhard", "Signhild", "Enar", "Dagmar", + "Lennart", "Mikael", "Helge", "r", "Ludvig", "Evald", "Frans", + "Bror", "Jenny", "Birgitta", "Nils", "Ingrid", "Helmer", + "Erling", "Valfrid", "Teofil", "Manfred", "Hedvig", "Fingal", + "Antonietta", "Lukas", "Tore", "Sibylla", "Birger", "Seved", + "Sören", "Evert", "Inga", "Amanda", "Sabina", "Simon", "Viola", + "Elsa", "Edit", 0 /* allhelgona */, "Tobias", "Hubert", + "Sverker", "Eugen", "Gustav Adolf", "Ingegerd", "Vendela", + "Teodor", "Martin Luther", "Mårten", "Konrad", "Kristian", + "Emil", "Leopold", "Edmund", "Napoleon", "Magnhild", "Elisabet", + "Pontus", "Helga", "Cecilia", "Klemens", "Gudrun", "Katarina", + "Torkel", "Astrid", "Malte", "Sune", "Anders", "Oskar", "Beata", + "Lydia", "Barbro", "Sven", "Nikolaus", "Agaton", "Virginia", + "Anna", "Malin", "Daniel", "Alexander", "Lucia", "Sten", + "Gottfrid", "Assar", "Inge", "Abraham", "Isak", "Israel", + "Tomas", "Natanael", "Adam", "Eva", "Stefan", "Johannes", + "Abel", "Set", "Sylvester",0}); + + constant swedish_namedays_1986= + ({ 0, "Svea,Bore,Sverre", + "Alfred,Alfrida,Annefrid", "Rut,Ritva,Roger", + "Hanna,Hannele,Hanny", 0 /* trettondag */, "August,Öjar,Örjan", + "Erland,Erhard,Erla", "Gunnar,Gun,Gunno", "Sigurd,Sigrun,Sigyn", + "Hugo,Hagar", "Frideborg,Fridolf,Fridolin", "Knut,Kent,Kennet", + "Felix,Felicia,Fritz", "Laura,Lauritz,Lotten", + "Hjalmar,Herdis,Hjördis", "Anton,Anja,Antonia", + "Hilda,Hildor,Hildur", "Henrik,Henrika,Henry", "Fabian,Lina,Linus", + "Agnes,Agnar,Agneta", "Vincent,Vanja,Veine", + "Emilia,Emilie,Mildred", "Erika,Jarl,Jarla", "Paulus,Paul,Paula", + "Botolda,Tilda,Tilly", "Göte,Götar,Jöns", "Karl,Kally,Karla", + "Valter,Valerie,Volter", "Gunhild,Gunilla,Gunnel", "Ivar,Iva,Ivan", + "Max,Marielle,Marietta", 0/*kyndels*/, "Disa,Dick,Didrik", + "Ansgar,Anneli,Ansa", "Agata,Aili,Aivi", "Dorotea,Dora,Doris", + "Rikard,Ricky,Rigmor", "Berta,Bert,Bertram", "Fanny,Sanny,Sonny", + "Eugenia,Egon,Eira", "Yngve,Yvette,Yvonne", + "Evelina,Elaine,Evelyn", "Agne,Alin,Alina", + "Valentin,Valentina,Vally", "Sigfrid,Sigbert,Sigbritt", + "Julia,Juliana,Juliette", "Alexandra,Sandor,Sandra", + "Frida,Fride,Frode", "Gabriella,Ella,Elna", "Hulda,Haldis,Haldo", + "Hilding,Hildeborg,Hildemar", "Martina,Tim,Tina", + "Torsten,Toivo,Torun", "Mattias,Matti,Mats", + "Sigvard,Sigvald,Sigvor", "Torgny,Torvald", "Lage,Laila,Lave", + "Maria,Marie,Mary", "Albin,Alba,Alban", "Ernst,Erna,Ernfrid", + "Gunborg,Gunbritt,Gunvald", "Adrian,Adrienne,Astor", + "Tora,Toini,Tor", "Ebba,Ebon,Evonne", "Ottilia,Petra,Petronella", + "Filippa,Gunlög,Åslög", "Torbjörn,Torben,Torgun", + "Edla,Edling,Ethel", "Edvin,Diana,Edna", "Viktoria,Vibeke,Viking", + "Greger,Grels,Greta", "Matilda,Maud,Moa", + "Kristofer,Christel,Christer", "Herbert,Herta,Hervor", + "Gertrud,Gertie,Gölin", "Edvard,Eda,Eddie", "Josef,James,Janet", + "Joakim,Jockum,Kim", "Bengt,Bengta,Benita", "Viktor,Vimar,Våge", + "Gerda,Anngerd,Gerd", "Gabriel,Gabrielle,Gunni", "Mary,Marion", + "Emanuel,Emanuella,Immanuel", "Rudolf,Rode,Rudi", + "Malkolm,Elma,Elmer", "Jonas,Jon,Jonna", "Holger,Olga", + "Ester,Estrid,Vasti", "Harald,Hadar,Hardy", + "Gudmund,Gudmar,Gunder", "Ferdinand,Gunvi,Gunvor", + "Ambrosius,Irene,Irina", "Nanna,Nancy,Nanny", + "Vilhelm,William,Willy", "Ingemund,Ingemo,Irma", + "Hemming,Heimer,Helmut", "Otto,Orvar,Ottar", + "Ingvar,Ingvald,Ingvor", "Ulf,Ylva,Yrsa", "Julius,Gillis", + "Artur,Aldor,Atle", "Tiburtius,Ellen,Elly", "Olivia,Oliver,Ove", + "Patrik,Patricia,Percy", "Elias,Elis,Elise", + "Valdemar,Valdis,Volmar", "Olavus Petri,Olaus Petri", + "Amalia,Amelie,Amy", "Anselm,Annevi,Annvor", + "Albertina,Alida,Allan", "Georg,Georgina,Jörgen", + "Vega,Viggo,Viveka", "Markus,Marika,Mark", "Teresia,Terese,Tessy", + "Engelbrekt,Engelbert,Enok", "Ture,Turid,Tuve", + "Tyko,Toralf,Torulf", "Mariana,Marianne,Marina", + "Valborg,Maj,Maja", "Filip,Åsa,Åse", "Göta,Görel,Götmar", + "Monika,Majne,Mona", "Gotthard,Gotthild,Gotty", "Sigmund,Sigge", + "Gustava,Gullvi,Gullbritt", "Åke,Åge,Ågot", "Jonathan,John,Johnny", + "Esbjörn,Elvy,Essy", "Märta,Meta,Märit", + "Charlotta,Charlotte,Lotta", "Linnea,Linn,Lis", + "Halvard,Hallvor,Halvar", "Sofia,Sia,Sofie", "Hilma,Helvi,Hilmer", + "Rebecka,Renee,Rosita", "Erik,Erk,Jerker", "Alrik,Alda,Altea", + "Karolina,Carola,Caroline", "Konstantin,Conny,Konstatia", + "Henning,Henny,Pål", "Desideria,Dennis,Desiree", + "Ragnvald,Ragnvi,Ragnvor", "Urban,Una,Uno", + "Vilhelmina,Vilma,Vilmar", "Blenda,Beda,Britten", + "Ingeborg,Ingabritt,Ingbritt", "Baltsar,Bill,Billy", + "Fritjof,Majny,Majvi", "Isabella,Iris,Isa", "Nikodemus,Nina,Ninni", + "Rutger,Runa,Rune", "Ingemar,Ingar,Ingmarie", + "Holmfrid,Helfrid,Helfrida", "Bo,Bodil,Boel", + "Gustav,Gusten,Gösta", "Robert,Robin,Ruben", "Salomon,Sally", + "Börje,Belinda,Björg", "Svante,Sante,Sjunne", + "Bertil,Berit,Berthold", "Eskil,Eje,Evan", "Aina,Aino,Roine", + "Håkan,Hakon,Hakvin", "Justina,Jim,Jimmy", "Axel,Axelia,Axelina", + "Torborg,Torhild,Toril", "Björn,Bjarne,Björne", + "Germund,Jerry,Jill", "Flora,Florence,Florentin", + "Alf,Alvin,Alvina", "Paulina,Pamela,Paulette", + "Adolf,Adolfina,Ally", "Johan,Jan", "David,Davida,Daisy", + "Rakel,Rafael,Ralf", "Selma,Selim,Selmer", "Leo,Lola,Liselott", + "Petrus,Peter,Petter", "Elof,Elvira,Viran", "Aron,Arent,Arild", + "Rosa,Rose,Rosemarie", "Aurora,Andre,Aurelia", + "Ulrika,Ellika,Ulla", "Melker,Marja,Mirjam", "Esaias,Elisiv,Esse", + "Klas,Claudia,Klaus", "Kjell,Kajsa,Kettil", "Götilda,Göran,Jörn", + "Anund,Anita,Ante", "Eleonora,Eleonor,Ellinor", + "Herman,Hanne,Hermine", "Joel,Joar,Jorunn", "Folke,Fale,Fylgia", + "Ragnhild,Ragni,Runo", "Reinhold,Reine,Reino", "Alexis,Alex,Alice", + "Fredrik,Fred,Freddy", "Sara,Charles,Saga", + "Margareta,Margit,Margret", "Johanna,Jean,Jeanette", + "Magdalena,Magda,Madeleine", "Emma,Elena,Emmy", + "Kristina,Kerstin,Kristin", "Jakob,Jack", "Jesper,Jessika,Jessie", + "Marta,Marit,Marita", "Botvid,Reidar,Reidun", "Olof,Ola,Olle", + "Algot,Margot,Vilgot", "Elin,Elon,Elina", "Per,Peder,Pernilla", + "Karin,Karen,Kåre", "Tage,Tanja,Truls", "Arne,Arna,Arnevi", + "Ulrik,Unn,Unni", "Sixten,Säve,Sölve", "Arnold,Annika,Annmari", + "Sylvia,Silja,Silvia", "Roland,Ronald,Ronny", "Lars,Lasse,Lorentz", + "Susanna,Sanna,Susanne", "Klara,Clarence,Clary", + "Hillevi,Hilja,Irja", "Ebbe,Eberhard,Efraim", + "Stella,Estelle,Stellan", "Brynolf,Benjamin,Benny", + "Verner,Verna,Veronika", "Helena,Helen,Helny", + "Magnus,Mogens,Måns", "Bernhard,Berna,Bernt", "Josefina,Josefin", + "Henrietta,Harriet,Harry", "Signe,Signar,Signy", + "Bartolomeus,Carita,Rita", "Lovisa,Louis,Louise", + "Östen,Ejvind,Öjvind", "Rolf,Raoul,Rasmus", "Augustin,Gusti,Gurli", + "Hans,Hampus,Hasse", "Albert,Albrekt,Aste", "Arvid,Arvida,Vidar", + "Samuel,Sam,Solveig", "Justus,Jane,Judit", "Alfhild,Alfons,Arja", + "Moses,Molly,My", "Adela,Adele,Adin", "Sakarias,Siv,Sivert", + "Regina,Gilbert,Gisela", "Alma,Adils,Almar", "Augusta,Gunda,Gunde", + "Tord,Tordis,Torgil", "Dagny,Dag,Daga", "Tyra,Tyr", + "Ambjörn,Stig,Styrbjörn", "Ida,Idar,Vida", "Sigrid,Siri,Solbritt", + "Eufemia,Cornelia,Cornelius", "Hildegard,Hilbert,Hildebrand", + "Alvar,Alva,Alve", "Fredrika,Frej,Freja", "Agda,Jan,Jannika", + "Matteus,Majbritt,Majlis", "Maurits,Marlene,Moritz", + "Tekla,Trond,Tryggve", "Gerhard,Gert,Glenn", + "Signhild,Sanfrid,Signhild", "Enar,Einar,Eja", + "Dagmar,Donald,Douglas", "Lennart,Lena,Leonard", + "Mikael,Majken,Mikaela", "Helge,Heidi,Härje", "r,Ragna,Ragne", + "Ludvig,Levi,Liv", "Evald,Eila,Eilert", "Frans,Franciska,Frank", + "Bror,Brage,Bruno", "Jenny,Jennifer,Jens", "Birgitta,Birgit,Britt", + "Nils,Nilla,Nelly", "Ingrid,Inger,Ingolf", "Helmer,Helmina,Helmy", + "Erling,Elvin,Elvina", "Valfrid,Ina,Inez", "Teofil,Terje,tjelvar", + "Manfred,Mandor,Manne", "Hedvig,Hartvig,Hedda", + "Fingal,Finn,Flemming", "Antonietta,Anette,Tony", + "Lukas,Lillemor,Lilly", "Tore,Bojan Borghild", + "Sibylla,Camilla,Kasper", "Birger,Brita,Britta", + "Seved,Sigvid,Ursula", "Sören,Severin", "Evert,Eivor,Elving", + "Inga,Ingalill,Ingert", "Amanda,Manda,Mandy", + "Sabina,Sebastian,Sussy", "Simon,Simeon,Simone", + "Viola,Vivi,Vivianne", "Elsa,Elsie,Ilse", "Edit,Edgar,Edor", + 0/*allhelgona */, "Tobias,Tova,Tove", "Hubert,Raymond,Roy", + "Sverker,Nora,Nore", "Eugen,Ebert,Egil", "Gustav Adolf,Gull,Gulli", + "Ingegerd,Ingel,Ingela", "Vendela,Vanda,Ville", "Teodor,Tea,Ted", + "Martin Luther,Mait,Martin", "Mårten,Marion,Morgan", + "Konrad,Kuno,Kurt", "Kristian,Karsten,Kersti", "Emil,Milly,Mimmi", + "Leopold,Leif,Lilian", "Edmund,Elida,Elisa", + "Napoleon,Naemi,Naima", "Magnhild,Magna,Magne", + "Elisabet,Lisa,Lisbeth", "Pontus,Polly,Povel", "Helga,Helle,Hilde", + "Cecilia,Cilla,Cissi", "Klemens,Ketty,Kitty", + "Gudrun,Gullan,Gullvor", "Katarina,Carina,Katrin", + "Torkel,Torleif", "Astrid,Asta,Astri", "Malte,Malvina,Mia", + "Sune,Sonja,Synnöve", "Anders,Andrea,Andreas", "Oskar,Ole,Ossian", + "Beata,Beatrice,Betty", "Lydia,Linda,Love", "Barbro,Barbara,Boris", + "Sven,Svend,Svenning", "Nikolaus,Niklas,nikolina", + "Agaton,Angela,Angelika", "Virginia,Vera,Vesta", "Anna,Ann,Annie", + "Malin,Majvor,Malena", "Daniel,Dan,Daniela", + "Alexander,Pia,Pierre", "Lucia,Lisen,Lisette", "Sten,Stina,Sture", + "Gottfrid,Kaj,Kajsa", "Assar,Odd,Osvald", "Inge,Ilona,Irmeli", + "Abraham,Abdon,Gideon", "Isak,Isidor,Isidora", "Israel,Gina,Gitte", + "Tomas,Tom,Tommy", "Natanael,Natalia,Natan", "Adam,Ada,Adina", + "Eva,Evita,Evy", "Stefan,Staffan,Stefanie", + "Johannes,Hannes,Johan", "Abel,Abbe", "Set,Viva,Vivari", + "Sylvester,Sylve,Sylvi",0}); + + constant swedish_namedays_1993= + ({ 0, "Svea,Sverker", + "Alfred,Alfrida", "Rut,Ritva", "Hanna,Hannele", "Baltsar,Kasper", + "August,Augusta", "Erland,Erhard", "Gunnar,Gunder", + "Sigurd,Sigmund", "Hugo,Hagar", "Frideborg,Fridolf", "Knut", + "Felix,Felicia", "Laura,Liv", "Hjalmar,Hervor", "Anton,Tony", + "Hilda,Hildur", "Henrik,Henry", "Fabian,Sebastian", "Agnes,Agneta", + "Vincent,Veine", "Emilia,Emilie", "Erika,Eira", "Paul,Pål", + "Bodil,Boel", "Göte,Göta", "Karl,Karla", "Valter,Vilma", + "Gunhild,Gunilla", "Ivar,Joar", "Max,Magda", "Marja,Mia", + "Disa,Hjördis", "Ansgar,Anselm", "Lisa,Elise", "Dorotea,Dora", + "Rikard,Dick", "Berta,Berthold", "Fanny,Betty", "Egon,Egil", + "Yngve,Ingolf", "Evelina,Evy", "Agne,Agnar", "Valentin,Tina", + "Sigfrid,Sigbritt", "Julia,Jill", "Alexandra,Sandra", + "Frida,Fritz", "Gabriella,Ella", "Rasmus,Ruben", "Hilding,Hulda", + "Marina,Marlene", "Torsten,Torun", "Mattias,Mats", + "Sigvard,Sivert", "Torgny,Torkel", "Lage,Laila", "Maria,Maja", + "Albin,Inez", "Ernst,Erna", "Gunborg,Gunvor", "Adrian,Ada", + "Tora,Tor", "Ebba,Ebbe", "Isidor,Doris", "Siv,Saga", + "Torbjörn,Ambjörn", "Edla,Ethel", "Edvin,Elon", "Viktoria,Viktor", + "Greger,Iris", "Matilda,Maud", "Kristofer,Christel", + "Herbert,Gilbert", "Gertrud,Görel", "Edvard,Eddie", + "Josef,Josefina", "Joakim,Kim", "Bengt,Benny", "Viking,Vilgot", + "Gerda,Gert", "Gabriel,Rafael", "Mary,Marion", "Emanuel,Manne", + "Ralf,Raymond", "Elma,Elmer", "Jonas,Jens", "Holger,Reidar", + "Ester,Estrid", "Harald,Halvar", "Gunnel,Gun", + "Ferdinand,Florence", "Irene,Irja", "Nanna,Nanny", "Vilhelm,Willy", + "Irma,Mimmi", "Vanja,Ronja", "Otto,Ottilia", "Ingvar,Ingvor", + "Ulf,Ylva", "Julius,Gillis", "Artur,Douglas", "Tiburtius,Tim", + "Olivia,Oliver", "Patrik,Patricia", "Elias,Elis", + "Valdemar,Volmar", "Olaus,Ola", "Amalia,Amelie", "Annika,Anneli", + "Allan,Alida", "Georg,Göran", "Vega,Viveka", "Markus,Mark", + "Teresia,Terese", "Engelbrekt,Enok", "Ture,Tyko", "Kennet,Kent", + "Mariana,Marianne", "Valborg,Maj", "Filip,Filippa", "John,Jack", + "Monika,Mona", "Vivianne,Vivan", "Marit,Rita", "Lilian,Lilly", + "Åke,Ove", "Jonatan,Gideon", "Elvira,Elvy", "Märta,Märit", + "Charlotta,Lotta", "Linnea,Nina", "Lillemor,Lill", "Sofia,Sonja", + "Hilma,Hilmer", "Nore,Nora", "Erik,Jerker", "Majken,Majvor", + "Karolina,Lina", "Konstantin,Conny", "Henning,Hemming", + "Desiree,Renee", "Ivan,Yvonne", "Urban,Ursula", "Vilhelmina,Helmy", + "Blenda,Beda", "Ingeborg,Borghild", "Jean,Jeanette", + "Fritiof,Frej", "Isabella,Isa", "Rune,Runa", "Rutger,Roger", + "Ingemar,Gudmar", "Solveig,Solbritt", "Bo,Boris", "Gustav,Gösta", + "Robert,Robin", "Eivor,Elaine", "Petra,Petronella", + "Kerstin,Karsten", "Bertil,Berit", "Eskil,Esbjörn", "Aina,Eila", + "Håkan,Heidi", "Margit,Mait", "Axel,Axelina", "Torborg,Torvald", + "Björn,Bjarne", "Germund,Jerry", "Linda,Linn", "Alf,Alva", + "Paulina,Paula", "Adolf,Adela", "Johan,Jan", "David,Salomon", + "Gunni,Jim", "Selma,Herta", "Leo,Leopold", "Petrus,Peter", + "Elof,Leif", "Aron,Mirjam", "Rosa,Rosita", "Aurora,Adina", + "Ulrika,Ulla", "Melker,Agaton", "Ronald,Ronny", "Klas,Kaj", + "Kjell,Tjelvar", "Jörgen,Örjan", "Anund,Gunda", "Eleonora,Ellinor", + "Herman,Hermine", "Joel,Judit", "Folke,Odd", "Ragnhild,Ragnvald", + "Reinhold,Reine", "Alexis,Alice", "Fredrik,Fred", "Sara,Sally", + "Margareta,Greta", "Johanna,Jane", "Magdalena,Madeleine", + "Emma,Emmy", "Kristina,Stina", "Jakob,James", "Jesper,Jessika", + "Marta,Moa", "Botvid,Seved", "Olof,Olle", "Algot,Margot", + "Elin,Elna", "Per,Pernilla", "Karin,Kajsa", "Tage,Tanja", + "Arne,Arnold", "Ulrik,Alrik", "Sixten,Sölve", "Dennis,Donald", + "Silvia,Sylvia", "Roland,Roine", "Lars,Lorentz", "Susanna,Sanna", + "Klara,Clary", "Hillevi,Gullvi", "William,Bill", "Stella,Stellan", + "Brynolf,Sigyn", "Verner,Veronika", "Helena,Lena", "Magnus,Måns", + "Bernhard,Bernt", "Jon,Jonna", "Henrietta,Henny", "Signe,Signhild", + "Bartolomeus,Bert", "Lovisa,Louise", "Östen,Ejvind", "Rolf,Rudolf", + "Gurli,Gull", "Hans,Hampus", "Albert,Albertina", "Arvid,Vidar", + "Samuel,Sam", "Justus,Justina", "Alfhild,Alfons", "Gisela,Glenn", + "Harry,Harriet", "Sakarias,Esaias", "Regina,Roy", "Alma,Ally", + "Anita,Anja", "Tord,Tove", "Dagny,Daniela", "Tyra,Åsa", + "Sture,Styrbjörn", "Ida,Ellida", "Sigrid,Siri", "Dag,Daga", + "Hildegard,Magnhild", "Alvar,Orvar", "Fredrika,Carita", + "Agda,Agata", "Ellen,Elly", "Maurits,Morgan", "Tekla,Tea", + "Gerhard,Gert", "Kåre,Tryggve", "Einar,Enar", "Dagmar,Rigmor", + "Lennart,Leonard", "Mikael,Mikaela", "Helge,Helny", "Ragnar,Ragna", + "Ludvig,Louis", "Evald,Osvald", "Frans,Frank", "Bror,Bruno", + "Jenny,Jennifer", "Birgitta,Britta", "Nils,Nelly", "Ingrid,Inger", + "Helmer,Hadar", "Erling,Jarl", "Valfrid,Ernfrid", "Birgit,Britt", + "Manfred,Helfrid", "Hedvig,Hedda", "Fingal,Finn", + "Antonia,Annette", "Lukas,Matteus", "Tore,Torleif", + "Sibylla,Camilla", "Birger,Börje", "Marika,Marita", + "Sören,Severin", "Evert,Eilert", "Inga,Ingvald", "Amanda,My", + "Sabina,Ina", "Simon,Simone", "Viola,Vivi", "Elsa,Elsie", + "Edit,Edgar", "Andre,Andrea", "Tobias,Toini", "Hubert,Diana", + "Uno,Unn", "Eugen,Eugenia", "Gustav Adolf", "Ingegerd,Ingela", + "Vendela,Vanda", "Teodor,Ted", "Martin,Martina", "Mårten", + "Konrad,Kurt", "Kristian,Krister", "Emil,Mildred", "Katja,Nadja", + "Edmund,Gudmund", "Naemi,Nancy", "Pierre,Percy", + "Elisabet,Lisbeth", "Pontus,Pia", "Helga,Olga", "Cecilia,Cornelia", + "Klemens,Clarence", "Gudrun,Runar", "Katarina,Carina", + "Linus,Love", "Astrid,Asta", "Malte,Malkolm", "Sune,Synnöve", + "Anders,Andreas", "Oskar,Ossian", "Beata,Beatrice", "Lydia,Carola", + "Barbro,Barbara", "Sven,Svante", "Nikolaus,Niklas", + "Angelika,Angela", "Virginia,Vera", "Anna,Annie", "Malin,Malena", + "Daniel,Dan", "Alexander,Alex", "Lucia", "Sten,Stig", + "Gottfrid,Gotthard", "Assar,Astor", "Inge,Ingemund", + "Abraham,Efraim", "Isak,Rebecka", "Israel,Moses", "Tomas,Tom", + "Natanael,Natalia", "Adam", "Eva", 0, "Stefan,Staffan", + "Johannes,Hannes", "Abel,Set", "Gunlög,Åslög", "Sylvester", 0}); + +} + +class Hungary +{ + inherit Namedays; + + mapping lookup=0; + + void create() + { + name="Sweden"; + } + + static array(string) namedays_year(int y) + { + return hungarian_namedays; + } + + static int nameday_lookup(int y,string s) + { + return (lookup|| + (lookup=make_lookup(hungarian_namedays))) + [lower_case(s)]; + } + + constant hungarian_namedays= + ({ + "Fruzsina", + "Ábel", + "Genovéna,Benjámin", + "Titusz,Leóna,Angéla", + "Simon,Amata", + "Boldizsár", + "Attila,Ramóna", + "Gyöngyvér", + "Marcell", + "Melánia", + "Ágota", + "Ernõ", + "Veronika", + "Bódog", + "Lóránt,Lóránd", + "Gusztáv", + "Antal,Antónia", + "Piroska", + "Sára,Márió", + "Fábián,Sebestyén", + "Ágnes", + "Vince,Artúr,Anasztáz", + "Zelma,Rajmund", + "Timót", + "Pál", + "Vanda,Paula", + "Angelika,Angéla", + "Károly,Karola", + "Adél", + "Martina,Gerda", + "Marcella", + "Ignác", + "Karolina,Aida", + "Balázs", + "Ráhel,Csenge,András", + "Ágota,Ingrid", + "Dorottya,Dóra,Ajándék,Amanda", + "Tódor,Rómeó", + "Aranka", + "Abigél,Alex", + "Elvira", + "Bertold,Marietta,Adolf", + "Lívia,Lídia", + "Ella,Linda", + "Bálint,Valentin", + "Kolos,Georgina", + "Julianna,Lilla", + "Donát", + "Bernadett", + "Zsuzsanna", + "Aladár,Álmos,Amata", + "Eleonóra", + "Gerzson", + "Alfréd", + "Mátyás", + "Géza", + "Edina", + "Ákos,Bátor", + "Elemér", + "Albin,Albina", + "Lujza", + "Kornélia", + "Kázmér,Adorján,Adrián,Adrienn", + "Adorján,Adrián,Adrienn", + "Leonora,Inez", + "Tamás", + "Zoltán", + "Franciska,Fanni", + "Ildikó", + "Szilárd,Aladár", + "Gergely", + "Krisztián,Ajtóny", + "Matild", + "Kristóf", + "Henrietta", + "Gertrúd,Patrik", + "Sándor,Ede,Alexandra", + "József,Bánk", + "Klaudia", + "Benedek", + "Beáta,Izolda", + "Emõke", + "Gábor,Karina", + "Irén,Írisz", + "Emánuel", + "Hajnalka", + "Gedeon,Johanna", + "Aguszta", + "Zalán,Amade", + "Árpád,Ajtóny", + "Hugó", + "Áron", + "Buda,Richárd", + "Izidor", + "Vince", + "Vilmos,Bíborka", + "Herman", + "Dénes", + "Erhard", + "Zsolt", + "Leó,Szaniszló", + "Gyula", + "Ida", + "Tibor", + "Anasztázia,Tas", + "Csongor", + "Rudolf", + "Andrea,Ilma,András", + "Emma", + "Tivadar", + "Konrád", + "Csilla,Noémi", + "Béla", + "György", + "Márk", + "Ervin", + "Zita", + "Valéria", + "Péter,Albert,Albertína", + "Katalin,Kitti", + "Fülöp,Jakab,Amarilla", + "Zsigmond", + "Tímea,Irma", + "Mónika,Flórián", + "Györgyi", + "Ivett,Frida", + "Gizella", + "Mihály", + "Gergely", + "Ármin,Pálma", + "Ferenc,Adolf", + "Pongrác", + "Szervác,Imola", + "Bonifác", + "Zsófia,Szonja", + "Mózes,Botond", + "Paszkál", + "Erik,Alexandra", + "Ivó,Milán", + "Bernát,Felícia", + "Konstantin,András", + "Júlia,Rita", + "Dezsõ", + "Eszter,Eliza", + "Orbán", + "Fülöp,Evelin,Amanda", + "Hella", + "Emil,Csanád,Ágoston", + "Magdolna", + "Janka,Zsanett", + "Angéla,Petronella", + "Tünde", + "Kármen,Anita,Anna,Annamária", + "Klotild", + "Bulcsú", + "Fatime", + "Norbert,Cintia", + "Róbert", + "Medárd", + "Félix,Annabella", + "Margit,Gréta", + "Barnabás", + "Villó", + "Antal,Anett,Anna", + "Vazul", + "Jolán,Vid", + "Jusztin", + "Laura,Alida,Adolf,Alina,Alinda", + "Arnold,Levente", + "Gyárfás", + "Rafael", + "Alajos,Leila,Aladár,Aloma", + "Paulina", + "Zoltán", + "Iván", + "Vilmos", + "János,Pál", + "Lászlo", + "Levente,Irén", + "Péter,Pál", + "Pál", + "Tihamér,Annamária", + "Ottó", + "Kornél,Soma,Anatol", + "Ulrik", + "Emese,Sarolta,Antal", + "Csaba", + "Apollonia", + "Ellák", + "Lukrécia", + "Amália,Alma", + "Nóra,Lili", + "Izabella,Dalma", + "Jenõ", + "Örs,Stella", + "Henrik,Roland", + "Valter", + "Endre,Elek,Ajándék,András", + "Frigyes", + "Emília", + "Íllás", + "Dániel,Daniella", + "Magdolna", + "Lenke", + "Kinga,Kincsó", + "Kristóf,Jakab", + "Anna,Anikó,Annamária", + "Olga,Liliana,Ajtóny", + "Szabolcs", + "Márta,Flóra", + "Judit,Xénia", + "Oszkár", + "Boglárka", + "Lehel,Alfonz", + "Hermina", + "Domonkos,Dominika", + "Krisztina,Afrodité", + "Berta,Bettína", + "Ibolya,Afrodité", + "László", + "Emõd", + "Lõrinc", + "Zsuzsanna,Tiborc", + "Klára", + "Ipoly", + "Marcell", + "Mária", + "Ábrahám", + "Jácint,Anasztáz", + "Ilona", + "Huba", + "István", + "Sámuel,Hajna", + "Menyhért,Mirjam", + "Bence", + "Bertalan", + "Lajos,Patrícia", + "Izsó", + "Gáspár", + "Ágoston", + "Beatrix,Erna", + "Rózsa", + "Erika,Bella", + "Egyed,Egon", + "Rebeka,Dorina", + "Hilda", + "Rozália", + "Viktor,Lõrinc,Alpár", + "Zakariás", + "Regina", + "Mária,Adrienn,Adorján,Adrián", + "Ádám,András", + "Nikolett,Hunor", + "Teodóra", + "Mária", + "Kornél,Amata", + "Szeréna,Roxána", + "Enikõ,Melitta", + "Edit", + "Zsófia", + "Diána", + "Vilhelmina", + "Friderika", + "Máté,Mirella", + "Móric", + "Tekla", + "Gellért,Mercédesz", + "Eufrózina,Kende", + "Jusztina", + "Adalbert,Adolf,Albertina", + "Vencel", + "Mihály", + "Jeromos", + "Malvin", + "Petra", + "Helga", + "Ferenc", + "Aurél", + "Brúnó,Renáta", + "Amália", + "Koppány", + "Dénes", + "Gedeon", + "Brigitta", + "Miksa", + "Kálmán,Ede", + "Helén", + "Teréz", + "Gál", + "Hedvig", + "Lukács", + "Nándor", + "Vendel", + "Orsolya", + "Elõd", + "Gyöngyi", + "Salamon", + "Blanka,Bianka", + "Dömötör", + "Szabina", + "Simon,Szimonetta", + "Nárcisz", + "Alfonz", + "Farkas", + "Marianna", + "Achilles", + "Gyõzõ", + "Károly", + "Imre", + "Lénárd", + "Rezsõ", + "Zsombor", + "Tivadar", + "Réka,András", + "Márton", + "Jónás,Renátó,Aba", + "Szilvia", + "Alíz", + "Albert,Lipót", + "Ödön", + "Hortenzia,Gergõ", + "Jenõ", + "Erzsébet", + "Jolán", + "Olivér", + "Cecília", + "Kelemen,Klementína", + "Emma", + "Katalin,Alan", + "Virág", + "Virgil", + "Stefánia", + "Taksony", + "András,Andor", + "Elza", + "Melinda,Vivien", + "Ferenc", + "Borbála,Barbara", + "Vilma", + "Miklós", + "Ambrus", + "Mária", + "Natália", + "Judit", + "Árpád", + "Gabriella", + "Luca,Otília", + "Szilárda", + "Valér", + "Etelka,Aletta,Albina", + "Lázár,Olimpia", + "Auguszta", + "Viola", + "Teofil", + "Tamás", + "Zénó", + "Viktória", + "Ádám,Éva,Ada,Adél", + "Eugénia", + "István", + "János", + "Kamilla", + "Tamás,Tamara", + "Dávid", + "Szilveszter", + 0, + }); +} diff --git a/lib/modules/Calendar.pmod/Roman.pmod b/lib/modules/Calendar.pmod/Roman.pmod new file mode 100644 index 0000000000000000000000000000000000000000..a0c5121b48c16bf1ee48fbe3ac43523a662ccdcd --- /dev/null +++ b/lib/modules/Calendar.pmod/Roman.pmod @@ -0,0 +1,20 @@ +//! +//! module Calendar +//! submodule Roman +//! +//! base for all Roman-kind of calendars +//! ie, one with years, months, weeks and days +//! + +#pragma strict_types + +import "."; +inherit Time:Time; + +class cMinute +{ + inherit Time::cMinute; + void bip() { werror("roman\n"); } + int roman(int x,int y) { return 17; } +} + diff --git a/lib/modules/Calendar.pmod/Ruleset.pike b/lib/modules/Calendar.pmod/Ruleset.pike new file mode 100644 index 0000000000000000000000000000000000000000..8b81169cfca201e04e2d955646d3c0832fb70627 --- /dev/null +++ b/lib/modules/Calendar.pmod/Ruleset.pike @@ -0,0 +1,109 @@ +class Timezone +{ + constant is_timezone=1; + +// seconds to utc, not counting DST + static int offset_to_utc; + +// timezone name + string name; + + static void create(int offset,string _name) + { + offset_to_utc=offset; + name=_name; + } + + // seconds to UTC, counting DST + + array(int) tz_ux(int unixtime) + { + return ({offset_to_utc,name}); + } + + array(int) tz_jd(int julian_day) + { + return ({offset_to_utc,name}); + } + + string _sprintf(int t) { return (t=='O')?"Timezone("+name+")":0; } + + int raw_utc_offset() { return offset_to_utc; } +}; + +Timezone timezone; + +class Language +{ + constant is_language=1; + + string month_name_from_number(int n); + string month_shortname_from_number(int n); + int month_number_from_name(string name); + + string week_day_name_from_number(int n); + string week_day_shortname_from_number(int n); + int week_day_number_from_name(string name); + + string gregoiran_week_day_name_from_number(int n); + string gregorian_week_day_shortname_from_number(int n); + int gregorian_week_day_number_from_name(string name); + + string week_name_from_number(int n); + int week_number_from_name(string s); + string year_name_from_number(int y); +} + +Language language; + +this_program set_timezone(string|Timezone t) +{ + this_program r=clone(); + if (stringp(t)) + { + t=master()->resolv("Calendar")["Timezone"][t]; + if (!t) error("no timezone %O\n",t); + } + + if (!t->is_timezone) + error("Not a timezone: %O\n",t); + r->timezone=t; + return r; +} + +this_program set_language(string|Language lang) +{ + this_program r=clone(); + if (stringp(lang)) + { + lang=master()->resolv("Calendar")["Language"][lang]; + if (!lang) lang=master()->resolv("Calendar")["Language"]["ISO"]; + } + if (!lang->is_language) + error("Not a language: %O\n",lang); + r->language=lang; + return r; +} + +this_program set_rule(Language|Timezone rule) +{ + this_program r=clone(); + if (rule->is_timezone) r->timezone=rule; + if (rule->is_language) r->language=rule; + return r; +} + +this_program clone() +{ + this_program r=object_program(this_object())(); + r->timezone=timezone; + r->language=language; + return r; +} + +int(0..1) `==(this_program other) +{ + return + other->timezone==timezone && + other->language==language; +} diff --git a/lib/modules/Calendar.pmod/Stardate.pmod b/lib/modules/Calendar.pmod/Stardate.pmod index a91e964fca62279d71949e5522cb65a7fa45aa73..d81099120599e7354bbef06cc11204f2e0629662 100644 --- a/lib/modules/Calendar.pmod/Stardate.pmod +++ b/lib/modules/Calendar.pmod/Stardate.pmod @@ -1,106 +1,305 @@ +//! module Calendar //! submodule Stardate -//! time unit: TNGDate +//! This implements TNG stardates. -//! class TNGDate -//! implements ST:TNG stardates -//! can be used as create argument to Day +import "."; -class TNGDate -{ - inherit Calendar._TimeUnit; +inherit TimeRanges; + +static constant TNGSTARPERJULIAN=1000.0/365.2425; +static constant TNGSTARPERSECOND=TNGSTARPERJULIAN/86400; +static constant TNG0JULIAN=2569518.5; +static constant TNG0UNIX=11139552000; + +string calendar_name() { return "Stardate"; } - // 40759.5 2363-10-05 2584405 - // 47391.2 2370-05-23 2586827 +function(mixed...:cTick) Tick=cTick; +class cTick +{ + inherit TimeRange; - // 50893.5 2373-11-23 2588107 + constant is_stardate=1; - // 6631.7 ---------- 2422 - // 10134.0 ---------- 3702 - // 1000.0 ---------- 365.2425 - // 0.0 - - 2569519 -#define TNGSTARPERJULIAN (1000.0/365.2425) + float tick; + float len; -//-- variables ------------------------------------------------------ +//! method void create(mixed ...) +//! method void create(int|float date) +//! method void create() +//! Apart from the standard creation methods +//! (julian day, etc), you can create a stardate +//! from the stardate number. The length +//! of the period will then be zero. +//! +//! You can also omit any arguments to create now. +//! +//! known bugs: +//! Since the precision is limited to the float type +//! of pike you can get non-precise results: +//! +//! <pre> +//! > Calendar.Second(Calendar.Stardate.Day(Calendar.Year())); +//! Result: Second(Fri 31 Dec 1999 23:59:18 CET - Sun 31 Dec 2000 23:59:18 CET) +//! </pre> - float jd; - float tics; - -//-- standard methods ----------------------------------------------- - void create(int|float|object ... day) + void create(mixed ...args) { - float jd; - if (!sizeof(day)) - day=({Calendar.Gregorian.Second()}); - else if (floatp(day[0])) - { - from_stardate(day[0]); - return; - } - if (!intp(day[0])) + switch (sizeof(args)) { - object o=day[0]; - - if (o->julian_day || o->julian_day_f) - jd=(float)(o->julian_day_f||o->julian_day)(); - else // dig - if (o->day) // larger + case 4: + // internal + if (args[0]=="stardate") { - o=o->day(0); - if (o->julian_day_f) - jd=o->julian_day_f(); - else if (o->julian_day) - jd=(float)o->julian_day(); - else - ; // error, like + rules=args[1]; + tick=args[2]; + len=args[3]; + return; } - else // smaller + break; + case 1: + if (intp(args[0]) || floatp(args[0])) { - float z=1.0; - while (sizeof(o->greater())) - { - string name=o->is(); - o=o[o->greater()[0]](); - z*=o["number_of_"+name+"s"](); - if (o->julian_day_f || o->julian_day) - { - jd=(o->julian_day||o->julian_day_f)()/z; - break; - } - } + rules=default_rules; + tick=(float)args[0]; + len=0.0; + return; } + break; + case 0: + rules=default_rules; + create_unixtime_default(time()); + return; } + rules=default_rules; + ::create(@args); + } + + static void create_unixtime(int unixtime,int seconds) + { + tick=(unixtime-TNG0UNIX)*TNGSTARPERSECOND; + len=seconds*TNGSTARPERSECOND; + } + + static void create_unixtime_default(int unixtime) + { + tick=(unixtime-TNG0UNIX)*TNGSTARPERSECOND; + len=0.0; + } + + static void create_julian_day(int|float jd) + { + tick=(jd-TNG0JULIAN)*TNGSTARPERJULIAN; + len=0.0; + } + +//! method float tics() +//! This gives back the number of stardate tics +//! in the period. + + float tics() + { + return len; + } + +//! method int number_of_seconds() +//! method int number_of_days() +//! This gives back the Gregorian/Earth/ISO number of seconds +//! and number of days, for convinience and conversion to +//! other calendars. + + int number_of_seconds() + { + return (int)(len/TNGSTARPERSECOND); + } + + int number_of_days() + { + return (int)(len/TNGSTARPERJULIAN); + } + + int unix_time() + { + return ((int)(tick/TNGSTARPERSECOND))+TNG0UNIX; + } + + float julian_day() + { + return ((int)(tick/TNGSTARPERJULIAN))+TNG0JULIAN; + } + + TimeRange add(int n,void|this_program step) + { + float x; + if (!step) + x=len; else - jd=(float)day[0]; - from_julian_day(jd); + { + if (!step->is_stardate) + error("add: Incompatible type %O\n",step); + x=step->len; + } + + + if (n&&x) + return Tick("stardate",rules,tick+x,len); + return this_object(); } - static void from_stardate(float f) + static void convert_from(TimeRange other) { - tics=f; - jd=f/TNGSTARPERJULIAN+2569518.5; + if (other->unix_time) + create_unixtime_default(other->unix_time()); + else + ::convert_from(other); + if (other->is_stardate) + { + tick=other->tick; + len=other->len; + } + else if (other->number_of_seconds) + len=TNGSTARPERSECOND*other->number_of_seconds(); + else if (other->number_of_days) + len=TNGSTARPERJULIAN*other->number_of_days(); + else + len=0.0; } - static void from_julian_day(float f) + static TimeRange _set_size(int n,TimeRange x) { - jd=f; - tics=(f-2569518.5)*TNGSTARPERJULIAN; + if (!x->is_stardate) + error("distance: Incompatible type %O\n",x); + return Tick("stardate",rules,tick,x->len); } -//-- nonstandard methods -------------------------------------------- + TimeRange place(TimeRange what,void|int force) + { +// can't do this + return this_object(); + } - float number() + array(TimeRange) split(int n) { - return tics; + if (!n) return ({this_object()}); // foo + + float z=tick; + float l=len/n; + array(TimeRange) res=({}); + + while (n--) + res+=({Tick("stardate",rules,z,l)}),z+=l; + + return res; + } + + TimeRange beginning() + { + if (!len) return this_object(); + return Tick("stardate",rules,tick,0.0); + } + + TimeRange end() + { + if (!len) return this_object(); + return Tick("stardate",rules,tick+len,0.0); + } + + TimeRange distance(TimeRange to) + { + if (!to->is_stardate) + error("distance: Incompatible type %O\n",to); + if (to->tick<tick) + error("negative distance\n"); + return Tick("stardate",rules,tick,to->tick-tick); } - - int julian_day() + + array _compare(TimeRange with) { - return (int)jd; + float b1=tick; + float e1=tick+len; + float b2,e2; + if (with->is_stardate) + b2=with->tick,e2=b2+with->len; + else + ::_compare(with); +#define CMP(A,B) ( ((A)<(B))?-1:((A)>(B))?1:0 ) + return ({ CMP(b1,b2),CMP(b1,e2),CMP(e1,b2),CMP(e1,e2) }); } - float julian_day_f() + int __hash() { return (int)tick; } + + cTick set_ruleset(Ruleset r) { - return jd; + return Tick("stardate",r,tick,len); } + + string _sprintf(int t) + { + switch (t) + { + case 'O': + if (len!=0.0) + return sprintf("Tick(%s)",nice_print_period()); + return sprintf("Tick(%s)",nice_print()); + default: + return 0; + } + } + + string nice_print_period() + { + if (len>0.010) + return sprintf("%s..%s",nice_print(),end()->nice_print()); + else + return sprintf("%s..%+g",nice_print(),len); + } + + string nice_print() + { + return sprintf("%.3f",tick); + } + +//! string format_long() +//! string format_short() +//! string format_vshort() +//! Format the stardate tick nicely. +//! <pre> +//! long "-322537.312" +//! short "77463.312" (w/o >100000-component) +//! short "7463.312" (w/o >10000-component) +//! </pre> + + string format_long() + { + return sprintf("%.3f",tick); + } + + string format_short() + { + return sprintf("%.3f",tick-((int)tick/100000)*100000); + } + + string format_vshort() + { + return sprintf("%.3f",tick-((int)tick/10000)*10000); + } +} + +// compat +function(mixed...:cTick) TNGDate=cTick; + +// for events +function(mixed...:cTick) Day=cTick; + +//------------------------------------------------------------------------ +// global convinience functions +//------------------------------------------------------------------------ + +//! method TimeofDay now() +//! Give the zero-length time period of the +//! current time. + +TimeofDay now() +{ + return Tick(); } diff --git a/lib/modules/Calendar.pmod/Swedish.pmod b/lib/modules/Calendar.pmod/Swedish.pmod index 861bd0a7f8fb3c7690cf34fc7407f1c5452d66c2..39a9dd88a553eb1d7b78800c2907fce9f533aba7 100644 --- a/lib/modules/Calendar.pmod/Swedish.pmod +++ b/lib/modules/Calendar.pmod/Swedish.pmod @@ -1,238 +1,19 @@ -// by Mirar - -inherit Calendar.ISO:ISO; - -void create() -{ - month_names= - ({"januari","februari","mars","april","maj","juni","juli","augusti", - "september","oktober","november","december"}); - - week_day_names= - ({"måndag","tisdag","onsdag","torsdag", - "fredag","lördag","söndag"}); -} - -class Week -{ - inherit ISO::Week; - - string name() - { - return "v"+(string)this->number(); - } -} - -class Year -{ - inherit ISO::Year; - - array(array(string)) _namedays; - mapping(string:int) _nameday_lookup; - - string name() - { - if (this->number()<=0) - return (string)(1-this->number())+" fk"; - return (string)this->number(); - } - - array(array(string)) namedays() - { - if (_namedays) return _namedays; - - array(array(string)) a; - - // insert test for year here - if (!(a=namedays_cache[this->leap()+" "+this->leap_day()])) - { - // insert test for year here - a=namedays_1993; - - if (this->leap()) - { - a=a[..this->leap_day()-1]+ - Array.map(allocate(this->leap()), - lambda(int x) { return ({}); })+ - a[this->leap_day()..]; - } - - namedays_cache[this->leap()+" "+this->leap_day()]=a; - } - - return _namedays=a; - } - - object nameday(string name) - { - if (!_nameday_lookup - && !(_nameday_lookup= - namedays_lookup_cache[this->leap()+" "+this->leap_day()])) - { - mapping m=([]); - int i; - foreach (this->namedays(),array a) - { - foreach (a,string name) m[lower_case(name)]=i; - i++; - } - _nameday_lookup = - namedays_lookup_cache[this->leap()+" "+this->leap_day()] = m; - } - - if (zero_type(_nameday_lookup[lower_case(name)])) return 0; - return this->day(_nameday_lookup[lower_case(name)]); - } -} - -class Day +//! +//! module Calendar +//! submodule Swedish +//! +//! Same as the ISO calendar, +//! but with swedish namedays added, and +//! swedish is the default language. +//! +//! This calendar exist only for backwards compatible +//! purposes. +//! + +import "."; +inherit ISO:ISO; + +private static mixed __initstuff=lambda() { - inherit ISO::Day; - - array(string) names() - { - return this->year()->namedays()[this->year_day()]; - } -} - -// --- namnsdagar, data ------------------------------------------------- - -mapping namedays_cache=([]); -mapping namedays_lookup_cache=([]); - -/** - -Name database from alma-1.0, -http://www.lysator.liu.se/~tab/alma-1.0.tar.gz - -Permission to use from Kent Engström, 1998-01-28 - - **/ - - -array(array(string)) namedays_1993= -({ ({}), ({"Svea","Sverker"}), ({"Alfred","Alfrida"}), - ({"Rut","Ritva"}), ({"Hanna","Hannele"}), ({"Baltsar","Kasper"}), - ({"August","Augusta"}), ({"Erland","Erhard"}), ({"Gunnar","Gunder"}), - ({"Sigurd","Sigmund"}), ({"Hugo","Hagar"}), ({"Frideborg","Fridolf"}), - ({"Knut"}), ({"Felix","Felicia"}), ({"Laura","Liv"}), - ({"Hjalmar","Hervor"}), ({"Anton","Tony"}), ({"Hilda","Hildur"}), - ({"Henrik","Henry"}), ({"Fabian","Sebastian"}), ({"Agnes","Agneta"}), - ({"Vincent","Veine"}), ({"Emilia","Emilie"}), ({"Erika","Eira"}), - ({"Paul","Pål"}), ({"Bodil","Boel"}), ({"Göte","Göta"}), - ({"Karl","Karla"}), ({"Valter","Vilma"}), ({"Gunhild","Gunilla"}), - ({"Ivar","Joar"}), ({"Max","Magda"}), ({"Marja","Mia"}), - ({"Disa","Hjördis"}), ({"Ansgar","Anselm"}), ({"Lisa","Elise"}), - ({"Dorotea","Dora"}), ({"Rikard","Dick"}), ({"Berta","Berthold"}), - ({"Fanny","Betty"}), ({"Egon","Egil"}), ({"Yngve","Ingolf"}), - ({"Evelina","Evy"}), ({"Agne","Agnar"}), ({"Valentin","Tina"}), - ({"Sigfrid","Sigbritt"}), ({"Julia","Jill"}), - ({"Alexandra","Sandra"}), ({"Frida","Fritz"}), ({"Gabriella","Ella"}), - ({"Rasmus","Ruben"}), ({"Hilding","Hulda"}), ({"Marina","Marlene"}), - ({"Torsten","Torun"}), ({"Mattias","Mats"}), ({"Sigvard","Sivert"}), - ({"Torgny","Torkel"}), ({"Lage","Laila"}), ({"Maria","Maja"}), - ({"Albin","Inez"}), ({"Ernst","Erna"}), ({"Gunborg","Gunvor"}), - ({"Adrian","Ada"}), ({"Tora","Tor"}), ({"Ebba","Ebbe"}), - ({"Isidor","Doris"}), ({"Siv","Saga"}), ({"Torbjörn","Ambjörn"}), - ({"Edla","Ethel"}), ({"Edvin","Elon"}), ({"Viktoria","Viktor"}), - ({"Greger","Iris"}), ({"Matilda","Maud"}), ({"Kristofer","Christel"}), - ({"Herbert","Gilbert"}), ({"Gertrud","Görel"}), ({"Edvard","Eddie"}), - ({"Josef","Josefina"}), ({"Joakim","Kim"}), ({"Bengt","Benny"}), - ({"Viking","Vilgot"}), ({"Gerda","Gert"}), ({"Gabriel","Rafael"}), - ({"Mary","Marion"}), ({"Emanuel","Manne"}), ({"Ralf","Raymond"}), - ({"Elma","Elmer"}), ({"Jonas","Jens"}), ({"Holger","Reidar"}), - ({"Ester","Estrid"}), ({"Harald","Halvar"}), ({"Gunnel","Gun"}), - ({"Ferdinand","Florence"}), ({"Irene","Irja"}), ({"Nanna","Nanny"}), - ({"Vilhelm","Willy"}), ({"Irma","Mimmi"}), ({"Vanja","Ronja"}), - ({"Otto","Ottilia"}), ({"Ingvar","Ingvor"}), ({"Ulf","Ylva"}), - ({"Julius","Gillis"}), ({"Artur","Douglas"}), ({"Tiburtius","Tim"}), - ({"Olivia","Oliver"}), ({"Patrik","Patricia"}), ({"Elias","Elis"}), - ({"Valdemar","Volmar"}), ({"Olaus","Ola"}), ({"Amalia","Amelie"}), - ({"Annika","Anneli"}), ({"Allan","Alida"}), ({"Georg","Göran"}), - ({"Vega","Viveka"}), ({"Markus","Mark"}), ({"Teresia","Terese"}), - ({"Engelbrekt","Enok"}), ({"Ture Tyko"}), ({"Kennet","Kent"}), - ({"Mariana","Marianne"}), ({"Valborg","Maj"}), ({"Filip","Filippa"}), - ({"John","Jack"}), ({"Monika","Mona"}), ({"Vivianne","Vivan"}), - ({"Marit","Rita"}), ({"Lilian","Lilly"}), ({"Åke","Ove"}), - ({"Jonatan","Gideon"}), ({"Elvira","Elvy"}), ({"Märta","Märit"}), - ({"Charlotta","Lotta"}), ({"Linnea","Nina"}), ({"Lillemor","Lill"}), - ({"Sofia","Sonja"}), ({"Hilma","Hilmer"}), ({"Nore","Nora"}), - ({"Erik","Jerker"}), ({"Majken","Majvor"}), ({"Karolina","Lina"}), - ({"Konstantin","Conny"}), ({"Henning","Hemming"}), - ({"Desiree","Renee"}), ({"Ivan","Yvonne"}), ({"Urban","Ursula"}), - ({"Vilhelmina","Helmy"}), ({"Blenda","Beda"}), - ({"Ingeborg","Borghild"}), ({"Jean","Jeanette"}), - ({"Fritiof","Frej"}), ({"Isabella","Isa"}), ({"Rune","Runa"}), - ({"Rutger","Roger"}), ({"Ingemar","Gudmar"}), - ({"Solveig","Solbritt"}), ({"Bo","Boris"}), ({"Gustav","Gösta"}), - ({"Robert","Robin"}), ({"Eivor","Elaine"}), ({"Petra","Petronella"}), - ({"Kerstin","Karsten"}), ({"Bertil","Berit"}), ({"Eskil","Esbjörn"}), - ({"Aina","Eila"}), ({"Håkan","Heidi"}), ({"Margit","Mait"}), - ({"Axel","Axelina"}), ({"Torborg","Torvald"}), ({"Björn","Bjarne"}), - ({"Germund","Jerry"}), ({"Linda","Linn"}), ({"Alf","Alva"}), - ({"Paulina","Paula"}), ({"Adolf","Adela"}), ({"Johan","Jan"}), - ({"David","Salomon"}), ({"Gunni","Jim"}), ({"Selma","Herta"}), - ({"Leo","Leopold"}), ({"Petrus","Peter"}), ({"Elof","Leif"}), - ({"Aron","Mirjam"}), ({"Rosa","Rosita"}), ({"Aurora","Adina"}), - ({"Ulrika","Ulla"}), ({"Melker","Agaton"}), ({"Ronald","Ronny"}), - ({"Klas","Kaj"}), ({"Kjell","Tjelvar"}), ({"Jörgen","Örjan"}), - ({"Anund","Gunda"}), ({"Eleonora","Ellinor"}), ({"Herman","Hermine"}), - ({"Joel","Judit"}), ({"Folke","Odd"}), ({"Ragnhild","Ragnvald"}), - ({"Reinhold","Reine"}), ({"Alexis","Alice"}), ({"Fredrik","Fred"}), - ({"Sara","Sally"}), ({"Margareta","Greta"}), ({"Johanna","Jane"}), - ({"Magdalena","Madeleine"}), ({"Emma","Emmy"}), - ({"Kristina","Stina"}), ({"Jakob","James"}), ({"Jesper","Jessika"}), - ({"Marta","Moa"}), ({"Botvid","Seved"}), ({"Olof","Olle"}), - ({"Algot","Margot"}), ({"Elin","Elna"}), ({"Per","Pernilla"}), - ({"Karin","Kajsa"}), ({"Tage","Tanja"}), ({"Arne","Arnold"}), - ({"Ulrik","Alrik"}), ({"Sixten","Sölve"}), ({"Dennis","Donald"}), - ({"Silvia","Sylvia"}), ({"Roland","Roine"}), ({"Lars","Lorentz"}), - ({"Susanna","Sanna"}), ({"Klara","Clary"}), ({"Hillevi","Gullvi"}), - ({"William","Bill"}), ({"Stella","Stellan"}), ({"Brynolf","Sigyn"}), - ({"Verner","Veronika"}), ({"Helena","Lena"}), ({"Magnus","Måns"}), - ({"Bernhard","Bernt"}), ({"Jon","Jonna"}), ({"Henrietta","Henny"}), - ({"Signe","Signhild"}), ({"Bartolomeus","Bert"}), - ({"Lovisa","Louise"}), ({"Östen","Ejvind"}), ({"Rolf","Rudolf"}), - ({"Gurli","Gull"}), ({"Hans","Hampus"}), ({"Albert","Albertina"}), - ({"Arvid","Vidar"}), ({"Samuel","Sam"}), ({"Justus","Justina"}), - ({"Alfhild","Alfons"}), ({"Gisela","Glenn"}), ({"Harry","Harriet"}), - ({"Sakarias","Esaias"}), ({"Regina","Roy"}), ({"Alma","Ally"}), - ({"Anita","Anja"}), ({"Tord","Tove"}), ({"Dagny","Daniela"}), - ({"Tyra","Åsa"}), ({"Sture","Styrbjörn"}), ({"Ida","Ellida"}), - ({"Sigrid","Siri"}), ({"Dag","Daga"}), ({"Hildegard","Magnhild"}), - ({"Alvar","Orvar"}), ({"Fredrika","Carita"}), ({"Agda","Agata"}), - ({"Ellen","Elly"}), ({"Maurits","Morgan"}), ({"Tekla","Tea"}), - ({"Gerhard","Gert"}), ({"Kåre","Tryggve"}), ({"Einar","Enar"}), - ({"Dagmar","Rigmor"}), ({"Lennart","Leonard"}), - ({"Mikael","Mikaela"}), ({"Helge","Helny"}), ({"Ragnar","Ragna"}), - ({"Ludvig","Louis"}), ({"Evald","Osvald"}), ({"Frans","Frank"}), - ({"Bror","Bruno"}), ({"Jenny","Jennifer"}), ({"Birgitta","Britta"}), - ({"Nils","Nelly"}), ({"Ingrid","Inger"}), ({"Helmer","Hadar"}), - ({"Erling","Jarl"}), ({"Valfrid","Ernfrid"}), ({"Birgit","Britt"}), - ({"Manfred","Helfrid"}), ({"Hedvig","Hedda"}), ({"Fingal","Finn"}), - ({"Antonia","Annette"}), ({"Lukas","Matteus"}), ({"Tore","Torleif"}), - ({"Sibylla","Camilla"}), ({"Birger","Börje"}), ({"Marika","Marita"}), - ({"Sören","Severin"}), ({"Evert","Eilert"}), ({"Inga","Ingvald"}), - ({"Amanda","My"}), ({"Sabina","Ina"}), ({"Simon","Simone"}), - ({"Viola","Vivi"}), ({"Elsa","Elsie"}), ({"Edit","Edgar"}), - ({"Andre","Andrea"}), ({"Tobias","Toini"}), ({"Hubert","Diana"}), - ({"Uno","Unn"}), ({"Eugen","Eugenia"}), ({"Gustav Adolf"}), - ({"Ingegerd","Ingela"}), ({"Vendela","Vanda"}), ({"Teodor","Ted"}), - ({"Martin","Martina"}), ({"Mårten"}), ({"Konrad","Kurt"}), - ({"Kristian","Krister"}), ({"Emil","Mildred"}), ({"Katja","Nadja"}), - ({"Edmund","Gudmund"}), ({"Naemi","Nancy"}), ({"Pierre","Percy"}), - ({"Elisabet","Lisbeth"}), ({"Pontus","Pia"}), ({"Helga","Olga"}), - ({"Cecilia","Cornelia"}), ({"Klemens","Clarence"}), - ({"Gudrun","Runar"}), ({"Katarina","Carina"}), ({"Linus","Love"}), - ({"Astrid","Asta"}), ({"Malte","Malkolm"}), ({"Sune","Synnöve"}), - ({"Anders","Andreas"}), ({"Oskar","Ossian"}), ({"Beata","Beatrice"}), - ({"Lydia","Carola"}), ({"Barbro","Barbara"}), ({"Sven","Svante"}), - ({"Nikolaus","Niklas"}), ({"Angelika","Angela"}), - ({"Virginia","Vera"}), ({"Anna","Annie"}), ({"Malin","Malena"}), - ({"Daniel","Dan"}), ({"Alexander","Alex"}), ({"Lucia"}), - ({"Sten","Stig"}), ({"Gottfrid","Gotthard"}), ({"Assar","Astor"}), - ({"Inge","Ingemund"}), ({"Abraham","Efraim"}), ({"Isak","Rebecka"}), - ({"Israel","Moses"}), ({"Tomas","Tom"}), ({"Natanael","Natalia"}), - ({"Adam"}), ({"Eva"}), ({}), ({"Stefan","Staffan"}), - ({"Johannes","Hannes"}), ({"Abel","Set"}), ({"Gunlög","Åslög"}), - ({"Sylvester"}), }); + default_rules=default_rules->set_language("SE_sv"); +}(); diff --git a/lib/modules/Calendar.pmod/TZnames.pmod b/lib/modules/Calendar.pmod/TZnames.pmod new file mode 100644 index 0000000000000000000000000000000000000000..0e36c57f70236f9eaf1afd8a330cf7c3ffa8ab7e --- /dev/null +++ b/lib/modules/Calendar.pmod/TZnames.pmod @@ -0,0 +1,86 @@ +// ---------------------------------------------------------------- +// Timezone names +// +// NOTE: this file is generated by mkrules.pike; +// please do not edit manually /Mirar +// ---------------------------------------------------------------- + +mapping _module_value= +([ + "America": ({"Scoresbysund","Godthab","Thule","New_York","Chicago", + "Denver","Los_Angeles","Juneau","Yakutat","Anchorage", + "Nome","Adak","Phoenix","Boise","Indianapolis", + "Indiana/Marengo","Indiana/Knox","Indiana/Vevay", + "Louisville","Detroit","Menominee","St_Johns","Goose_Bay", + "Halifax","Glace_Bay","Montreal","Thunder_Bay","Nipigon", + "Rainy_River","Winnipeg","Regina","Swift_Current", + "Edmonton","Vancouver","Dawson_Creek","Pangnirtung", + "Iqaluit","Rankin_Inlet","Cambridge_Bay","Yellowknife", + "Inuvik","Whitehorse","Dawson","Cancun","Mexico_City", + "Chihuahua","Hermosillo","Mazatlan","Tijuana","Anguilla", + "Antigua","Nassau","Barbados","Belize","Cayman", + "Costa_Rica","Havana","Dominica","Santo_Domingo", + "El_Salvador","Grenada","Guadeloupe","Guatemala", + "Port-au-Prince","Tegucigalpa","Jamaica","Martinique", + "Montserrat","Managua","Panama","Puerto_Rico","St_Kitts", + "St_Lucia","Miquelon","St_Vincent","Grand_Turk","Tortola", + "St_Thomas","Buenos_Aires","Rosario","Cordoba","Jujuy", + "Catamarca","Mendoza","Aruba","La_Paz","Noronha","Belem", + "Fortaleza","Araguaina","Maceio","Sao_Paulo","Cuiaba", + "Porto_Velho","Boa_Vista","Manaus","Porto_Acre","Santiago", + "Bogota","Curacao","Guayaquil","Cayenne","Guyana", + "Asuncion","Lima","Paramaribo","Port_of_Spain", + "Montevideo","Caracas"}), + "Pacific": ({"Rarotonga","Fiji","Gambier","Marquesas","Tahiti","Guam", + "Tarawa","Enderbury","Kiritimati","Saipan","Majuro", + "Kwajalein","Yap","Truk","Ponape","Kosrae","Nauru", + "Noumea","Auckland","Chatham","Niue","Norfolk","Palau", + "Port_Moresby","Pitcairn","Pago_Pago","Apia","Guadalcanal", + "Fakaofo","Tongatapu","Funafuti","Johnston","Midway", + "Wake","Efate","Wallis","Honolulu","Easter","Galapagos"}), + "Antarctica":({"Casey","Davis","Mawson","DumontDUrville","Syowa", + "Palmer","McMurdo"}), + "Atlantic": ({"Cape_Verde","St_Helena","Faeroe","Reykjavik","Jan_Mayen", + "Azores","Madeira","Canary","Bermuda","Stanley", + "South_Georgia"}), + "Indian": ({"Comoro","Antananarivo","Mauritius","Mayotte","Reunion", + "Mahe","Kerguelen","Chagos","Maldives","Christmas", + "Cocos"}), + "Europe": ({"London","Belfast","Dublin","Tirane","Andorra","Vienna", + "Minsk","Brussels","Sofia","Prague","Copenhagen", + "Tallinn","Helsinki","Paris","Berlin","Gibraltar", + "Athens","Budapest","Rome","Riga","Vaduz","Vilnius", + "Luxembourg","Malta","Chisinau","Tiraspol","Monaco", + "Amsterdam","Oslo","Warsaw","Lisbon","Bucharest", + "Kaliningrad","Moscow","Samara","Madrid","Stockholm", + "Zurich","Istanbul","Kiev","Uzhgorod","Zaporozhye", + "Simferopol","Belgrade"}), + "Africa": ({"Algiers","Luanda","Porto-Novo","Gaborone","Ouagadougou", + "Bujumbura","Douala","Bangui","Ndjamena","Kinshasa", + "Lubumbashi","Brazzaville","Abidjan","Djibouti","Cairo", + "Malabo","Asmera","Addis_Ababa","Libreville","Banjul", + "Accra","Conakry","Bissau","Nairobi","Maseru","Monrovia", + "Tripoli","Blantyre","Bamako","Timbuktu","Nouakchott", + "Casablanca","El_Aaiun","Maputo","Windhoek","Niamey", + "Lagos","Kigali","Sao_Tome","Dakar","Freetown", + "Mogadishu","Johannesburg","Khartoum","Mbabane", + "Dar_es_Salaam","Lome","Tunis","Kampala","Lusaka", + "Harare","Ceuta"}), + "Asia": ({"Kabul","Yerevan","Baku","Bahrain","Dacca","Thimbu", + "Brunei","Rangoon","Phnom_Penh","Harbin","Shanghai", + "Chungking","Urumqi","Kashgar","Hong_Kong","Taipei", + "Macao","Nicosia","Tbilisi","Dili","Calcutta","Jakarta", + "Ujung_Pandang","Jayapura","Tehran","Baghdad","Jerusalem", + "Tokyo","Amman","Almaty","Aqtobe","Aqtau","Bishkek", + "Seoul","Pyongyang","Kuwait","Vientiane","Beirut", + "Kuala_Lumpur","Kuching","Hovd","Ulaanbaatar","Katmandu", + "Muscat","Karachi","Gaza","Manila","Qatar","Riyadh", + "Singapore","Colombo","Damascus","Dushanbe","Bangkok", + "Ashkhabad","Dubai","Samarkand","Tashkent","Saigon", + "Aden","Yekaterinburg","Omsk","Novosibirsk","Krasnoyarsk", + "Irkutsk","Yakutsk","Vladivostok","Magadan","Kamchatka", + "Anadyr"}), + "Australia": ({"Darwin","Perth","Brisbane","Lindeman","Adelaide", + "Hobart","Melbourne","Sydney","Broken_Hill","Lord_Howe"}), +]); + diff --git a/lib/modules/Calendar.pmod/TZrules.pmod b/lib/modules/Calendar.pmod/TZrules.pmod new file mode 100644 index 0000000000000000000000000000000000000000..60cbd2c308c4b8fc9461ce9c1980c1e4e8ad1cc3 --- /dev/null +++ b/lib/modules/Calendar.pmod/TZrules.pmod @@ -0,0 +1,6003 @@ +// ---------------------------------------------------------------- +// Daylight savings and war time rules +// +// NOTE: this file is generated by mkrules.pike; +// please do not edit manually /Mirar +// ---------------------------------------------------------------- + +// ---------------------------------------------------------------- +// all rules are based on the gregorian calendar, so +// this is the gregorian rule: +// ---------------------------------------------------------------- + +static array gregorian_yjd(int jd) +{ + int d=jd-1721426; + + int century=(4*d+3)/146097; + int century_jd=(century*146097)/4; + int century_day=d-century_jd; + int century_year=(100*century_day+75)/36525; + + int y=century*100+century_year+1; + + return + ({ + y, + 1721426+century_year*365+century_year/4+century_jd, + (!(((y)%4) || (!((y)%100) && ((y)%400)))) + }); +} + +// ---------------------------------------------------------------- +// Base "Timezone with rules" class +// ---------------------------------------------------------------- + +class TZRules +{ + constant is_timezone=1; + constant is_dst_timezone=1; + static int offset_to_utc; + string name; + + static function(string:string) tzformat; + static array names; + + static void create(int offset,string _name) + { + offset_to_utc=offset; + name=_name; + if (search(name,"/")!=-1) + { + names=name/"/"; + tzformat=lambda(string s) + { + if (s=="") return names[0]; else return names[1]; + }; + } + else + tzformat=lambda(string s) { return sprintf(name,s); }; + } + +// the Rule: +// which julian day does dst start and end this year? + static array(array(string|int)) jd_year_periods(int jd); + +// is (midnight) this julian day dst? + array tz_jd(int jd) + { + array(array(string|int)) a=jd_year_periods(jd); + + int i=0,n=sizeof(a)-1; + while (i<n) + { + array b=a[i+1]; + if (jd<b[0]) break; + if (jd==b[0] && -offset_to_utc+b[1]>=0) break; + i++; + } + + return ({offset_to_utc-a[i][2],tzformat(a[i][3])}); + } + +// is this unixtime (utc) dst? + array tz_ux(int ux) + { + int jd=2440588+ux/86400; + array(array(string|int)) a=jd_year_periods(jd); + + int i=0,n=sizeof(a)-1; + while (i<n) + { + array b=a[i+1]; + if (jd<b[0]-1) break; + if (jd<b[0]+1 && + ux<(b[0]-2440588)*86400+b[1]) break; + i++; + } + + return ({offset_to_utc-a[i][2],tzformat(a[i][3])}); + } + + string _sprintf(int t) { return (t=='O')?"Timezone("+name+")":0; } + + int raw_utc_offset() { return offset_to_utc; } +} + +// ---------------------------------------------------------------------- +// DST Rules +// ---------------------------------------------------------------------- + +// useful macros +#define FIXED(D) (yjd+((D)-1)) +#define FIX_L(D) (yjd+leap+((D)-1)) +#define LDAY(D,W) (yjd+((D)-1)-( (yjd+((D)+(8-W)-1)) % 7)) +#define LDAYL(D,W) (yjd+((D)-1)+leap-( (yjd+leap+((D)+(8-W)-1)) % 7)) +#define UO offset_to_utc + +// ---------------------------------------------------------------------- +class Algeria +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1916: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(166) ,UO+82800 ,3600 ,"S" }), // Jun 14 + ({LDAY (281,7),UO+82800 ,0 ,"" })});// Oct Sun<=7 + case 1917: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(83) ,UO+82800 ,3600 ,"S" }), // Mar 24 + ({LDAY (280,7),UO+82800 ,0 ,"" })});// Oct Sun<=7 + case 1918: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(68) ,UO+82800 ,3600 ,"S" }), // Mar 9 + ({LDAY (280,7),UO+82800 ,0 ,"" })});// Oct Sun<=7 + case 1919: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(60) ,UO+82800 ,3600 ,"S" }), // Mar 1 + ({LDAY (280,7),UO+82800 ,0 ,"" })});// Oct Sun<=7 + case 1920: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(45) ,UO+82800 ,3600 ,"S" }), // Feb 14 + ({FIXED(297) ,UO+82800 ,0 ,"" })});// Oct 23 + case 1921: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(73) ,UO+82800 ,3600 ,"S" }), // Mar 14 + ({FIXED(172) ,UO+82800 ,0 ,"" })});// Jun 21 + case 1939: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(254) ,UO+82800 ,3600 ,"S" }), // Sep 11 + ({FIXED(323) ,UO+0 ,0 ,"" })});// Nov 19 + case 1944: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (98,1) ,UO+7200 ,3600 ,"S" }), // Apr Mon<=7 + ({FIXED(282) ,UO+3600 ,0 ,"" })});// Oct 8 + case 1945: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,1) ,UO+7200 ,3600 ,"S" }), // Apr Mon<=7 + ({FIXED(259) ,UO+0 ,0 ,"" })});// Sep 16 + case 1971: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(115) ,UO+82800 ,3600 ,"S" }), // Apr 25 + ({FIXED(269) ,UO+82800 ,0 ,"" })});// Sep 26 + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(126) ,UO+0 ,3600 ,"S" }), // May 6 + ({FIXED(294) ,UO-3600 ,0 ,"" })});// Oct 21 + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(83) ,UO+3600 ,3600 ,"S" }), // Mar 24 + ({FIXED(265) ,UO+7200 ,0 ,"" })});// Sep 22 + case 1980: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(116) ,UO+0 ,3600 ,"S" }), // Apr 25 + ({FIXED(305) ,UO+3600 ,0 ,"" })});// Oct 31 + default: // ..1915 and 1981.. + case 1922..1938: + case 1940..1943: + case 1946..1970: + case 1972..1976: + case 1979: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Egypt +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1940: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(197) ,UO+0 ,3600 ,"S" }), // Jul 15 + ({FIXED(275) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1941: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(105) ,UO+0 ,3600 ,"S" }), // Apr 15 + ({FIXED(259) ,UO-3600 ,0 ,"" })});// Sep 16 + case 1942: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(91) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({FIXED(300) ,UO-3600 ,0 ,"" })});// Oct 27 + case 1943..1944: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(91) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({FIX_L(305) ,UO-3600 ,0 ,"" })});// Nov 1 + case 1945: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(106) ,UO+0 ,3600 ,"S" }), // Apr 16 + ({FIXED(305) ,UO-3600 ,0 ,"" })});// Nov 1 + default: // ..1939: + case 1946..1956: + return ({({0 ,0 ,0 ,"" })}); + case 1957: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(130) ,UO+0 ,3600 ,"S" }), // May 10 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1958: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1959..1965: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(121) ,UO+3600 ,3600 ,"S" }), // May 1 + ({FIX_L(273) ,UO+7200 ,0 ,"" })});// Sep 30 + case 1982: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(206) ,UO+3600 ,3600 ,"S" }), // Jul 25 + ({FIXED(274) ,UO+7200 ,0 ,"" })});// Oct 1 + case 1983: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(193) ,UO+3600 ,3600 ,"S" }), // Jul 12 + ({FIXED(274) ,UO+7200 ,0 ,"" })});// Oct 1 + case 1989: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(126) ,UO+3600 ,3600 ,"S" }), // May 6 + ({FIXED(274) ,UO+7200 ,0 ,"" })});// Oct 1 + case 1966..1981: + case 1984..1988: + case 1990..1994: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(121) ,UO+3600 ,3600 ,"S" }), // May 1 + ({FIX_L(274) ,UO+7200 ,0 ,"" })});// Oct 1 + case 1995..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(120,5),UO+0 ,3600 ,"S" }), // Apr lastFri + ({LDAYL(273,4),UO+82800 ,0 ,"" })});// Sep lastThu + } + } +} + +class Ghana +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1936..1942: + return ({({0 ,0 ,0 ,"GMT" }), + ({FIX_L(244) ,UO+0 ,1200 ,"GHST"}), // Sep 1 + ({FIX_L(365) ,UO-1200 ,0 ,"GMT" })});// Dec 31 + default: // ..1935 and 1943.. + return ({({0 ,0 ,0 ,"GMT" })}); + } + } +} + +class Libya +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1951: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(287) ,UO+7200 ,3600 ,"S" })});// Oct 14 + case 1953: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(282) ,UO+7200 ,3600 ,"S" })});// Oct 9 + case 1955: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(273) ,UO+0 ,3600 ,"S" })});// Sep 30 + case 1952: + case 1954: + case 1956: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(1) ,UO-3600 ,0 ,"" })});// Jan 1 + case 1985: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(96) ,UO+0 ,3600 ,"S" }), // Apr 6 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1986: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(94) ,UO+0 ,3600 ,"S" }), // Apr 4 + ({FIXED(276) ,UO-3600 ,0 ,"" })});// Oct 3 + case 1982..1984: + case 1987..1989: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(91) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({FIX_L(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1990: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(274) ,UO+0 ,0 ,"" })});// Oct 1 + default: // ..1950 and 1991.. + case 1957..1981: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Morocco +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1939: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(255) ,UO+0 ,3600 ,"S" }), // Sep 12 + ({FIXED(323) ,UO-3600 ,0 ,"" })});// Nov 19 + case 1940: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(56) ,UO+0 ,3600 ,"S" })});// Feb 25 + case 1941..1944: + return ({({0 ,0 ,3600 ,"S" })}); + case 1945: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(322) ,UO-3600 ,0 ,"" })});// Nov 18 + case 1950: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(162) ,UO+0 ,3600 ,"S" }), // Jun 11 + ({FIXED(302) ,UO-3600 ,0 ,"" })});// Oct 29 + case 1967: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(154) ,UO+43200 ,3600 ,"S" }), // Jun 3 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1974: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(175) ,UO+0 ,3600 ,"S" }), // Jun 24 + ({FIXED(244) ,UO-3600 ,0 ,"" })});// Sep 1 + case 1976: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(122) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIXED(214) ,UO-3600 ,0 ,"" })});// Aug 1 + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIXED(271) ,UO-3600 ,0 ,"" })});// Sep 28 + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(152) ,UO+0 ,3600 ,"S" }), // Jun 1 + ({FIXED(216) ,UO-3600 ,0 ,"" })});// Aug 4 + default: // ..1938 and 1979.. + case 1946..1949: + case 1951..1966: + case 1968..1973: + case 1975: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Namibia +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1993: + return ({({0 ,0 ,0 ,"" })});// ? + case 1994: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (250,7),UO+7200 ,3600 ,"S" })});// Sep Sun>=1 + case 1995..: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(97,7) ,UO+3600 ,0 ,"" }), // Apr Sun>=1 + ({LDAYL(250,7),UO+7200 ,3600 ,"S" })});// Sep Sun>=1 + } + } +} + +class SL +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1935..1942: + return ({({0 ,0 ,0 ,"WAT" }), + ({FIX_L(152) ,UO+0 ,2400 ,"SLST"}), // Jun 1 + ({FIX_L(274) ,UO-2400 ,0 ,"WAT" })});// Oct 1 + default: // ..1934: + case 1943..1956: + return ({({0 ,0 ,0 ,"WAT" })}); + case 1957: + return ({({0 ,0 ,0 ,"WAT" }), + ({FIXED(152) ,UO+0 ,3600 ,"SLST"}), // Jun 1 + ({FIXED(244) ,UO-3600 ,0 ,"GMT" })});// Sep 1 + case 1958..1962: + return ({({0 ,0 ,0 ,"GMT" }), + ({FIX_L(152) ,UO+0 ,3600 ,"SLST"}), // Jun 1 + ({FIX_L(244) ,UO-3600 ,0 ,"GMT" })});// Sep 1 + case 1963..: + return ({({0 ,0 ,0 ,"GMT" })}); + } + } +} + +class SA +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1942: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (264,7),UO+7200 ,3600 ,"" })});// Sep Sun>=15 + case 1943: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (80,7) ,UO+3600 ,0 ,"" }), // Mar Sun>=15 + ({LDAY (264,7),UO+7200 ,3600 ,"" })});// Sep Sun>=15 + case 1944: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (81,7) ,UO+3600 ,0 ,"" })});// Mar Sun>=15 + default: // ..1941 and 1945.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Sudan +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1970: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(121) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIXED(288) ,UO-3600 ,0 ,"" })});// Oct 15 + case 1971: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(120) ,UO+0 ,3600 ,"S" }), // Apr 30 + ({FIXED(288) ,UO-3600 ,0 ,"" })});// Oct 15 + case 1972..1985: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(120,7),UO+0 ,3600 ,"S" }), // Apr lastSun + ({FIX_L(288) ,UO-3600 ,0 ,"" })});// Oct 15 + default: // ..1969 and 1986.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Tunisia +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1939: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(105) ,UO+82800 ,3600 ,"S" }), // Apr 15 + ({FIXED(322) ,UO+82800 ,0 ,"" })});// Nov 18 + case 1940: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(56) ,UO+82800 ,3600 ,"S" })});// Feb 25 + case 1941: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(279) ,UO-3600 ,0 ,"" })});// Oct 6 + case 1942: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(68) ,UO+0 ,3600 ,"S" }), // Mar 9 + ({FIXED(306) ,UO+7200 ,0 ,"" })});// Nov 2 + case 1943: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(88) ,UO+7200 ,3600 ,"S" }), // Mar 29 + ({FIXED(107) ,UO+3600 ,0 ,"" }), // Apr 17 + ({FIXED(115) ,UO+7200 ,3600 ,"S" }), // Apr 25 + ({FIXED(277) ,UO+3600 ,0 ,"" })});// Oct 4 + case 1944: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (98,1) ,UO+7200 ,3600 ,"S" }), // Apr Mon>=1 + ({FIXED(282) ,UO-3600 ,0 ,"" })});// Oct 8 + case 1945: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,1) ,UO+7200 ,3600 ,"S" }), // Apr Mon>=1 + ({FIXED(259) ,UO-3600 ,0 ,"" })});// Sep 16 + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(120) ,UO+0 ,3600 ,"S" }), // Apr 30 + ({FIXED(267) ,UO+0 ,0 ,"" })});// Sep 24 + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIXED(274) ,UO+0 ,0 ,"" })});// Oct 1 + case 1988: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(153) ,UO+0 ,3600 ,"S" }), // Jun 1 + ({LDAY (274,7),UO+0 ,0 ,"" })});// Sep lastSun + case 1989: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(85) ,UO+0 ,3600 ,"S" }), // Mar 26 + ({LDAY (273,7),UO+0 ,0 ,"" })});// Sep lastSun + case 1990: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+0 ,3600 ,"S" }), // May 1 + ({LDAY (273,7),UO+0 ,0 ,"" })});// Sep lastSun + default: // ..1938 and 1991.. + case 1946..1976: + case 1979..1987: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class ArgAQ +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1964: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(61) ,UO+0 ,0 ,"" }), // Mar 1 + ({FIXED(289) ,UO+0 ,3600 ,"S" })});// Oct 15 + case 1965..1966: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(60) ,UO-3600 ,0 ,"" }), // Mar 1 + ({FIXED(288) ,UO+0 ,3600 ,"S" })});// Oct 15 + case 1967: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(91) ,UO-3600 ,0 ,"" }), // Apr 1 + ({LDAY (280,7),UO+0 ,3600 ,"S" })});// Oct Sun<=7 + case 1974: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(23) ,UO+0 ,3600 ,"S" }), // Jan 23 + ({FIXED(121) ,UO-3600 ,0 ,"" }), // May 1 + ({LDAY (280,7),UO+0 ,3600 ,"S" })});// Oct Sun<=7 + case 1968: + case 1975..1976: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(97,7) ,UO-3600 ,0 ,"" }), // Apr Sun<=7 + ({LDAYL(280,7),UO+0 ,3600 ,"S" })});// Oct Sun<=7 + case 1969: + case 1977: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (97,7) ,UO-3600 ,0 ,"" })});// Apr Sun<=7 + default: // ..1963 and 1978.. + case 1970..1973: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class ChileAQ +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1968: + return ({({0 ,0 ,0 ,"" })});// ? + case 1969: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (288,7),UO+0 ,3600 ,"S" })});// Oct Sun>=9 + case 1998: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (74,7) ,UO-3600 ,0 ,"" }), // Mar Sun>=9 + ({FIXED(270) ,UO+0 ,3600 ,"S" })});// Sep 27 + case 1999: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(94) ,UO-3600 ,0 ,"" }), // Apr 4 + ({LDAY (288,7),UO+0 ,3600 ,"S" })});// Oct Sun>=9 + case 1970..1997: + case 2000..: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(74,7) ,UO-3600 ,0 ,"" }), // Mar Sun>=9 + ({LDAYL(288,7),UO+0 ,3600 ,"S" })});// Oct Sun>=9 + } + } +} + +class NZAQ +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1973: + return ({({0 ,0 ,0 ,"S" })});// ? + case 1974: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(307) ,UO+7200 ,3600 ,"D" })});// Nov 3 + case 1975: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(54) ,UO+7200 ,0 ,"S" }), // Feb 23 + ({LDAY (304,7),UO+7200 ,3600 ,"D" })});// Oct lastSun + case 1976..1988: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAYL(66,7) ,UO+7200 ,0 ,"S" }), // Mar Sun>=1 + ({LDAYL(304,7),UO+7200 ,3600 ,"D" })});// Oct lastSun + case 1989: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAY (66,7) ,UO+7200 ,0 ,"S" }), // Mar Sun>=1 + ({FIXED(281) ,UO+7200 ,3600 ,"D" })});// Oct 8 + case 1990..: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAYL(80,7) ,UO+7200 ,0 ,"S" }), // Mar Sun>=15 + ({LDAYL(280,7),UO+7200 ,3600 ,"D" })});// Oct Sun>=1 + } + } +} + +class EUAsia +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1980: + return ({({0 ,0 ,0 ,"" })});// ? + case 1981: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (90,7) ,3600 ,3600 ,"S" })});// Mar lastSun + case 1982..1995: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(90,7) ,3600 ,3600 ,"S" })});// Mar lastSun + case 1996: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (91,7) ,3600 ,3600 ,"S" }), // Mar lastSun + ({LDAY (305,7),3600 ,0 ,"" })});// Oct lastSun + case 1997..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,3600 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(304,7),3600 ,0 ,"" })});// Oct lastSun + } + } +} + +class E_EurAsia +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1978: + return ({({0 ,0 ,0 ,"" })});// ? + case 1979..1980: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(273,7),UO+0 ,0 ,"" })});// Sep lastSun + case 1981..1995: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+0 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),UO-3600 ,0 ,"" })});// Sep lastSun + case 1996..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+0 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(304,7),UO-3600 ,0 ,"" })});// Oct lastSun + } + } +} + +class RussiaAsia +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1980: + return ({({0 ,0 ,0 ,"" })});// ? + case 1981..1983: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(91) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1984: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({LDAY (274,7),UO+7200 ,0 ,"" })});// Sep lastSun + case 1992: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (91,6) ,UO+82800 ,3600 ,"S" }), // Mar lastSat + ({LDAY (274,6),UO+79200 ,0 ,"" })});// Sep lastSat + case 1985..1991: + case 1993..1995: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),UO+7200 ,0 ,"" })});// Sep lastSun + case 1996..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(304,7),UO+7200 ,0 ,"" })});// Oct lastSun + } + } +} + +class Azer +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1996: + return ({({0 ,0 ,0 ,"" })});// ? + case 1997..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+3600 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(304,7),UO+0 ,0 ,"" })});// Oct lastSun + } + } +} + +class Shang +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1940: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(155) ,UO+0 ,3600 ,"D" }), // Jun 3 + ({FIXED(275) ,UO-3600 ,0 ,"S" })});// Oct 1 + case 1941: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(75) ,UO+0 ,3600 ,"D" }), // Mar 16 + ({FIXED(274) ,UO-3600 ,0 ,"S" })});// Oct 1 + default: // ..1939 and 1942.. + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class PRC +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1949: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(1) ,UO+0 ,0 ,"S" })});// Jan 1 + case 1986: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(124) ,UO+0 ,3600 ,"D" }), // May 4 + ({LDAY (260,7),UO-3600 ,0 ,"S" })});// Sep Sun>=11 + case 1987..1991: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(106,7),UO+0 ,3600 ,"D" }), // Apr Sun>=10 + ({LDAYL(260,7),UO-3600 ,0 ,"S" })});// Sep Sun>=11 + default: // ..1948 and 1992.. + case 1950..1985: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class HK +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1946: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(110) ,UO+12600 ,3600 ,"S" }), // Apr 20 + ({FIXED(335) ,UO+9000 ,0 ,"" })});// Dec 1 + case 1947: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(103) ,UO+12600 ,3600 ,"S" }), // Apr 13 + ({FIXED(364) ,UO+9000 ,0 ,"" })});// Dec 30 + case 1948: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(123) ,UO+12600 ,3600 ,"S" }), // May 2 + ({LDAY (305,7),UO+9000 ,0 ,"" })});// Oct lastSun + case 1949..1952: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(97,7) ,UO+12600 ,3600 ,"S" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+9000 ,0 ,"" })});// Oct lastSun + case 1953: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+12600 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(305) ,UO+9000 ,0 ,"" })});// Nov 1 + case 1954: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (83,7) ,UO+12600 ,3600 ,"S" }), // Mar Sun>=18 + ({FIXED(304) ,UO+9000 ,0 ,"" })});// Oct 31 + case 1955..1964: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(83,7) ,UO+12600 ,3600 ,"S" }), // Mar Sun>=18 + ({LDAYL(311,7),UO+9000 ,0 ,"" })});// Nov Sun>=1 + case 1965..1977: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(112,7),UO+12600 ,3600 ,"S" }), // Apr Sun>=16 + ({LDAYL(295,7),UO+9000 ,0 ,"" })});// Oct Sun>=16 + case 1979..1980: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(134,7),UO+12600 ,3600 ,"S" }), // May Sun>=8 + ({LDAYL(295,7),UO+9000 ,0 ,"" })});// Oct Sun>=16 + default: // ..1945 and 1981.. + case 1978: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Taiwan +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1945..1951: + return ({({0 ,0 ,0 ,"S" }), + ({FIX_L(121) ,UO+0 ,3600 ,"D" }), // May 1 + ({FIX_L(274) ,UO-3600 ,0 ,"S" })});// Oct 1 + case 1952: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(61) ,UO+0 ,3600 ,"D" }), // Mar 1 + ({FIXED(306) ,UO-3600 ,0 ,"S" })});// Nov 1 + case 1953..1954: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(91) ,UO+0 ,3600 ,"D" }), // Apr 1 + ({FIXED(305) ,UO-3600 ,0 ,"S" })});// Nov 1 + case 1960..1961: + return ({({0 ,0 ,0 ,"S" }), + ({FIX_L(152) ,UO+0 ,3600 ,"D" }), // Jun 1 + ({FIX_L(274) ,UO-3600 ,0 ,"S" })});// Oct 1 + case 1955..1959: + case 1974..1975: + return ({({0 ,0 ,0 ,"S" }), + ({FIX_L(91) ,UO+0 ,3600 ,"D" }), // Apr 1 + ({FIX_L(274) ,UO-3600 ,0 ,"S" })});// Oct 1 + case 1980: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(182) ,UO+0 ,3600 ,"D" }), // Jun 30 + ({FIXED(274) ,UO-3600 ,0 ,"S" })});// Sep 30 + default: // ..1944 and 1981.. + case 1962..1973: + case 1976..1979: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Macao +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1963: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (81,7) ,UO+0 ,3600 ,"S" }), // Mar Sun>=16 + ({LDAY (311,7),UO+9000 ,0 ,"" })});// Nov Sun>=1 + case 1961..1962: + case 1964: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(81,7) ,UO+12600 ,3600 ,"S" }), // Mar Sun>=16 + ({LDAYL(311,7),UO+9000 ,0 ,"" })});// Nov Sun>=1 + case 1965: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (81,7) ,UO+0 ,3600 ,"S" }), // Mar Sun>=16 + ({FIXED(304) ,UO-3600 ,0 ,"" })});// Oct 31 + case 1966..1971: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(112,7),UO+12600 ,3600 ,"S" }), // Apr Sun>=16 + ({LDAYL(295,7),UO+9000 ,0 ,"" })});// Oct Sun>=16 + case 1974: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (111,7),UO+0 ,3600 ,"S" }), // Apr Sun>=15 + ({LDAY (294,7),UO+9000 ,0 ,"" })});// Oct Sun>=15 + case 1975..1977: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(111,7),UO+12600 ,3600 ,"S" }), // Apr Sun>=15 + ({LDAYL(294,7),UO+9000 ,0 ,"" })});// Oct Sun>=15 + case 1972..1973: + case 1978..1980: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(111,7),UO+0 ,3600 ,"S" }), // Apr Sun>=15 + ({LDAYL(294,7),UO-3600 ,0 ,"" })});// Oct Sun>=15 + default: // ..1960 and 1981.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Cyprus +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1974: + return ({({0 ,0 ,0 ,"" })});// ? + case 1975: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(103) ,UO+0 ,3600 ,"S" }), // Apr 13 + ({FIXED(285) ,UO-3600 ,0 ,"" })});// Oct 12 + case 1976: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(136) ,UO+0 ,3600 ,"S" }), // May 15 + ({FIXED(285) ,UO-3600 ,0 ,"" })});// Oct 11 + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+0 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(268) ,UO-3600 ,0 ,"" })});// Sep 25 + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+0 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(275) ,UO-3600 ,0 ,"" })});// Oct 2 + case 1979..1980: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(97,7) ,UO+0 ,3600 ,"S" }), // Apr Sun>=1 + ({LDAYL(273,7),UO-3600 ,0 ,"" })});// Sep lastSun + case 1981..1997: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+0 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),UO-3600 ,0 ,"" })});// Sep lastSun + case 1998: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (90,7) ,UO+0 ,3600 ,"S" })});// Mar lastSun + case 1999..: + return ({({0 ,0 ,3600 ,"S" })}); + } + } +} + +class Iran +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1978: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(80) ,UO+0 ,3600 ,"S" }), // Mar 21 + ({FIXED(294) ,UO-3600 ,0 ,"" })});// Oct 21 + case 1979: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(80) ,UO+0 ,3600 ,"S" }), // Mar 21 + ({FIXED(262) ,UO-3600 ,0 ,"" })});// Sep 19 + case 1991: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(123) ,UO+0 ,3600 ,"S" }), // May 3 + ({FIXED(263) ,UO+0 ,0 ,"" })});// Sep 20 + case 1980: + case 1992..1995: + case 1997..1999: + case 2001..2003: + case 2005..2007: + case 2009..2011: + case 2013..2015: + case 2017..2019: + case 2021..2023: + case 2026..2027: + case 2030..2031: + case 2034..2035: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(80) ,UO+0 ,3600 ,"S" }), // Mar 21 + ({FIX_L(266) ,UO-3600 ,0 ,"" })});// Sep 23 + case 1996: + case 2000: + case 2004: + case 2008: + case 2012: + case 2016: + case 2020: + case 2024..2025: + case 2028..2029: + case 2032..2033: + case 2036..2037: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(79) ,UO+0 ,3600 ,"S" }), // Mar 20 + ({FIX_L(265) ,UO-3600 ,0 ,"" })});// Sep 22 + default: // ..1977 and 2038.. + case 1981..1990: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Iraq +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1981: + return ({({0 ,0 ,0 ,"S" })});// ? + case 1982: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(121) ,UO+0 ,3600 ,"D" }), // May 1 + ({FIXED(274) ,UO-3600 ,0 ,"S" })});// Oct 1 + case 1983: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(90) ,UO+0 ,3600 ,"D" }), // Mar 31 + ({FIXED(274) ,UO-3600 ,0 ,"S" })});// Oct 1 + case 1984: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(92) ,UO+0 ,3600 ,"D" }), // Apr 1 + ({FIXED(275) ,UO-3600 ,0 ,"S" })});// Oct 1 + case 1985: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(91) ,UO+0 ,3600 ,"D" }), // Apr 1 + ({LDAY (273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1986..1990: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(90,7) ,UO+3600 ,3600 ,"D" }), // Mar lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1991: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(91) ,UO+10800 ,3600 ,"D" }), // Apr 1 + ({FIXED(274) ,UO+10800 ,0 ,"D" })});// Oct 1 + case 1992..: + return ({({0 ,0 ,0 ,"D" }), + ({FIX_L(91) ,UO+10800 ,3600 ,"D" }), // Apr 1 + ({FIX_L(274) ,UO+10800 ,0 ,"D" })});// Oct 1 + } + } +} + +class Zion +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1940: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(153) ,UO+0 ,3600 ,"D" })});// Jun 1 + case 1941: + return ({({0 ,0 ,3600 ,"D" })}); + case 1942: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(305) ,UO-3600 ,0 ,"S" })});// Nov 1 + case 1943: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(91) ,UO+7200 ,3600 ,"D" }), // Apr 1 + ({FIXED(305) ,UO-3600 ,0 ,"S" })});// Nov 1 + case 1944: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(92) ,UO+0 ,3600 ,"D" }), // Apr 1 + ({FIXED(306) ,UO-3600 ,0 ,"S" })});// Nov 1 + case 1945: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(106) ,UO+0 ,3600 ,"D" }), // Apr 16 + ({FIXED(305) ,UO+3600 ,0 ,"S" })});// Nov 1 + case 1946: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(106) ,UO+7200 ,3600 ,"D" }), // Apr 16 + ({FIXED(305) ,UO-3600 ,0 ,"S" })});// Nov 1 + case 1948: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(144) ,UO+0 ,7200 ,"DD" }), // May 23 + ({FIXED(245) ,UO-7200 ,3600 ,"D" }), // Sep 1 + ({FIXED(306) ,UO+3600 ,0 ,"S" })});// Nov 1 + case 1949: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(121) ,UO+0 ,3600 ,"D" }), // May 1 + ({FIXED(305) ,UO+3600 ,0 ,"S" })});// Nov 1 + case 1950: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(106) ,UO+0 ,3600 ,"D" }), // Apr 16 + ({FIXED(258) ,UO+7200 ,0 ,"S" })});// Sep 15 + case 1951: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(91) ,UO+0 ,3600 ,"D" }), // Apr 1 + ({FIXED(315) ,UO+7200 ,0 ,"S" })});// Nov 11 + case 1952: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(111) ,UO+7200 ,3600 ,"D" }), // Apr 20 + ({FIXED(293) ,UO+7200 ,0 ,"S" })});// Oct 19 + case 1953: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(102) ,UO+7200 ,3600 ,"D" }), // Apr 12 + ({FIXED(256) ,UO+7200 ,0 ,"S" })});// Sep 13 + case 1954: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(164) ,UO+0 ,3600 ,"D" }), // Jun 13 + ({FIXED(255) ,UO-3600 ,0 ,"S" })});// Sep 12 + case 1955: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(162) ,UO+7200 ,3600 ,"D" }), // Jun 11 + ({FIXED(254) ,UO-3600 ,0 ,"S" })});// Sep 11 + case 1956: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(155) ,UO+0 ,3600 ,"D" }), // Jun 3 + ({FIXED(274) ,UO+7200 ,0 ,"S" })});// Sep 30 + case 1957: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(119) ,UO+7200 ,3600 ,"D" }), // Apr 29 + ({FIXED(265) ,UO-3600 ,0 ,"S" })});// Sep 22 + case 1974: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(188) ,UO+0 ,3600 ,"D" }), // Jul 7 + ({FIXED(286) ,UO-3600 ,0 ,"S" })});// Oct 13 + case 1975: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(110) ,UO+0 ,3600 ,"D" }), // Apr 20 + ({FIXED(243) ,UO-3600 ,0 ,"S" })});// Aug 31 + default: // ..1939: + case 1947: + case 1958..1973: + case 1976..1984: + return ({({0 ,0 ,0 ,"S" })}); + case 1985: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(104) ,UO+0 ,3600 ,"D" }), // Apr 14 + ({FIXED(258) ,UO-3600 ,0 ,"S" })});// Sep 15 + case 1986: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(138) ,UO+0 ,3600 ,"D" }), // May 18 + ({FIXED(250) ,UO-3600 ,0 ,"S" })});// Sep 7 + case 1987: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(105) ,UO+0 ,3600 ,"D" }), // Apr 15 + ({FIXED(256) ,UO-3600 ,0 ,"S" })});// Sep 13 + case 1988: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(100) ,UO+0 ,3600 ,"D" }), // Apr 9 + ({FIXED(247) ,UO-3600 ,0 ,"S" })});// Sep 3 + case 1989: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(120) ,UO+0 ,3600 ,"D" }), // Apr 30 + ({FIXED(246) ,UO-3600 ,0 ,"S" })});// Sep 3 + case 1990: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(84) ,UO+0 ,3600 ,"D" }), // Mar 25 + ({FIXED(238) ,UO-3600 ,0 ,"S" })});// Aug 26 + case 1991: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(83) ,UO+0 ,3600 ,"D" }), // Mar 24 + ({FIXED(244) ,UO-3600 ,0 ,"S" })});// Sep 1 + case 1992: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(89) ,UO+0 ,3600 ,"D" }), // Mar 29 + ({FIXED(250) ,UO-3600 ,0 ,"S" })});// Sep 6 + case 1993: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(92) ,UO+0 ,3600 ,"D" }), // Apr 2 + ({FIXED(248) ,UO-3600 ,0 ,"S" })});// Sep 5 + case 1994: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(91) ,UO+0 ,3600 ,"D" }), // Apr 1 + ({FIXED(240) ,UO-3600 ,0 ,"S" })});// Aug 28 + case 1995: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(90) ,UO+0 ,3600 ,"D" }), // Mar 31 + ({FIXED(246) ,UO-3600 ,0 ,"S" })});// Sep 3 + case 1996: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(75) ,UO+0 ,3600 ,"D" }), // Mar 15 + ({FIXED(260) ,UO-3600 ,0 ,"S" })});// Sep 16 + case 1997: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(80) ,UO+0 ,3600 ,"D" }), // Mar 21 + ({FIXED(257) ,UO-3600 ,0 ,"S" })});// Sep 14 + case 1998: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(79) ,UO+0 ,3600 ,"D" }), // Mar 20 + ({FIXED(249) ,UO-3600 ,0 ,"S" })});// Sep 6 + case 1999: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(92) ,UO+7200 ,3600 ,"D" }), // Apr 2 + ({FIXED(246) ,UO+3600 ,0 ,"S" })});// Sep 3 + case 2000: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(105) ,UO+7200 ,3600 ,"D" }), // Apr 14 + ({FIXED(296) ,UO+3600 ,0 ,"S" })});// Oct 22 + case 2001: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(96) ,UO+7200 ,3600 ,"D" }), // Apr 6 + ({FIXED(283) ,UO+3600 ,0 ,"S" })});// Oct 10 + case 2002: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(88) ,UO+7200 ,3600 ,"D" }), // Mar 29 + ({FIXED(272) ,UO+3600 ,0 ,"S" })});// Sep 29 + case 2003..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(90,5) ,UO+7200 ,3600 ,"D" }), // Mar Fri>=25 + ({FIX_L(274) ,UO+3600 ,0 ,"S" })});// Oct 1 + } + } +} + +class Jordan +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1973: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(157) ,UO+0 ,3600 ,"S" }), // Jun 6 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1976: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(122) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIXED(306) ,UO-3600 ,0 ,"" })});// Nov 1 + case 1974..1975: + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(120) ,UO+0 ,3600 ,"S" }), // Apr 30 + ({FIXED(273) ,UO-3600 ,0 ,"" })});// Sep 30 + default: // ..1972: + case 1979..1984: + return ({({0 ,0 ,0 ,"" })}); + case 1985: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(91) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1989: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(128) ,UO+0 ,3600 ,"S" }), // May 8 + ({LDAY (280,5),UO-3600 ,0 ,"" })});// Oct Fri>=1 + case 1990: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(117) ,UO+0 ,3600 ,"S" }), // Apr 27 + ({LDAY (280,5),UO-3600 ,0 ,"" })});// Oct Fri>=1 + case 1991: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(107) ,UO+0 ,3600 ,"S" }), // Apr 17 + ({FIXED(270) ,UO-3600 ,0 ,"" })});// Sep 27 + case 1992: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(101) ,UO+0 ,3600 ,"S" }), // Apr 10 + ({LDAY (281,5),UO-3600 ,0 ,"" })});// Oct Fri>=1 + case 1986..1988: + case 1993: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(97,5) ,UO+0 ,3600 ,"S" }), // Apr Fri>=1 + ({LDAYL(280,5),UO-3600 ,0 ,"" })});// Oct Fri>=1 + case 1994: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,5) ,UO+0 ,3600 ,"S" }), // Apr Fri>=1 + ({LDAY (264,5),UO-3600 ,0 ,"" })});// Sep Fri>=15 + case 1995..1998: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(97,5) ,UO+0 ,3600 ,"S" }), // Apr Fri>=1 + ({LDAYL(264,5),UO+0 ,0 ,"" })});// Sep Fri>=15 + case 1999: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(182) ,UO+0 ,3600 ,"S" }), // Jul 1 + ({LDAY (273,4),UO+0 ,0 ,"" })});// Sep lastThu + case 2000..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,4) ,UO+0 ,3600 ,"S" }), // Mar lastThu + ({LDAYL(273,4),UO+0 ,0 ,"" })});// Sep lastThu + } + } +} + +class Kirgiz +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1991: + return ({({0 ,0 ,0 ,"" })});// ? + case 1992..1996: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(103,7),UO+0 ,3600 ,"S" }), // Apr Sun>=7 + ({LDAYL(273,7),UO-3600 ,0 ,"" })});// Sep lastSun + case 1997..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+9000 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(304,7),UO+5400 ,0 ,"" })});// Oct lastSun + } + } +} + +class ROK +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1960: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(136) ,UO+0 ,3600 ,"D" }), // May 15 + ({FIXED(257) ,UO-3600 ,0 ,"S" })});// Sep 13 + case 1987..1988: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(134,7),UO+0 ,3600 ,"D" }), // May Sun<=14 + ({LDAYL(287,7),UO-3600 ,0 ,"S" })});// Oct Sun<=14 + default: // ..1959 and 1989.. + case 1961..1986: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Lebanon +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1920: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(88) ,UO+0 ,3600 ,"S" }), // Mar 28 + ({FIXED(299) ,UO-3600 ,0 ,"" })});// Oct 25 + case 1921: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(93) ,UO+0 ,3600 ,"S" }), // Apr 3 + ({FIXED(276) ,UO-3600 ,0 ,"" })});// Oct 3 + case 1922: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(85) ,UO+0 ,3600 ,"S" }), // Mar 26 + ({FIXED(281) ,UO-3600 ,0 ,"" })});// Oct 8 + case 1923: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(112) ,UO+0 ,3600 ,"S" }), // Apr 22 + ({FIXED(259) ,UO-3600 ,0 ,"" })});// Sep 16 + case 1972: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(174) ,UO+0 ,3600 ,"S" }), // Jun 22 + ({FIXED(275) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1957..1961: + case 1973..1977: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(121) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIX_L(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(120) ,UO+0 ,3600 ,"S" }), // Apr 30 + ({FIXED(273) ,UO-3600 ,0 ,"" })});// Sep 30 + default: // ..1919: + case 1924..1956: + case 1962..1971: + case 1979..1983: + return ({({0 ,0 ,0 ,"" })}); + case 1988: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(153) ,UO+0 ,3600 ,"S" }), // Jun 1 + ({FIXED(290) ,UO-3600 ,0 ,"" })});// Oct 16 + case 1989: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(130) ,UO+0 ,3600 ,"S" }), // May 10 + ({FIXED(289) ,UO-3600 ,0 ,"" })});// Oct 16 + case 1984..1987: + case 1990..1991: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(121) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIX_L(289) ,UO-3600 ,0 ,"" })});// Oct 16 + case 1992: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(122) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIXED(278) ,UO-3600 ,0 ,"" })});// Oct 4 + case 1993..1998: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+0 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),UO-3600 ,0 ,"" })});// Sep lastSun + case 1999..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+0 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(304,7),UO-3600 ,0 ,"" })});// Oct lastSun + } + } +} + +class NBorneo +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1935..1941: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(257) ,UO+0 ,1200 ,"TS" }), // Sep 14 + ({FIX_L(348) ,UO-1200 ,0 ,"" })});// Dec 14 + default: // ..1934 and 1942.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Mongol +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1981..1984: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(91) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({FIX_L(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1985..1990: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),UO+7200 ,0 ,"" })});// Sep lastSun + case 1996: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (91,7) ,UO+0 ,3600 ,"S" }), // Mar lastSun + ({LDAY (305,7),UO-3600 ,0 ,"" })});// Oct lastSun + case 1991..1995: + case 1997..1998: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+0 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),UO-3600 ,0 ,"" })});// Sep lastSun + default: // ..1980 and 1999.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class EgyptAsia +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1956: + return ({({0 ,0 ,0 ,"" })});// ? + case 1957: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(130) ,UO+0 ,3600 ,"S" }), // May 10 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1958: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1959..1965: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(121) ,UO+3600 ,3600 ,"S" }), // May 1 + ({FIX_L(273) ,UO+7200 ,0 ,"" })});// Sep 30 + case 1966: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+3600 ,3600 ,"S" }), // May 1 + ({FIXED(274) ,UO+7200 ,0 ,"" })});// Oct 1 + case 1967: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+3600 ,3600 ,"S" })});// May 1 + case 1968..: + return ({({0 ,0 ,3600 ,"S" })}); + } + } +} + +class Palestine +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1998: + return ({({0 ,0 ,0 ,"" })});// ? + case 1999..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(111,5),UO+0 ,3600 ,"S" }), // Apr Fri>=15 + ({LDAYL(294,5),UO-3600 ,0 ,"" })});// Oct Fri>=15 + } + } +} + +class Phil +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1936: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(306) ,UO+0 ,3600 ,"S" })});// Nov 1 + case 1937: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(32) ,UO-3600 ,0 ,"" })});// Feb 1 + case 1954: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(102) ,UO+0 ,3600 ,"S" }), // Apr 12 + ({FIXED(182) ,UO-3600 ,0 ,"" })});// Jul 1 + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(81) ,UO+0 ,3600 ,"S" }), // Mar 22 + ({FIXED(264) ,UO-3600 ,0 ,"" })});// Sep 21 + default: // ..1935 and 1979.. + case 1938..1953: + case 1955..1977: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Syria +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1920..1923: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(111,7),UO+7200 ,3600 ,"S" }), // Apr Sun>=15 + ({LDAYL(280,7),UO+3600 ,0 ,"" })});// Oct Sun>=1 + case 1962: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(119) ,UO+7200 ,3600 ,"S" }), // Apr 29 + ({FIXED(274) ,UO+3600 ,0 ,"" })});// Oct 1 + case 1963: + case 1965: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+7200 ,3600 ,"S" }), // May 1 + ({FIXED(273) ,UO+3600 ,0 ,"" })});// Sep 30 + case 1966: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(114) ,UO+7200 ,3600 ,"S" }), // Apr 24 + ({FIXED(274) ,UO+3600 ,0 ,"" })});// Oct 1 + case 1964: + case 1967..1976: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(121) ,UO+7200 ,3600 ,"S" }), // May 1 + ({FIX_L(274) ,UO+3600 ,0 ,"" })});// Oct 1 + case 1977..1978: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+7200 ,3600 ,"S" }), // May 1 + ({FIXED(244) ,UO+3600 ,0 ,"" })});// Sep 1 + case 1983..1984: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(99) ,UO+7200 ,3600 ,"S" }), // Apr 9 + ({FIX_L(274) ,UO+3600 ,0 ,"" })});// Oct 1 + default: // ..1919: + case 1924..1961: + case 1979..1982: + case 1985: + return ({({0 ,0 ,0 ,"" })}); + case 1986: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(47) ,UO+7200 ,3600 ,"S" }), // Feb 16 + ({FIXED(282) ,UO+3600 ,0 ,"" })});// Oct 9 + case 1987: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(60) ,UO+7200 ,3600 ,"S" }), // Mar 1 + ({FIXED(304) ,UO+3600 ,0 ,"" })});// Oct 31 + case 1988: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(75) ,UO+7200 ,3600 ,"S" }), // Mar 15 + ({FIXED(305) ,UO+3600 ,0 ,"" })});// Oct 31 + case 1989: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(90) ,UO+7200 ,3600 ,"S" }), // Mar 31 + ({FIXED(274) ,UO+3600 ,0 ,"" })});// Oct 1 + case 1990: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(91) ,UO+7200 ,3600 ,"S" }), // Apr 1 + ({FIXED(273) ,UO+3600 ,0 ,"" })});// Sep 30 + case 1992: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(99) ,UO+0 ,3600 ,"S" }), // Apr 8 + ({FIXED(275) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1993: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(85) ,UO+0 ,3600 ,"S" }), // Mar 26 + ({FIXED(268) ,UO-3600 ,0 ,"" })});// Sep 25 + case 1997..1998: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (90,1) ,UO+0 ,3600 ,"S" }), // Mar lastMon + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1991: + case 1994..1996: + case 1999..: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(91) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({FIX_L(274) ,UO-3600 ,0 ,"" })});// Oct 1 + } + } +} + +class Aus +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1917: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(1) ,UO+60 ,3600 ,"" }), // Jan 1 + ({FIXED(84) ,UO+3600 ,0 ,"" })});// Mar 25 + case 1942: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(1) ,UO+7200 ,3600 ,"" }), // Jan 1 + ({FIXED(88) ,UO+3600 ,0 ,"" }), // Mar 29 + ({FIXED(270) ,UO+7200 ,3600 ,"" })});// Sep 27 + case 1943: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (90,7) ,UO+3600 ,0 ,"" }), // Mar lastSun + ({FIXED(276) ,UO+7200 ,3600 ,"" })});// Oct 3 + case 1944: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (91,7) ,UO+3600 ,0 ,"" })});// Mar lastSun + default: // ..1916 and 1945.. + case 1918..1941: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class AQ +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1972: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (60,7) ,UO+7200 ,0 ,"" })});// Feb lastSun + case 1971: + case 1989: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1990..1991: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (66,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=1 + ({LDAY (304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1992: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (67,7) ,UO+7200 ,0 ,"" })});// Mar Sun>=1 + default: // ..1970 and 1993.. + case 1973..1988: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Holiday +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1992: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (305,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1993: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (66,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=1 + ({LDAY (304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1994: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (66,7) ,UO+7200 ,0 ,"" })});// Mar Sun>=1 + default: // ..1991 and 1995.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class AS +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1970: + return ({({0 ,0 ,0 ,"" })});// ? + case 1971: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1972: + return ({({0 ,0 ,3600 ,"" }), + ({FIXED(58) ,UO+7200 ,0 ,"" }), // Feb 27 + ({LDAY (305,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1986: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (80,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=15 + ({FIXED(292) ,UO+7200 ,3600 ,"" })});// Oct 19 + case 1987..1989: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(80,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=15 + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1973..1985: + case 1991: + case 1993: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(66,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=1 + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1990: + case 1992: + case 1994: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(83,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=18 + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1995..: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,0 ,"" }), // Mar lastSun + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + } + } +} + +class AT +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1966: + return ({({0 ,0 ,0 ,"" })});// ? + case 1967: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (280,7),UO+7200 ,3600 ,"" })});// Oct Sun>=1 + case 1969..1971: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (73,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=8 + ({LDAY (304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1972: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (60,7) ,UO+7200 ,0 ,"" }), // Feb lastSun + ({LDAY (305,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1968: + case 1982..1983: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,0 ,"" }), // Mar lastSun + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1973..1981: + case 1984..1985: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(66,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=1 + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1986: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (66,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=1 + ({LDAY (294,7),UO+7200 ,3600 ,"" })});// Oct Sun>=15 + case 1987: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (80,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=15 + ({LDAY (301,7),UO+7200 ,3600 ,"" })});// Oct Sun>=22 + case 1988..1990: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(80,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=15 + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 2000: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (91,7) ,UO+7200 ,0 ,"" }), // Mar lastSun + ({LDAY (244,7),UO+7200 ,3600 ,"" })});// Aug lastSun + case 1991..1999: + case 2001..: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,0 ,"" }), // Mar lastSun + ({LDAYL(280,7),UO+7200 ,3600 ,"" })});// Oct Sun>=1 + } + } +} + +class AV +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1970: + return ({({0 ,0 ,0 ,"" })});// ? + case 1971: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1972: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (60,7) ,UO+7200 ,0 ,"" }), // Feb lastSun + ({LDAY (305,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1986..1987: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (80,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=15 + ({LDAY (294,7),UO+7200 ,3600 ,"" })});// Oct Sun>=15 + case 1988..1990: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(80,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=15 + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1973..1985: + case 1991..1994: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(66,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=1 + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 2000: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (91,7) ,UO+7200 ,0 ,"" }), // Mar lastSun + ({LDAY (244,7),UO+7200 ,3600 ,"" })});// Aug lastSun + case 1995..1999: + case 2001..: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,0 ,"" }), // Mar lastSun + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + } + } +} + +class AN +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1970: + return ({({0 ,0 ,0 ,"" })});// ? + case 1971: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1972: + return ({({0 ,0 ,3600 ,"" }), + ({FIXED(58) ,UO+7200 ,0 ,"" }), // Feb 27 + ({LDAY (305,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1982: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (97,7) ,UO+7200 ,0 ,"" }), // Apr Sun>=1 + ({LDAY (304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1986: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (80,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=15 + ({FIXED(292) ,UO+7200 ,3600 ,"" })});// Oct 19 + case 1987..1989: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(80,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=15 + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1973..1981: + case 1983..1985: + case 1990..1995: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(66,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=1 + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 2000: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (91,7) ,UO+7200 ,0 ,"" }), // Mar lastSun + ({LDAY (244,7),UO+7200 ,3600 ,"" })});// Aug lastSun + case 1996..1999: + case 2001..: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,0 ,"" }), // Mar lastSun + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + } + } +} + +class LH +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1980: + return ({({0 ,0 ,0 ,"" })});// ? + case 1981: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1982..1984: + return ({({0 ,0 ,3600 ,"" }), + ({LDAYL(66,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=1 + ({LDAYL(304,7),UO+7200 ,3600 ,"" })});// Oct lastSun + case 1985: + return ({({0 ,0 ,3600 ,"" }), + ({LDAY (66,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=1 + ({LDAY (304,7),UO+7200 ,1800 ,"" })});// Oct lastSun + case 1986: + return ({({0 ,0 ,1800 ,"" }), + ({LDAY (80,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=15 + ({FIXED(292) ,UO+7200 ,1800 ,"" })});// Oct 19 + case 1987..1989: + return ({({0 ,0 ,1800 ,"" }), + ({LDAYL(80,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=15 + ({LDAYL(304,7),UO+7200 ,1800 ,"" })});// Oct lastSun + case 1990..1995: + return ({({0 ,0 ,1800 ,"" }), + ({LDAYL(66,7) ,UO+7200 ,0 ,"" }), // Mar Sun>=1 + ({LDAYL(304,7),UO+7200 ,1800 ,"" })});// Oct lastSun + case 2000: + return ({({0 ,0 ,1800 ,"" }), + ({LDAY (91,7) ,UO+7200 ,0 ,"" }), // Mar lastSun + ({LDAY (244,7),UO+7200 ,1800 ,"" })});// Aug lastSun + case 1996..1999: + case 2001..: + return ({({0 ,0 ,1800 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,0 ,"" }), // Mar lastSun + ({LDAYL(304,7),UO+7200 ,1800 ,"" })});// Oct lastSun + } + } +} + +class Cook +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1978: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(316) ,UO+0 ,1800 ,"HS" })});// Nov 12 + case 1979..1990: + return ({({0 ,0 ,1800 ,"HS" }), + ({LDAYL(66,7) ,UO-1800 ,0 ,"" }), // Mar Sun>=1 + ({LDAYL(304,7),UO+0 ,1800 ,"HS" })});// Oct lastSun + case 1991: + return ({({0 ,0 ,1800 ,"HS" }), + ({LDAY (66,7) ,UO-1800 ,0 ,"" })});// Mar Sun>=1 + default: // ..1977 and 1992.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Fiji +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1997: + return ({({0 ,0 ,0 ,"" })});// ? + case 1998: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (311,7),UO+7200 ,3600 ,"S" })});// Nov Sun>=1 + case 1999..: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(59,7) ,UO+7200 ,0 ,"" }), // Feb lastSun + ({LDAYL(311,7),UO+7200 ,3600 ,"S" })});// Nov Sun>=1 + } + } +} + +class NC +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1977: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (341,7),UO+0 ,3600 ,"S" })});// Dec Sun>=1 + case 1978: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(58) ,UO-3600 ,0 ,"" }), // Feb 27 + ({LDAY (341,7),UO+0 ,3600 ,"S" })});// Dec Sun>=1 + case 1979: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(58) ,UO-3600 ,0 ,"" })});// Feb 27 + case 1996: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(336) ,UO+7200 ,3600 ,"S" })});// Dec 1 + case 1997: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(61) ,UO+7200 ,0 ,"" })});// Mar 2 + default: // ..1976 and 1998.. + case 1980..1995: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class NZ +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1927: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(330) ,UO+7200 ,1800 ,"HD" })});// Nov 26 + case 1928: + return ({({0 ,0 ,1800 ,"HD" }), + ({LDAY (67,7) ,UO+5400 ,0 ,"S" }), // Mar Sun>=1 + ({FIXED(309) ,UO+7200 ,1800 ,"HD" })});// Nov 4 + case 1929: + return ({({0 ,0 ,1800 ,"HD" }), + ({LDAY (66,7) ,UO+5400 ,0 ,"S" }), // Mar Sun>=1 + ({FIXED(303) ,UO+7200 ,1800 ,"HD" })});// Oct 30 + case 1930..1933: + return ({({0 ,0 ,1800 ,"HD" }), + ({LDAYL(80,7) ,UO+5400 ,0 ,"S" }), // Mar Sun>=15 + ({LDAYL(287,7),UO+7200 ,1800 ,"HD" })});// Oct Sun>=8 + case 1934..1939: + return ({({0 ,0 ,1800 ,"HD" }), + ({LDAYL(120,7),UO+5400 ,0 ,"S" }), // Apr lastSun + ({LDAYL(273,7),UO+7200 ,1800 ,"HD" })});// Sep lastSun + case 1940: + return ({({0 ,0 ,1800 ,"HD" }), + ({LDAY (121,7),UO+5400 ,0 ,"S" })});// Apr lastSun + default: // ..1926: + case 1941..1973: + return ({({0 ,0 ,0 ,"S" })}); + case 1974: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(307) ,UO+7200 ,3600 ,"D" })});// Nov 3 + case 1975: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(54) ,UO+7200 ,0 ,"S" }), // Feb 23 + ({LDAY (304,7),UO+7200 ,3600 ,"D" })});// Oct lastSun + case 1976..1988: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAYL(66,7) ,UO+7200 ,0 ,"S" }), // Mar Sun>=1 + ({LDAYL(304,7),UO+7200 ,3600 ,"D" })});// Oct lastSun + case 1989: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAY (66,7) ,UO+7200 ,0 ,"S" }), // Mar Sun>=1 + ({FIXED(281) ,UO+7200 ,3600 ,"D" })});// Oct 8 + case 1990..: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAYL(80,7) ,UO+7200 ,0 ,"S" }), // Mar Sun>=15 + ({LDAYL(280,7),UO+7200 ,3600 ,"D" })});// Oct Sun>=1 + } + } +} + +class Chatham +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1989: + return ({({0 ,0 ,0 ,"S" })});// ? + case 1990: + return ({({0 ,0 ,0 ,"S" }), // ? + ({LDAY (280,7),UO+9900 ,3600 ,"D" })});// Oct Sun>=1 + case 1991..: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAYL(80,7) ,UO+9900 ,0 ,"S" }), // Mar Sun>=15 + ({LDAYL(280,7),UO+9900 ,3600 ,"D" })});// Oct Sun>=1 + } + } +} + +class Tonga +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1998: + return ({({0 ,0 ,0 ,"" })});// ? + case 1999: + return ({({0 ,0 ,0 ,"" }), // ? + ({LDAY (280,6),UO+7200 ,3600 ,"S" })});// Oct Sat>=1 + case 2000..: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(112,7),UO+7200 ,0 ,"" }), // Apr Sun>=16 + ({LDAYL(280,6),UO+7200 ,3600 ,"S" })});// Oct Sat>=1 + } + } +} + +class Vanuatu +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1983: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(268) ,UO+0 ,3600 ,"S" })});// Sep 25 + case 1984: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (89,7) ,UO-3600 ,0 ,"" }), // Mar Sun>=23 + ({FIXED(297) ,UO+0 ,3600 ,"S" })});// Oct 23 + case 1985..1991: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(88,7) ,UO-3600 ,0 ,"" }), // Mar Sun>=23 + ({LDAYL(272,7),UO+0 ,3600 ,"S" })});// Sep Sun>=23 + case 1992: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (29,7) ,UO-3600 ,0 ,"" }), // Jan Sun>=23 + ({LDAY (303,7),UO+0 ,3600 ,"S" })});// Oct Sun>=23 + case 1993: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (29,7) ,UO-3600 ,0 ,"" })});// Jan Sun>=23 + default: // ..1982 and 1994.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class GB_Eire +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1916: + return ({({0 ,0 ,0 ,"GMT" }), // ? + ({FIXED(142) ,UO+7200 ,3600 ,"BST" }), // May 21 + ({FIXED(275) ,UO+7200 ,0 ,"GMT" })});// Oct 1 + case 1917: + return ({({0 ,0 ,0 ,"GMT" }), + ({FIXED(98) ,UO+7200 ,3600 ,"BST" }), // Apr 8 + ({FIXED(260) ,UO+7200 ,0 ,"GMT" })});// Sep 17 + case 1918: + return ({({0 ,0 ,0 ,"GMT" }), + ({FIXED(83) ,UO+7200 ,3600 ,"BST" }), // Mar 24 + ({FIXED(273) ,UO+7200 ,0 ,"GMT" })});// Sep 30 + case 1919: + return ({({0 ,0 ,0 ,"GMT" }), + ({FIXED(89) ,UO+7200 ,3600 ,"BST" }), // Mar 30 + ({FIXED(272) ,UO+7200 ,0 ,"GMT" })});// Sep 29 + case 1920: + return ({({0 ,0 ,0 ,"GMT" }), + ({FIXED(88) ,UO+7200 ,3600 ,"BST" }), // Mar 28 + ({FIXED(299) ,UO+7200 ,0 ,"GMT" })});// Oct 25 + case 1921: + return ({({0 ,0 ,0 ,"GMT" }), + ({FIXED(93) ,UO+7200 ,3600 ,"BST" }), // Apr 3 + ({FIXED(276) ,UO+7200 ,0 ,"GMT" })});// Oct 3 + case 1922: + return ({({0 ,0 ,0 ,"GMT" }), + ({FIXED(85) ,UO+7200 ,3600 ,"BST" }), // Mar 26 + ({FIXED(281) ,UO+7200 ,0 ,"GMT" })});// Oct 8 + case 1923: + return ({({0 ,0 ,0 ,"GMT" }), + ({LDAY (112,7),UO+7200 ,3600 ,"BST" }), // Apr Sun>=16 + ({LDAY (265,7),UO+7200 ,0 ,"GMT" })});// Sep Sun>=16 + case 1924: + return ({({0 ,0 ,0 ,"GMT" }), + ({LDAY (106,7),UO+7200 ,3600 ,"BST" }), // Apr Sun>=9 + ({LDAY (266,7),UO+7200 ,0 ,"GMT" })});// Sep Sun>=16 + case 1939: + return ({({0 ,0 ,0 ,"GMT" }), + ({LDAY (112,7),UO+7200 ,3600 ,"BST" }), // Apr Sun>=16 + ({LDAY (326,7),UO+7200 ,0 ,"GMT" })});// Nov Sun>=16 + case 1940: + return ({({0 ,0 ,0 ,"GMT" }), + ({LDAY (61,7) ,UO+7200 ,3600 ,"BST" })});// Feb Sun>=23 + case 1941: + return ({({0 ,0 ,3600 ,"BST" }), + ({LDAY (128,7),UO+3600 ,7200 ,"BDST"}), // May Sun>=2 + ({LDAY (227,7),UO+3600 ,3600 ,"BST" })});// Aug Sun>=9 + case 1942..1943: + return ({({0 ,0 ,3600 ,"BST" }), + ({LDAY (98,7) ,UO+3600 ,7200 ,"BDST"}), // Apr Sun>=2 + ({LDAY (227,7),UO+3600 ,3600 ,"BST" })});// Aug Sun>=9 + case 1944: + return ({({0 ,0 ,3600 ,"BST" }), + ({LDAY (99,7) ,UO+3600 ,7200 ,"BDST"}), // Apr Sun>=2 + ({LDAY (266,7),UO+3600 ,3600 ,"BST" })});// Sep Sun>=16 + case 1945: + return ({({0 ,0 ,3600 ,"BST" }), + ({LDAY (98,1) ,UO+3600 ,7200 ,"BDST"}), // Apr Mon>=2 + ({LDAY (196,7),UO+3600 ,3600 ,"BST" }), // Jul Sun>=9 + ({LDAY (281,7),UO+7200 ,0 ,"GMT" })});// Oct Sun>=2 + case 1947: + return ({({0 ,0 ,0 ,"GMT" }), + ({FIXED(75) ,UO+7200 ,3600 ,"BST" }), // Mar 16 + ({FIXED(103) ,UO+3600 ,7200 ,"BDST"}), // Apr 13 + ({FIXED(222) ,UO+3600 ,3600 ,"BST" }), // Aug 10 + ({FIXED(306) ,UO+7200 ,0 ,"GMT" })});// Nov 2 + case 1948: + return ({({0 ,0 ,0 ,"GMT" }), + ({FIXED(74) ,UO+7200 ,3600 ,"BST" }), // Mar 14 + ({FIXED(305) ,UO+7200 ,0 ,"GMT" })});// Oct 31 + case 1949: + return ({({0 ,0 ,0 ,"GMT" }), + ({FIXED(93) ,UO+7200 ,3600 ,"BST" }), // Apr 3 + ({FIXED(303) ,UO+7200 ,0 ,"GMT" })});// Oct 30 + case 1950..1952: + return ({({0 ,0 ,0 ,"GMT" }), + ({LDAYL(110,7),UO+7200 ,3600 ,"BST" }), // Apr Sun>=14 + ({LDAYL(300,7),UO+7200 ,0 ,"GMT" })});// Oct Sun>=21 + case 1925..1926: + case 1928..1929: + case 1931..1932: + case 1934: + case 1936..1937: + case 1953: + case 1955..1956: + case 1958..1959: + return ({({0 ,0 ,0 ,"GMT" }), + ({LDAYL(112,7),UO+7200 ,3600 ,"BST" }), // Apr Sun>=16 + ({LDAYL(281,7),UO+7200 ,0 ,"GMT" })});// Oct Sun>=2 + case 1927: + case 1930: + case 1933: + case 1935: + case 1938: + case 1946: + case 1954: + case 1957: + case 1960: + return ({({0 ,0 ,0 ,"GMT" }), + ({LDAYL(105,7),UO+7200 ,3600 ,"BST" }), // Apr Sun>=9 + ({LDAYL(281,7),UO+7200 ,0 ,"GMT" })});// Oct Sun>=2 + case 1961..1963: + return ({({0 ,0 ,0 ,"GMT" }), + ({LDAY (90,7) ,UO+7200 ,3600 ,"BST" }), // Mar lastSun + ({LDAY (302,7),UO+7200 ,0 ,"GMT" })});// Oct Sun>=23 + case 1964..1967: + return ({({0 ,0 ,0 ,"GMT" }), + ({LDAYL(84,7) ,UO+7200 ,3600 ,"BST" }), // Mar Sun>=19 + ({LDAYL(302,7),UO+7200 ,0 ,"GMT" })});// Oct Sun>=23 + case 1968: + return ({({0 ,0 ,0 ,"GMT" }), + ({FIXED(49) ,UO+7200 ,3600 ,"BST" }), // Feb 18 + ({LDAY (303,7),UO+7200 ,0 ,"GMT" })});// Oct Sun>=23 + case 1972..1980: + return ({({0 ,0 ,0 ,"GMT" }), + ({LDAYL(81,7) ,UO+7200 ,3600 ,"BST" }), // Mar Sun>=16 + ({LDAYL(302,7),UO+7200 ,0 ,"GMT" })});// Oct Sun>=23 + case 1981..1989: + return ({({0 ,0 ,0 ,"GMT" }), + ({LDAYL(90,7) ,3600 ,3600 ,"BST" }), // Mar lastSun + ({LDAYL(302,7),3600 ,0 ,"GMT" })});// Oct Sun>=23 + case 1990..1995: + return ({({0 ,0 ,0 ,"GMT" }), + ({LDAYL(90,7) ,3600 ,3600 ,"BST" }), // Mar lastSun + ({LDAYL(301,7),3600 ,0 ,"GMT" })});// Oct Sun>=22 + default: // ..1915 and 1996.. + case 1969..1971: + return ({({0 ,0 ,0 ,"GMT" })}); + } + } +} + +class EU +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1976: + return ({({0 ,0 ,0 ,"" })});// ? + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,3600 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(274) ,3600 ,0 ,"" })});// Oct 1 + case 1977: + case 1979..1980: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(97,7) ,3600 ,3600 ,"S" }), // Apr Sun>=1 + ({LDAYL(273,7),3600 ,0 ,"" })});// Sep lastSun + case 1981..1995: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,3600 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),3600 ,0 ,"" })});// Sep lastSun + case 1996..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,3600 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(304,7),3600 ,0 ,"" })});// Oct lastSun + } + } +} + +class W_Eur +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1976: + return ({({0 ,0 ,0 ,"" })});// ? + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+3600 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(274) ,UO+3600 ,0 ,"" })});// Oct 1 + case 1977: + case 1979..1980: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(97,7) ,UO+3600 ,3600 ,"S" }), // Apr Sun>=1 + ({LDAYL(273,7),UO+3600 ,0 ,"" })});// Sep lastSun + case 1981..1995: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+3600 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"" })});// Sep lastSun + case 1996..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+3600 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"" })});// Oct lastSun + } + } +} + +class C_Eur +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1916: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(121) ,UO+82800 ,3600 ,"S" }), // Apr 30 + ({FIXED(275) ,UO+0 ,0 ,"" })});// Oct 1 + case 1917..1918: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (111,1),UO+7200 ,3600 ,"S" }), // Apr Mon>=15 + ({LDAY (264,1),UO+7200 ,0 ,"" })});// Sep Mon>=15 + case 1940: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+7200 ,3600 ,"S" })});// Apr 1 + case 1941: + return ({({0 ,0 ,3600 ,"S" })}); + case 1942: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(306) ,UO+7200 ,0 ,"" })});// Nov 2 + case 1943: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(88) ,UO+7200 ,3600 ,"S" }), // Mar 29 + ({FIXED(277) ,UO+7200 ,0 ,"" })});// Oct 4 + case 1944: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(94) ,UO+7200 ,3600 ,"S" }), // Apr 3 + ({FIXED(276) ,UO+7200 ,0 ,"" })});// Oct 2 + default: // ..1915: + case 1919..1939: + case 1945..1976: + return ({({0 ,0 ,0 ,"" })}); + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+7200 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(274) ,UO+7200 ,0 ,"" })});// Oct 1 + case 1977: + case 1979..1980: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"S" }), // Apr Sun>=1 + ({LDAYL(273,7),UO+7200 ,0 ,"" })});// Sep lastSun + case 1981..1995: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),UO+7200 ,0 ,"" })});// Sep lastSun + case 1996..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(304,7),UO+7200 ,0 ,"" })});// Oct lastSun + } + } +} + +class E_Eur +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1976: + return ({({0 ,0 ,0 ,"" })});// ? + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+0 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1977: + case 1979..1980: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(97,7) ,UO+0 ,3600 ,"S" }), // Apr Sun>=1 + ({LDAYL(273,7),UO-3600 ,0 ,"" })});// Sep lastSun + case 1981..1995: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+0 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),UO-3600 ,0 ,"" })});// Sep lastSun + case 1996..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+0 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(304,7),UO-3600 ,0 ,"" })});// Oct lastSun + } + } +} + +class Russia +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1916: + return ({({0 ,0 ,0 ,"MMT" })});// ? + case 1917: + return ({({0 ,0 ,0 ,"MMT" }), // ? + ({FIXED(182) ,UO+82800 ,3600 ,"MST" }), // Jul 1 + ({FIXED(362) ,UO-3600 ,0 ,"MMT" })});// Dec 28 + case 1918: + return ({({0 ,0 ,0 ,"MMT" }), + ({FIXED(151) ,UO+79200 ,7200 ,"MDST"}), // May 31 + ({FIXED(259) ,UO-3600 ,3600 ,"MST" })});// Sep 16 + case 1919: + return ({({0 ,0 ,3600 ,"MST" }), + ({FIXED(151) ,UO+79200 ,7200 ,"MDST"}), // May 31 + ({FIXED(182) ,UO+0 ,3600 ,"S" }), // Jul 1 + ({FIXED(228) ,UO-3600 ,0 ,"" })});// Aug 16 + case 1921: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(45) ,UO+82800 ,3600 ,"S" }), // Feb 14 + ({FIXED(79) ,UO+79200 ,7200 ,"M" }), // Mar 20 + ({FIXED(244) ,UO-7200 ,3600 ,"S" }), // Sep 1 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1920: + case 1922..1980: + return ({({0 ,0 ,0 ,"" })}); + case 1981..1983: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(91) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1984: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({LDAY (274,7),UO+7200 ,0 ,"" })});// Sep lastSun + case 1992: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (91,6) ,UO+82800 ,3600 ,"S" }), // Mar lastSat + ({LDAY (274,6),UO+79200 ,0 ,"" })});// Sep lastSat + case 1985..1991: + case 1993..1995: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),UO+7200 ,0 ,"" })});// Sep lastSun + case 1996..: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(304,7),UO+7200 ,0 ,"" })});// Oct lastSun + } + } +} + +class Albania +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1940: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(168) ,UO+0 ,3600 ,"S" })});// Jun 16 + case 1942: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(306) ,UO+7200 ,0 ,"" })});// Nov 2 + case 1943: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(88) ,UO+7200 ,3600 ,"S" }), // Mar 29 + ({FIXED(100) ,UO+7200 ,0 ,"" })});// Apr 10 + default: // ..1939: + case 1944..1973: + return ({({0 ,0 ,0 ,"" })}); + case 1974: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(124) ,UO+0 ,3600 ,"S" }), // May 4 + ({FIXED(275) ,UO-3600 ,0 ,"" })});// Oct 2 + case 1975: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIXED(275) ,UO-3600 ,0 ,"" })});// Oct 2 + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(128) ,UO+0 ,3600 ,"S" }), // May 8 + ({FIXED(275) ,UO-3600 ,0 ,"" })});// Oct 2 + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(126) ,UO+0 ,3600 ,"S" }), // May 6 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1979: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(125) ,UO+0 ,3600 ,"S" }), // May 5 + ({FIXED(273) ,UO-3600 ,0 ,"" })});// Sep 30 + case 1980: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(124) ,UO+0 ,3600 ,"S" }), // May 3 + ({FIXED(278) ,UO-3600 ,0 ,"" })});// Oct 4 + case 1981: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(116) ,UO+0 ,3600 ,"S" }), // Apr 26 + ({FIXED(270) ,UO-3600 ,0 ,"" })});// Sep 27 + case 1976: + case 1982: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(122) ,UO+0 ,3600 ,"S" }), // May 2 + ({FIX_L(276) ,UO-3600 ,0 ,"" })});// Oct 3 + case 1983: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(108) ,UO+0 ,3600 ,"S" }), // Apr 18 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1984: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+0 ,3600 ,"S" })});// Apr 1 + case 1941: + case 1985..: + return ({({0 ,0 ,3600 ,"S" })}); + } + } +} + +class Austria +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1920: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(96) ,UO+7200 ,3600 ,"S" }), // Apr 5 + ({FIXED(257) ,UO+7200 ,0 ,"" })});// Sep 13 + case 1945: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+7200 ,3600 ,"S" }), // Apr 2 + ({FIXED(322) ,UO+7200 ,0 ,"" })});// Nov 18 + case 1946: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(104) ,UO+7200 ,3600 ,"S" }), // Apr 14 + ({LDAY (280,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + case 1947: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(96) ,UO+7200 ,3600 ,"S" }), // Apr 6 + ({LDAY (280,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + case 1948: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(109) ,UO+7200 ,3600 ,"S" }), // Apr 18 + ({LDAY (281,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + default: // ..1919 and 1949.. + case 1921..1944: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Belgium +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1918: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(68) ,UO+0 ,3600 ,"S" }), // Mar 9 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1919: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(60) ,UO+82800 ,3600 ,"S" }), // Mar 1 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1920: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(45) ,UO+82800 ,3600 ,"S" }), // Feb 14 + ({FIXED(297) ,UO+82800 ,0 ,"" })});// Oct 23 + case 1921: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(73) ,UO+82800 ,3600 ,"S" }), // Mar 14 + ({FIXED(298) ,UO+82800 ,0 ,"" })});// Oct 25 + case 1922: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(84) ,UO+82800 ,3600 ,"S" }), // Mar 25 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1923: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(111) ,UO+82800 ,3600 ,"S" }), // Apr 21 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1924: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(89) ,UO+82800 ,3600 ,"S" }), // Mar 29 + ({LDAY (281,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1925: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(94) ,UO+82800 ,3600 ,"S" }), // Apr 4 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1926: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(107) ,UO+82800 ,3600 ,"S" }), // Apr 17 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1927: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(99) ,UO+82800 ,3600 ,"S" }), // Apr 9 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1928: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(105) ,UO+82800 ,3600 ,"S" }), // Apr 14 + ({LDAY (282,7),UO+7200 ,0 ,"" })});// Oct Sun>=2 + case 1929: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(111) ,UO+7200 ,3600 ,"S" }), // Apr 21 + ({LDAY (281,7),UO+7200 ,0 ,"" })});// Oct Sun>=2 + case 1930: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(103) ,UO+7200 ,3600 ,"S" }), // Apr 13 + ({LDAY (281,7),UO+7200 ,0 ,"" })});// Oct Sun>=2 + case 1932: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(94) ,UO+7200 ,3600 ,"S" }), // Apr 3 + ({LDAY (282,7),UO+7200 ,0 ,"" })});// Oct Sun>=2 + case 1933: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(85) ,UO+7200 ,3600 ,"S" }), // Mar 26 + ({LDAY (281,7),UO+7200 ,0 ,"" })});// Oct Sun>=2 + case 1934: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(98) ,UO+7200 ,3600 ,"S" }), // Apr 8 + ({LDAY (281,7),UO+7200 ,0 ,"" })});// Oct Sun>=2 + case 1935: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(90) ,UO+7200 ,3600 ,"S" }), // Mar 31 + ({LDAY (281,7),UO+7200 ,0 ,"" })});// Oct Sun>=2 + case 1931: + case 1936: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(109) ,UO+7200 ,3600 ,"S" }), // Apr 19 + ({LDAYL(281,7),UO+7200 ,0 ,"" })});// Oct Sun>=2 + case 1937: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(94) ,UO+7200 ,3600 ,"S" }), // Apr 4 + ({LDAY (281,7),UO+7200 ,0 ,"" })});// Oct Sun>=2 + case 1938: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(86) ,UO+7200 ,3600 ,"S" }), // Mar 27 + ({LDAY (281,7),UO+7200 ,0 ,"" })});// Oct Sun>=2 + case 1939: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(106) ,UO+7200 ,3600 ,"S" }), // Apr 16 + ({FIXED(323) ,UO+7200 ,0 ,"" })});// Nov 19 + case 1940: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(56) ,UO+7200 ,3600 ,"S" })});// Feb 25 + case 1941..1943: + return ({({0 ,0 ,3600 ,"S" })}); + case 1944: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(261) ,UO+7200 ,0 ,"" })});// Sep 17 + case 1945: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+7200 ,3600 ,"S" }), // Apr 2 + ({FIXED(259) ,UO+7200 ,0 ,"" })});// Sep 16 + case 1946: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(139) ,UO+7200 ,3600 ,"S" }), // May 19 + ({FIXED(280) ,UO+7200 ,0 ,"" })});// Oct 7 + default: // ..1917 and 1947.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Bulg +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1978: + return ({({0 ,0 ,0 ,"" })});// ? + case 1979: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(90) ,UO+82800 ,3600 ,"S" }), // Mar 31 + ({FIXED(274) ,UO+0 ,0 ,"" })});// Oct 1 + case 1980: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (98,6) ,UO+82800 ,3600 ,"S" }), // Apr Sat<=7 + ({FIXED(273) ,UO+0 ,0 ,"" })});// Sep 29 + case 1981: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,6) ,UO+82800 ,3600 ,"S" }), // Apr Sat<=7 + ({FIXED(270) ,UO+3600 ,0 ,"" })});// Sep 27 + case 1982: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,6) ,UO+82800 ,3600 ,"S" })});// Apr Sat<=7 + case 1983..: + return ({({0 ,0 ,3600 ,"S" })}); + } + } +} + +class Czech +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1945: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(98) ,UO+7200 ,3600 ,"S" }), // Apr 8 + ({FIXED(322) ,UO+7200 ,0 ,"" })});// Nov 18 + case 1946: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(126) ,UO+7200 ,3600 ,"S" }), // May 6 + ({LDAY (280,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + case 1947: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(110) ,UO+7200 ,3600 ,"S" }), // Apr 20 + ({LDAY (280,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + case 1948: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(109) ,UO+7200 ,3600 ,"S" }), // Apr 18 + ({LDAY (281,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + case 1949: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(99) ,UO+7200 ,3600 ,"S" }), // Apr 9 + ({LDAY (280,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + default: // ..1944 and 1950.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Denmark +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1916: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(135) ,UO+82800 ,3600 ,"S" }), // May 14 + ({FIXED(274) ,UO+79200 ,0 ,"" })});// Sep 30 + case 1940: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(136) ,UO+0 ,3600 ,"S" })});// May 15 + case 1941..1944: + return ({({0 ,0 ,3600 ,"S" })}); + case 1945: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(92) ,UO+7200 ,3600 ,"S" }), // Apr 2 + ({FIXED(227) ,UO+7200 ,0 ,"" })});// Aug 15 + case 1946: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+7200 ,3600 ,"S" }), // May 1 + ({FIXED(244) ,UO+7200 ,0 ,"" })});// Sep 1 + case 1947: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(124) ,UO+7200 ,3600 ,"S" }), // May 4 + ({FIXED(222) ,UO+7200 ,0 ,"" })});// Aug 10 + case 1948: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(130) ,UO+7200 ,3600 ,"S" }), // May 9 + ({FIXED(221) ,UO+7200 ,0 ,"" })});// Aug 8 + default: // ..1915 and 1949.. + case 1917..1939: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Thule +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1992: + return ({({0 ,0 ,0 ,"S" })});// ? + case 1993..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class Finland +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1942: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(93) ,UO+0 ,3600 ,"S" }), // Apr 3 + ({FIXED(276) ,UO-3600 ,0 ,"" })});// Oct 3 + default: // ..1941 and 1943.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class France +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1916: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(166) ,UO+82800 ,3600 ,"S" }), // Jun 14 + ({LDAY (281,7),UO+82800 ,0 ,"" })});// Oct Sun>=1 + case 1917: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(83) ,UO+82800 ,3600 ,"S" }), // Mar 24 + ({LDAY (280,7),UO+82800 ,0 ,"" })});// Oct Sun>=1 + case 1918: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(68) ,UO+82800 ,3600 ,"S" }), // Mar 9 + ({LDAY (280,7),UO+82800 ,0 ,"" })});// Oct Sun>=1 + case 1919: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(60) ,UO+82800 ,3600 ,"S" }), // Mar 1 + ({LDAY (280,7),UO+82800 ,0 ,"" })});// Oct Sun>=1 + case 1920: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(45) ,UO+82800 ,3600 ,"S" }), // Feb 14 + ({FIXED(297) ,UO+82800 ,0 ,"" })});// Oct 23 + case 1921: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(73) ,UO+82800 ,3600 ,"S" }), // Mar 14 + ({FIXED(298) ,UO+82800 ,0 ,"" })});// Oct 25 + case 1923: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(146) ,UO+82800 ,3600 ,"S" }), // May 26 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1924: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(89) ,UO+82800 ,3600 ,"S" }), // Mar 29 + ({LDAY (281,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1925: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(94) ,UO+82800 ,3600 ,"S" }), // Apr 4 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1926: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(107) ,UO+82800 ,3600 ,"S" }), // Apr 17 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1927: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(99) ,UO+82800 ,3600 ,"S" }), // Apr 9 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1928: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(105) ,UO+82800 ,3600 ,"S" }), // Apr 14 + ({LDAY (281,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1929: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(110) ,UO+82800 ,3600 ,"S" }), // Apr 20 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1930: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(102) ,UO+82800 ,3600 ,"S" }), // Apr 12 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1932: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(93) ,UO+82800 ,3600 ,"S" }), // Apr 2 + ({LDAY (281,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1922: + case 1933: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(84) ,UO+82800 ,3600 ,"S" }), // Mar 25 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1934: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(97) ,UO+82800 ,3600 ,"S" }), // Apr 7 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1935: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(89) ,UO+82800 ,3600 ,"S" }), // Mar 30 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1931: + case 1936: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(108) ,UO+82800 ,3600 ,"S" }), // Apr 18 + ({LDAYL(280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1937: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(93) ,UO+82800 ,3600 ,"S" }), // Apr 3 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1938: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(85) ,UO+82800 ,3600 ,"S" }), // Mar 26 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1939: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(105) ,UO+82800 ,3600 ,"S" }), // Apr 15 + ({FIXED(322) ,UO+82800 ,0 ,"" })});// Nov 18 + case 1940: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(56) ,UO+7200 ,3600 ,"S" })});// Feb 25 + case 1941: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(125) ,UO-3600 ,7200 ,"M" }), // May 5 + ({FIXED(279) ,UO-7200 ,3600 ,"S" })});// Oct 6 + case 1942: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(68) ,UO-3600 ,7200 ,"M" }), // Mar 9 + ({FIXED(306) ,UO+3600 ,3600 ,"S" })});// Nov 2 + case 1943: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(88) ,UO+3600 ,7200 ,"M" }), // Mar 29 + ({FIXED(277) ,UO+3600 ,3600 ,"S" })});// Oct 4 + case 1944: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(94) ,UO+3600 ,7200 ,"M" }), // Apr 3 + ({FIXED(282) ,UO-3600 ,3600 ,"S" })});// Oct 8 + case 1945: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(92) ,UO+3600 ,7200 ,"M" }), // Apr 2 + ({FIXED(259) ,UO+3600 ,0 ,"" })});// Sep 16 + case 1976: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(88) ,UO+3600 ,3600 ,"S" }), // Mar 28 + ({FIXED(270) ,UO+0 ,0 ,"" })});// Sep 26 + default: // ..1915 and 1977.. + case 1946..1975: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Germany +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1945: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(92) ,UO+7200 ,3600 ,"S" }), // Apr 2 + ({FIXED(151) ,UO+7200 ,7200 ,"M" }), // May 31 + ({FIXED(266) ,UO+3600 ,3600 ,"S" }), // Sep 23 + ({FIXED(322) ,UO+7200 ,0 ,"" })});// Nov 18 + case 1946: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(104) ,UO+7200 ,3600 ,"S" }), // Apr 14 + ({FIXED(280) ,UO+7200 ,0 ,"" })});// Oct 7 + case 1947: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(96) ,UO+7200 ,3600 ,"S" }), // Apr 6 + ({FIXED(131) ,UO+7200 ,7200 ,"M" }), // May 11 + ({FIXED(180) ,UO+3600 ,3600 ,"S" }), // Jun 29 + ({LDAY (280,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + case 1948: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(109) ,UO+7200 ,3600 ,"S" }), // Apr 18 + ({LDAY (281,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + case 1949: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(100) ,UO+7200 ,3600 ,"S" }), // Apr 10 + ({LDAY (280,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + default: // ..1944 and 1950.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Greece +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1932: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(189) ,UO+0 ,3600 ,"S" }), // Jul 7 + ({FIXED(245) ,UO-3600 ,0 ,"" })});// Sep 1 + case 1941: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(97) ,UO+0 ,3600 ,"S" })});// Apr 7 + case 1942: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(306) ,UO+7200 ,0 ,"" })});// Nov 2 + case 1943: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(89) ,UO+0 ,3600 ,"S" }), // Mar 30 + ({FIXED(277) ,UO-3600 ,0 ,"" })});// Oct 4 + case 1952: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(183) ,UO+0 ,3600 ,"S" }), // Jul 1 + ({FIXED(307) ,UO-3600 ,0 ,"" })});// Nov 2 + case 1975: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(102) ,UO+0 ,3600 ,"S" }), // Apr 12 + ({FIXED(330) ,UO+0 ,0 ,"" })});// Nov 26 + case 1976: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(102) ,UO+7200 ,3600 ,"S" }), // Apr 11 + ({FIXED(284) ,UO+7200 ,0 ,"" })});// Oct 10 + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+7200 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(269) ,UO+7200 ,0 ,"" })});// Sep 26 + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+7200 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(267) ,UO+10800 ,0 ,"" })});// Sep 24 + case 1979: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(91) ,UO+32400 ,3600 ,"S" }), // Apr 1 + ({FIXED(272) ,UO+3600 ,0 ,"" })});// Sep 29 + case 1980: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({FIXED(272) ,UO-3600 ,0 ,"" })});// Sep 28 + default: // ..1931 and 1981.. + case 1933..1940: + case 1944..1951: + case 1953..1974: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Hungary +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1918: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(91) ,UO+10800 ,3600 ,"S" }), // Apr 1 + ({FIXED(272) ,UO+7200 ,0 ,"" })});// Sep 29 + case 1919: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(105) ,UO+10800 ,3600 ,"S" }), // Apr 15 + ({FIXED(258) ,UO+7200 ,0 ,"" })});// Sep 15 + case 1920: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(96) ,UO+10800 ,3600 ,"S" }), // Apr 5 + ({FIXED(274) ,UO+7200 ,0 ,"" })});// Sep 30 + case 1945: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+82800 ,3600 ,"S" }), // May 1 + ({FIXED(307) ,UO-3600 ,0 ,"" })});// Nov 3 + case 1946: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(90) ,UO+7200 ,3600 ,"S" }), // Mar 31 + ({LDAY (280,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + case 1947..1949: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(100,7),UO+7200 ,3600 ,"S" }), // Apr Sun>=4 + ({LDAYL(280,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + case 1950: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(107) ,UO+7200 ,3600 ,"S" }), // Apr 17 + ({FIXED(296) ,UO+7200 ,0 ,"" })});// Oct 23 + case 1954..1955: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(143) ,UO+0 ,3600 ,"S" }), // May 23 + ({FIXED(276) ,UO-3600 ,0 ,"" })});// Oct 3 + case 1956: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (159,7),UO+0 ,3600 ,"S" }), // Jun Sun>=1 + ({LDAY (274,7),UO-3600 ,0 ,"" })});// Sep lastSun + case 1957: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (158,7),UO+3600 ,3600 ,"S" }), // Jun Sun>=1 + ({LDAY (273,7),UO+7200 ,0 ,"" })});// Sep lastSun + default: // ..1917: + case 1921..1944: + case 1951..1953: + case 1958..1979: + return ({({0 ,0 ,0 ,"" })}); + case 1980: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(97) ,UO+3600 ,3600 ,"S" })});// Apr 6 + case 1981..: + return ({({0 ,0 ,3600 ,"S" })}); + } + } +} + +class Iceland +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1917: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(50) ,UO+82800 ,3600 ,"S" }), // Feb 19 + ({FIXED(294) ,UO+0 ,0 ,"" })});// Oct 21 + case 1918: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(50) ,UO+82800 ,3600 ,"S" }), // Feb 19 + ({FIXED(320) ,UO+0 ,0 ,"" })});// Nov 16 + case 1939: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(119) ,UO+82800 ,3600 ,"S" }), // Apr 29 + ({FIXED(333) ,UO+3600 ,0 ,"" })});// Nov 29 + case 1940: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(56) ,UO+7200 ,3600 ,"S" }), // Feb 25 + ({FIXED(308) ,UO+3600 ,0 ,"" })});// Nov 3 + case 1941: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(61) ,UO+3600 ,3600 ,"S" }), // Mar 2 + ({FIXED(306) ,UO+3600 ,0 ,"" })});// Nov 2 + case 1942: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(67) ,UO+3600 ,3600 ,"S" }), // Mar 8 + ({FIXED(298) ,UO+3600 ,0 ,"" })});// Oct 25 + case 1943..1946: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(66,7) ,UO+3600 ,3600 ,"S" }), // Mar Sun>=1 + ({LDAYL(301,7),UO+3600 ,0 ,"" })});// Oct Sun>=22 + case 1949: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+3600 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(303) ,UO+3600 ,0 ,"" })});// Oct 30 + case 1947..1948: + case 1950..1966: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(97,7) ,UO+3600 ,3600 ,"S" }), // Apr Sun>=1 + ({LDAYL(301,7),UO+3600 ,0 ,"" })});// Oct Sun>=22 + case 1967: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+3600 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(302) ,UO+3600 ,0 ,"" })});// Oct 29 + default: // ..1916 and 1968.. + case 1919..1938: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Italy +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1916: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(155) ,UO+0 ,3600 ,"S" }), // Jun 3 + ({FIXED(275) ,UO+0 ,0 ,"" })});// Oct 1 + case 1917: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(91) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({FIXED(273) ,UO+0 ,0 ,"" })});// Sep 30 + case 1918: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(69) ,UO+0 ,3600 ,"S" }), // Mar 10 + ({LDAY (280,7),UO+0 ,0 ,"" })});// Oct Sun>=1 + case 1919: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(61) ,UO+0 ,3600 ,"S" }), // Mar 2 + ({LDAY (280,7),UO+0 ,0 ,"" })});// Oct Sun>=1 + case 1920: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(81) ,UO+0 ,3600 ,"S" }), // Mar 21 + ({FIXED(263) ,UO+0 ,0 ,"" })});// Sep 19 + case 1940: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(167) ,UO+0 ,3600 ,"S" })});// Jun 15 + case 1941..1943: + return ({({0 ,0 ,3600 ,"S" })}); + case 1944: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(261) ,UO+0 ,0 ,"" })});// Sep 17 + case 1945: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+7200 ,3600 ,"S" }), // Apr 2 + ({FIXED(258) ,UO+0 ,0 ,"" })});// Sep 15 + case 1946: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(76) ,UO+7200 ,3600 ,"S" }), // Mar 17 + ({FIXED(279) ,UO+7200 ,0 ,"" })});// Oct 6 + case 1947: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(75) ,UO+0 ,3600 ,"S" }), // Mar 16 + ({FIXED(278) ,UO+0 ,0 ,"" })});// Oct 5 + case 1948: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(60) ,UO+7200 ,3600 ,"S" }), // Feb 29 + ({FIXED(277) ,UO+7200 ,0 ,"" })});// Oct 3 + case 1966..1968: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(148,7),UO+0 ,3600 ,"S" }), // May Sun>=22 + ({LDAYL(271,7),UO-3600 ,0 ,"" })});// Sep Sun>=22 + case 1969: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(152) ,UO+0 ,3600 ,"S" }), // Jun 1 + ({LDAY (271,7),UO-3600 ,0 ,"" })});// Sep Sun>=22 + case 1970: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(151) ,UO+0 ,3600 ,"S" }), // May 31 + ({LDAY (273,7),UO-3600 ,0 ,"" })});// Sep lastSun + case 1971: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (148,7),UO+0 ,3600 ,"S" }), // May Sun>=22 + ({LDAY (273,7),UO+0 ,0 ,"" })});// Sep lastSun + case 1972: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (149,7),UO+0 ,3600 ,"S" }), // May Sun>=22 + ({FIXED(275) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1973: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(154) ,UO+0 ,3600 ,"S" }), // Jun 3 + ({LDAY (273,7),UO-3600 ,0 ,"" })});// Sep lastSun + case 1974: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(146) ,UO+0 ,3600 ,"S" }), // May 26 + ({LDAY (273,7),UO-3600 ,0 ,"" })});// Sep lastSun + case 1975: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(152) ,UO+0 ,3600 ,"S" }), // Jun 1 + ({LDAY (273,7),UO+0 ,0 ,"" })});// Sep lastSun + case 1976: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(151) ,UO+0 ,3600 ,"S" }), // May 30 + ({LDAY (274,7),UO+0 ,0 ,"" })});// Sep lastSun + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (148,7),UO+0 ,3600 ,"S" }), // May Sun>=22 + ({LDAY (273,7),UO+0 ,0 ,"" })});// Sep lastSun + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (148,7),UO+0 ,3600 ,"S" }), // May Sun>=22 + ({FIXED(274) ,UO+0 ,0 ,"" })});// Oct 1 + case 1979: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (148,7),UO+0 ,3600 ,"S" }), // May Sun>=22 + ({FIXED(273) ,UO+0 ,0 ,"" })});// Sep 30 + default: // ..1915 and 1980.. + case 1921..1939: + case 1949..1965: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Latvia +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1989..1996: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+7200 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),UO+7200 ,0 ,"" })});// Sep lastSun + default: // ..1988 and 1997.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Lux +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1915: + return ({({0 ,0 ,0 ,"" })});// ? + case 1916: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(135) ,UO+82800 ,3600 ,"S" }), // May 14 + ({FIXED(275) ,UO+0 ,0 ,"" })});// Oct 1 + case 1917: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(118) ,UO+82800 ,3600 ,"S" }), // Apr 28 + ({FIXED(260) ,UO+0 ,0 ,"" })});// Sep 17 + case 1918: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (111,1),UO+7200 ,3600 ,"S" }), // Apr Mon>=15 + ({LDAY (264,1),UO+7200 ,0 ,"" })});// Sep Mon>=15 + case 1919: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(60) ,UO+82800 ,3600 ,"S" }), // Mar 1 + ({FIXED(278) ,UO+7200 ,0 ,"" })});// Oct 5 + case 1920: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(45) ,UO+82800 ,3600 ,"S" }), // Feb 14 + ({FIXED(298) ,UO+3600 ,0 ,"" })});// Oct 24 + case 1921: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(73) ,UO+82800 ,3600 ,"S" }), // Mar 14 + ({FIXED(299) ,UO+3600 ,0 ,"" })});// Oct 26 + case 1922: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(84) ,UO+82800 ,3600 ,"S" }), // Mar 25 + ({LDAY (281,7),UO+0 ,0 ,"" })});// Oct Sun>=2 + case 1923: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(111) ,UO+82800 ,3600 ,"S" }), // Apr 21 + ({LDAY (281,7),UO+3600 ,0 ,"" })});// Oct Sun>=2 + case 1924: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(89) ,UO+82800 ,3600 ,"S" }), // Mar 29 + ({LDAY (282,7),UO+0 ,0 ,"" })});// Oct Sun>=2 + case 1925: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(95) ,UO+82800 ,3600 ,"S" }), // Apr 5 + ({LDAY (281,7),UO+0 ,0 ,"" })});// Oct Sun>=2 + case 1926: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(107) ,UO+82800 ,3600 ,"S" }), // Apr 17 + ({LDAY (281,7),UO+0 ,0 ,"" })});// Oct Sun>=2 + case 1927: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(99) ,UO+82800 ,3600 ,"S" }), // Apr 9 + ({LDAY (281,7),UO+0 ,0 ,"" })});// Oct Sun>=2 + case 1928: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(105) ,UO+82800 ,3600 ,"S" }), // Apr 14 + ({LDAY (282,7),UO+0 ,0 ,"" })});// Oct Sun>=2 + case 1929: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(110) ,UO+82800 ,3600 ,"S" })});// Apr 20 + case 1930..: + return ({({0 ,0 ,3600 ,"S" })}); + } + } +} + +class Malta +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1973: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(90) ,UO+0 ,3600 ,"S" }), // Mar 31 + ({FIXED(272) ,UO+0 ,0 ,"" })});// Sep 29 + case 1974: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(111) ,UO+0 ,3600 ,"S" }), // Apr 21 + ({FIXED(259) ,UO+0 ,0 ,"" })});// Sep 16 + case 1975..1979: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(111,7),UO+7200 ,3600 ,"S" }), // Apr Sun>=15 + ({LDAYL(264,7),UO+3600 ,0 ,"" })});// Sep Sun>=15 + case 1980: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(91) ,UO+7200 ,3600 ,"S" }), // Mar 31 + ({LDAY (265,7),UO+3600 ,0 ,"" })});// Sep Sun>=15 + default: // ..1972 and 1981.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Neth +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1915: + return ({({0 ,0 ,0 ,"AMT" })});// ? + case 1916: + return ({({0 ,0 ,0 ,"AMT" }), // ? + ({FIXED(122) ,UO+7200 ,3600 ,"NST" }), // May 1 + ({FIXED(276) ,UO+7200 ,0 ,"AMT" })});// Oct 2 + case 1917: + return ({({0 ,0 ,0 ,"AMT" }), + ({FIXED(106) ,UO+7200 ,3600 ,"NST" }), // Apr 16 + ({FIXED(260) ,UO+7200 ,0 ,"AMT" })});// Sep 17 + case 1918..1921: + return ({({0 ,0 ,0 ,"AMT" }), + ({LDAYL(97,1) ,UO+7200 ,3600 ,"NST" }), // Apr Mon>=1 + ({LDAYL(273,1),UO+7200 ,0 ,"AMT" })});// Sep Mon>=24 + case 1922: + return ({({0 ,0 ,0 ,"AMT" }), + ({FIXED(85) ,UO+7200 ,3600 ,"NST" }), // Mar 26 + ({LDAY (281,7),UO+7200 ,0 ,"AMT" })});// Oct Sun>=2 + case 1923: + return ({({0 ,0 ,0 ,"AMT" }), + ({FIXED(152) ,UO+7200 ,3600 ,"NST" }), // Jun 1 + ({LDAY (281,7),UO+7200 ,0 ,"AMT" })});// Oct Sun>=2 + case 1924: + return ({({0 ,0 ,0 ,"AMT" }), + ({FIXED(90) ,UO+7200 ,3600 ,"NST" }), // Mar 30 + ({LDAY (282,7),UO+7200 ,0 ,"AMT" })});// Oct Sun>=2 + case 1925: + return ({({0 ,0 ,0 ,"AMT" }), + ({FIXED(156) ,UO+7200 ,3600 ,"NST" }), // Jun 5 + ({LDAY (281,7),UO+7200 ,0 ,"AMT" })});// Oct Sun>=2 + case 1932: + return ({({0 ,0 ,0 ,"AMT" }), + ({FIXED(143) ,UO+7200 ,3600 ,"NST" }), // May 22 + ({LDAY (282,7),UO+7200 ,0 ,"AMT" })});// Oct Sun>=2 + case 1926..1931: + case 1933..1936: + return ({({0 ,0 ,0 ,"AMT" }), + ({FIX_L(135) ,UO+7200 ,3600 ,"NST" }), // May 15 + ({LDAYL(281,7),UO+7200 ,0 ,"AMT" })});// Oct Sun>=2 + case 1937: + return ({({0 ,0 ,0 ,"AMT" }), + ({FIXED(142) ,UO+7200 ,3600 ,"NST" }), // May 22 + ({FIXED(182) ,UO-3600 ,3600 ,"S" }), // Jul 1 + ({LDAY (281,7),UO+7200 ,0 ,"" })});// Oct Sun>=2 + case 1938..1939: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(135) ,UO+7200 ,3600 ,"S" }), // May 15 + ({LDAY (281,7),UO+7200 ,0 ,"" })});// Oct Sun>=2 + case 1945: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+7200 ,3600 ,"S" }), // Apr 2 + ({FIXED(140) ,UO+7200 ,0 ,"" })});// May 20 + case 1940..1944: + case 1946..: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Norway +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1916: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(143) ,UO+3600 ,3600 ,"S" }), // May 22 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Sep 30 + case 1945: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+7200 ,3600 ,"S" }), // Apr 2 + ({FIXED(274) ,UO+7200 ,0 ,"" })});// Oct 1 + case 1959..1964: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(80,7) ,UO+7200 ,3600 ,"S" }), // Mar Sun>=15 + ({LDAYL(264,7),UO+7200 ,0 ,"" })});// Sep Sun>=15 + case 1965: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(115) ,UO+7200 ,3600 ,"S" }), // Apr 25 + ({LDAY (264,7),UO+7200 ,0 ,"" })});// Sep Sun>=15 + default: // ..1915 and 1966.. + case 1917..1944: + case 1946..1958: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Poland +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1918: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(259) ,UO+7200 ,0 ,"" })});// Sep 16 + case 1919: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(105) ,UO+7200 ,3600 ,"S" }), // Apr 15 + ({FIXED(259) ,UO+7200 ,0 ,"" })});// Sep 16 + case 1944: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(278) ,UO+7200 ,0 ,"" })});// Oct 4 + case 1945: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(119) ,UO+0 ,3600 ,"S" }), // Apr 29 + ({FIXED(305) ,UO-3600 ,0 ,"" })});// Nov 1 + case 1946: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(104) ,UO+0 ,3600 ,"S" }), // Apr 14 + ({FIXED(250) ,UO-3600 ,0 ,"" })});// Sep 7 + case 1947: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(124) ,UO+0 ,3600 ,"S" }), // May 4 + ({LDAY (280,7),UO-3600 ,0 ,"" })});// Oct Sun>=1 + case 1948: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(109) ,UO+0 ,3600 ,"S" }), // Apr 18 + ({LDAY (281,7),UO-3600 ,0 ,"" })});// Oct Sun>=1 + case 1957: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(153) ,UO+3600 ,3600 ,"S" }), // Jun 2 + ({LDAY (273,7),UO+3600 ,0 ,"" })});// Sep lastSun + case 1958: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(89) ,UO+3600 ,3600 ,"S" }), // Mar 30 + ({LDAY (273,7),UO+3600 ,0 ,"" })});// Sep lastSun + case 1959: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(151) ,UO+3600 ,3600 ,"S" }), // May 31 + ({LDAY (280,7),UO+3600 ,0 ,"" })});// Oct Sun>=1 + case 1960: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(94) ,UO+3600 ,3600 ,"S" }), // Apr 3 + ({LDAY (281,7),UO+3600 ,0 ,"" })});// Oct Sun>=1 + case 1961: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (151,7),UO+3600 ,3600 ,"S" }), // May Sun>=25 + ({LDAY (280,7),UO+3600 ,0 ,"" })});// Oct Sun>=1 + case 1962..1964: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(151,7),UO+3600 ,3600 ,"S" }), // May Sun>=25 + ({LDAYL(273,7),UO+3600 ,0 ,"" })});// Sep lastSun + default: // ..1917 and 1965.. + case 1920..1943: + case 1949..1956: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Port +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1916: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(169) ,UO+82800 ,3600 ,"S" }), // Jun 17 + ({FIXED(306) ,UO+0 ,0 ,"" })});// Nov 1 + case 1918: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(60) ,UO+82800 ,3600 ,"S" }), // Mar 1 + ({FIXED(287) ,UO+82800 ,0 ,"" })});// Oct 14 + case 1920: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(60) ,UO+82800 ,3600 ,"S" }), // Feb 29 + ({FIXED(288) ,UO+82800 ,0 ,"" })});// Oct 14 + case 1917: + case 1919: + case 1921: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(59) ,UO+82800 ,3600 ,"S" }), // Feb 28 + ({FIXED(287) ,UO+82800 ,0 ,"" })});// Oct 14 + case 1924: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(107) ,UO+82800 ,3600 ,"S" }), // Apr 16 + ({FIXED(288) ,UO+82800 ,0 ,"" })});// Oct 14 + case 1926: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(107) ,UO+82800 ,3600 ,"S" }), // Apr 17 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1927: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(99) ,UO+82800 ,3600 ,"S" }), // Apr 9 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1928: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(105) ,UO+82800 ,3600 ,"S" }), // Apr 14 + ({LDAY (281,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1929: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(110) ,UO+82800 ,3600 ,"S" }), // Apr 20 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1932: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(93) ,UO+82800 ,3600 ,"S" }), // Apr 2 + ({LDAY (281,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1934: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(97) ,UO+82800 ,3600 ,"S" }), // Apr 7 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1935: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(89) ,UO+82800 ,3600 ,"S" }), // Mar 30 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1931: + case 1936: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(108) ,UO+82800 ,3600 ,"S" }), // Apr 18 + ({LDAYL(280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1937: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(93) ,UO+82800 ,3600 ,"S" }), // Apr 3 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1938: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(85) ,UO+82800 ,3600 ,"S" }), // Mar 26 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1939: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(105) ,UO+82800 ,3600 ,"S" }), // Apr 15 + ({FIXED(322) ,UO+82800 ,0 ,"" })});// Nov 18 + case 1940: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(55) ,UO+82800 ,3600 ,"S" }), // Feb 24 + ({FIXED(279) ,UO+82800 ,0 ,"" })});// Oct 5 + case 1941: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(95) ,UO+82800 ,3600 ,"S" }), // Apr 5 + ({FIXED(278) ,UO+82800 ,0 ,"" })});// Oct 5 + case 1942: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (73,6) ,UO+82800 ,3600 ,"S" }), // Mar Sat>=8 + ({FIXED(115) ,UO+79200 ,7200 ,"M" }), // Apr 25 + ({FIXED(227) ,UO+79200 ,3600 ,"S" }), // Aug 15 + ({LDAY (303,6),UO+82800 ,0 ,"" })});// Oct Sat>=24 + case 1943: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (73,6) ,UO+82800 ,3600 ,"S" }), // Mar Sat>=8 + ({FIXED(107) ,UO+79200 ,7200 ,"M" }), // Apr 17 + ({LDAY (243,6),UO+79200 ,3600 ,"S" }), // Aug Sat>=25 + ({LDAY (303,6),UO+82800 ,0 ,"" })});// Oct Sat>=24 + case 1944..1945: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(73,6) ,UO+82800 ,3600 ,"S" }), // Mar Sat>=8 + ({LDAYL(117,6),UO+79200 ,7200 ,"M" }), // Apr Sat>=21 + ({LDAYL(243,6),UO+79200 ,3600 ,"S" }), // Aug Sat>=25 + ({LDAYL(303,6),UO+82800 ,0 ,"" })});// Oct Sat>=24 + case 1946: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,6) ,UO+82800 ,3600 ,"S" }), // Apr Sat>=1 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1947..1949: + case 1951..1965: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"S" }), // Apr Sun>=1 + ({LDAYL(280,7),UO+7200 ,0 ,"" })});// Oct Sun>=1 + default: // ..1915: + case 1922..1923: + case 1925: + case 1930: + case 1933: + case 1950: + case 1966..1976: + return ({({0 ,0 ,0 ,"" })}); + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(86) ,UO+0 ,3600 ,"S" }), // Mar 27 + ({FIXED(268) ,UO+0 ,0 ,"" })});// Sep 25 + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+0 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(274) ,UO+0 ,0 ,"" })});// Oct 1 + case 1979: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+0 ,3600 ,"S" }), // Apr Sun>=1 + ({LDAY (273,7),UO+3600 ,0 ,"" })});// Sep lastSun + case 1980: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (91,7) ,UO+0 ,3600 ,"S" }), // Mar lastSun + ({LDAY (274,7),UO+3600 ,0 ,"" })});// Sep lastSun + case 1981..1982: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (90,7) ,UO+3600 ,3600 ,"S" }), // Mar lastSun + ({LDAY (273,7),UO+3600 ,0 ,"" })});// Sep lastSun + case 1983: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (90,7) ,UO+7200 ,3600 ,"S" })});// Mar lastSun + case 1984..: + return ({({0 ,0 ,3600 ,"S" })}); + } + } +} + +class Romania +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1932: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(142) ,UO+0 ,3600 ,"S" }), // May 21 + ({LDAY (281,7),UO+0 ,0 ,"" })});// Oct Sun>=1 + case 1933..1939: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(98,7) ,UO+0 ,3600 ,"S" }), // Apr Sun>=2 + ({LDAYL(280,7),UO+0 ,0 ,"" })});// Oct Sun>=1 + case 1979: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(147) ,UO+0 ,3600 ,"S" }), // May 27 + ({LDAY (273,7),UO-3600 ,0 ,"" })});// Sep lastSun + case 1980: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(96) ,UO+82800 ,3600 ,"S" }), // Apr 5 + ({LDAY (274,7),UO+0 ,0 ,"" })});// Sep lastSun + case 1991..1993: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(90,7) ,UO+0 ,3600 ,"S" }), // Mar lastSun + ({LDAYL(273,7),UO+0 ,0 ,"" })});// Sep lastSun + default: // ..1931 and 1994.. + case 1940..1978: + case 1981..1990: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Spain +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1917: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(125) ,UO+82800 ,3600 ,"S" }), // May 5 + ({FIXED(279) ,UO+82800 ,0 ,"" })});// Oct 6 + case 1918: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(105) ,UO+82800 ,3600 ,"S" }), // Apr 15 + ({FIXED(279) ,UO+82800 ,0 ,"" })});// Oct 6 + case 1919: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(95) ,UO+82800 ,3600 ,"S" }), // Apr 5 + ({FIXED(279) ,UO+82800 ,0 ,"" })});// Oct 6 + case 1924: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(107) ,UO+82800 ,3600 ,"S" }), // Apr 16 + ({FIXED(278) ,UO+82800 ,0 ,"" })});// Oct 4 + case 1926: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(107) ,UO+82800 ,3600 ,"S" }), // Apr 17 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1927: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(99) ,UO+82800 ,3600 ,"S" }), // Apr 9 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1928: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(105) ,UO+82800 ,3600 ,"S" }), // Apr 14 + ({LDAY (281,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1929: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(110) ,UO+82800 ,3600 ,"S" }), // Apr 20 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1937: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(142) ,UO+82800 ,3600 ,"S" }), // May 22 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1938: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(81) ,UO+82800 ,3600 ,"S" }), // Mar 22 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1939: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(105) ,UO+82800 ,3600 ,"S" }), // Apr 15 + ({LDAY (280,6),UO+82800 ,0 ,"" })});// Oct Sat>=1 + case 1940: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(76) ,UO+82800 ,3600 ,"S" })});// Mar 16 + case 1941: + return ({({0 ,0 ,3600 ,"S" })}); + case 1942: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(122) ,UO+79200 ,7200 ,"M" }), // May 2 + ({FIXED(244) ,UO+79200 ,3600 ,"S" })});// Sep 1 + case 1943: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (109,6),UO+79200 ,7200 ,"M" }), // Apr Sat>=13 + ({FIXED(276) ,UO+79200 ,3600 ,"S" })});// Oct 3 + case 1944: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (110,6),UO+79200 ,7200 ,"M" }), // Apr Sat>=13 + ({FIXED(284) ,UO+79200 ,3600 ,"S" })});// Oct 10 + case 1945: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (109,6),UO+79200 ,7200 ,"M" }), // Apr Sat>=13 + ({FIXED(273) ,UO-3600 ,3600 ,"S" })});// Sep 30 + case 1946: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (109,6),UO+79200 ,7200 ,"M" }), // Apr Sat>=13 + ({FIXED(273) ,UO-7200 ,0 ,"" })});// Sep 30 + case 1949: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(120) ,UO+82800 ,3600 ,"S" }), // Apr 30 + ({FIXED(273) ,UO+0 ,0 ,"" })});// Sep 30 + case 1974..1975: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (109,6),UO+82800 ,3600 ,"S" }), // Apr Sat>=13 + ({LDAY (280,7),UO+0 ,0 ,"" })});// Oct Sun>=1 + case 1976: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(87) ,UO+82800 ,3600 ,"S" }), // Mar 27 + ({LDAY (274,7),UO+0 ,0 ,"" })});// Sep lastSun + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+82800 ,3600 ,"S" }), // Apr 2 + ({LDAY (273,7),UO+0 ,0 ,"" })});// Sep lastSun + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+82800 ,3600 ,"S" }), // Apr 2 + ({FIXED(274) ,UO+0 ,0 ,"" })});// Oct 1 + default: // ..1916 and 1979.. + case 1920..1923: + case 1925: + case 1930..1936: + case 1947..1948: + case 1950..1973: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class SpainAfrica +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1967: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(154) ,UO+43200 ,3600 ,"S" }), // Jun 3 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1974: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(175) ,UO+0 ,3600 ,"S" }), // Jun 24 + ({FIXED(244) ,UO-3600 ,0 ,"" })});// Sep 1 + case 1976: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(122) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIXED(214) ,UO-3600 ,0 ,"" })});// Aug 1 + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(121) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIXED(271) ,UO-3600 ,0 ,"" })});// Sep 28 + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(152) ,UO+0 ,3600 ,"S" }), // Jun 1 + ({FIXED(216) ,UO-3600 ,0 ,"" })});// Aug 4 + default: // ..1966 and 1979.. + case 1968..1973: + case 1975: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Swiss +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1940: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(307) ,UO+0 ,3600 ,"S" }), // Nov 2 + ({FIXED(366) ,UO-3600 ,0 ,"" })});// Dec 31 + case 1941..1942: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (127,7),UO+7200 ,3600 ,"S" }), // May Sun>=1 + ({LDAY (280,7),UO-3600 ,0 ,"" })});// Oct Sun>=1 + default: // ..1939 and 1943.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Turkey +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1920: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(88) ,UO+0 ,3600 ,"S" }), // Mar 28 + ({FIXED(299) ,UO-3600 ,0 ,"" })});// Oct 25 + case 1921: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(93) ,UO+0 ,3600 ,"S" }), // Apr 3 + ({FIXED(276) ,UO-3600 ,0 ,"" })});// Oct 3 + case 1922: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(85) ,UO+0 ,3600 ,"S" }), // Mar 26 + ({FIXED(281) ,UO-3600 ,0 ,"" })});// Oct 8 + case 1924: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(134) ,UO+0 ,3600 ,"S" }), // May 13 + ({FIXED(275) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1916: + case 1925: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(121) ,UO+0 ,3600 ,"S" }), // May 1 + ({FIX_L(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1940: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(182) ,UO+0 ,3600 ,"S" }), // Jun 30 + ({FIXED(279) ,UO-3600 ,0 ,"" }), // Oct 5 + ({FIXED(336) ,UO+0 ,3600 ,"S" })});// Dec 1 + case 1941: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(264) ,UO-3600 ,0 ,"" })});// Sep 21 + case 1942: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(91) ,UO+0 ,3600 ,"S" }), // Apr 1 + ({FIXED(305) ,UO-3600 ,0 ,"" })});// Nov 1 + case 1945: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(92) ,UO+0 ,3600 ,"S" }), // Apr 2 + ({FIXED(281) ,UO-3600 ,0 ,"" })});// Oct 8 + case 1946: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(152) ,UO+0 ,3600 ,"S" }), // Jun 1 + ({FIXED(274) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1947..1948: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(112,7),UO+0 ,3600 ,"S" }), // Apr Sun>=16 + ({LDAYL(281,7),UO-3600 ,0 ,"" })});// Oct Sun>=2 + case 1949: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(100) ,UO+0 ,3600 ,"S" }), // Apr 10 + ({LDAY (281,7),UO-3600 ,0 ,"" })});// Oct Sun>=2 + case 1950: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(109) ,UO+0 ,3600 ,"S" }), // Apr 19 + ({LDAY (281,7),UO-3600 ,0 ,"" })});// Oct Sun>=2 + case 1951: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(112) ,UO+0 ,3600 ,"S" }), // Apr 22 + ({FIXED(281) ,UO-3600 ,0 ,"" })});// Oct 8 + case 1962: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(196) ,UO+0 ,3600 ,"S" }), // Jul 15 + ({FIXED(281) ,UO-3600 ,0 ,"" })});// Oct 8 + case 1964: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(136) ,UO+0 ,3600 ,"S" }), // May 15 + ({FIXED(275) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1970..1972: + return ({({0 ,0 ,0 ,"" }), + ({LDAYL(128,7),UO+0 ,3600 ,"S" }), // May Sun>=2 + ({LDAYL(281,7),UO-3600 ,0 ,"" })});// Oct Sun>=2 + case 1973: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(154) ,UO+3600 ,3600 ,"S" }), // Jun 3 + ({FIXED(308) ,UO+7200 ,0 ,"" })});// Nov 4 + case 1974: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(90) ,UO+7200 ,3600 ,"S" }), // Mar 31 + ({FIXED(307) ,UO+14400 ,0 ,"" })});// Nov 3 + case 1975: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(89) ,UO+0 ,3600 ,"S" }), // Mar 30 + ({LDAY (304,7),UO-3600 ,0 ,"" })});// Oct lastSun + case 1976: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(153) ,UO+0 ,3600 ,"S" }), // Jun 1 + ({LDAY (305,7),UO-3600 ,0 ,"" })});// Oct lastSun + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+0 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(289) ,UO-3600 ,0 ,"" })});// Oct 16 + case 1978: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+0 ,3600 ,"S" })});// Apr Sun>=1 + case 1979: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (97,7) ,UO+7200 ,3600 ,"S" }), // Apr Sun>=1 + ({LDAY (290,1),UO-3600 ,0 ,"" })});// Oct Mon>=11 + case 1980: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (98,7) ,UO+10800 ,3600 ,"S" }), // Apr Sun>=1 + ({LDAY (291,1),UO-3600 ,0 ,"" })});// Oct Mon>=11 + case 1981..1982: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (90,7) ,UO+10800 ,3600 ,"S" }), // Mar lastSun + ({LDAY (290,1),UO-3600 ,0 ,"" })});// Oct Mon>=11 + case 1983: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(212) ,UO+0 ,3600 ,"S" }), // Jul 31 + ({FIXED(275) ,UO-3600 ,0 ,"" })});// Oct 2 + case 1985: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(110) ,UO+0 ,3600 ,"S" }), // Apr 20 + ({FIXED(271) ,UO-3600 ,0 ,"" })});// Sep 28 + default: // ..1915 and 1986.. + case 1917..1919: + case 1923: + case 1926..1939: + case 1943..1944: + case 1952..1961: + case 1963: + case 1965..1969: + case 1984: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class US +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1918..1919: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (90,7) ,UO+7200 ,3600 ,"W" }), // Mar lastSun + ({LDAY (304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1942: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(40) ,UO+7200 ,3600 ,"W" })});// Feb 9 + case 1943..1944: + return ({({0 ,0 ,3600 ,"W" })}); + case 1945: + return ({({0 ,0 ,3600 ,"W" }), + ({FIXED(273) ,UO+3600 ,0 ,"S" })});// Sep 30 + default: // ..1917: + case 1920..1941: + case 1946..1966: + return ({({0 ,0 ,0 ,"S" })}); + case 1974: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(6) ,UO+7200 ,3600 ,"D" }), // Jan 6 + ({LDAY (304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1975: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(54) ,UO+7200 ,3600 ,"D" }), // Feb 23 + ({LDAY (304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1967..1973: + case 1976..1986: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1987..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class NYC +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1920: + return ({({0 ,0 ,0 ,"S" }), // ? + ({LDAY (91,7) ,UO+7200 ,3600 ,"D" }), // Mar lastSun + ({LDAY (305,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1921..1954: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1955..1966: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + default: // ..1919 and 1967.. + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Chicago +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1920: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(165) ,UO+7200 ,3600 ,"D" }), // Jun 13 + ({LDAY (305,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1921: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (90,7) ,UO+7200 ,3600 ,"D" }), // Mar lastSun + ({LDAY (304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1922..1954: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1955..1966: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + default: // ..1919 and 1967.. + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Denver +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1920: + return ({({0 ,0 ,0 ,"S" }), // ? + ({LDAY (91,7) ,UO+7200 ,3600 ,"D" }), // Mar lastSun + ({LDAY (305,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1921: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (90,7) ,UO+7200 ,3600 ,"D" }), // Mar lastSun + ({FIXED(142) ,UO+3600 ,0 ,"S" })});// May 22 + case 1965..1966: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAY (304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + default: // ..1919 and 1967.. + case 1922..1964: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class CA +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1948: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(74) ,UO+7200 ,3600 ,"D" })});// Mar 14 + case 1949: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(1) ,UO+3600 ,0 ,"S" })});// Jan 1 + case 1950..1961: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1962..1966: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + default: // ..1947 and 1967.. + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Indianapolis +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1941: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(173) ,UO+7200 ,3600 ,"D" }), // Jun 22 + ({LDAY (273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1942..1945: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(273,7),UO+7200 ,0 ,"S" })});// Sep lastSun + case 1946..1954: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + default: // ..1940 and 1955.. + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Marengo +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1951: + case 1954..1960: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + default: // ..1950 and 1961.. + case 1952..1953: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Starke +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1947..1954: + case 1957..1958: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1955..1956: + case 1959..1961: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + default: // ..1946 and 1962.. + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Louisville +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1921: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(121) ,UO+7200 ,3600 ,"D" }), // May 1 + ({FIXED(244) ,UO+3600 ,0 ,"S" })});// Sep 1 + default: // ..1920: + case 1922..1940: + return ({({0 ,0 ,0 ,"S" })}); + case 1946: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAY (120,7),UO+3600 ,3600 ,"D" }), // Apr lastSun + ({FIXED(153) ,UO+3600 ,0 ,"S" })});// Jun 2 + case 1943..1945: + case 1948..1949: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAYL(120,7),UO+3600 ,3600 ,"D" })});// Apr lastSun + case 1950: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAY (120,7),UO+3600 ,3600 ,"D" }), // Apr lastSun + ({LDAY (273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1941: + case 1951..1955: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1956..1960: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1942: + case 1947: + case 1961: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (120,7),UO+7200 ,3600 ,"D" })});// Apr lastSun + case 1962..: + return ({({0 ,0 ,3600 ,"D" })}); + } + } +} + +class Detroit +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1948: + return ({({0 ,0 ,0 ,"S" }), // ? + ({LDAY (121,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAY (274,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1967: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(165) ,UO+7200 ,3600 ,"D" }), // Jun 14 + ({LDAY (304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + default: // ..1947 and 1968.. + case 1949..1966: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Menominee +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1946: + return ({({0 ,0 ,0 ,"S" }), // ? + ({LDAY (120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAY (273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1966: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAY (304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + default: // ..1945 and 1967.. + case 1947..1965: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Canada +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1918: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(104) ,UO+7200 ,3600 ,"D" }), // Apr 14 + ({FIXED(304) ,UO+3600 ,0 ,"S" })});// Oct 31 + case 1942: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(40) ,UO+7200 ,3600 ,"D" })});// Feb 9 + case 1943..1944: + return ({({0 ,0 ,3600 ,"D" })}); + case 1945: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(273) ,UO+3600 ,0 ,"S" })});// Sep 30 + default: // ..1917: + case 1919..1941: + case 1946..1973: + return ({({0 ,0 ,0 ,"S" })}); + case 1974..1986: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1987..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class StJohns +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1916: + return ({({0 ,0 ,0 ,"S" })});// ? + case 1917: + return ({({0 ,0 ,0 ,"S" }), // ? + ({LDAY (104,7),UO+7200 ,3600 ,"D" }), // Apr Sun>=8 + ({FIXED(260) ,UO+3600 ,0 ,"S" })});// Sep 17 + case 1918: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (104,7),UO+7200 ,3600 ,"D" }), // Apr Sun>=8 + ({FIXED(304) ,UO+3600 ,0 ,"S" })});// Oct 31 + case 1919: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(125) ,UO+82800 ,3600 ,"D" }), // May 5 + ({FIXED(224) ,UO+79200 ,0 ,"S" })});// Aug 12 + case 1920..1935: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(127,7),UO+82800 ,3600 ,"D" }), // May Sun>=1 + ({LDAYL(304,7),UO+79200 ,0 ,"S" })});// Oct lastSun + case 1936..1941: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(134,7),UO+0 ,3600 ,"D" }), // May Sun>=8 + ({LDAYL(280,7),UO-3600 ,0 ,"S" })});// Oct Sun>=1 + case 1942: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(60) ,UO+0 ,3600 ,"D" }), // Mar 1 + ({FIXED(365) ,UO-3600 ,0 ,"S" })});// Dec 31 + case 1943: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(150) ,UO+0 ,3600 ,"D" }), // May 30 + ({FIXED(248) ,UO-3600 ,0 ,"S" })});// Sep 5 + case 1944: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(192) ,UO+0 ,3600 ,"D" }), // Jul 10 + ({FIXED(246) ,UO-3600 ,0 ,"S" })});// Sep 2 + case 1945: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(1) ,UO+0 ,3600 ,"D" }), // Jan 1 + ({FIXED(280) ,UO+3600 ,0 ,"S" })});// Oct 7 + case 1946..1950: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(134,7),UO+7200 ,3600 ,"D" }), // May Sun>=8 + ({LDAYL(281,7),UO+3600 ,0 ,"S" })});// Oct Sun>=2 + case 1951..1959: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1960..1986: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1988: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (98,7) ,UO+7200 ,7200 ,"DD" }), // Apr Sun>=1 + ({LDAY (305,7),UO+0 ,0 ,"S" })});// Oct lastSun + case 1987: + case 1989..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class Halifax +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1916: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(92) ,UO+0 ,3600 ,"D" }), // Apr 1 + ({FIXED(275) ,UO-3600 ,0 ,"S" })});// Oct 1 + case 1918: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(104) ,UO+7200 ,3600 ,"D" }), // Apr 14 + ({FIXED(304) ,UO+3600 ,0 ,"S" })});// Oct 31 + case 1920: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(130) ,UO+0 ,3600 ,"D" }), // May 9 + ({FIXED(242) ,UO-3600 ,0 ,"S" })});// Aug 29 + case 1921: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(126) ,UO+0 ,3600 ,"D" }), // May 6 + ({FIXED(248) ,UO-3600 ,0 ,"S" })});// Sep 5 + case 1922: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(120) ,UO+0 ,3600 ,"D" }), // Apr 30 + ({FIXED(248) ,UO-3600 ,0 ,"S" })});// Sep 5 + case 1923: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (127,7),UO+0 ,3600 ,"D" }), // May Sun>=1 + ({FIXED(247) ,UO-3600 ,0 ,"S" })});// Sep 4 + case 1924: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (128,7),UO+0 ,3600 ,"D" }), // May Sun>=1 + ({FIXED(259) ,UO-3600 ,0 ,"S" })});// Sep 15 + case 1925: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (127,7),UO+0 ,3600 ,"D" }), // May Sun>=1 + ({FIXED(271) ,UO-3600 ,0 ,"S" })});// Sep 28 + case 1926: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(136) ,UO+0 ,3600 ,"D" }), // May 16 + ({FIXED(256) ,UO-3600 ,0 ,"S" })});// Sep 13 + case 1927: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(121) ,UO+0 ,3600 ,"D" }), // May 1 + ({FIXED(269) ,UO-3600 ,0 ,"S" })});// Sep 26 + case 1928: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (135,7),UO+0 ,3600 ,"D" }), // May Sun>=8 + ({FIXED(253) ,UO-3600 ,0 ,"S" })});// Sep 9 + case 1929: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (134,7),UO+0 ,3600 ,"D" }), // May Sun>=8 + ({FIXED(246) ,UO-3600 ,0 ,"S" })});// Sep 3 + case 1930: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (134,7),UO+0 ,3600 ,"D" }), // May Sun>=8 + ({FIXED(258) ,UO-3600 ,0 ,"S" })});// Sep 15 + case 1931: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (134,7),UO+0 ,3600 ,"D" }), // May Sun>=8 + ({LDAY (273,1),UO-3600 ,0 ,"S" })});// Sep Mon>=24 + case 1932: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (274,1),UO+0 ,0 ,"S" })});// Sep Mon>=24 + case 1933: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(120) ,UO+0 ,3600 ,"D" }), // Apr 30 + ({FIXED(275) ,UO-3600 ,0 ,"S" })});// Oct 2 + case 1934: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(140) ,UO+0 ,3600 ,"D" }), // May 20 + ({FIXED(259) ,UO-3600 ,0 ,"S" })});// Sep 16 + case 1935: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(153) ,UO+0 ,3600 ,"D" }), // Jun 2 + ({FIXED(273) ,UO-3600 ,0 ,"S" })});// Sep 30 + case 1936: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(153) ,UO+0 ,3600 ,"D" }), // Jun 1 + ({FIXED(258) ,UO-3600 ,0 ,"S" })});// Sep 14 + case 1939: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(148) ,UO+0 ,3600 ,"D" }), // May 28 + ({LDAY (273,1),UO-3600 ,0 ,"S" })});// Sep Mon>=24 + case 1937..1938: + case 1940..1941: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(127,7),UO+0 ,3600 ,"D" }), // May Sun>=1 + ({LDAYL(273,1),UO-3600 ,0 ,"S" })});// Sep Mon>=24 + case 1942: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(40) ,UO+7200 ,3600 ,"D" })});// Feb 9 + case 1943..1944: + return ({({0 ,0 ,3600 ,"D" })}); + case 1945: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAY (273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1946..1959: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + default: // ..1915: + case 1917: + case 1919: + case 1960..1961: + return ({({0 ,0 ,0 ,"S" })}); + case 1962..1986: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1987..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class Mont +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1917: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(84) ,UO+7200 ,3600 ,"D" }), // Mar 25 + ({FIXED(114) ,UO-3600 ,0 ,"S" })});// Apr 24 + case 1918: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(104) ,UO+7200 ,3600 ,"D" }), // Apr 14 + ({FIXED(304) ,UO+3600 ,0 ,"S" })});// Oct 31 + case 1919: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(90) ,UO+9000 ,3600 ,"D" }), // Mar 31 + ({FIXED(298) ,UO+5400 ,0 ,"S" })});// Oct 25 + case 1920: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(123) ,UO+9000 ,3600 ,"D" }), // May 2 + ({FIXED(277) ,UO+5400 ,0 ,"S" })});// Oct 3 + case 1921: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(121) ,UO+7200 ,3600 ,"D" }), // May 1 + ({FIXED(275) ,UO+5400 ,0 ,"S" })});// Oct 2 + case 1922: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(120) ,UO+7200 ,3600 ,"D" }), // Apr 30 + ({FIXED(274) ,UO+5400 ,0 ,"S" })});// Oct 1 + default: // ..1916: + case 1923: + return ({({0 ,0 ,0 ,"S" })}); + case 1924: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(138) ,UO+7200 ,3600 ,"D" }), // May 17 + ({LDAY (274,7),UO+5400 ,0 ,"S" })});// Sep lastSun + case 1925..1926: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (127,7),UO+7200 ,3600 ,"D" }), // May Sun>=1 + ({LDAY (273,7),UO+5400 ,0 ,"S" })});// Sep lastSun + case 1928..1931: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(121,7),UO+0 ,3600 ,"D" }), // Apr Sun>=25 + ({LDAYL(274,7),UO-3600 ,0 ,"S" })});// Sep Sun>=25 + case 1927: + case 1932: + return ({({0 ,0 ,0 ,"S" }), + ({FIX_L(121) ,UO+0 ,3600 ,"D" }), // May 1 + ({LDAYL(274,7),UO-3600 ,0 ,"S" })});// Sep Sun>=25 + case 1933: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (120,7),UO+0 ,3600 ,"D" }), // Apr Sun>=24 + ({FIXED(274) ,UO-3600 ,0 ,"S" })});// Oct 1 + case 1934..1939: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+0 ,3600 ,"D" }), // Apr Sun>=24 + ({LDAYL(273,7),UO-3600 ,0 ,"S" })});// Sep Sun>=24 + case 1940: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (121,7),UO+0 ,3600 ,"D" })});// Apr Sun>=24 + case 1941..1944: + return ({({0 ,0 ,3600 ,"D" })}); + case 1945: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAY (273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1946..1948: + case 1951..1956: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1949..1950: + case 1957..1986: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1987..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class Winn +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1916: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(114) ,UO+0 ,3600 ,"D" }), // Apr 23 + ({FIXED(261) ,UO-3600 ,0 ,"S" })});// Sep 17 + case 1918: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(104) ,UO+7200 ,3600 ,"D" }), // Apr 14 + ({FIXED(304) ,UO+3600 ,0 ,"S" })});// Oct 31 + case 1937: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(136) ,UO+7200 ,3600 ,"D" }), // May 16 + ({FIXED(269) ,UO+3600 ,0 ,"S" })});// Sep 26 + case 1942: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(40) ,UO+7200 ,3600 ,"D" })});// Feb 9 + case 1943..1944: + return ({({0 ,0 ,3600 ,"D" })}); + case 1945: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAY (273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1946: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(132) ,UO+7200 ,3600 ,"D" }), // May 12 + ({FIXED(286) ,UO+3600 ,0 ,"S" })});// Oct 13 + case 1950: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(121) ,UO+7200 ,3600 ,"D" }), // May 1 + ({FIXED(273) ,UO+3600 ,0 ,"S" })});// Sep 30 + case 1947..1949: + case 1951..1958: + case 1960: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1963: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({FIXED(265) ,UO+3600 ,0 ,"S" })});// Sep 22 + default: // ..1915: + case 1917: + case 1919..1936: + case 1938..1941: + case 1961..1962: + case 1964..1965: + return ({({0 ,0 ,0 ,"S" })}); + case 1959: + case 1966..1986: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1987..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class Regina +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1918: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(104) ,UO+7200 ,3600 ,"D" }), // Apr 14 + ({FIXED(304) ,UO+3600 ,0 ,"S" })});// Oct 31 + case 1930..1934: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(127,7),UO+0 ,3600 ,"D" }), // May Sun>=1 + ({LDAYL(280,7),UO-3600 ,0 ,"S" })});// Oct Sun>=1 + case 1938: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (104,7),UO+0 ,3600 ,"D" }), // Apr Sun>=8 + ({LDAY (280,7),UO-3600 ,0 ,"S" })});// Oct Sun>=1 + case 1937: + case 1939..1941: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(104,7),UO+0 ,3600 ,"D" }), // Apr Sun>=8 + ({LDAYL(287,7),UO-3600 ,0 ,"S" })});// Oct Sun>=8 + case 1942: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(40) ,UO+7200 ,3600 ,"D" })});// Feb 9 + case 1943..1944: + return ({({0 ,0 ,3600 ,"D" })}); + case 1945: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAY (273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1946: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (104,7),UO+7200 ,3600 ,"D" }), // Apr Sun>=8 + ({LDAY (287,7),UO+3600 ,0 ,"S" })});// Oct Sun>=8 + case 1947..1958: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1959: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAY (304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + default: // ..1917 and 1960.. + case 1919..1929: + case 1935..1936: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Swift +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1957: + case 1959: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAY (304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1960..1961: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + default: // ..1956 and 1962.. + case 1958: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Edm +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1918: + return ({({0 ,0 ,0 ,"S" }), // ? + ({LDAY (104,7),UO+7200 ,3600 ,"D" }), // Apr Sun>=8 + ({FIXED(304) ,UO+3600 ,0 ,"S" })});// Oct 31 + case 1919: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (104,7),UO+7200 ,3600 ,"D" }), // Apr Sun>=8 + ({FIXED(147) ,UO+3600 ,0 ,"S" })});// May 27 + case 1942: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(40) ,UO+7200 ,3600 ,"D" })});// Feb 9 + case 1943..1944: + return ({({0 ,0 ,3600 ,"D" })}); + case 1945: + return ({({0 ,0 ,3600 ,"D" }), + ({LDAY (273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1921..1923: + case 1947: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAY (273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + default: // ..1917: + case 1924..1941: + case 1946: + case 1948..1966: + case 1968: + case 1970..1971: + return ({({0 ,0 ,0 ,"S" })}); + case 1920: + case 1967: + case 1969: + case 1972..1986: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1987..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class Vanc +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1918: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(104) ,UO+7200 ,3600 ,"D" }), // Apr 14 + ({FIXED(304) ,UO+3600 ,0 ,"S" })});// Oct 31 + default: // ..1917: + case 1919..1941: + return ({({0 ,0 ,0 ,"S" })}); + case 1942: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(40) ,UO+7200 ,3600 ,"D" })});// Feb 9 + case 1943..1944: + return ({({0 ,0 ,3600 ,"D" })}); + case 1945: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(273) ,UO+3600 ,0 ,"S" })});// Sep 30 + case 1946: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({FIXED(286) ,UO+3600 ,0 ,"S" })});// Oct 13 + case 1947..1961: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + case 1962..1986: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1987..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class NT_YK +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1918: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(104) ,UO+7200 ,3600 ,"D" }), // Apr 14 + ({FIXED(300) ,UO+3600 ,0 ,"S" })});// Oct 27 + case 1919: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(145) ,UO+7200 ,3600 ,"D" }), // May 25 + ({FIXED(305) ,UO-3600 ,0 ,"S" })});// Nov 1 + case 1942: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(40) ,UO+7200 ,3600 ,"D" })});// Feb 9 + case 1943..1944: + return ({({0 ,0 ,3600 ,"D" })}); + case 1945: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(273) ,UO+3600 ,0 ,"S" })});// Sep 30 + case 1965: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (120,7),UO+0 ,7200 ,"DD" }), // Apr lastSun + ({LDAY (304,7),UO+0 ,0 ,"S" })});// Oct lastSun + default: // ..1917: + case 1920..1941: + case 1946..1964: + case 1966..1979: + return ({({0 ,0 ,0 ,"S" })}); + case 1980..1986: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1987..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class Mexico +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1939: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(36) ,UO+0 ,3600 ,"D" }), // Feb 5 + ({FIXED(176) ,UO-3600 ,0 ,"S" })});// Jun 25 + case 1940: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(344) ,UO+0 ,3600 ,"D" })});// Dec 9 + case 1941: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(91) ,UO-3600 ,0 ,"S" })});// Apr 1 + case 1943: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(350) ,UO+0 ,3600 ,"D" })});// Dec 16 + case 1944: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(122) ,UO-3600 ,0 ,"S" })});// May 1 + case 1950: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(43) ,UO+0 ,3600 ,"D" }), // Feb 12 + ({FIXED(211) ,UO-3600 ,0 ,"S" })});// Jul 30 + default: // ..1938: + case 1942: + case 1945..1949: + case 1951..1995: + return ({({0 ,0 ,0 ,"S" })}); + case 1996..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class BajaN +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1954..1961: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(273,7),UO+3600 ,0 ,"S" })});// Sep lastSun + default: // ..1953 and 1962.. + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Bahamas +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1963: + return ({({0 ,0 ,0 ,"S" })});// ? + case 1964..1986: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + case 1987..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+7200 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class Barb +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1977: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(163) ,UO+7200 ,3600 ,"D" }), // Jun 12 + ({LDAY (280,7),UO+3600 ,0 ,"S" })});// Oct Sun>=1 + case 1978: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (111,7),UO+7200 ,3600 ,"D" }), // Apr Sun>=15 + ({LDAY (280,7),UO+3600 ,0 ,"S" })});// Oct Sun>=1 + case 1979: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (111,7),UO+7200 ,3600 ,"D" }), // Apr Sun>=15 + ({FIXED(273) ,UO+3600 ,0 ,"S" })});// Sep 30 + case 1980: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (112,7),UO+7200 ,3600 ,"D" }), // Apr Sun>=15 + ({FIXED(269) ,UO+3600 ,0 ,"S" })});// Sep 25 + default: // ..1976 and 1981.. + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Belize +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1918: + return ({({0 ,0 ,0 ,"S" }), // ? + ({LDAY (281,7),UO+0 ,1800 ,"HD" })});// Oct Sun>=2 + case 1919..1942: + return ({({0 ,0 ,1800 ,"HD" }), + ({LDAYL(46,7) ,UO-1800 ,0 ,"S" }), // Feb Sun>=9 + ({LDAYL(281,7),UO+0 ,1800 ,"HD" })});// Oct Sun>=2 + case 1943: + return ({({0 ,0 ,1800 ,"HD" }), + ({LDAY (46,7) ,UO-1800 ,0 ,"S" })});// Feb Sun>=9 + case 1973: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(339) ,UO+0 ,3600 ,"D" })});// Dec 5 + case 1974: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(40) ,UO-3600 ,0 ,"S" })});// Feb 9 + case 1982: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(352) ,UO+0 ,3600 ,"D" })});// Dec 18 + case 1983: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(43) ,UO-3600 ,0 ,"S" })});// Feb 12 + default: // ..1917 and 1984.. + case 1944..1972: + case 1975..1981: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class CR +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1979..1980: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(59,7) ,UO+0 ,3600 ,"D" }), // Feb lastSun + ({LDAYL(158,7),UO-3600 ,0 ,"S" })});// Jun Sun>=1 + case 1991: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (21,6) ,UO+0 ,3600 ,"D" }), // Jan Sat>=15 + ({FIXED(182) ,UO-3600 ,0 ,"S" })});// Jul 1 + case 1992: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (21,6) ,UO+0 ,3600 ,"D" }), // Jan Sat>=15 + ({FIXED(75) ,UO-3600 ,0 ,"S" })});// Mar 15 + default: // ..1978 and 1993.. + case 1981..1990: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Cuba +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1928: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(162) ,UO+0 ,3600 ,"D" }), // Jun 10 + ({FIXED(284) ,UO-3600 ,0 ,"S" })});// Oct 10 + case 1940..1942: + case 1945..1946: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(158,7),UO+0 ,3600 ,"D" }), // Jun Sun>=1 + ({LDAYL(250,7),UO-3600 ,0 ,"S" })});// Sep Sun>=1 + default: // ..1927: + case 1929..1939: + case 1943..1944: + case 1947..1964: + return ({({0 ,0 ,0 ,"S" })}); + case 1965: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(152) ,UO+0 ,3600 ,"D" }), // Jun 1 + ({FIXED(273) ,UO-3600 ,0 ,"S" })});// Sep 30 + case 1966: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(149) ,UO+0 ,3600 ,"D" }), // May 29 + ({FIXED(275) ,UO-3600 ,0 ,"S" })});// Oct 2 + case 1967: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(98) ,UO+0 ,3600 ,"D" }), // Apr 8 + ({LDAY (257,7),UO-3600 ,0 ,"S" })});// Sep Sun>=8 + case 1968: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(105) ,UO+0 ,3600 ,"D" }), // Apr 14 + ({LDAY (258,7),UO-3600 ,0 ,"S" })});// Sep Sun>=8 + case 1972..1974: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+0 ,3600 ,"D" }), // Apr lastSun + ({FIX_L(281) ,UO-3600 ,0 ,"S" })});// Oct 8 + case 1969..1971: + case 1975..1977: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+0 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO-3600 ,0 ,"S" })});// Oct lastSun + case 1978: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(127) ,UO+0 ,3600 ,"D" }), // May 7 + ({LDAY (287,7),UO-3600 ,0 ,"S" })});// Oct Sun>=8 + case 1979..1980: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(80,7) ,UO+0 ,3600 ,"D" }), // Mar Sun>=15 + ({LDAYL(287,7),UO-3600 ,0 ,"S" })});// Oct Sun>=8 + case 1981..1985: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(131,7),UO+0 ,3600 ,"D" }), // May Sun>=5 + ({LDAYL(287,7),UO-3600 ,0 ,"S" })});// Oct Sun>=8 + case 1986..1989: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(79,7) ,UO+0 ,3600 ,"D" }), // Mar Sun>=14 + ({LDAYL(287,7),UO-3600 ,0 ,"S" })});// Oct Sun>=8 + case 1990: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (97,7) ,UO+0 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAY (287,7),UO-3600 ,0 ,"S" })});// Oct Sun>=8 + case 1991..1995: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+0 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(287,7),UO+0 ,0 ,"S" })});// Oct Sun>=8 + case 1996: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (98,7) ,UO+0 ,3600 ,"D" }), // Apr Sun>=1 + ({FIXED(280) ,UO+0 ,0 ,"S" })});// Oct 6 + case 1997: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (97,7) ,UO+0 ,3600 ,"D" }), // Apr Sun>=1 + ({FIXED(285) ,UO+0 ,0 ,"S" })});// Oct 12 + case 1998..1999: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (90,7) ,UO+0 ,3600 ,"D" }), // Mar lastSun + ({LDAY (304,7),UO+0 ,0 ,"S" })});// Oct lastSun + case 2000..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+0 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+0 ,0 ,"S" })});// Oct lastSun + } + } +} + +class DR +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1966: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(303) ,UO+0 ,3600 ,"D" })});// Oct 30 + case 1967: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(59) ,UO-3600 ,0 ,"S" })});// Feb 28 + case 1969: + return ({({0 ,0 ,0 ,"S" }), + ({LDAY (304,7),UO+0 ,1800 ,"HD" })});// Oct lastSun + case 1970: + return ({({0 ,0 ,1800 ,"HD" }), + ({FIXED(52) ,UO-1800 ,0 ,"S" }), // Feb 21 + ({LDAY (304,7),UO+0 ,1800 ,"HD" })});// Oct lastSun + case 1971: + return ({({0 ,0 ,1800 ,"HD" }), + ({FIXED(20) ,UO-1800 ,0 ,"S" }), // Jan 20 + ({LDAY (304,7),UO+0 ,1800 ,"HD" })});// Oct lastSun + case 1972..1973: + return ({({0 ,0 ,1800 ,"HD" }), + ({FIXED(21) ,UO-1800 ,0 ,"S" }), // Jan 21 + ({LDAYL(304,7),UO+0 ,1800 ,"HD" })});// Oct lastSun + case 1974: + return ({({0 ,0 ,1800 ,"HD" }), + ({FIXED(21) ,UO-1800 ,0 ,"S" })});// Jan 21 + default: // ..1965 and 1975.. + case 1968: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Salv +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1987..1988: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(127,7),UO+0 ,3600 ,"D" }), // May Sun>=1 + ({LDAYL(273,7),UO-3600 ,0 ,"S" })});// Sep lastSun + default: // ..1986 and 1989.. + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Guat +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1973: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(329) ,UO+0 ,3600 ,"D" })});// Nov 25 + case 1974: + return ({({0 ,0 ,3600 ,"D" }), + ({FIXED(55) ,UO-3600 ,0 ,"S" })});// Feb 24 + case 1983: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(141) ,UO+0 ,3600 ,"D" }), // May 21 + ({FIXED(265) ,UO-3600 ,0 ,"S" })});// Sep 22 + case 1991: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(82) ,UO+0 ,3600 ,"D" }), // Mar 23 + ({FIXED(250) ,UO-3600 ,0 ,"S" })});// Sep 7 + default: // ..1972 and 1992.. + case 1975..1982: + case 1984..1990: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Haiti +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1983: + return ({({0 ,0 ,0 ,"S" }), // ? + ({FIXED(128) ,UO+0 ,3600 ,"D" }), // May 8 + ({LDAY (304,7),UO-3600 ,0 ,"S" })});// Oct lastSun + case 1984..1987: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+0 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO-3600 ,0 ,"S" })});// Oct lastSun + case 1988..1997: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+3600 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + default: // ..1982 and 1998.. + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class Nic +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1979..1980: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(81,7) ,UO+0 ,3600 ,"D" }), // Mar Sun>=16 + ({LDAYL(180,1),UO-3600 ,0 ,"S" })});// Jun Mon>=23 + case 1992: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(1) ,UO+14400 ,3600 ,"D" }), // Jan 1 + ({FIXED(268) ,UO-3600 ,0 ,"S" })});// Sep 24 + default: // ..1978 and 1993.. + case 1981..1991: + return ({({0 ,0 ,0 ,"S" })}); + } + } +} + +class TC +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1978: + return ({({0 ,0 ,0 ,"S" })});// ? + case 1979..1986: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+0 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO-3600 ,0 ,"S" })});// Oct lastSun + case 1987..: + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(97,7) ,UO+0 ,3600 ,"D" }), // Apr Sun>=1 + ({LDAYL(304,7),UO-3600 ,0 ,"S" })});// Oct lastSun + } + } +} + +class Arg +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1930: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(335) ,UO+0 ,3600 ,"S" })});// Dec 1 + case 1931: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(91) ,UO-3600 ,0 ,"" }), // Apr 1 + ({FIXED(288) ,UO+0 ,3600 ,"S" })});// Oct 15 + case 1932..1939: + return ({({0 ,0 ,3600 ,"S" }), + ({FIX_L(60) ,UO-3600 ,0 ,"" }), // Mar 1 + ({FIX_L(305) ,UO+0 ,3600 ,"S" })});// Nov 1 + case 1940: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(61) ,UO-3600 ,0 ,"" }), // Mar 1 + ({FIXED(183) ,UO+0 ,3600 ,"S" })});// Jul 1 + case 1941: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(166) ,UO-3600 ,0 ,"" }), // Jun 15 + ({FIXED(288) ,UO+0 ,3600 ,"S" })});// Oct 15 + case 1943: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(213) ,UO-3600 ,0 ,"" }), // Aug 1 + ({FIXED(288) ,UO+0 ,3600 ,"S" })});// Oct 15 + case 1946: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(60) ,UO-3600 ,0 ,"" }), // Mar 1 + ({FIXED(274) ,UO+0 ,3600 ,"S" })});// Oct 1 + case 1942: + case 1944..1945: + case 1947..1962: + return ({({0 ,0 ,3600 ,"S" })}); + case 1963: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(274) ,UO-3600 ,0 ,"" }), // Oct 1 + ({FIXED(349) ,UO+0 ,3600 ,"S" })});// Dec 15 + case 1964..1966: + return ({({0 ,0 ,3600 ,"S" }), + ({FIX_L(60) ,UO-3600 ,0 ,"" }), // Mar 1 + ({FIX_L(288) ,UO+0 ,3600 ,"S" })});// Oct 15 + case 1967: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(91) ,UO-3600 ,0 ,"" }), // Apr 1 + ({LDAY (280,7),UO+0 ,3600 ,"S" })});// Oct Sun>=1 + case 1974: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(23) ,UO+0 ,3600 ,"S" }), // Jan 23 + ({FIXED(121) ,UO-3600 ,0 ,"" }), // May 1 + ({LDAY (280,7),UO+0 ,3600 ,"S" })});// Oct Sun>=1 + case 1968: + case 1975..1976: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(97,7) ,UO-3600 ,0 ,"" }), // Apr Sun>=1 + ({LDAYL(280,7),UO+0 ,3600 ,"S" })});// Oct Sun>=1 + case 1969: + case 1977: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (97,7) ,UO-3600 ,0 ,"" })});// Apr Sun>=1 + case 1985: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(306) ,UO+0 ,3600 ,"S" })});// Nov 2 + case 1986: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(73) ,UO-3600 ,0 ,"" }), // Mar 14 + ({FIXED(298) ,UO+0 ,3600 ,"S" })});// Oct 25 + case 1987: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(44) ,UO-3600 ,0 ,"" }), // Feb 13 + ({FIXED(298) ,UO+0 ,3600 ,"S" })});// Oct 25 + case 1988: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(38) ,UO-3600 ,0 ,"" }), // Feb 7 + ({FIXED(336) ,UO+0 ,3600 ,"S" })});// Dec 1 + case 1989..1992: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(66,7) ,UO-3600 ,0 ,"" }), // Mar Sun>=1 + ({LDAYL(294,7),UO+0 ,3600 ,"S" })});// Oct Sun>=15 + case 1993: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (66,7) ,UO-3600 ,0 ,"" })});// Mar Sun>=1 + default: // ..1929 and 1994.. + case 1970..1973: + case 1978..1984: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Brazil +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1931: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(276) ,UO+39600 ,3600 ,"S" })});// Oct 3 + case 1932: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(92) ,UO-3600 ,0 ,"" }), // Apr 1 + ({FIXED(277) ,UO+0 ,3600 ,"S" })});// Oct 3 + case 1933: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(91) ,UO-3600 ,0 ,"" })});// Apr 1 + case 1949: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(335) ,UO+0 ,3600 ,"S" })});// Dec 1 + case 1950: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(106) ,UO+0 ,0 ,"" }), // Apr 16 + ({FIXED(335) ,UO+0 ,3600 ,"S" })});// Dec 1 + case 1951..1952: + return ({({0 ,0 ,3600 ,"S" }), + ({FIX_L(91) ,UO-3600 ,0 ,"" }), // Apr 1 + ({FIX_L(335) ,UO+0 ,3600 ,"S" })});// Dec 1 + case 1963: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(343) ,UO+0 ,3600 ,"S" })});// Dec 9 + case 1965: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(31) ,UO+0 ,3600 ,"S" }), // Jan 31 + ({FIXED(90) ,UO-3600 ,0 ,"" }), // Mar 31 + ({FIXED(335) ,UO+0 ,3600 ,"S" })});// Dec 1 + case 1966..1967: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(60) ,UO-3600 ,0 ,"" }), // Mar 1 + ({FIXED(305) ,UO+0 ,3600 ,"S" })});// Nov 1 + case 1953: + case 1964: + case 1968: + return ({({0 ,0 ,3600 ,"S" }), + ({FIX_L(60) ,UO-3600 ,0 ,"" })});// Mar 1 + default: // ..1930: + case 1934..1948: + case 1954..1962: + case 1969..1984: + return ({({0 ,0 ,0 ,"" })}); + case 1985: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(306) ,UO+0 ,3600 ,"S" })});// Nov 2 + case 1986: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(74) ,UO-3600 ,0 ,"" }), // Mar 15 + ({FIXED(298) ,UO+0 ,3600 ,"S" })});// Oct 25 + case 1987: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(45) ,UO-3600 ,0 ,"" }), // Feb 14 + ({FIXED(298) ,UO+0 ,3600 ,"S" })});// Oct 25 + case 1988: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(38) ,UO-3600 ,0 ,"" }), // Feb 7 + ({FIXED(290) ,UO+0 ,3600 ,"S" })});// Oct 16 + case 1989: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(29) ,UO-3600 ,0 ,"" }), // Jan 29 + ({FIXED(288) ,UO+0 ,3600 ,"S" })});// Oct 15 + case 1990: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(42) ,UO-3600 ,0 ,"" }), // Feb 11 + ({FIXED(294) ,UO+0 ,3600 ,"S" })});// Oct 21 + case 1991: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(48) ,UO-3600 ,0 ,"" }), // Feb 17 + ({FIXED(293) ,UO+0 ,3600 ,"S" })});// Oct 20 + case 1992: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(40) ,UO-3600 ,0 ,"" }), // Feb 9 + ({FIXED(299) ,UO+0 ,3600 ,"S" })});// Oct 25 + case 1993: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(31) ,UO-3600 ,0 ,"" }), // Jan 31 + ({LDAY (290,7),UO+0 ,3600 ,"S" })});// Oct Sun>=11 + case 1994..1995: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (52,7) ,UO-3600 ,0 ,"" }), // Feb Sun>=15 + ({LDAY (290,7),UO+0 ,3600 ,"S" })});// Oct Sun>=11 + case 1996: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(42) ,UO-3600 ,0 ,"" }), // Feb 11 + ({FIXED(280) ,UO+0 ,3600 ,"S" })});// Oct 6 + case 1997: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(47) ,UO-3600 ,0 ,"" }), // Feb 16 + ({FIXED(279) ,UO+0 ,3600 ,"S" })});// Oct 6 + case 1998: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(60) ,UO-3600 ,0 ,"" }), // Mar 1 + ({FIXED(284) ,UO+0 ,3600 ,"S" })});// Oct 11 + case 1999: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(52) ,UO-3600 ,0 ,"" }), // Feb 21 + ({LDAY (280,7),UO+0 ,3600 ,"S" })});// Oct Sun>=1 + case 2000..: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(59,7) ,UO-3600 ,0 ,"" }), // Feb lastSun + ({LDAYL(280,7),UO+0 ,3600 ,"S" })});// Oct Sun>=1 + } + } +} + +class Chile +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1919: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(183) ,UO-3600 ,0 ,"" })});// Jul 2 + case 1918: + case 1927: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(244) ,UO+0 ,3600 ,"S" })});// Sep 1 + case 1928..1931: + return ({({0 ,0 ,3600 ,"S" }), + ({FIX_L(91) ,UO-3600 ,0 ,"" }), // Apr 1 + ({FIX_L(244) ,UO+0 ,3600 ,"S" })});// Sep 1 + case 1932: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(92) ,UO-3600 ,0 ,"" })});// Apr 1 + default: // ..1917: + case 1920..1926: + case 1933..1968: + return ({({0 ,0 ,0 ,"" })}); + case 1969: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (288,7),UO+0 ,3600 ,"S" })});// Oct Sun>=9 + case 1998: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (74,7) ,UO-3600 ,0 ,"" }), // Mar Sun>=9 + ({FIXED(270) ,UO+0 ,3600 ,"S" })});// Sep 27 + case 1999: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(94) ,UO-3600 ,0 ,"" }), // Apr 4 + ({LDAY (288,7),UO+0 ,3600 ,"S" })});// Oct Sun>=9 + case 1970..1997: + case 2000..: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(74,7) ,UO-3600 ,0 ,"" }), // Mar Sun>=9 + ({LDAYL(288,7),UO+0 ,3600 ,"S" })});// Oct Sun>=9 + } + } +} + +class CO +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1992: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(123) ,UO+0 ,3600 ,"S" }), // May 2 + ({FIXED(366) ,UO-3600 ,0 ,"" })});// Dec 31 + default: // ..1991 and 1993.. + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Falk +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1939: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (84,7) ,UO-3600 ,0 ,"" }), // Mar Sun>=19 + ({FIXED(274) ,UO+0 ,3600 ,"S" })});// Oct 1 + case 1938: + case 1940..1942: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(84,7) ,UO-3600 ,0 ,"" }), // Mar Sun>=19 + ({LDAYL(273,7),UO+0 ,3600 ,"S" })});// Sep lastSun + case 1943: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(1) ,UO-3600 ,0 ,"" })});// Jan 1 + default: // ..1936: + case 1944..1982: + return ({({0 ,0 ,0 ,"" })}); + case 1937: + case 1983: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (273,7),UO+0 ,3600 ,"S" })});// Sep lastSun + case 1984: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (121,7),UO-3600 ,0 ,"" }), // Apr lastSun + ({FIXED(260) ,UO+0 ,3600 ,"S" })});// Sep 16 + case 1985: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (120,7),UO-3600 ,0 ,"" }), // Apr lastSun + ({LDAY (258,7),UO+0 ,3600 ,"S" })});// Sep Sun>=9 + case 1986..1995: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(112,7),UO-3600 ,0 ,"" }), // Apr Sun>=16 + ({LDAYL(258,7),UO+0 ,3600 ,"S" })});// Sep Sun>=9 + case 1996..: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(112,7),UO-3600 ,0 ,"" }), // Apr Sun>=16 + ({LDAYL(257,7),UO+0 ,3600 ,"S" })});// Sep Sun>=8 + } + } +} + +class Para +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + default: // ..1974: + return ({({0 ,0 ,0 ,"" })});// ? + case 1975: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(60) ,UO+0 ,0 ,"" }), // Mar 1 + ({FIXED(274) ,UO+0 ,3600 ,"S" })});// Oct 1 + case 1976..1978: + return ({({0 ,0 ,3600 ,"S" }), + ({FIX_L(60) ,UO-3600 ,0 ,"" }), // Mar 1 + ({FIX_L(274) ,UO+0 ,3600 ,"S" })});// Oct 1 + case 1989: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(91) ,UO-3600 ,0 ,"" }), // Apr 1 + ({FIXED(295) ,UO+0 ,3600 ,"S" })});// Oct 22 + case 1979..1988: + case 1990: + return ({({0 ,0 ,3600 ,"S" }), + ({FIX_L(91) ,UO-3600 ,0 ,"" }), // Apr 1 + ({FIX_L(274) ,UO+0 ,3600 ,"S" })});// Oct 1 + case 1991: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(91) ,UO-3600 ,0 ,"" }), // Apr 1 + ({FIXED(279) ,UO+0 ,3600 ,"S" })});// Oct 6 + case 1992: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(61) ,UO-3600 ,0 ,"" }), // Mar 1 + ({FIXED(279) ,UO+0 ,3600 ,"S" })});// Oct 5 + case 1993: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(90) ,UO-3600 ,0 ,"" }), // Mar 31 + ({FIXED(274) ,UO+0 ,3600 ,"S" })});// Oct 1 + case 1994..1995: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (59,7) ,UO-3600 ,0 ,"" }), // Feb lastSun + ({FIXED(274) ,UO+0 ,3600 ,"S" })});// Oct 1 + case 1997: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (59,7) ,UO-3600 ,0 ,"" }), // Feb lastSun + ({LDAY (280,7),UO+0 ,3600 ,"S" })});// Oct Sun>=1 + case 1996: + case 1998: + return ({({0 ,0 ,3600 ,"S" }), + ({FIX_L(60) ,UO-3600 ,0 ,"" }), // Mar 1 + ({LDAYL(280,7),UO+0 ,3600 ,"S" })});// Oct Sun>=1 + case 1999..: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAYL(59,7) ,UO-3600 ,0 ,"" }), // Feb lastSun + ({LDAYL(287,7),UO+0 ,3600 ,"S" })});// Oct Sun>=8 + } + } +} + +class Peru +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1938: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(1) ,UO+0 ,3600 ,"S" }), // Jan 1 + ({FIXED(91) ,UO-3600 ,0 ,"" }), // Apr 1 + ({LDAY (273,7),UO+0 ,3600 ,"S" })});// Sep lastSun + case 1939: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (89,7) ,UO-3600 ,0 ,"" }), // Mar Sun>=24 + ({LDAY (273,7),UO+0 ,3600 ,"S" })});// Sep lastSun + case 1940: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (90,7) ,UO-3600 ,0 ,"" })});// Mar Sun>=24 + case 1987: + case 1990: + case 1994: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(1) ,UO+0 ,3600 ,"S" }), // Jan 1 + ({FIXED(91) ,UO-3600 ,0 ,"" })});// Apr 1 + default: // ..1937 and 1995.. + case 1941..1986: + case 1988..1989: + case 1991..1993: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class Uruguay +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1923: + return ({({0 ,0 ,0 ,"" }), // ? + ({FIXED(275) ,UO+0 ,1800 ,"HS" })});// Oct 2 + case 1924..1925: + return ({({0 ,0 ,1800 ,"HS" }), + ({FIX_L(91) ,UO-1800 ,0 ,"" }), // Apr 1 + ({FIX_L(274) ,UO+0 ,1800 ,"HS" })});// Oct 1 + case 1926: + return ({({0 ,0 ,1800 ,"HS" }), + ({FIXED(91) ,UO-1800 ,0 ,"" })});// Apr 1 + case 1933: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (304,7),UO+0 ,1800 ,"HS" })});// Oct lastSun + case 1934..1935: + return ({({0 ,0 ,1800 ,"HS" }), + ({LDAY (90,6) ,UO+84600 ,0 ,"" }), // Mar Sat>=25 + ({LDAY (304,7),UO+0 ,1800 ,"HS" })});// Oct lastSun + case 1936: + return ({({0 ,0 ,1800 ,"HS" }), + ({LDAY (91,6) ,UO+84600 ,0 ,"" }), // Mar Sat>=25 + ({FIXED(306) ,UO+0 ,1800 ,"HS" })});// Nov 1 + case 1937..1940: + return ({({0 ,0 ,1800 ,"HS" }), + ({LDAYL(90,7) ,UO-1800 ,0 ,"" }), // Mar lastSun + ({LDAYL(304,7),UO+0 ,1800 ,"HS" })});// Oct lastSun + case 1941: + return ({({0 ,0 ,1800 ,"HS" }), + ({LDAY (90,7) ,UO-1800 ,0 ,"" }), // Mar lastSun + ({FIXED(213) ,UO+0 ,0 ,"" })});// Aug 1 + case 1942: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(1) ,UO+0 ,1800 ,"HS" }), // Jan 1 + ({FIXED(348) ,UO-1800 ,3600 ,"S" })});// Dec 14 + case 1943: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(73) ,UO-3600 ,0 ,"" })});// Mar 14 + case 1959: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(144) ,UO+0 ,3600 ,"S" }), // May 24 + ({FIXED(319) ,UO-3600 ,0 ,"" })});// Nov 15 + case 1960: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(17) ,UO+0 ,3600 ,"S" }), // Jan 17 + ({FIXED(66) ,UO-3600 ,0 ,"" })});// Mar 6 + case 1965: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+0 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(269) ,UO-3600 ,0 ,"" })});// Sep 26 + case 1966..1967: + return ({({0 ,0 ,0 ,"" }), + ({LDAY (97,7) ,UO+0 ,3600 ,"S" }), // Apr Sun>=1 + ({FIXED(304) ,UO-3600 ,0 ,"" })});// Oct 31 + case 1968..1970: + return ({({0 ,0 ,0 ,"" }), + ({FIX_L(147) ,UO+0 ,1800 ,"HS" }), // May 27 + ({FIX_L(336) ,UO-1800 ,0 ,"" })});// Dec 2 + case 1972: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(115) ,UO+0 ,3600 ,"S" }), // Apr 24 + ({FIXED(228) ,UO-3600 ,0 ,"" })});// Aug 15 + case 1974: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(69) ,UO+0 ,1800 ,"HS" }), // Mar 10 + ({FIXED(356) ,UO-1800 ,3600 ,"S" })});// Dec 22 + case 1975: + return ({({0 ,0 ,3600 ,"S" })}); + case 1976: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(275) ,UO-3600 ,0 ,"" })});// Oct 1 + case 1977: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(338) ,UO+0 ,3600 ,"S" })});// Dec 4 + case 1978: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(91) ,UO-3600 ,0 ,"" })});// Apr 1 + case 1979: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(274) ,UO+0 ,3600 ,"S" })});// Oct 1 + case 1980: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(122) ,UO-3600 ,0 ,"" })});// May 1 + case 1987: + return ({({0 ,0 ,0 ,"" }), + ({FIXED(348) ,UO+0 ,3600 ,"S" })});// Dec 14 + case 1988: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(74) ,UO-3600 ,0 ,"" }), // Mar 14 + ({FIXED(346) ,UO+0 ,3600 ,"S" })});// Dec 11 + case 1989: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(71) ,UO-3600 ,0 ,"" }), // Mar 12 + ({FIXED(302) ,UO+0 ,3600 ,"S" })});// Oct 29 + case 1990..1991: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (66,7) ,UO-3600 ,0 ,"" }), // Mar Sun>=1 + ({LDAY (300,7),UO+0 ,3600 ,"S" })});// Oct Sun>=21 + case 1992: + return ({({0 ,0 ,3600 ,"S" }), + ({LDAY (67,7) ,UO-3600 ,0 ,"" }), // Mar Sun>=1 + ({FIXED(292) ,UO+0 ,3600 ,"S" })});// Oct 18 + case 1993: + return ({({0 ,0 ,3600 ,"S" }), + ({FIXED(59) ,UO-3600 ,0 ,"" })});// Feb 28 + default: // ..1922 and 1994.. + case 1927..1932: + case 1944..1958: + case 1961..1964: + case 1971: + case 1973: + case 1981..1986: + return ({({0 ,0 ,0 ,"" })}); + } + } +} + +class SystemV +{ + inherit TZRules; + static array(array(string|int)) jd_year_periods(int jd) + { + [int y,int yjd,int leap]=gregorian_yjd(jd); + switch (y) + { + case 1974: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(6) ,UO+7200 ,3600 ,"D" }), // Jan 6 + ({LDAY (334,7),UO+3600 ,0 ,"S" })});// Nov lastSun + case 1975: + return ({({0 ,0 ,0 ,"S" }), + ({FIXED(54) ,UO+7200 ,3600 ,"D" }), // Feb 23 + ({LDAY (304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + default: // ..1973 and 1976.. + return ({({0 ,0 ,0 ,"S" }), + ({LDAYL(120,7),UO+7200 ,3600 ,"D" }), // Apr lastSun + ({LDAYL(304,7),UO+3600 ,0 ,"S" })});// Oct lastSun + } + } +} + diff --git a/lib/modules/Calendar.pmod/TZs.h b/lib/modules/Calendar.pmod/TZs.h new file mode 100644 index 0000000000000000000000000000000000000000..0bf033cef8a332cf8e7a029ccb1ba7c9db93d136 --- /dev/null +++ b/lib/modules/Calendar.pmod/TZs.h @@ -0,0 +1,6096 @@ +// ---------------------------------------------------------------- +// Timezones +// +// NOTE: this file is generated by mkrules.pike; +// please do not edit manually /Mirar +// ---------------------------------------------------------------- + +import "."; + +// ---------------------------------------------------------------------- +// Timezones +// ---------------------------------------------------------------------- + +Ruleset.Timezone Indian_Chagos=Ruleset.Timezone(-18000,"IOT"); +Ruleset.Timezone Indian_Cocos=Ruleset.Timezone(-23400,"CCT"); +Ruleset.Timezone Pacific_Chatham=TZrules.Chatham(-45900,"CHA%sT"); +Ruleset.Timezone NZ_CHAT=Pacific_Chatham; +Ruleset.Timezone Pacific_Johnston=Ruleset.Timezone(36000,"HST"); +Ruleset.Timezone Etc_GMT=Ruleset.Timezone(0,"GMT"); +Ruleset.Timezone GMT=Etc_GMT; +Ruleset.Timezone Etc_Greenwich=Etc_GMT; +Ruleset.Timezone Etc_GMT_0=Etc_GMT; +Ruleset.Timezone Etc_GMTp0=Etc_GMT; +Ruleset.Timezone Etc_GMT0=Etc_GMT; +Ruleset.Timezone Etc_UTC=Ruleset.Timezone(0,"UTC"); +Ruleset.Timezone UTC=Etc_UTC; +Ruleset.Timezone Etc_Universal=Etc_UTC; +Ruleset.Timezone Etc_Zulu=Etc_UTC; +Ruleset.Timezone Etc_UCT=Ruleset.Timezone(0,"UCT"); +Ruleset.Timezone UCT=Etc_UCT; +Ruleset.Timezone Etc_GMT_14=Ruleset.Timezone(-50400,"GMT-14"); +Ruleset.Timezone Etc_GMT_13=Ruleset.Timezone(-46800,"GMT-13"); +Ruleset.Timezone Etc_GMT_12=Ruleset.Timezone(-43200,"GMT-12"); +Ruleset.Timezone Etc_GMT_11=Ruleset.Timezone(-39600,"GMT-11"); +Ruleset.Timezone Etc_GMT_10=Ruleset.Timezone(-36000,"GMT-10"); +Ruleset.Timezone Etc_GMT_9=Ruleset.Timezone(-32400,"GMT-9"); +Ruleset.Timezone Etc_GMT_8=Ruleset.Timezone(-28800,"GMT-8"); +Ruleset.Timezone Etc_GMT_7=Ruleset.Timezone(-25200,"GMT-7"); +Ruleset.Timezone Etc_GMT_6=Ruleset.Timezone(-21600,"GMT-6"); +Ruleset.Timezone Etc_GMT_5=Ruleset.Timezone(-18000,"GMT-5"); +Ruleset.Timezone Etc_GMT_4=Ruleset.Timezone(-14400,"GMT-4"); +Ruleset.Timezone Etc_GMT_3=Ruleset.Timezone(-10800,"GMT-3"); +Ruleset.Timezone Etc_GMT_2=Ruleset.Timezone(-7200,"GMT-2"); +Ruleset.Timezone Etc_GMT_1=Ruleset.Timezone(-3600,"GMT-1"); +Ruleset.Timezone Etc_GMTp1=Ruleset.Timezone(3600,"GMT+1"); +Ruleset.Timezone Etc_GMTp2=Ruleset.Timezone(7200,"GMT+2"); +Ruleset.Timezone Etc_GMTp3=Ruleset.Timezone(10800,"GMT+3"); +Ruleset.Timezone Etc_GMTp4=Ruleset.Timezone(14400,"GMT+4"); +Ruleset.Timezone Etc_GMTp5=Ruleset.Timezone(18000,"GMT+5"); +Ruleset.Timezone Etc_GMTp6=Ruleset.Timezone(21600,"GMT+6"); +Ruleset.Timezone Etc_GMTp7=Ruleset.Timezone(25200,"GMT+7"); +Ruleset.Timezone Etc_GMTp8=Ruleset.Timezone(28800,"GMT+8"); +Ruleset.Timezone Etc_GMTp9=Ruleset.Timezone(32400,"GMT+9"); +Ruleset.Timezone Etc_GMTp10=Ruleset.Timezone(36000,"GMT+10"); +Ruleset.Timezone Etc_GMTp11=Ruleset.Timezone(39600,"GMT+11"); +Ruleset.Timezone Etc_GMTp12=Ruleset.Timezone(43200,"GMT+12"); +Ruleset.Timezone WET=TZrules.EU(0,"WE%sT"); +Ruleset.Timezone CET=TZrules.C_Eur(-3600,"CE%sT"); +Ruleset.Timezone MET=TZrules.C_Eur(-3600,"ME%sT"); +Ruleset.Timezone EET=TZrules.EU(-7200,"EE%sT"); +Ruleset.Timezone Atlantic_Jan_Mayen=Ruleset.Timezone(3600,"EGT"); +Ruleset.Timezone SystemV_AST4ADT=TZrules.SystemV(14400,"A%sT"); +Ruleset.Timezone SystemV_EST5EDT=TZrules.SystemV(18000,"E%sT"); +Ruleset.Timezone SystemV_CST6CDT=TZrules.SystemV(21600,"C%sT"); +Ruleset.Timezone SystemV_MST7MDT=TZrules.SystemV(25200,"M%sT"); +Ruleset.Timezone SystemV_PST8PDT=TZrules.SystemV(28800,"P%sT"); +Ruleset.Timezone SystemV_YST9YDT=TZrules.SystemV(32400,"Y%sT"); +Ruleset.Timezone SystemV_AST4=Ruleset.Timezone(14400,"AST"); +Ruleset.Timezone SystemV_EST5=Ruleset.Timezone(18000,"EST"); +Ruleset.Timezone SystemV_CST6=Ruleset.Timezone(21600,"CST"); +Ruleset.Timezone SystemV_MST7=Ruleset.Timezone(25200,"MST"); +Ruleset.Timezone SystemV_PST8=Ruleset.Timezone(28800,"PST"); +Ruleset.Timezone SystemV_YST9=Ruleset.Timezone(32400,"YST"); +Ruleset.Timezone SystemV_HST10=Ruleset.Timezone(36000,"HST"); + +// ---------------------------------------------------------------------- +// Timezones with an attitude +// ---------------------------------------------------------------------- + +class Africa_Algiers +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=357523200) // from 1981 May + return tz6 || (tz6=Ruleset.Timezone(-3600,"CET")); + if (ux>=309747600) // from 1979 Oct 26 + return tz3 || (tz3=TZrules.Algeria(0,"WE%sT")); + if (ux>=246240000) // from 1977 Oct 21 + return tz4 || (tz4=TZrules.Algeria(-3600,"CE%sT")); + if (ux>=-212029200) // from 1963 Apr 14 + return tz3 || (tz3=TZrules.Algeria(0,"WE%sT")); + if (ux>=-439430400) // from 1956 Jan 29 + return tz6 || (tz6=Ruleset.Timezone(-3600,"CET")); + if (ux>=-733273200) // from 1946 Oct 7 + return tz5 || (tz5=Ruleset.Timezone(0,"WET")); + if (ux>=-942012000) // from 1940 Feb 25 2:00 + return tz4 || (tz4=TZrules.Algeria(-3600,"CE%sT")); + if (ux>=-1855958961) // from 1911 Mar 11 + return tz3 || (tz3=TZrules.Algeria(0,"WE%sT")); + if (ux>=-2486679072) // from 1891 Mar 15 0:01 Paris Mean Time + return tz2 || (tz2=Ruleset.Timezone(-561,"PMT")); + return tz1 || (tz1=Ruleset.Timezone(-732,"LMT")); + } +} + +class Africa_Luanda +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1849395124) // from 1911 May 26 + return tz3 || (tz3=Ruleset.Timezone(-3600,"WAT")); + if (ux>=-2461452776) // from 1892 Luanda Mean Time? + return tz2 || (tz2=Ruleset.Timezone(-3124,"LMT")); + return tz1 || (tz1=Ruleset.Timezone(-3176,"LMT")); + } +} + +class Africa_Porto_Novo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1131235200) // from 1934 Feb 26 + return tz3 || (tz3=Ruleset.Timezone(-3600,"WAT")); + if (ux>=-1830384628) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(0,"GMT")); + return tz1 || (tz1=Ruleset.Timezone(-628,"LMT")); + } +} + +class Africa_Gaborone +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-813805200) // from 1944 Mar 19 2:00 + return tz2 || (tz2=Ruleset.Timezone(-7200,"CAT")); + if (ux>=-829526400) // from 1943 Sep 19 2:00 + return tz3 || (tz3=Ruleset.Timezone(-10800,"CAST")); + if (ux>=-2682294220) // from 1885 + return tz2 || (tz2=Ruleset.Timezone(-7200,"CAT")); + return tz1 || (tz1=Ruleset.Timezone(-6220,"LMT")); + } +} + +class Africa_Ouagadougou +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1830383636) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(0,"GMT")); + return tz1 || (tz1=Ruleset.Timezone(364,"LMT")); + } +} + +class Africa_Bujumbura +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2524528648) // from 1890 + return tz2 || (tz2=Ruleset.Timezone(-7200,"CAT")); + return tz1 || (tz1=Ruleset.Timezone(-7048,"LMT")); + } +} + +class Africa_Douala +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1830386328) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(-3600,"WAT")); + return tz1 || (tz1=Ruleset.Timezone(-2328,"LMT")); + } +} + +class Atlantic_Cape_Verde +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=186120000) // from 1975 Nov 25 2:00 + return tz4 || (tz4=Ruleset.Timezone(3600,"CVT")); + if (ux>=-764118000) // from 1945 Oct 15 + return tz2 || (tz2=Ruleset.Timezone(7200,"CVT")); + if (ux>=-862610400) // from 1942 Sep + return tz3 || (tz3=Ruleset.Timezone(3600,"CVST")); + if (ux>=-1988144756) // from 1907 + return tz2 || (tz2=Ruleset.Timezone(7200,"CVT")); + // Praia + return tz1 || (tz1=Ruleset.Timezone(5644,"LMT")); + } +} + +class Africa_Bangui +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1830388460) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(-3600,"WAT")); + return tz1 || (tz1=Ruleset.Timezone(-4460,"LMT")); + } +} + +class Africa_Ndjamena +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=321314400) // from 1980 Mar 8 + return tz2 || (tz2=Ruleset.Timezone(-3600,"WAT")); + if (ux>=308703600) // from 1979 Oct 14 + return tz3 || (tz3=Ruleset.Timezone(-7200,"WAST")); + if (ux>=-1830387612) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(-3600,"WAT")); + return tz1 || (tz1=Ruleset.Timezone(-3612,"LMT")); + } +} + +class Indian_Comoro +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1846291984) // from 1911 Jul + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + // Moroni, Gran Comoro + return tz1 || (tz1=Ruleset.Timezone(-10384,"LMT")); + } +} + +class Africa_Kinshasa +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2276643672) // from 1897 Nov 9 + return tz2 || (tz2=Ruleset.Timezone(-3600,"WAT")); + return tz1 || (tz1=Ruleset.Timezone(-3672,"LMT")); + } +} + +class Africa_Lubumbashi +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2276646592) // from 1897 Nov 9 + return tz2 || (tz2=Ruleset.Timezone(-7200,"CAT")); + return tz1 || (tz1=Ruleset.Timezone(-6592,"LMT")); + } +} + +class Africa_Brazzaville +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1830387668) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(-3600,"WAT")); + return tz1 || (tz1=Ruleset.Timezone(-3668,"LMT")); + } +} + +class Africa_Abidjan +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1830383032) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(0,"GMT")); + return tz1 || (tz1=Ruleset.Timezone(968,"LMT")); + } +} + +class Africa_Djibouti +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1846291956) // from 1911 Jul + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + return tz1 || (tz1=Ruleset.Timezone(-10356,"LMT")); + } +} + +class Africa_Cairo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2185409100) // from 1900 Oct + return tz2 || (tz2=TZrules.Egypt(-7200,"EE%sT")); + return tz1 || (tz1=Ruleset.Timezone(-7500,"LMT")); + } +} +constant Egypt=Africa_Cairo; + +class Africa_Malabo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-190857600) // from 1963 Dec 15 + return tz3 || (tz3=Ruleset.Timezone(-3600,"WAT")); + if (ux>=-1830386108) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(0,"GMT")); + return tz1 || (tz1=Ruleset.Timezone(-2108,"LMT")); + } +} + +class Africa_Asmera +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1062210920) // from 1936 May 5 + return tz4 || (tz4=Ruleset.Timezone(-10800,"EAT")); + if (ux>=-2524530932) // from 1890 Adis Dera MT + return tz3 || (tz3=Ruleset.Timezone(-9320,"ADMT")); + if (ux>=-3155682932) // from 1870 Asmera Mean Time + return tz2 || (tz2=Ruleset.Timezone(-9332,"AMT")); + return tz1 || (tz1=Ruleset.Timezone(-9332,"LMT")); + } +} + +class Africa_Addis_Ababa +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1062210920) // from 1936 May 5 + return tz3 || (tz3=Ruleset.Timezone(-10800,"EAT")); + if (ux>=-3155682888) // from 1870 Adis Dera MT + return tz2 || (tz2=Ruleset.Timezone(-9320,"ADMT")); + return tz1 || (tz1=Ruleset.Timezone(-9288,"LMT")); + } +} + +class Africa_Libreville +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1830386268) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(-3600,"WAT")); + return tz1 || (tz1=Ruleset.Timezone(-2268,"LMT")); + } +} + +class Africa_Banjul +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-189385200) // from 1964 + return tz4 || (tz4=Ruleset.Timezone(0,"GMT")); + if (ux>=-1104533604) // from 1935 + return tz3 || (tz3=Ruleset.Timezone(3600,"WAT")); + if (ux>=-1830380004) // from 1912 Banjul Mean Time + return tz2 || (tz2=Ruleset.Timezone(3996,"BMT")); + return tz1 || (tz1=Ruleset.Timezone(3996,"LMT")); + } +} + +class Africa_Accra +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1640995148) // from 1918 + return tz2 || (tz2=TZrules.Ghana(0,"%s")); + return tz1 || (tz1=Ruleset.Timezone(52,"LMT")); + } +} + +class Africa_Conakry +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-315615600) // from 1960 + return tz2 || (tz2=Ruleset.Timezone(0,"GMT")); + if (ux>=-1131235200) // from 1934 Feb 26 + return tz3 || (tz3=Ruleset.Timezone(3600,"WAT")); + if (ux>=-1830380708) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(0,"GMT")); + return tz1 || (tz1=Ruleset.Timezone(3292,"LMT")); + } +} + +class Africa_Bissau +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=157770000) // from 1975 + return tz3 || (tz3=Ruleset.Timezone(0,"GMT")); + if (ux>=-1849388260) // from 1911 May 26 + return tz2 || (tz2=Ruleset.Timezone(3600,"WAT")); + return tz1 || (tz1=Ruleset.Timezone(3740,"LMT")); + } +} + +class Africa_Nairobi +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-315629100) // from 1960 + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + if (ux>=-946780200) // from 1940 + return tz4 || (tz4=Ruleset.Timezone(-9900,"BEAUT")); + if (ux>=-1262314800) // from 1930 + return tz3 || (tz3=Ruleset.Timezone(-9000,"BEAT")); + if (ux>=-1309746436) // from 1928 Jul + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + return tz1 || (tz1=Ruleset.Timezone(-8836,"LMT")); + } +} + +class Africa_Maseru +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-813805200) // from 1944 Mar 19 2:00 + return tz2 || (tz2=Ruleset.Timezone(-7200,"SAST")); + if (ux>=-829526400) // from 1943 Sep 19 2:00 + return tz3 || (tz3=Ruleset.Timezone(-10800,"SAST")); + if (ux>=-2109289800) // from 1903 Mar + return tz2 || (tz2=Ruleset.Timezone(-7200,"SAST")); + return tz1 || (tz1=Ruleset.Timezone(-6600,"LMT")); + } +} + +class Africa_Monrovia +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=73529070) // from 1972 May + return tz4 || (tz4=Ruleset.Timezone(0,"GMT")); + if (ux>=-1604359012) // from 1919 Mar Liberia Time + return tz3 || (tz3=Ruleset.Timezone(2670,"LRT")); + if (ux>=-2776979812) // from 1882 Monrovia Mean Time + return tz2 || (tz2=Ruleset.Timezone(2588,"MMT")); + return tz1 || (tz1=Ruleset.Timezone(2588,"LMT")); + } +} + +class Africa_Tripoli +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=875916000) // from 1997 Oct 4 + return tz3 || (tz3=Ruleset.Timezone(-7200,"EET")); + if (ux>=860108400) // from 1997 Apr 4 + return tz5 || (tz5=Ruleset.Timezone(-7200,"CEST")); + if (ux>=844034400) // from 1996 Sep 30 + return tz4 || (tz4=Ruleset.Timezone(-3600,"CET")); + if (ux>=641782800) // from 1990 May 4 + return tz3 || (tz3=Ruleset.Timezone(-7200,"EET")); + if (ux>=378684000) // from 1982 + return tz2 || (tz2=TZrules.Libya(-3600,"CE%sT")); + if (ux>=-347151600) // from 1959 + return tz3 || (tz3=Ruleset.Timezone(-7200,"EET")); + if (ux>=-1577926364) // from 1920 + return tz2 || (tz2=TZrules.Libya(-3600,"CE%sT")); + return tz1 || (tz1=Ruleset.Timezone(-3164,"LMT")); + } +} +constant Libya=Africa_Tripoli; + +class Indian_Antananarivo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-492062400) // from 1954 May 29 23:00s + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + if (ux>=-499924800) // from 1954 Feb 27 23:00s + return tz3 || (tz3=Ruleset.Timezone(-14400,"EAST")); + if (ux>=-1846293004) // from 1911 Jul + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + return tz1 || (tz1=Ruleset.Timezone(-11404,"LMT")); + } +} + +class Africa_Blantyre +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2109291600) // from 1903 Mar + return tz2 || (tz2=Ruleset.Timezone(-7200,"CAT")); + return tz1 || (tz1=Ruleset.Timezone(-8400,"LMT")); + } +} + +class Africa_Bamako +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-300841200) // from 1960 Jun 20 + return tz2 || (tz2=Ruleset.Timezone(0,"GMT")); + if (ux>=-1131235200) // from 1934 Feb 26 + return tz3 || (tz3=Ruleset.Timezone(3600,"WAT")); + if (ux>=-1830382080) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(0,"GMT")); + return tz1 || (tz1=Ruleset.Timezone(1920,"LMT")); + } +} + +class Africa_Timbuktu +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1830383276) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(0,"GMT")); + return tz1 || (tz1=Ruleset.Timezone(724,"LMT")); + } +} + +class Africa_Nouakchott +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-286930800) // from 1960 Nov 28 + return tz2 || (tz2=Ruleset.Timezone(0,"GMT")); + if (ux>=-1131235200) // from 1934 Feb 26 + return tz3 || (tz3=Ruleset.Timezone(3600,"WAT")); + if (ux>=-1830380172) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(0,"GMT")); + return tz1 || (tz1=Ruleset.Timezone(3828,"LMT")); + } +} + +class Indian_Mauritius +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1988164200) // from 1907 Mauritius Time + return tz2 || (tz2=Ruleset.Timezone(-14400,"MUT")); + // Port Louis + return tz1 || (tz1=Ruleset.Timezone(-13800,"LMT")); + } +} + +class Indian_Mayotte +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1846292456) // from 1911 Jul + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + // Mamoutzou + return tz1 || (tz1=Ruleset.Timezone(-10856,"LMT")); + } +} + +class Africa_Casablanca +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=504918000) // from 1986 + return tz4 || (tz4=Ruleset.Timezone(0,"WET")); + if (ux>=448243200) // from 1984 Mar 16 + return tz3 || (tz3=Ruleset.Timezone(-3600,"CET")); + if (ux>=-1773012580) // from 1913 Oct 26 + return tz2 || (tz2=TZrules.Morocco(0,"WE%sT")); + return tz1 || (tz1=Ruleset.Timezone(1820,"LMT")); + } +} + +class Africa_El_Aaiun +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=198291600) // from 1976 Apr 14 + return tz3 || (tz3=Ruleset.Timezone(0,"WET")); + if (ux>=-1136070432) // from 1934 Jan + return tz2 || (tz2=Ruleset.Timezone(3600,"WAT")); + return tz1 || (tz1=Ruleset.Timezone(3168,"LMT")); + } +} + +class Africa_Maputo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2109291020) // from 1903 Mar + return tz2 || (tz2=Ruleset.Timezone(-7200,"CAT")); + return tz1 || (tz1=Ruleset.Timezone(-7820,"LMT")); + } +} + +class Africa_Windhoek +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=765324000) // from 1994 Apr 3 + return tz6 || (tz6=TZrules.Namibia(-3600,"WA%sT")); + if (ux>=637970400) // from 1990 Mar 21 + return tz5 || (tz5=Ruleset.Timezone(-7200,"CAT")); + if (ux>=-845254800) // from 1943 Mar 21 2:00 independence + return tz3 || (tz3=Ruleset.Timezone(-7200,"SAST")); + if (ux>=-860976000) // from 1942 Sep 20 2:00 + return tz4 || (tz4=Ruleset.Timezone(-10800,"SAST")); + if (ux>=-2109288600) // from 1903 Mar + return tz3 || (tz3=Ruleset.Timezone(-7200,"SAST")); + if (ux>=-2458170504) // from 1892 Feb 8 SW Africa Time + return tz2 || (tz2=Ruleset.Timezone(-5400,"SWAT")); + return tz1 || (tz1=Ruleset.Timezone(-4104,"LMT")); + } +} + +class Africa_Niamey +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-315619200) // from 1960 + return tz4 || (tz4=Ruleset.Timezone(-3600,"WAT")); + if (ux>=-1131231600) // from 1934 Feb 26 + return tz3 || (tz3=Ruleset.Timezone(0,"GMT")); + if (ux>=-1830384508) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(3600,"WAT")); + return tz1 || (tz1=Ruleset.Timezone(-508,"LMT")); + } +} + +class Africa_Lagos +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1588464816) // from 1919 Sep + return tz2 || (tz2=Ruleset.Timezone(-3600,"WAT")); + return tz1 || (tz1=Ruleset.Timezone(-816,"LMT")); + } +} + +class Indian_Reunion +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1848886912) // from 1911 Jun Reunion Time + return tz2 || (tz2=Ruleset.Timezone(-14400,"RET")); + // Saint-Denis + return tz1 || (tz1=Ruleset.Timezone(-13312,"LMT")); + } +} + +class Africa_Kigali +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1091498416) // from 1935 Jun + return tz2 || (tz2=Ruleset.Timezone(-7200,"CAT")); + return tz1 || (tz1=Ruleset.Timezone(-7216,"LMT")); + } +} + +class Atlantic_St_Helena +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-599614632) // from 1951 + return tz3 || (tz3=Ruleset.Timezone(0,"GMT")); + if (ux>=-2524520232) // from 1890 Jamestown Mean Time + return tz2 || (tz2=Ruleset.Timezone(1368,"JMT")); + // Jamestown + return tz1 || (tz1=Ruleset.Timezone(1368,"LMT")); + } +} + +class Africa_Sao_Tome +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1830381808) // from 1912 + return tz3 || (tz3=Ruleset.Timezone(0,"GMT")); + if (ux>=-2713912016) // from 1884 Lisbon Mean Time + return tz2 || (tz2=Ruleset.Timezone(2192,"LMT")); + return tz1 || (tz1=Ruleset.Timezone(-1616,"LMT")); + } +} + +class Africa_Dakar +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-902098800) // from 1941 Jun + return tz3 || (tz3=Ruleset.Timezone(0,"GMT")); + if (ux>=-1830379816) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(3600,"WAT")); + return tz1 || (tz1=Ruleset.Timezone(4184,"LMT")); + } +} + +class Indian_Mahe +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2006653308) // from 1906 Jun Seychelles Time + return tz2 || (tz2=Ruleset.Timezone(-14400,"SCT")); + // Victoria + return tz1 || (tz1=Ruleset.Timezone(-13308,"LMT")); + } +} + +class Africa_Freetown +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-410230800) // from 1957 + return tz4 || (tz4=TZrules.SL(0,"%s")); + if (ux>=-1785712020) // from 1913 Jun + return tz3 || (tz3=TZrules.SL(3600,"%s")); + if (ux>=-2776979220) // from 1882 Freetown Mean Time + return tz2 || (tz2=Ruleset.Timezone(3180,"FMT")); + return tz1 || (tz1=Ruleset.Timezone(3180,"LMT")); + } +} + +class Africa_Mogadishu +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-410236200) // from 1957 + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + if (ux>=-1230778800) // from 1931 + return tz3 || (tz3=Ruleset.Timezone(-9000,"BEAT")); + if (ux>=-2403572488) // from 1893 Nov + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + return tz1 || (tz1=Ruleset.Timezone(-10888,"LMT")); + } +} + +class Africa_Johannesburg +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2109288600) // from 1903 Mar + return tz3 || (tz3=TZrules.SA(-7200,"SAST")); + if (ux>=-2458173120) // from 1892 Feb 8 + return tz2 || (tz2=Ruleset.Timezone(-5400,"SAST")); + return tz1 || (tz1=Ruleset.Timezone(-6720,"LMT")); + } +} + +class Africa_Khartoum +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=947944800) // from 2000 Jan 15 12:00 + return tz3 || (tz3=Ruleset.Timezone(-10800,"EAT")); + if (ux>=-1230775808) // from 1931 + return tz2 || (tz2=TZrules.Sudan(-7200,"CA%sT")); + return tz1 || (tz1=Ruleset.Timezone(-7808,"LMT")); + } +} + +class Africa_Mbabane +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2109290664) // from 1903 Mar + return tz2 || (tz2=Ruleset.Timezone(-7200,"SAST")); + return tz1 || (tz1=Ruleset.Timezone(-7464,"LMT")); + } +} + +class Africa_Dar_es_Salaam +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-284006700) // from 1961 + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + if (ux>=-694321200) // from 1948 + return tz3 || (tz3=Ruleset.Timezone(-9900,"BEAUT")); + if (ux>=-1230777428) // from 1931 + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + return tz1 || (tz1=Ruleset.Timezone(-9428,"LMT")); + } +} + +class Africa_Lome +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2429827492) // from 1893 + return tz2 || (tz2=Ruleset.Timezone(0,"GMT")); + return tz1 || (tz1=Ruleset.Timezone(-292,"LMT")); + } +} + +class Africa_Tunis +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1855958961) // from 1911 Mar 11 + return tz3 || (tz3=TZrules.Tunisia(-3600,"CE%sT")); + if (ux>=-2797202444) // from 1881 May 12 Paris Mean Time + return tz2 || (tz2=Ruleset.Timezone(-561,"PMT")); + return tz1 || (tz1=Ruleset.Timezone(-2444,"LMT")); + } +} + +class Africa_Kampala +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-410237100) // from 1957 + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + if (ux>=-694319400) // from 1948 + return tz4 || (tz4=Ruleset.Timezone(-9900,"BEAUT")); + if (ux>=-1262314800) // from 1930 + return tz3 || (tz3=Ruleset.Timezone(-9000,"BEAT")); + if (ux>=-1309745380) // from 1928 Jul + return tz2 || (tz2=Ruleset.Timezone(-10800,"EAT")); + return tz1 || (tz1=Ruleset.Timezone(-7780,"LMT")); + } +} + +class Africa_Lusaka +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2109289988) // from 1903 Mar + return tz2 || (tz2=Ruleset.Timezone(-7200,"CAT")); + return tz1 || (tz1=Ruleset.Timezone(-6788,"LMT")); + } +} + +class Africa_Harare +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2109290652) // from 1903 Mar + return tz2 || (tz2=Ruleset.Timezone(-7200,"CAT")); + return tz1 || (tz1=Ruleset.Timezone(-7452,"LMT")); + } +} + +class Antarctica_Casey +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-31536000) // from 1969 Western (Aus) Standard Time + return tz2 || (tz2=Ruleset.Timezone(-28800,"WST")); + return tz1 || (tz1=Ruleset.Timezone(0,"___")); + } +} + +class Antarctica_Davis +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-28857600) // from 1969 Feb + return tz2 || (tz2=Ruleset.Timezone(-25200,"DAVT")); + if (ux>=-163062000) // from 1964 Nov + return tz1 || (tz1=Ruleset.Timezone(0,"___")); + if (ux>=-409190400) // from 1957 Jan 13 Davis Time + return tz2 || (tz2=Ruleset.Timezone(-25200,"DAVT")); + return tz1 || (tz1=Ruleset.Timezone(0,"___")); + } +} + +class Antarctica_Mawson +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-501206400) // from 1954 Feb 13 Mawson Time + return tz2 || (tz2=Ruleset.Timezone(-21600,"MAWT")); + return tz1 || (tz1=Ruleset.Timezone(0,"___")); + } +} + +class Indian_Kerguelen +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-631152000) // from 1950 ISO code TF Time + return tz2 || (tz2=Ruleset.Timezone(-18000,"TFT")); + // Port-aux-Francais + return tz1 || (tz1=Ruleset.Timezone(0,"___")); + } +} + +class Antarctica_DumontDUrville +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-415497600) // from 1956 Nov Dumont-d'Urville Time + return tz3 || (tz3=Ruleset.Timezone(-36000,"DDUT")); + if (ux>=-566992800) // from 1952 Jan 14 + return tz1 || (tz1=Ruleset.Timezone(0,"___")); + if (ux>=-725846400) // from 1947 Port-Martin Time + return tz2 || (tz2=Ruleset.Timezone(-36000,"PMT")); + return tz1 || (tz1=Ruleset.Timezone(0,"___")); + } +} + +class Antarctica_Syowa +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-407808000) // from 1957 Jan 29 Syowa Time + return tz2 || (tz2=Ruleset.Timezone(-10800,"SYOT")); + return tz1 || (tz1=Ruleset.Timezone(0,"___")); + } +} + +class Antarctica_Palmer +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=389048400) // from 1982 May + return tz4 || (tz4=TZrules.ChileAQ(14400,"CL%sT")); + if (ux>=-7617600) // from 1969 Oct 5 + return tz3 || (tz3=TZrules.ArgAQ(10800,"AR%sT")); + if (ux>=-157766400) // from 1965 + return tz2 || (tz2=TZrules.ArgAQ(14400,"AR%sT")); + return tz1 || (tz1=Ruleset.Timezone(0,"___")); + } +} + +class Antarctica_McMurdo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-441849600) // from 1956 + return tz2 || (tz2=TZrules.NZAQ(-43200,"NZ%sT")); + return tz1 || (tz1=Ruleset.Timezone(0,"___")); + } +} +constant Antarctica_South_Pole=Antarctica_McMurdo; + +class Asia_Kabul +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-788932800) // from 1945 + return tz3 || (tz3=Ruleset.Timezone(-16200,"AFT")); + if (ux>=-2524538208) // from 1890 + return tz2 || (tz2=Ruleset.Timezone(-14400,"AFT")); + return tz1 || (tz1=Ruleset.Timezone(-16608,"LMT")); + } +} + +class Asia_Yerevan +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=852062400) // from 1997 + return tz7 || (tz7=TZrules.RussiaAsia(-14400,"AM%sT")); + if (ux>=811897200) // from 1995 Sep 24 2:00s + return tz6 || (tz6=Ruleset.Timezone(-14400,"AMT")); + if (ux>=685569600) // from 1991 Sep 23 + return tz5 || (tz5=TZrules.RussiaAsia(-10800,"AM%sT")); + if (ux>=670370400) // from 1991 Mar 31 2:00s independence + return tz4 || (tz4=Ruleset.Timezone(-14400,"YERST")); + if (ux>=-405140400) // from 1957 Mar + return tz3 || (tz3=TZrules.RussiaAsia(-14400,"YER%sT")); + if (ux>=-1441162680) // from 1924 May 2 Yerevan Time + return tz2 || (tz2=Ruleset.Timezone(-10800,"YERT")); + return tz1 || (tz1=Ruleset.Timezone(-10680,"LMT")); + } +} + +class Asia_Baku +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=852091200) // from 1997 + return tz8 || (tz8=TZrules.Azer(-14400,"AZ%sT")); + if (ux>=820440000) // from 1996 + return tz7 || (tz7=TZrules.EUAsia(-14400,"AZ%sT")); + if (ux>=715320000) // from 1992 Sep lastSun 2:00s Azerbaijan time + return tz6 || (tz6=Ruleset.Timezone(-14400,"AZT")); + if (ux>=683496000) // from 1991 Aug 30 + return tz5 || (tz5=TZrules.RussiaAsia(-10800,"AZ%sT")); + if (ux>=670370400) // from 1991 Mar 31 2:00s independence + return tz4 || (tz4=Ruleset.Timezone(-14400,"BAKST")); + if (ux>=-405140400) // from 1957 Mar + return tz3 || (tz3=TZrules.RussiaAsia(-14400,"BAK%sT")); + if (ux>=-1441163964) // from 1924 May 2 Baku Time + return tz2 || (tz2=Ruleset.Timezone(-10800,"BAKT")); + return tz1 || (tz1=Ruleset.Timezone(-11964,"LMT")); + } +} + +class Asia_Bahrain +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=76190400) // from 1972 Jun + return tz3 || (tz3=Ruleset.Timezone(-10800,"AST")); + if (ux>=-1577935340) // from 1920 + return tz2 || (tz2=Ruleset.Timezone(-14400,"GST")); + // Al-Manamah + return tz1 || (tz1=Ruleset.Timezone(-12140,"LMT")); + } +} + +class Asia_Dacca +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=38772000) // from 1971 Mar 26 Bangladesh Time + return tz6 || (tz6=Ruleset.Timezone(-21600,"BDT")); + if (ux>=-576138600) // from 1951 Sep 30 Dacca Time + return tz5 || (tz5=Ruleset.Timezone(-21600,"DACT")); + if (ux>=-862637400) // from 1942 Sep + return tz3 || (tz3=Ruleset.Timezone(-23400,"BURT")); + if (ux>=-872058600) // from 1942 May 15 + return tz4 || (tz4=Ruleset.Timezone(-19800,"IST")); + if (ux>=-891582800) // from 1941 Oct Burma Time + return tz3 || (tz3=Ruleset.Timezone(-23400,"BURT")); + if (ux>=-2524543300) // from 1890 Howrah Mean Time? + return tz2 || (tz2=Ruleset.Timezone(-21200,"HMT")); + return tz1 || (tz1=Ruleset.Timezone(-21700,"LMT")); + } +} + +class Asia_Thimbu +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=560025000) // from 1987 Oct Bhutan Time + return tz3 || (tz3=Ruleset.Timezone(-21600,"BTT")); + if (ux>=-706341516) // from 1947 Aug 15 + return tz2 || (tz2=Ruleset.Timezone(-19800,"IST")); + return tz1 || (tz1=Ruleset.Timezone(-21516,"LMT")); + } +} + +class Asia_Brunei +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1167636600) // from 1933 + return tz3 || (tz3=Ruleset.Timezone(-28800,"BNT")); + if (ux>=-1383464380) // from 1926 Mar + return tz2 || (tz2=Ruleset.Timezone(-27000,"BNT")); + // Bandar Seri Begawan + return tz1 || (tz1=Ruleset.Timezone(-27580,"LMT")); + } +} + +class Asia_Rangoon +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-778410000) // from 1945 May 3 Myanmar Time + return tz5 || (tz5=Ruleset.Timezone(-23400,"MMT")); + if (ux>=-873268200) // from 1942 May + return tz4 || (tz4=Ruleset.Timezone(-32400,"JST")); + if (ux>=-1577946276) // from 1920 Burma Time + return tz3 || (tz3=Ruleset.Timezone(-23400,"BURT")); + if (ux>=-2840163880) // from 1880 Rangoon Mean Time? + return tz2 || (tz2=Ruleset.Timezone(-23076,"RMT")); + // or Yangon + return tz1 || (tz1=Ruleset.Timezone(-23080,"LMT")); + } +} + +class Asia_Phnom_Penh +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1220428800) // from 1931 May + return tz3 || (tz3=Ruleset.Timezone(-25200,"ICT")); + if (ux>=-1819954800) // from 1912 May + return tz4 || (tz4=Ruleset.Timezone(-28800,"ICT")); + if (ux>=-1855983920) // from 1911 Mar 11 0:01 + return tz3 || (tz3=Ruleset.Timezone(-25200,"ICT")); + if (ux>=-2005973980) // from 1906 Jun 9 Saigon MT? + return tz2 || (tz2=Ruleset.Timezone(-25580,"SMT")); + return tz1 || (tz1=Ruleset.Timezone(-25180,"LMT")); + } +} + +class Asia_Harbin +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=325956600) // from 1980 May + return tz5 || (tz5=TZrules.PRC(-28800,"C%sT")); + if (ux>=-115894800) // from 1966 May + return tz2 || (tz2=Ruleset.Timezone(-30600,"HART")); + if (ux>=-946800000) // from 1940 + return tz4 || (tz4=Ruleset.Timezone(-32400,"HART")); + if (ux>=-1194078600) // from 1932 Mar + return tz3 || (tz3=Ruleset.Timezone(-28800,"CST")); + if (ux>=-1325492804) // from 1928 Harbin Time + return tz2 || (tz2=Ruleset.Timezone(-30600,"HART")); + return tz1 || (tz1=Ruleset.Timezone(-30404,"LMT")); + } +} + +class Asia_Shanghai +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-662659200) // from 1949 + return tz3 || (tz3=TZrules.PRC(-28800,"C%sT")); + if (ux>=-1325491552) // from 1928 + return tz2 || (tz2=TZrules.Shang(-28800,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(-29152,"LMT")); + } +} +constant PRC=Asia_Shanghai; + +class Asia_Chungking +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=325962000) // from 1980 May + return tz3 || (tz3=TZrules.PRC(-28800,"C%sT")); + if (ux>=-1325487980) // from 1928 Chungking Time + return tz2 || (tz2=Ruleset.Timezone(-25200,"CHUT")); + return tz1 || (tz1=Ruleset.Timezone(-25580,"LMT")); + } +} + +class Asia_Urumqi +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=325965600) // from 1980 May + return tz3 || (tz3=TZrules.PRC(-28800,"C%sT")); + if (ux>=-1325483420) // from 1928 Urumqi Time + return tz2 || (tz2=Ruleset.Timezone(-21600,"URUT")); + return tz1 || (tz1=Ruleset.Timezone(-21020,"LMT")); + } +} + +class Asia_Kashgar +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=325969200) // from 1980 May + return tz4 || (tz4=TZrules.PRC(-28800,"C%sT")); + if (ux>=-946791000) // from 1940 + return tz3 || (tz3=Ruleset.Timezone(-18000,"KAST")); + if (ux>=-1325480636) // from 1928 Kashgar Time + return tz2 || (tz2=Ruleset.Timezone(-19800,"KAST")); + return tz1 || (tz1=Ruleset.Timezone(-18236,"LMT")); + } +} + +class Asia_Hong_Kong +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2056692996) // from 1904 Oct 30 + return tz2 || (tz2=TZrules.HK(-28800,"HK%sT")); + return tz1 || (tz1=Ruleset.Timezone(-27396,"LMT")); + } +} +constant Hongkong=Asia_Hong_Kong; + +class Asia_Taipei +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2335248360) // from 1896 + return tz2 || (tz2=TZrules.Taiwan(-28800,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(-29160,"LMT")); + } +} +constant ROC=Asia_Taipei; + +class Asia_Macao +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=945676800) // from 1999 Dec 20 + return tz3 || (tz3=TZrules.PRC(-28800,"C%sT")); + if (ux>=-1830411260) // from 1912 return to China + return tz2 || (tz2=TZrules.Macao(-28800,"MO%sT")); + return tz1 || (tz1=Ruleset.Timezone(-27260,"LMT")); + } +} + +class Asia_Nicosia +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=904618800) // from 1998 Sep + return tz3 || (tz3=TZrules.EUAsia(-7200,"EE%sT")); + if (ux>=-1518920008) // from 1921 Nov 14 + return tz2 || (tz2=TZrules.Cyprus(-7200,"EE%sT")); + return tz1 || (tz1=Ruleset.Timezone(-8008,"LMT")); + } +} + +class Asia_Tbilisi +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8,tz9; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=857156400) // from 1997 Mar lastSun + return tz8 || (tz8=TZrules.E_EurAsia(-14400,"GE%sT")); + if (ux>=844146000) // from 1996 Oct lastSun + return tz9 || (tz9=Ruleset.Timezone(-18000,"GEST")); + if (ux>=778392000) // from 1994 Sep lastSun + return tz8 || (tz8=TZrules.E_EurAsia(-14400,"GE%sT")); + if (ux>=694234800) // from 1992 + return tz7 || (tz7=TZrules.E_EurAsia(-10800,"GE%sT")); + if (ux>=671140800) // from 1991 Apr 9 Georgia Time + return tz6 || (tz6=TZrules.RussiaAsia(-10800,"GE%sT")); + if (ux>=670370400) // from 1991 Mar 31 2:00s independence + return tz5 || (tz5=Ruleset.Timezone(-14400,"TBIST")); + if (ux>=-405140400) // from 1957 Mar + return tz4 || (tz4=TZrules.RussiaAsia(-14400,"TBI%sT")); + if (ux>=-1441162756) // from 1924 May 2 Tbilisi Time + return tz3 || (tz3=Ruleset.Timezone(-10800,"TBIT")); + if (ux>=-2840151556) // from 1880 Tbilisi Mean Time + return tz2 || (tz2=Ruleset.Timezone(-10756,"TBMT")); + return tz1 || (tz1=Ruleset.Timezone(-10756,"LMT")); + } +} + +class Asia_Dili +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=199897200) // from 1976 May 3 East Timor Time + return tz2 || (tz2=Ruleset.Timezone(-28800,"TPT")); + if (ux>=-770634000) // from 1945 Aug + return tz4 || (tz4=Ruleset.Timezone(-32400,"TPT")); + if (ux>=-879152400) // from 1942 Feb 21 23:00 + return tz3 || (tz3=Ruleset.Timezone(-32400,"JST")); + if (ux>=-1830414140) // from 1912 + return tz2 || (tz2=Ruleset.Timezone(-28800,"TPT")); + return tz1 || (tz1=Ruleset.Timezone(-30140,"LMT")); + } +} + +class Asia_Calcutta +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-764145000) // from 1945 Oct 15 + return tz4 || (tz4=Ruleset.Timezone(-19800,"IST")); + if (ux>=-862637400) // from 1942 Sep + return tz5 || (tz5=Ruleset.Timezone(-23400,"IST")); + if (ux>=-872058600) // from 1942 May 15 + return tz4 || (tz4=Ruleset.Timezone(-19800,"IST")); + if (ux>=-891582800) // from 1941 Oct Burma Time + return tz3 || (tz3=Ruleset.Timezone(-23400,"BURT")); + if (ux>=-2840162008) // from 1880 Howrah Mean Time? + return tz2 || (tz2=Ruleset.Timezone(-21200,"HMT")); + return tz1 || (tz1=Ruleset.Timezone(-21208,"LMT")); + } +} + +class Asia_Jakarta +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-189415800) // from 1964 + return tz7 || (tz7=Ruleset.Timezone(-25200,"JAVT")); + if (ux>=-620812800) // from 1950 May + return tz4 || (tz4=Ruleset.Timezone(-27000,"JAVT")); + if (ux>=-683883000) // from 1948 May + return tz6 || (tz6=Ruleset.Timezone(-28800,"JAVT")); + if (ux>=-770634000) // from 1945 Aug + return tz4 || (tz4=Ruleset.Timezone(-27000,"JAVT")); + if (ux>=-876641400) // from 1942 Mar 23 + return tz5 || (tz5=Ruleset.Timezone(-32400,"JST")); + if (ux>=-1172906400) // from 1932 Nov + return tz4 || (tz4=Ruleset.Timezone(-27000,"JAVT")); + if (ux>=-1451719200) // from 1923 Dec 31 23:47:12 Java Time + return tz3 || (tz3=Ruleset.Timezone(-26400,"JAVT")); + if (ux>=-3231299232) // from 1867 Aug 10 Jakarta + return tz2 || (tz2=Ruleset.Timezone(-25632,"JMT")); + return tz1 || (tz1=Ruleset.Timezone(-25632,"LMT")); + } +} + +class Asia_Ujung_Pandang +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-770634000) // from 1945 Aug + return tz3 || (tz3=Ruleset.Timezone(-28800,"BORT")); + if (ux>=-880272000) // from 1942 Feb 9 + return tz4 || (tz4=Ruleset.Timezone(-32400,"JST")); + if (ux>=-1172908656) // from 1932 Nov Borneo Time + return tz3 || (tz3=Ruleset.Timezone(-28800,"BORT")); + if (ux>=-1577951856) // from 1920 Macassar MT + return tz2 || (tz2=Ruleset.Timezone(-28656,"MMT")); + return tz1 || (tz1=Ruleset.Timezone(-28656,"LMT")); + } +} + +class Asia_Jayapura +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-189423000) // from 1964 + return tz2 || (tz2=Ruleset.Timezone(-32400,"JAYT")); + if (ux>=-820573200) // from 1944 + return tz3 || (tz3=Ruleset.Timezone(-34200,"CST")); + if (ux>=-1172913768) // from 1932 Nov Jayapura Time + return tz2 || (tz2=Ruleset.Timezone(-32400,"JAYT")); + return tz1 || (tz1=Ruleset.Timezone(-33768,"LMT")); + } +} + +class Asia_Tehran +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=284011200) // from 1979 + return tz5 || (tz5=TZrules.Iran(-12600,"IR%sT")); + if (ux>=247177800) // from 1977 Nov + return tz4 || (tz4=TZrules.Iran(-14400,"IR%sT")); + if (ux>=-757394744) // from 1946 + return tz3 || (tz3=Ruleset.Timezone(-12600,"IRT")); + if (ux>=-1704165944) // from 1916 Tehran Mean Time + return tz2 || (tz2=Ruleset.Timezone(-12344,"TMT")); + return tz1 || (tz1=Ruleset.Timezone(-12344,"LMT")); + } +} +constant Iran=Asia_Tehran; + +class Asia_Baghdad +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=389048400) // from 1982 May + return tz4 || (tz4=TZrules.Iraq(-10800,"A%sT")); + if (ux>=-1641005856) // from 1918 + return tz3 || (tz3=Ruleset.Timezone(-10800,"AST")); + if (ux>=-2524532260) // from 1890 Baghdad Mean Time? + return tz2 || (tz2=Ruleset.Timezone(-10656,"BMT")); + return tz1 || (tz1=Ruleset.Timezone(-10660,"LMT")); + } +} + +class Asia_Jerusalem +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1641003640) // from 1918 + return tz3 || (tz3=TZrules.Zion(-7200,"I%sT")); + if (ux>=-2840149256) // from 1880 Jerusalem Mean Time? + return tz2 || (tz2=Ruleset.Timezone(-8440,"JMT")); + return tz1 || (tz1=Ruleset.Timezone(-8456,"LMT")); + } +} +constant Asia_Tel_Aviv=Asia_Jerusalem; +constant Israel=Asia_Jerusalem; + +class Asia_Tokyo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1009875600) // from 1938 + return tz2 || (tz2=Ruleset.Timezone(-32400,"JST")); + if (ux>=-2335251600) // from 1896 + return tz3 || (tz3=Ruleset.Timezone(-32400,"CJT")); + if (ux>=-2587712400) // from 1887 Dec 31 15:00u + return tz2 || (tz2=Ruleset.Timezone(-32400,"JST")); + return tz1 || (tz1=Ruleset.Timezone(-33539,"LMT")); + } +} +constant Japan=Asia_Tokyo; + +class Asia_Amman +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1230776624) // from 1931 + return tz2 || (tz2=TZrules.Jordan(-7200,"EE%sT")); + return tz1 || (tz1=Ruleset.Timezone(-8624,"LMT")); + } +} + +class Asia_Almaty +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695768400) // from 1992 Jan 19 2:00s + return tz5 || (tz5=TZrules.E_EurAsia(-21600,"ALM%sT")); + if (ux>=686091600) // from 1991 Sep 29 2:00s + return tz2 || (tz2=Ruleset.Timezone(-18000,"ALMT")); + if (ux>=670363200) // from 1991 Mar 31 2:00s + return tz4 || (tz4=Ruleset.Timezone(-21600,"ALMST")); + if (ux>=-405147600) // from 1957 Mar + return tz3 || (tz3=TZrules.RussiaAsia(-21600,"ALM%sT")); + if (ux>=-1441170468) // from 1924 May 2 Alma-Ata Time + return tz2 || (tz2=Ruleset.Timezone(-18000,"ALMT")); + // or Alma-Ata + return tz1 || (tz1=Ruleset.Timezone(-18468,"LMT")); + } +} + +class Asia_Aqtobe +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695772000) // from 1992 Jan 19 2:00s + return tz6 || (tz6=TZrules.E_EurAsia(-18000,"AQT%sT")); + if (ux>=686095200) // from 1991 Sep 29 2:00s Aqtobe Time + return tz5 || (tz5=Ruleset.Timezone(-14400,"AQTT")); + if (ux>=670366800) // from 1991 Mar 31 2:00s + return tz4 || (tz4=Ruleset.Timezone(-18000,"AKTST")); + if (ux>=-405144000) // from 1957 Mar + return tz3 || (tz3=TZrules.RussiaAsia(-18000,"AK%sT")); + if (ux>=-1441165720) // from 1924 May 2 Aktyubinsk Time + return tz2 || (tz2=Ruleset.Timezone(-14400,"AKT")); + return tz1 || (tz1=Ruleset.Timezone(-13720,"LMT")); + } +} + +class Asia_Aqtau +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=809935200) // from 1995 Sep lastSun + return tz7 || (tz7=TZrules.E_EurAsia(-14400,"AQT%sT")); + if (ux>=695772000) // from 1992 Jan 19 2:00s + return tz6 || (tz6=TZrules.E_EurAsia(-18000,"AQT%sT")); + if (ux>=686095200) // from 1991 Sep 29 2:00s Aqtau Time + return tz5 || (tz5=Ruleset.Timezone(-14400,"AQTT")); + if (ux>=670366800) // from 1991 Mar 31 2:00s + return tz4 || (tz4=Ruleset.Timezone(-18000,"AQTST")); + if (ux>=-405144000) // from 1957 Mar + return tz3 || (tz3=TZrules.RussiaAsia(-18000,"SHE%sT")); + if (ux>=-1441164064) // from 1924 May 2 Fort Shevchenko Time + return tz2 || (tz2=Ruleset.Timezone(-14400,"SHET")); + // or Aktau + return tz1 || (tz1=Ruleset.Timezone(-12064,"LMT")); + } +} + +class Asia_Bishkek +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=683582400) // from 1991 Aug 31 2:00 Kirgizstan Time + return tz5 || (tz5=TZrules.Kirgiz(-18000,"KG%sT")); + if (ux>=670363200) // from 1991 Mar 31 2:00s independence + return tz4 || (tz4=Ruleset.Timezone(-21600,"FRUST")); + if (ux>=-1247547600) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.RussiaAsia(-21600,"FRU%sT")); + if (ux>=-1441169904) // from 1924 May 2 Frunze Time + return tz2 || (tz2=Ruleset.Timezone(-18000,"FRUT")); + return tz1 || (tz1=Ruleset.Timezone(-17904,"LMT")); + } +} + +class Asia_Seoul +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-39515400) // from 1968 Oct + return tz5 || (tz5=TZrules.ROK(-32400,"K%sT")); + if (ux>=-264873600) // from 1961 Aug 10 + return tz2 || (tz2=Ruleset.Timezone(-30600,"KST")); + if (ux>=-498128400) // from 1954 Mar 21 + return tz4 || (tz4=TZrules.ROK(-28800,"K%sT")); + if (ux>=-1199262600) // from 1932 + return tz3 || (tz3=Ruleset.Timezone(-32400,"KST")); + if (ux>=-1325494800) // from 1928 + return tz2 || (tz2=Ruleset.Timezone(-30600,"KST")); + if (ux>=-2053931400) // from 1904 Dec + return tz3 || (tz3=Ruleset.Timezone(-32400,"KST")); + if (ux>=-2524552072) // from 1890 + return tz2 || (tz2=Ruleset.Timezone(-30600,"KST")); + return tz1 || (tz1=Ruleset.Timezone(-30472,"LMT")); + } +} +constant ROK=Asia_Seoul; + +class Asia_Pyongyang +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-264931200) // from 1961 Aug 10 + return tz3 || (tz3=Ruleset.Timezone(-32400,"KST")); + if (ux>=-498128400) // from 1954 Mar 21 + return tz4 || (tz4=Ruleset.Timezone(-28800,"KST")); + if (ux>=-1199262600) // from 1932 + return tz3 || (tz3=Ruleset.Timezone(-32400,"KST")); + if (ux>=-1325494800) // from 1928 + return tz2 || (tz2=Ruleset.Timezone(-30600,"KST")); + if (ux>=-2053931400) // from 1904 Dec + return tz3 || (tz3=Ruleset.Timezone(-32400,"KST")); + if (ux>=-2524551780) // from 1890 + return tz2 || (tz2=Ruleset.Timezone(-30600,"KST")); + return tz1 || (tz1=Ruleset.Timezone(-30180,"LMT")); + } +} + +class Asia_Kuwait +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-631163516) // from 1950 + return tz2 || (tz2=Ruleset.Timezone(-10800,"AST")); + return tz1 || (tz1=Ruleset.Timezone(-11516,"LMT")); + } +} + +class Asia_Vientiane +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1220428800) // from 1931 May + return tz3 || (tz3=Ruleset.Timezone(-25200,"ICT")); + if (ux>=-1819954800) // from 1912 May + return tz4 || (tz4=Ruleset.Timezone(-28800,"ICT")); + if (ux>=-1855983920) // from 1911 Mar 11 0:01 + return tz3 || (tz3=Ruleset.Timezone(-25200,"ICT")); + if (ux>=-2005973424) // from 1906 Jun 9 Saigon MT? + return tz2 || (tz2=Ruleset.Timezone(-25580,"SMT")); + return tz1 || (tz1=Ruleset.Timezone(-24624,"LMT")); + } +} + +class Asia_Beirut +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2840149320) // from 1880 + return tz2 || (tz2=TZrules.Lebanon(-7200,"EE%sT")); + return tz1 || (tz1=Ruleset.Timezone(-8520,"LMT")); + } +} + +class Asia_Kuala_Lumpur +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=389032200) // from 1982 May Malaysia Time + return tz7 || (tz7=Ruleset.Timezone(-28800,"MYT")); + if (ux>=-631178400) // from 1950 + return tz6 || (tz6=Ruleset.Timezone(-27000,"MALT")); + if (ux>=-767869200) // from 1945 Sep 2 + return tz4 || (tz4=Ruleset.Timezone(-26400,"MALT")); + if (ux>=-879751200) // from 1942 Feb 15 + return tz5 || (tz5=Ruleset.Timezone(-32400,"JST")); + if (ux>=-1167634800) // from 1933 + return tz4 || (tz4=Ruleset.Timezone(-26400,"MALT")); + if (ux>=-2038200924) // from 1905 Jun Malaya Time + return tz3 || (tz3=Ruleset.Timezone(-25200,"MALT")); + if (ux>=-2840165208) // from 1880 Singapore Mean Time + return tz2 || (tz2=Ruleset.Timezone(-24924,"SMT")); + return tz1 || (tz1=Ruleset.Timezone(-24408,"LMT")); + } +} + +class Asia_Kuching +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=389030400) // from 1982 May + return tz6 || (tz6=Ruleset.Timezone(-28800,"MYT")); + if (ux>=-767869200) // from 1945 Sep 2 + return tz5 || (tz5=Ruleset.Timezone(-28800,"BORT")); + if (ux>=-883584000) // from 1942 + return tz4 || (tz4=Ruleset.Timezone(-32400,"JST")); + if (ux>=-1167636600) // from 1933 + return tz3 || (tz3=TZrules.NBorneo(-28800,"BOR%sT")); + if (ux>=-1383463280) // from 1926 Mar Borneo Time + return tz2 || (tz2=Ruleset.Timezone(-27000,"BORT")); + return tz1 || (tz1=Ruleset.Timezone(-26480,"LMT")); + } +} + +class Indian_Maldives +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-315636840) // from 1960 Maldives Time + return tz3 || (tz3=Ruleset.Timezone(-18000,"MVT")); + if (ux>=-2840158440) // from 1880 Male Mean Time + return tz2 || (tz2=Ruleset.Timezone(-17640,"MMT")); + // Male + return tz1 || (tz1=Ruleset.Timezone(-17640,"LMT")); + } +} + +class Asia_Hovd +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=252439200) // from 1978 + return tz3 || (tz3=TZrules.Mongol(-25200,"HOV%sT")); + if (ux>=-2032927596) // from 1905 Aug Hovd Time + return tz2 || (tz2=Ruleset.Timezone(-21600,"HOVT")); + return tz1 || (tz1=Ruleset.Timezone(-21996,"LMT")); + } +} + +class Asia_Ulaanbaatar +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=252435600) // from 1978 + return tz3 || (tz3=TZrules.Mongol(-28800,"ULA%sT")); + if (ux>=-2032931252) // from 1905 Aug Ulaanbaatar Time + return tz2 || (tz2=Ruleset.Timezone(-25200,"ULAT")); + return tz1 || (tz1=Ruleset.Timezone(-25652,"LMT")); + } +} +constant Asia_Ulan_Bator=Asia_Ulaanbaatar; + +class Asia_Katmandu +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=504901800) // from 1986 Nepal Time + return tz3 || (tz3=Ruleset.Timezone(-20700,"NPT")); + if (ux>=-1577943676) // from 1920 + return tz2 || (tz2=Ruleset.Timezone(-19800,"IST")); + return tz1 || (tz1=Ruleset.Timezone(-20476,"LMT")); + } +} + +class Asia_Muscat +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1577937260) // from 1920 + return tz2 || (tz2=Ruleset.Timezone(-14400,"GST")); + return tz1 || (tz1=Ruleset.Timezone(-14060,"LMT")); + } +} + +class Asia_Karachi +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=38775600) // from 1971 Mar 26 Pakistan Time + return tz5 || (tz5=Ruleset.Timezone(-18000,"PKT")); + if (ux>=-576135000) // from 1951 Sep 30 Karachi Time + return tz4 || (tz4=Ruleset.Timezone(-18000,"KART")); + if (ux>=-764145000) // from 1945 Oct 15 + return tz2 || (tz2=Ruleset.Timezone(-19800,"IST")); + if (ux>=-862637400) // from 1942 Sep + return tz3 || (tz3=Ruleset.Timezone(-23400,"IST")); + if (ux>=-1988166492) // from 1907 + return tz2 || (tz2=Ruleset.Timezone(-19800,"IST")); + return tz1 || (tz1=Ruleset.Timezone(-16092,"LMT")); + } +} + +class Asia_Gaza +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=915156000) // from 1999 + return tz6 || (tz6=TZrules.Palestine(-7200,"EE%sT")); + if (ux>=820461600) // from 1996 + return tz5 || (tz5=TZrules.Jordan(-7200,"EE%sT")); + if (ux>=-81291600) // from 1967 Jun 5 + return tz4 || (tz4=TZrules.Zion(-7200,"I%sT")); + if (ux>=-682639200) // from 1948 May 15 + return tz3 || (tz3=TZrules.EgyptAsia(-7200,"EE%sT")); + if (ux>=-2185409872) // from 1900 Oct + return tz2 || (tz2=TZrules.Zion(-7200,"EET")); + return tz1 || (tz1=Ruleset.Timezone(-8272,"LMT")); + } +} + +class Asia_Manila +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-794221200) // from 1944 Nov + return tz3 || (tz3=TZrules.Phil(-28800,"PH%sT")); + if (ux>=-873216000) // from 1942 May + return tz4 || (tz4=Ruleset.Timezone(-32400,"JST")); + if (ux>=-2229321840) // from 1899 May 11 + return tz3 || (tz3=TZrules.Phil(-28800,"PH%sT")); + if (ux>=-3976157040) // from 1844 + return tz2 || (tz2=Ruleset.Timezone(-29040,"LMT")); + return tz1 || (tz1=Ruleset.Timezone(57360,"LMT")); + } +} + +class Asia_Qatar +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=76190400) // from 1972 Jun + return tz3 || (tz3=Ruleset.Timezone(-10800,"AST")); + if (ux>=-1577935568) // from 1920 + return tz2 || (tz2=Ruleset.Timezone(-14400,"GST")); + // Al Dawhah + return tz1 || (tz1=Ruleset.Timezone(-12368,"LMT")); + } +} + +class Asia_Riyadh +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-631163212) // from 1950 + return tz2 || (tz2=Ruleset.Timezone(-10800,"AST")); + return tz1 || (tz1=Ruleset.Timezone(-11212,"LMT")); + } +} + +class Asia_Singapore +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=389032200) // from 1982 May + return tz8 || (tz8=Ruleset.Timezone(-28800,"SGT")); + if (ux>=-138785400) // from 1965 Aug 9 Singapore Time + return tz7 || (tz7=Ruleset.Timezone(-27000,"SGT")); + if (ux>=-631178400) // from 1950 independence + return tz6 || (tz6=Ruleset.Timezone(-27000,"MALT")); + if (ux>=-767869200) // from 1945 Sep 2 + return tz4 || (tz4=Ruleset.Timezone(-26400,"MALT")); + if (ux>=-879751200) // from 1942 Feb 15 + return tz5 || (tz5=Ruleset.Timezone(-32400,"JST")); + if (ux>=-1167634800) // from 1933 + return tz4 || (tz4=Ruleset.Timezone(-26400,"MALT")); + if (ux>=-2038200924) // from 1905 Jun Malaya Time + return tz3 || (tz3=Ruleset.Timezone(-25200,"MALT")); + if (ux>=-2840165724) // from 1880 Singapore Mean Time + return tz2 || (tz2=Ruleset.Timezone(-24924,"SMT")); + return tz1 || (tz1=Ruleset.Timezone(-24924,"LMT")); + } +} +constant Singapore=Asia_Singapore; + +class Asia_Colombo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=846266400) // from 1996 Oct 26 0:30 + return tz7 || (tz7=Ruleset.Timezone(-21600,"LKT")); + if (ux>=832962600) // from 1996 May 25 0:00 + return tz6 || (tz6=Ruleset.Timezone(-23400,"LKT")); + if (ux>=-764051400) // from 1945 Oct 16 2:00 + return tz3 || (tz3=Ruleset.Timezone(-19800,"IST")); + if (ux>=-862639200) // from 1942 Sep + return tz5 || (tz5=Ruleset.Timezone(-23400,"IST")); + if (ux>=-883287000) // from 1942 Jan 5 + return tz4 || (tz4=Ruleset.Timezone(-21600,"IHST")); + if (ux>=-2019705572) // from 1906 + return tz3 || (tz3=Ruleset.Timezone(-19800,"IST")); + if (ux>=-2840159964) // from 1880 Moratuwa Mean Time + return tz2 || (tz2=Ruleset.Timezone(-19172,"MMT")); + return tz1 || (tz1=Ruleset.Timezone(-19164,"LMT")); + } +} + +class Asia_Damascus +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1577931912) // from 1920 + return tz2 || (tz2=TZrules.Syria(-7200,"EE%sT")); + return tz1 || (tz1=Ruleset.Timezone(-8712,"LMT")); + } +} + +class Asia_Dushanbe +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=684363600) // from 1991 Sep 9 2:00s Tajikistan Time + return tz5 || (tz5=Ruleset.Timezone(-18000,"TJT")); + if (ux>=670363200) // from 1991 Mar 31 2:00s + return tz4 || (tz4=Ruleset.Timezone(-21600,"DUSST")); + if (ux>=-1247547600) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.RussiaAsia(-21600,"DUS%sT")); + if (ux>=-1441168512) // from 1924 May 2 Dushanbe Time + return tz2 || (tz2=Ruleset.Timezone(-18000,"DUST")); + return tz1 || (tz1=Ruleset.Timezone(-16512,"LMT")); + } +} + +class Asia_Bangkok +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1570084924) // from 1920 Apr + return tz3 || (tz3=Ruleset.Timezone(-25200,"ICT")); + if (ux>=-2840164924) // from 1880 Bangkok Mean Time + return tz2 || (tz2=Ruleset.Timezone(-24124,"BMT")); + return tz1 || (tz1=Ruleset.Timezone(-24124,"LMT")); + } +} + +class Asia_Ashkhabad +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695800800) // from 1992 Jan 19 2:00 + return tz6 || (tz6=Ruleset.Timezone(-18000,"TMT")); + if (ux>=688536000) // from 1991 Oct 27 + return tz5 || (tz5=TZrules.RussiaAsia(-14400,"TM%sT")); + if (ux>=670402800) // from 1991 Mar 31 2:00 independence + return tz4 || (tz4=TZrules.RussiaAsia(-14400,"ASH%sT")); + if (ux>=-1247544000) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.RussiaAsia(-18000,"ASH%sT")); + if (ux>=-1441166012) // from 1924 May 2 Ashkhabad Time + return tz2 || (tz2=Ruleset.Timezone(-14400,"ASHT")); + // or Ashgabat + return tz1 || (tz1=Ruleset.Timezone(-14012,"LMT")); + } +} + +class Asia_Dubai +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1577936472) // from 1920 + return tz2 || (tz2=Ruleset.Timezone(-14400,"GST")); + return tz1 || (tz1=Ruleset.Timezone(-13272,"LMT")); + } +} + +class Asia_Samarkand +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=725864400) // from 1993 + return tz8 || (tz8=Ruleset.Timezone(-18000,"UZT")); + if (ux>=694242000) // from 1992 + return tz7 || (tz7=TZrules.RussiaAsia(-18000,"UZ%sT")); + if (ux>=683704800) // from 1991 Sep 1 + return tz7 || (tz7=TZrules.RussiaAsia(-18000,"UZ%sT")); + if (ux>=670406400) // from 1991 Mar 31 2:00 independence + return tz6 || (tz6=TZrules.RussiaAsia(-18000,"TAS%sT")); + if (ux>=370720800) // from 1981 Oct 1 Tashkent Time + return tz5 || (tz5=TZrules.RussiaAsia(-21600,"TAS%sT")); + if (ux>=354913200) // from 1981 Apr 1 + return tz4 || (tz4=Ruleset.Timezone(-21600,"SAMST")); + if (ux>=-1247544000) // from 1930 Jun 21 + return tz3 || (tz3=Ruleset.Timezone(-18000,"SAMT")); + if (ux>=-1441168032) // from 1924 May 2 Samarkand Time + return tz2 || (tz2=Ruleset.Timezone(-14400,"SAMT")); + return tz1 || (tz1=Ruleset.Timezone(-16032,"LMT")); + } +} + +class Asia_Tashkent +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=725864400) // from 1993 + return tz6 || (tz6=Ruleset.Timezone(-18000,"UZT")); + if (ux>=694242000) // from 1992 + return tz5 || (tz5=TZrules.RussiaAsia(-18000,"UZ%sT")); + if (ux>=683704800) // from 1991 Sep 1 + return tz5 || (tz5=TZrules.RussiaAsia(-18000,"UZ%sT")); + if (ux>=670363200) // from 1991 Mar 31 2:00s independence + return tz4 || (tz4=TZrules.RussiaAsia(-18000,"TAS%sT")); + if (ux>=-1247547600) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.RussiaAsia(-21600,"TAS%sT")); + if (ux>=-1441168632) // from 1924 May 2 Tashkent Time + return tz2 || (tz2=Ruleset.Timezone(-18000,"TAST")); + return tz1 || (tz1=Ruleset.Timezone(-16632,"LMT")); + } +} + +class Asia_Saigon +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1220428800) // from 1931 May + return tz3 || (tz3=Ruleset.Timezone(-25200,"ICT")); + if (ux>=-1819954800) // from 1912 May + return tz4 || (tz4=Ruleset.Timezone(-28800,"ICT")); + if (ux>=-1855983920) // from 1911 Mar 11 0:01 + return tz3 || (tz3=Ruleset.Timezone(-25200,"ICT")); + if (ux>=-2005974400) // from 1906 Jun 9 Saigon MT? + return tz2 || (tz2=Ruleset.Timezone(-25580,"SMT")); + return tz1 || (tz1=Ruleset.Timezone(-25600,"LMT")); + } +} + +class Asia_Aden +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-631162848) // from 1950 + return tz2 || (tz2=Ruleset.Timezone(-10800,"AST")); + return tz1 || (tz1=Ruleset.Timezone(-10848,"LMT")); + } +} + +class Australia_Darwin +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2230189200) // from 1899 May + return tz3 || (tz3=TZrules.Aus(-34200,"CST")); + if (ux>=-2364108200) // from 1895 Feb + return tz2 || (tz2=Ruleset.Timezone(-32400,"CST")); + return tz1 || (tz1=Ruleset.Timezone(-31400,"LMT")); + } +} +constant Australia_North=Australia_Darwin; + +class Australia_Perth +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=699375600) // from 1992 Mar Sun>=1 2:00s + return tz3 || (tz3=Ruleset.Timezone(-28800,"WST")); + if (ux>=690314400) // from 1991 Nov 17 2:00s + return tz4 || (tz4=Ruleset.Timezone(-32400,"WST")); + if (ux>=446914800) // from 1984 Mar Sun>=1 2:00s + return tz3 || (tz3=Ruleset.Timezone(-28800,"WST")); + if (ux>=433785600) // from 1983 Oct lastSun 2:00s + return tz4 || (tz4=Ruleset.Timezone(-32400,"WST")); + if (ux>=162831600) // from 1975 Mar Sun>=1 2:00s + return tz3 || (tz3=Ruleset.Timezone(-28800,"WST")); + if (ux>=149788800) // from 1974 Oct lastSun 2:00s + return tz4 || (tz4=Ruleset.Timezone(-32400,"WST")); + if (ux>=-836409600) // from 1943 Jul + return tz3 || (tz3=Ruleset.Timezone(-28800,"WST")); + if (ux>=-2337925404) // from 1895 Dec + return tz2 || (tz2=TZrules.Aus(-28800,"WST")); + return tz1 || (tz1=Ruleset.Timezone(-27804,"LMT")); + } +} +constant Australia_West=Australia_Perth; + +class Australia_Brisbane +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=31572000) // from 1971 + return tz3 || (tz3=TZrules.AQ(-36000,"EST")); + if (ux>=-2366791928) // from 1895 + return tz2 || (tz2=TZrules.Aus(-36000,"EST")); + return tz1 || (tz1=Ruleset.Timezone(-36728,"LMT")); + } +} +constant Australia_Queensland=Australia_Brisbane; + +class Australia_Lindeman +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=709984800) // from 1992 Jul + return tz4 || (tz4=TZrules.Holiday(-36000,"EST")); + if (ux>=31572000) // from 1971 + return tz3 || (tz3=TZrules.AQ(-36000,"EST")); + if (ux>=-2366790956) // from 1895 + return tz2 || (tz2=TZrules.Aus(-36000,"EST")); + return tz1 || (tz1=Ruleset.Timezone(-35756,"LMT")); + } +} + +class Australia_Adelaide +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=31570200) // from 1971 + return tz4 || (tz4=TZrules.AS(-34200,"CST")); + if (ux>=-2230189200) // from 1899 May + return tz3 || (tz3=TZrules.Aus(-34200,"CST")); + if (ux>=-2364110060) // from 1895 Feb + return tz2 || (tz2=Ruleset.Timezone(-32400,"CST")); + return tz1 || (tz1=Ruleset.Timezone(-33260,"LMT")); + } +} +constant Australia_South=Australia_Adelaide; + +class Australia_Hobart +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-94658400) // from 1967 + return tz5 || (tz5=TZrules.AT(-36000,"EST")); + if (ux>=-1669892400) // from 1917 Feb + return tz4 || (tz4=TZrules.Aus(-36000,"EST")); + if (ux>=-1680508800) // from 1916 Oct 1 2:00 + return tz3 || (tz3=Ruleset.Timezone(-39600,"EST")); + if (ux>=-2345795356) // from 1895 Sep + return tz2 || (tz2=Ruleset.Timezone(-36000,"EST")); + return tz1 || (tz1=Ruleset.Timezone(-35356,"LMT")); + } +} +constant Australia_Tasmania=Australia_Hobart; + +class Australia_Melbourne +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=31572000) // from 1971 + return tz3 || (tz3=TZrules.AV(-36000,"EST")); + if (ux>=-2364111592) // from 1895 Feb + return tz2 || (tz2=TZrules.Aus(-36000,"EST")); + return tz1 || (tz1=Ruleset.Timezone(-34792,"LMT")); + } +} +constant Australia_Victoria=Australia_Melbourne; + +class Australia_Sydney +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=31572000) // from 1971 + return tz3 || (tz3=TZrules.AN(-36000,"EST")); + if (ux>=-2364113092) // from 1895 Feb + return tz2 || (tz2=TZrules.Aus(-36000,"EST")); + return tz1 || (tz1=Ruleset.Timezone(-36292,"LMT")); + } +} +constant Australia_ACT=Australia_Sydney; +constant Australia_Canberra=Australia_Sydney; +constant Australia_NSW=Australia_Sydney; + +class Australia_Broken_Hill +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=946722600) // from 2000 + return tz6 || (tz6=TZrules.AS(-34200,"CST")); + if (ux>=31570200) // from 1971 + return tz5 || (tz5=TZrules.AN(-34200,"CST")); + if (ux>=-2230189200) // from 1899 May + return tz4 || (tz4=TZrules.Aus(-34200,"CST")); + if (ux>=-2314951200) // from 1896 Aug 23 + return tz3 || (tz3=Ruleset.Timezone(-32400,"CST")); + if (ux>=-2364110748) // from 1895 Feb + return tz2 || (tz2=Ruleset.Timezone(-36000,"EST")); + return tz1 || (tz1=Ruleset.Timezone(-33948,"LMT")); + } +} +constant Australia_Yancowinna=Australia_Broken_Hill; + +class Australia_Lord_Howe +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=352216800) // from 1981 Mar + return tz3 || (tz3=TZrules.LH(-37800,"LHST")); + if (ux>=-2364114980) // from 1895 Feb + return tz2 || (tz2=Ruleset.Timezone(-36000,"EST")); + return tz1 || (tz1=Ruleset.Timezone(-38180,"LMT")); + } +} +constant Australia_LHI=Australia_Lord_Howe; + +class Indian_Christmas +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2364102172) // from 1895 Feb Christmas Island Time + return tz2 || (tz2=Ruleset.Timezone(-25200,"CXT")); + return tz1 || (tz1=Ruleset.Timezone(-25372,"LMT")); + } +} + +class Pacific_Rarotonga +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=279714600) // from 1978 Nov 12 + return tz3 || (tz3=TZrules.Cook(36000,"CK%sT")); + if (ux>=-2177414456) // from 1901 Cook Is Time + return tz2 || (tz2=Ruleset.Timezone(37800,"CKT")); + // Avarua + return tz1 || (tz1=Ruleset.Timezone(38344,"LMT")); + } +} + +class Pacific_Fiji +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1709985220) // from 1915 Oct 26 Fiji Time + return tz2 || (tz2=TZrules.Fiji(-43200,"FJ%sT")); + // Suva + return tz1 || (tz1=Ruleset.Timezone(-42820,"LMT")); + } +} + +class Pacific_Gambier +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1806678012) // from 1912 Oct Gambier Time + return tz2 || (tz2=Ruleset.Timezone(32400,"GAMT")); + // Rikitea + return tz1 || (tz1=Ruleset.Timezone(32388,"LMT")); + } +} + +class Pacific_Marquesas +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1806676920) // from 1912 Oct Marquesas Time + return tz2 || (tz2=Ruleset.Timezone(34200,"MART")); + return tz1 || (tz1=Ruleset.Timezone(33480,"LMT")); + } +} + +class Pacific_Tahiti +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1806674504) // from 1912 Oct Tahiti Time + return tz2 || (tz2=Ruleset.Timezone(36000,"TAHT")); + // Papeete + return tz1 || (tz1=Ruleset.Timezone(35896,"LMT")); + } +} + +class Pacific_Guam +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2177487540) // from 1901 + return tz2 || (tz2=Ruleset.Timezone(-36000,"GST")); + // Agana + return tz1 || (tz1=Ruleset.Timezone(-34740,"LMT")); + } +} + +class Pacific_Tarawa +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2177494324) // from 1901 Gilbert Is Time + return tz2 || (tz2=Ruleset.Timezone(-43200,"GILT")); + // Bairiki + return tz1 || (tz1=Ruleset.Timezone(-41524,"LMT")); + } +} + +class Pacific_Enderbury +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=788958000) // from 1995 + return tz4 || (tz4=Ruleset.Timezone(-46800,"PHOT")); + if (ux>=307627200) // from 1979 Oct + return tz3 || (tz3=Ruleset.Timezone(39600,"PHOT")); + if (ux>=-2177411740) // from 1901 Phoenix Is Time + return tz2 || (tz2=Ruleset.Timezone(43200,"PHOT")); + return tz1 || (tz1=Ruleset.Timezone(41060,"LMT")); + } +} + +class Pacific_Kiritimati +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=788954400) // from 1995 + return tz4 || (tz4=Ruleset.Timezone(-50400,"LINT")); + if (ux>=307622400) // from 1979 Oct + return tz3 || (tz3=Ruleset.Timezone(36000,"LINT")); + if (ux>=-2177415040) // from 1901 Line Is Time + return tz2 || (tz2=Ruleset.Timezone(38400,"LINT")); + return tz1 || (tz1=Ruleset.Timezone(37760,"LMT")); + } +} + +class Pacific_Saipan +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-7981200) // from 1969 Oct + return tz3 || (tz3=Ruleset.Timezone(-36000,"MPT")); + if (ux>=-2177487780) // from 1901 N Mariana Is Time + return tz2 || (tz2=Ruleset.Timezone(-32400,"MPT")); + return tz1 || (tz1=Ruleset.Timezone(-34980,"LMT")); + } +} + +class Pacific_Majuro +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-7988400) // from 1969 Oct + return tz3 || (tz3=Ruleset.Timezone(-43200,"MHT")); + if (ux>=-2177493888) // from 1901 Marshall Islands Time + return tz2 || (tz2=Ruleset.Timezone(-39600,"MHT")); + return tz1 || (tz1=Ruleset.Timezone(-41088,"LMT")); + } +} + +class Pacific_Kwajalein +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=745848000) // from 1993 Aug 20 + return tz4 || (tz4=Ruleset.Timezone(-43200,"MHT")); + if (ux>=-7988400) // from 1969 Oct Kwajalein Time + return tz3 || (tz3=Ruleset.Timezone(43200,"KWAT")); + if (ux>=-2177492960) // from 1901 + return tz2 || (tz2=Ruleset.Timezone(-39600,"MHT")); + return tz1 || (tz1=Ruleset.Timezone(-40160,"LMT")); + } +} +constant Kwajalein=Pacific_Kwajalein; + +class Pacific_Yap +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-7981200) // from 1969 Oct + return tz3 || (tz3=Ruleset.Timezone(-36000,"YAPT")); + if (ux>=-2177485952) // from 1901 Yap Time + return tz2 || (tz2=Ruleset.Timezone(-32400,"YAPT")); + // Colonia + return tz1 || (tz1=Ruleset.Timezone(-33152,"LMT")); + } +} + +class Pacific_Truk +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2177489228) // from 1901 Truk Time + return tz2 || (tz2=Ruleset.Timezone(-36000,"TRUT")); + return tz1 || (tz1=Ruleset.Timezone(-36428,"LMT")); + } +} + +class Pacific_Ponape +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2177490772) // from 1901 Ponape Time + return tz2 || (tz2=Ruleset.Timezone(-39600,"PONT")); + // Kolonia + return tz1 || (tz1=Ruleset.Timezone(-37972,"LMT")); + } +} + +class Pacific_Kosrae +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=915105600) // from 1999 + return tz2 || (tz2=Ruleset.Timezone(-39600,"KOST")); + if (ux>=-7988400) // from 1969 Oct + return tz3 || (tz3=Ruleset.Timezone(-43200,"KOST")); + if (ux>=-2177491916) // from 1901 Kosrae Time + return tz2 || (tz2=Ruleset.Timezone(-39600,"KOST")); + return tz1 || (tz1=Ruleset.Timezone(-39116,"LMT")); + } +} + +class Pacific_Nauru +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=294323400) // from 1979 May + return tz4 || (tz4=Ruleset.Timezone(-43200,"NRT")); + if (ux>=-800960400) // from 1944 Aug 15 + return tz2 || (tz2=Ruleset.Timezone(-41400,"NRT")); + if (ux>=-877347000) // from 1942 Mar 15 + return tz3 || (tz3=Ruleset.Timezone(-32400,"JST")); + if (ux>=-1545131260) // from 1921 Jan 15 Nauru Time + return tz2 || (tz2=Ruleset.Timezone(-41400,"NRT")); + // Uaobe + return tz1 || (tz1=Ruleset.Timezone(-40060,"LMT")); + } +} + +class Pacific_Noumea +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1829387148) // from 1912 Jan 13 + return tz2 || (tz2=TZrules.NC(-39600,"NC%sT")); + return tz1 || (tz1=Ruleset.Timezone(-39948,"LMT")); + } +} + +class Pacific_Auckland +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-923221800) // from 1940 Sep 29 2:00 + return tz3 || (tz3=TZrules.NZ(-43200,"NZ%sT")); + if (ux>=-3218873944) // from 1868 + return tz2 || (tz2=TZrules.NZ(-41400,"NZ%sT")); + return tz1 || (tz1=Ruleset.Timezone(-41944,"LMT")); + } +} +constant NZ=Pacific_Auckland; + +class Pacific_Niue +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=276089400) // from 1978 Oct 1 + return tz4 || (tz4=Ruleset.Timezone(39600,"NUT")); + if (ux>=-599575200) // from 1951 + return tz3 || (tz3=Ruleset.Timezone(41400,"NUT")); + if (ux>=-2177412020) // from 1901 Niue Time + return tz2 || (tz2=Ruleset.Timezone(40800,"NUT")); + // Alofi + return tz1 || (tz1=Ruleset.Timezone(40780,"LMT")); + } +} + +class Pacific_Norfolk +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-599656320) // from 1951 Norfolk Time + return tz3 || (tz3=Ruleset.Timezone(-41400,"NFT")); + if (ux>=-2177493112) // from 1901 Norfolk Mean Time + return tz2 || (tz2=Ruleset.Timezone(-40320,"NMT")); + // Kingston + return tz1 || (tz1=Ruleset.Timezone(-40312,"LMT")); + } +} + +class Pacific_Palau +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2177485076) // from 1901 Palau Time + return tz2 || (tz2=Ruleset.Timezone(-32400,"PWT")); + // Koror + return tz1 || (tz1=Ruleset.Timezone(-32276,"LMT")); + } +} + +class Pacific_Port_Moresby +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2366790520) // from 1895 Papua New Guinea Time + return tz3 || (tz3=Ruleset.Timezone(-36000,"PGT")); + if (ux>=-2840176120) // from 1880 Port Moresby Mean Time + return tz2 || (tz2=Ruleset.Timezone(-35320,"PMMT")); + return tz1 || (tz1=Ruleset.Timezone(-35320,"LMT")); + } +} + +class Pacific_Pitcairn +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=893665800) // from 1998 Apr 27 00:00 Pitcairn Standard Time + return tz3 || (tz3=Ruleset.Timezone(28800,"PST")); + if (ux>=-2177421580) // from 1901 + return tz2 || (tz2=Ruleset.Timezone(30600,"PNT")); + // Adamstown + return tz1 || (tz1=Ruleset.Timezone(31220,"LMT")); + } +} + +class Pacific_Pago_Pago +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=439038000) // from 1983 Nov 30 S=Samoa + return tz6 || (tz6=Ruleset.Timezone(39600,"SST")); + if (ux>=-86878800) // from 1967 Apr B=Bering + return tz5 || (tz5=Ruleset.Timezone(39600,"BST")); + if (ux>=-631110600) // from 1950 N=Nome + return tz4 || (tz4=Ruleset.Timezone(39600,"NST")); + if (ux>=-1861879032) // from 1911 Samoa Time + return tz3 || (tz3=Ruleset.Timezone(41400,"SAMT")); + if (ux>=-2855738232) // from 1879 Jul 5 + return tz2 || (tz2=Ruleset.Timezone(40968,"LMT")); + return tz1 || (tz1=Ruleset.Timezone(-45432,"LMT")); + } +} +constant Pacific_Samoa=Pacific_Pago_Pago; +constant US_Samoa=Pacific_Pago_Pago; + +class Pacific_Apia +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-631110600) // from 1950 W Samoa Time + return tz4 || (tz4=Ruleset.Timezone(39600,"WST")); + if (ux>=-1861878784) // from 1911 Samoa Time + return tz3 || (tz3=Ruleset.Timezone(41400,"SAMT")); + if (ux>=-2855737984) // from 1879 Jul 5 + return tz2 || (tz2=Ruleset.Timezone(41216,"LMT")); + return tz1 || (tz1=Ruleset.Timezone(-45184,"LMT")); + } +} + +class Pacific_Guadalcanal +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1806748788) // from 1912 Oct Solomon Is Time + return tz2 || (tz2=Ruleset.Timezone(-39600,"SBT")); + // Honiara + return tz1 || (tz1=Ruleset.Timezone(-38388,"LMT")); + } +} + +class Pacific_Fakaofo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2177411704) // from 1901 Tokelau Time + return tz2 || (tz2=Ruleset.Timezone(36000,"TKT")); + return tz1 || (tz1=Ruleset.Timezone(41096,"LMT")); + } +} + +class Pacific_Tongatapu +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=915102000) // from 1999 + return tz4 || (tz4=TZrules.Tonga(-46800,"TO%sT")); + if (ux>=-915193200) // from 1941 + return tz3 || (tz3=Ruleset.Timezone(-46800,"TOT")); + if (ux>=-2177497160) // from 1901 Tonga Time + return tz2 || (tz2=Ruleset.Timezone(-44400,"TOT")); + return tz1 || (tz1=Ruleset.Timezone(-44360,"LMT")); + } +} + +class Pacific_Funafuti +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2177495812) // from 1901 Tuvalu Time + return tz2 || (tz2=Ruleset.Timezone(-43200,"TVT")); + return tz1 || (tz1=Ruleset.Timezone(-43012,"LMT")); + } +} + +class Pacific_Midway +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=439038000) // from 1983 Nov 30 S=Samoa + return tz4 || (tz4=Ruleset.Timezone(39600,"SST")); + if (ux>=-86878800) // from 1967 Apr B=Bering + return tz3 || (tz3=Ruleset.Timezone(39600,"BST")); + if (ux>=-2177410232) // from 1901 N=Nome + return tz2 || (tz2=Ruleset.Timezone(39600,"NST")); + return tz1 || (tz1=Ruleset.Timezone(42568,"LMT")); + } +} + +class Pacific_Wake +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2177492788) // from 1901 Wake Time + return tz2 || (tz2=Ruleset.Timezone(-43200,"WAKT")); + return tz1 || (tz1=Ruleset.Timezone(-39988,"LMT")); + } +} + +class Pacific_Efate +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1829387596) // from 1912 Jan 13 Vanuatu Time + return tz2 || (tz2=TZrules.Vanuatu(-39600,"VU%sT")); + // Vila + return tz1 || (tz1=Ruleset.Timezone(-40396,"LMT")); + } +} + +class Pacific_Wallis +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2177496920) // from 1901 Wallis & Futuna Time + return tz2 || (tz2=Ruleset.Timezone(-43200,"WFT")); + return tz1 || (tz1=Ruleset.Timezone(-44120,"LMT")); + } +} + +class Europe_London +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=820454400) // from 1996 + return tz4 || (tz4=TZrules.EU(0,"GMT/BST")); + if (ux>=57722400) // from 1971 Oct 31 2:00u + return tz2 || (tz2=TZrules.GB_Eire(0,"%s")); + if (ux>=-37234800) // from 1968 Oct 27 + return tz3 || (tz3=Ruleset.Timezone(-3600,"BST")); + if (ux>=-3852662325) // from 1847 Dec 1 + return tz2 || (tz2=TZrules.GB_Eire(0,"%s")); + return tz1 || (tz1=Ruleset.Timezone(75,"LMT")); + } +} +constant GB=Europe_London; +constant GB_Eire=Europe_London; + +class Europe_Belfast +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=820454400) // from 1996 + return tz6 || (tz6=TZrules.EU(0,"GMT/BST")); + if (ux>=57722400) // from 1971 Oct 31 2:00u + return tz4 || (tz4=TZrules.GB_Eire(0,"%s")); + if (ux>=-37234800) // from 1968 Oct 27 + return tz5 || (tz5=Ruleset.Timezone(-3600,"BST")); + if (ux>=-1680471279) // from 1916 Oct 1 2:00s + return tz4 || (tz4=TZrules.GB_Eire(0,"%s")); + if (ux>=-1691962479) // from 1916 May 21 2:00 Irish Summer Time + return tz3 || (tz3=Ruleset.Timezone(-2079,"IST")); + if (ux>=-2821649780) // from 1880 Aug 2 Dublin MT + return tz2 || (tz2=Ruleset.Timezone(1521,"DMT")); + return tz1 || (tz1=Ruleset.Timezone(1420,"LMT")); + } +} + +class Europe_Dublin +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=820454400) // from 1996 + return tz8 || (tz8=TZrules.EU(0,"GMT/IST")); + if (ux>=57722400) // from 1971 Oct 31 2:00u + return tz5 || (tz5=TZrules.GB_Eire(0,"GMT/IST")); + if (ux>=-37234800) // from 1968 Oct 27 + return tz6 || (tz6=Ruleset.Timezone(-3600,"IST")); + if (ux>=-684972000) // from 1948 Apr 18 2:00 + return tz5 || (tz5=TZrules.GB_Eire(0,"GMT/IST")); + if (ux>=-699490800) // from 1947 Nov 2 2:00 + return tz7 || (tz7=Ruleset.Timezone(0,"GMT")); + if (ux>=-719445600) // from 1947 Mar 16 2:00 + return tz6 || (tz6=Ruleset.Timezone(-3600,"IST")); + if (ux>=-733359600) // from 1946 Oct 6 2:00 + return tz7 || (tz7=Ruleset.Timezone(0,"GMT")); + if (ux>=-942012000) // from 1940 Feb 25 2:00 + return tz6 || (tz6=Ruleset.Timezone(-3600,"IST")); + if (ux>=-1517011200) // from 1921 Dec 6 + return tz5 || (tz5=TZrules.GB_Eire(0,"GMT/IST")); + if (ux>=-1680471279) // from 1916 Oct 1 2:00s independence + return tz4 || (tz4=TZrules.GB_Eire(0,"%s")); + if (ux>=-1691962479) // from 1916 May 21 2:00 + return tz3 || (tz3=Ruleset.Timezone(-2079,"IST")); + if (ux>=-2821649679) // from 1880 Aug 2 Dublin MT + return tz2 || (tz2=Ruleset.Timezone(1521,"DMT")); + return tz1 || (tz1=Ruleset.Timezone(1521,"LMT")); + } +} +constant Eire=Europe_Dublin; + +class Europe_Tirane +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=457495200) // from 1984 Jul + return tz4 || (tz4=TZrules.EU(-3600,"CE%sT")); + if (ux>=-932346000) // from 1940 Jun 16 + return tz3 || (tz3=TZrules.Albania(-3600,"CE%sT")); + if (ux>=-1767230360) // from 1914 + return tz2 || (tz2=Ruleset.Timezone(-3600,"CET")); + return tz1 || (tz1=Ruleset.Timezone(-4760,"LMT")); + } +} + +class Europe_Andorra +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=481078800) // from 1985 Mar 31 2:00 + return tz4 || (tz4=TZrules.EU(-3600,"CE%sT")); + if (ux>=-733881600) // from 1946 Sep 30 + return tz3 || (tz3=Ruleset.Timezone(-3600,"CET")); + if (ux>=-2177453164) // from 1901 + return tz2 || (tz2=Ruleset.Timezone(0,"WET")); + return tz1 || (tz1=Ruleset.Timezone(-364,"LMT")); + } +} + +class Europe_Vienna +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=347158800) // from 1981 + return tz4 || (tz4=TZrules.EU(-3600,"CE%sT")); + if (ux>=-781045200) // from 1945 Apr 2 2:00 + return tz3 || (tz3=TZrules.Austria(-3600,"CE%sT")); + if (ux>=-938898000) // from 1940 Apr 1 2:00 + return tz2 || (tz2=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-1626634800) // from 1918 Jun 16 3:00 + return tz3 || (tz3=TZrules.Austria(-3600,"CE%sT")); + if (ux>=-2422055120) // from 1893 Apr + return tz2 || (tz2=TZrules.C_Eur(-3600,"CE%sT")); + return tz1 || (tz1=Ruleset.Timezone(-3920,"LMT")); + } +} + +class Europe_Minsk +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=717544800) // from 1992 Sep 27 0:00s + return tz8 || (tz8=TZrules.Russia(-7200,"EE%sT")); + if (ux>=701820000) // from 1992 Mar 29 0:00s + return tz7 || (tz7=Ruleset.Timezone(-10800,"EEST")); + if (ux>=686102400) // from 1991 Sep 29 2:00s + return tz3 || (tz3=Ruleset.Timezone(-7200,"EET")); + if (ux>=670374000) // from 1991 Mar 31 2:00s + return tz7 || (tz7=Ruleset.Timezone(-10800,"EEST")); + if (ux>=631162800) // from 1990 + return tz4 || (tz4=Ruleset.Timezone(-10800,"MSK")); + if (ux>=-804636000) // from 1944 Jul 3 + return tz6 || (tz6=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-899780400) // from 1941 Jun 28 + return tz5 || (tz5=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-1247536800) // from 1930 Jun 21 + return tz4 || (tz4=Ruleset.Timezone(-10800,"MSK")); + if (ux>=-1441158600) // from 1924 May 2 + return tz3 || (tz3=Ruleset.Timezone(-7200,"EET")); + if (ux>=-2840147416) // from 1880 Minsk Mean Time + return tz2 || (tz2=Ruleset.Timezone(-6600,"MMT")); + return tz1 || (tz1=Ruleset.Timezone(-6616,"LMT")); + } +} + +class Europe_Brussels +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=220928400) // from 1977 + return tz8 || (tz8=TZrules.EU(-3600,"CE%sT")); + if (ux>=-799279200) // from 1944 Sep 3 + return tz7 || (tz7=TZrules.Belgium(-3600,"CE%sT")); + if (ux>=-934668000) // from 1940 May 20 2:00s + return tz5 || (tz5=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-1613826000) // from 1918 Nov 11 11:00u + return tz6 || (tz6=TZrules.Belgium(0,"WE%sT")); + if (ux>=-1693702800) // from 1916 May 1 0:00 + return tz5 || (tz5=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-1740355200) // from 1914 Nov 8 + return tz4 || (tz4=Ruleset.Timezone(-3600,"CET")); + if (ux>=-2450953050) // from 1892 May 1 12:00 + return tz3 || (tz3=Ruleset.Timezone(0,"WET")); + if (ux>=-2840141850) // from 1880 Brussels MT + return tz2 || (tz2=Ruleset.Timezone(-1050,"BMT")); + return tz1 || (tz1=Ruleset.Timezone(-1050,"LMT")); + } +} + +class Europe_Sofia +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=852084000) // from 1997 + return tz8 || (tz8=TZrules.EU(-7200,"EE%sT")); + if (ux>=662695200) // from 1991 + return tz7 || (tz7=TZrules.E_Eur(-7200,"EE%sT")); + if (ux>=401864400) // from 1982 Sep 26 2:00 + return tz6 || (tz6=TZrules.C_Eur(-7200,"EE%sT")); + if (ux>=291762000) // from 1979 Mar 31 23:00 + return tz5 || (tz5=TZrules.Bulg(-7200,"EE%sT")); + if (ux>=-781041600) // from 1945 Apr 2 3:00 + return tz3 || (tz3=Ruleset.Timezone(-7200,"EET")); + if (ux>=-857257200) // from 1942 Nov 2 3:00 + return tz4 || (tz4=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-2369527016) // from 1894 Nov 30 + return tz3 || (tz3=Ruleset.Timezone(-7200,"EET")); + if (ux>=-2840146396) // from 1880 Istanbul MT? + return tz2 || (tz2=Ruleset.Timezone(-7016,"IMT")); + return tz1 || (tz1=Ruleset.Timezone(-5596,"LMT")); + } +} + +class Europe_Prague +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=284000400) // from 1979 + return tz5 || (tz5=TZrules.EU(-3600,"CE%sT")); + if (ux>=-798073200) // from 1944 Sep 17 2:00s + return tz4 || (tz4=TZrules.Czech(-3600,"CE%sT")); + if (ux>=-2469401864) // from 1891 Oct + return tz3 || (tz3=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-3786829064) // from 1850 Prague Mean Time + return tz2 || (tz2=Ruleset.Timezone(-3464,"PMT")); + return tz1 || (tz1=Ruleset.Timezone(-3464,"LMT")); + } +} +constant Europe_Bratislava=Europe_Prague; + +class Europe_Copenhagen +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=315536400) // from 1980 + return tz5 || (tz5=TZrules.EU(-3600,"CE%sT")); + if (ux>=-781045200) // from 1945 Apr 2 2:00 + return tz3 || (tz3=TZrules.Denmark(-3600,"CE%sT")); + if (ux>=-857257200) // from 1942 Nov 2 2:00s + return tz4 || (tz4=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-2390518220) // from 1894 Apr + return tz3 || (tz3=TZrules.Denmark(-3600,"CE%sT")); + if (ux>=-2524524620) // from 1890 Copenhagen Mean Time + return tz2 || (tz2=Ruleset.Timezone(-3020,"CMT")); + return tz1 || (tz1=Ruleset.Timezone(-3020,"LMT")); + } +} + +class Atlantic_Faeroe +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=347155200) // from 1981 + return tz3 || (tz3=TZrules.EU(0,"WE%sT")); + if (ux>=-1955748776) // from 1908 Jan 11 + return tz2 || (tz2=Ruleset.Timezone(0,"WET")); + // Torshavn + return tz1 || (tz1=Ruleset.Timezone(1624,"LMT")); + } +} + +class America_Scoresbysund +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=354664800) // from 1981 Mar 29 + return tz4 || (tz4=TZrules.EU(3600,"EG%sT")); + if (ux>=323841600) // from 1980 Apr 6 2:00 + return tz3 || (tz3=TZrules.C_Eur(7200,"CG%sT")); + if (ux>=-1686090660) // from 1916 Jul 28 + return tz2 || (tz2=Ruleset.Timezone(7200,"CGT")); + // Ittoqqortoormit + return tz1 || (tz1=Ruleset.Timezone(5340,"LMT")); + } +} + +class America_Godthab +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=323845200) // from 1980 Apr 6 2:00 + return tz3 || (tz3=TZrules.EU(10800,"WG%sT")); + if (ux>=-1686083584) // from 1916 Jul 28 + return tz2 || (tz2=Ruleset.Timezone(10800,"WGT")); + // Nuuk + return tz1 || (tz1=Ruleset.Timezone(12416,"LMT")); + } +} + +class America_Thule +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1686079492) // from 1916 Jul 28 + return tz2 || (tz2=TZrules.Thule(14400,"A%sT")); + // Pituffik + return tz1 || (tz1=Ruleset.Timezone(16508,"LMT")); + } +} + +class Europe_Tallinn +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8,tz9; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=941421600) // from 1999 Nov 1 + return tz4 || (tz4=Ruleset.Timezone(-7200,"EET")); + if (ux>=906433200) // from 1998 Sep 22 + return tz9 || (tz9=TZrules.EU(-7200,"EE%sT")); + if (ux>=622598400) // from 1989 Sep 24 2:00s + return tz8 || (tz8=TZrules.C_Eur(-7200,"EE%sT")); + if (ux>=606870000) // from 1989 Mar 26 2:00s + return tz7 || (tz7=Ruleset.Timezone(-10800,"EEST")); + if (ux>=-797637600) // from 1944 Sep 22 + return tz6 || (tz6=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-892954800) // from 1941 Sep 15 + return tz3 || (tz3=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-927943200) // from 1940 Aug 6 + return tz5 || (tz5=Ruleset.Timezone(-10800,"MSK")); + if (ux>=-1535938740) // from 1921 May + return tz4 || (tz4=Ruleset.Timezone(-7200,"EET")); + if (ux>=-1593817200) // from 1919 Jul + return tz2 || (tz2=Ruleset.Timezone(-5940,"TMT")); + if (ux>=-1638322740) // from 1918 Feb + return tz3 || (tz3=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-2840146740) // from 1880 Tallinn Mean Time + return tz2 || (tz2=Ruleset.Timezone(-5940,"TMT")); + return tz1 || (tz1=Ruleset.Timezone(-5940,"LMT")); + } +} + +class Europe_Helsinki +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=354686400) // from 1981 Mar 29 2:00 + return tz4 || (tz4=TZrules.EU(-7200,"EE%sT")); + if (ux>=-1535938792) // from 1921 May + return tz3 || (tz3=TZrules.Finland(-7200,"EE%sT")); + if (ux>=-2890258792) // from 1878 May 31 Helsinki Mean Time + return tz2 || (tz2=Ruleset.Timezone(-5992,"HMT")); + return tz1 || (tz1=Ruleset.Timezone(-5992,"LMT")); + } +} + +class Europe_Paris +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=220928400) // from 1977 + return tz6 || (tz6=TZrules.EU(-3600,"CE%sT")); + if (ux>=-766609200) // from 1945 Sep 16 3:00 + return tz5 || (tz5=TZrules.France(-3600,"CE%sT")); + if (ux>=-800056800) // from 1944 Aug 25 + return tz3 || (tz3=TZrules.France(0,"WE%sT")); + if (ux>=-932428800) // from 1940 Jun 14 23:00 + return tz4 || (tz4=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-1855958961) // from 1911 Mar 11 + return tz3 || (tz3=TZrules.France(0,"WE%sT")); + if (ux>=-2486678901) // from 1891 Mar 15 0:01 Paris Mean Time + return tz2 || (tz2=Ruleset.Timezone(-561,"PMT")); + return tz1 || (tz1=Ruleset.Timezone(-561,"LMT")); + } +} + +class Europe_Berlin +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=315536400) // from 1980 + return tz4 || (tz4=TZrules.EU(-3600,"CE%sT")); + if (ux>=-781045200) // from 1945 Apr 2 2:00 + return tz3 || (tz3=TZrules.Germany(-3600,"CE%sT")); + if (ux>=-2422054408) // from 1893 Apr + return tz2 || (tz2=TZrules.C_Eur(-3600,"CE%sT")); + return tz1 || (tz1=Ruleset.Timezone(-3208,"LMT")); + } +} + +class Europe_Gibraltar +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=378687600) // from 1982 + return tz4 || (tz4=TZrules.EU(-3600,"CE%sT")); + if (ux>=-401320800) // from 1957 Apr 14 2:00 + return tz3 || (tz3=Ruleset.Timezone(-3600,"CET")); + if (ux>=-2821649916) // from 1880 Aug 2 + return tz2 || (tz2=TZrules.GB_Eire(0,"%s")); + return tz1 || (tz1=Ruleset.Timezone(1284,"LMT")); + } +} + +class Europe_Athens +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=347162400) // from 1981 + return tz5 || (tz5=TZrules.EU(-7200,"EE%sT")); + if (ux>=-812415600) // from 1944 Apr 4 + return tz3 || (tz3=TZrules.Greece(-7200,"EE%sT")); + if (ux>=-904856400) // from 1941 Apr 30 + return tz4 || (tz4=TZrules.Greece(-3600,"CE%sT")); + if (ux>=-1686101632) // from 1916 Jul 28 0:01 + return tz3 || (tz3=TZrules.Greece(-7200,"EE%sT")); + if (ux>=-2344642492) // from 1895 Sep 14 Athens MT + return tz2 || (tz2=Ruleset.Timezone(-5692,"AMT")); + return tz1 || (tz1=Ruleset.Timezone(-5692,"LMT")); + } +} + +class Europe_Budapest +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=338950800) // from 1980 Sep 28 2:00s + return tz4 || (tz4=TZrules.EU(-3600,"CE%sT")); + if (ux>=-778464000) // from 1945 May 1 23:00 + return tz3 || (tz3=TZrules.Hungary(-3600,"CE%sT")); + if (ux>=-906930000) // from 1941 Apr 6 2:00 + return tz2 || (tz2=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-1640991600) // from 1918 + return tz3 || (tz3=TZrules.Hungary(-3600,"CE%sT")); + if (ux>=-2500938980) // from 1890 Oct + return tz2 || (tz2=TZrules.C_Eur(-3600,"CE%sT")); + return tz1 || (tz1=Ruleset.Timezone(-4580,"LMT")); + } +} + +class Atlantic_Reykjavik +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-54770400) // from 1968 Apr 7 1:00s + return tz4 || (tz4=Ruleset.Timezone(0,"GMT")); + if (ux>=-1956609132) // from 1908 + return tz3 || (tz3=TZrules.Iceland(3600,"IS%sT")); + if (ux>=-4197047556) // from 1837 Reykjavik Mean Time? + return tz2 || (tz2=Ruleset.Timezone(5268,"RMT")); + return tz1 || (tz1=Ruleset.Timezone(5244,"LMT")); + } +} +constant Iceland=Atlantic_Reykjavik; + +class Europe_Rome +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=315536400) // from 1980 + return tz5 || (tz5=TZrules.EU(-3600,"CE%sT")); + if (ux>=-804808800) // from 1944 Jul + return tz3 || (tz3=TZrules.Italy(-3600,"CE%sT")); + if (ux>=-857257200) // from 1942 Nov 2 2:00s + return tz4 || (tz4=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-2403564596) // from 1893 Nov + return tz3 || (tz3=TZrules.Italy(-3600,"CE%sT")); + if (ux>=-3259097396) // from 1866 Sep 22 Rome Mean Time + return tz2 || (tz2=Ruleset.Timezone(-2996,"RMT")); + return tz1 || (tz1=Ruleset.Timezone(-2996,"LMT")); + } +} +constant Europe_Vatican=Europe_Rome; +constant Europe_San_Marino=Europe_Rome; + +class Europe_Riga +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz10,tz2,tz3,tz4,tz5,tz6,tz7,tz8,tz9; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=951789600) // from 2000 Feb 29 + return tz4 || (tz4=Ruleset.Timezone(-7200,"EET")); + if (ux>=853812000) // from 1997 Jan 21 + return tz10 || (tz10=TZrules.EU(-7200,"EE%sT")); + if (ux>=620600400) // from 1989 Sep lastSun 2:00s + return tz9 || (tz9=TZrules.Latvia(-7200,"EE%sT")); + if (ux>=604724400) // from 1989 Mar lastSun 2:00s + return tz8 || (tz8=Ruleset.Timezone(-10800,"EEST")); + if (ux>=-795826800) // from 1944 Oct 13 + return tz7 || (tz7=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-899521200) // from 1941 Jul + return tz6 || (tz6=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-928029600) // from 1940 Aug 5 + return tz5 || (tz5=Ruleset.Timezone(-10800,"MSK")); + if (ux>=-1377308184) // from 1926 May 11 + return tz4 || (tz4=Ruleset.Timezone(-7200,"EET")); + if (ux>=-1597275384) // from 1919 May 22 3:00 + return tz2 || (tz2=Ruleset.Timezone(-5784,"RMT")); + if (ux>=-1601681784) // from 1919 Apr 1 2:00 + return tz3 || (tz3=Ruleset.Timezone(-9384,"LST")); + if (ux>=-1618702584) // from 1918 Sep 16 3:00 + return tz2 || (tz2=Ruleset.Timezone(-5784,"RMT")); + if (ux>=-1632008184) // from 1918 Apr 15 2:00 Latvian Summer + return tz3 || (tz3=Ruleset.Timezone(-9384,"LST")); + if (ux>=-2840146584) // from 1880 Riga Mean Time + return tz2 || (tz2=Ruleset.Timezone(-5784,"RMT")); + return tz1 || (tz1=Ruleset.Timezone(-5784,"LMT")); + } +} + +class Europe_Vaduz +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=347151600) // from 1981 + return tz3 || (tz3=TZrules.EU(-3600,"CE%sT")); + if (ux>=-2385247084) // from 1894 Jun + return tz2 || (tz2=Ruleset.Timezone(-3600,"CET")); + return tz1 || (tz1=Ruleset.Timezone(-2284,"LMT")); + } +} + +class Europe_Vilnius +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz10,tz11,tz12,tz2,tz3,tz4,tz5,tz6,tz7,tz8,tz9; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=941331600) // from 1999 Oct 31 1:00u + return tz12 || (tz12=TZrules.EU(-7200,"EE%sT")); + if (ux>=891133200) // from 1998 Mar 29 1:00u + return tz11 || (tz11=TZrules.EU(-3600,"CE%sT")); + if (ux>=883620000) // from 1998 + return tz5 || (tz5=Ruleset.Timezone(-7200,"EET")); + if (ux>=686102400) // from 1991 Sep 29 2:00s + return tz10 || (tz10=TZrules.C_Eur(-7200,"EE%sT")); + if (ux>=670374000) // from 1991 Mar 31 2:00s + return tz9 || (tz9=Ruleset.Timezone(-10800,"EEST")); + if (ux>=-802130400) // from 1944 Aug + return tz8 || (tz8=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-900126000) // from 1941 Jun 24 + return tz7 || (tz7=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-928198800) // from 1940 Aug 3 + return tz6 || (tz6=Ruleset.Timezone(-10800,"MSK")); + if (ux>=-1553565600) // from 1920 Oct 9 + return tz4 || (tz4=Ruleset.Timezone(-3600,"CET")); + if (ux>=-1561251600) // from 1920 Jul 12 + return tz5 || (tz5=Ruleset.Timezone(-7200,"EET")); + if (ux>=-1585100136) // from 1919 Oct 10 + return tz4 || (tz4=Ruleset.Timezone(-3600,"CET")); + if (ux>=-1672536240) // from 1917 Kaunas Mean Time + return tz3 || (tz3=Ruleset.Timezone(-5736,"KMT")); + if (ux>=-2840146876) // from 1880 Warsaw Mean Time + return tz2 || (tz2=Ruleset.Timezone(-5040,"WMT")); + return tz1 || (tz1=Ruleset.Timezone(-6076,"LMT")); + } +} + +class Europe_Luxembourg +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=220928400) // from 1977 + return tz7 || (tz7=TZrules.EU(-3600,"CE%sT")); + if (ux>=-797972400) // from 1944 Sep 18 3:00 + return tz6 || (tz6=TZrules.Belgium(-3600,"CE%sT")); + if (ux>=-935179200) // from 1940 May 14 3:00 + return tz5 || (tz5=TZrules.C_Eur(-3600,"WE%sT")); + if (ux>=-1269813600) // from 1929 Oct 6 2:00s + return tz4 || (tz4=TZrules.Belgium(0,"WE%sT")); + if (ux>=-1612652400) // from 1918 Nov 25 + return tz3 || (tz3=TZrules.Lux(0,"WE%sT")); + if (ux>=-2069713476) // from 1904 Jun + return tz2 || (tz2=TZrules.Lux(-3600,"CE%sT")); + return tz1 || (tz1=Ruleset.Timezone(-1476,"LMT")); + } +} + +class Europe_Malta +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=347158800) // from 1981 + return tz5 || (tz5=TZrules.EU(-3600,"CE%sT")); + if (ux>=102387600) // from 1973 Mar 31 + return tz4 || (tz4=TZrules.Malta(-3600,"CE%sT")); + if (ux>=-781052400) // from 1945 Apr 2 2:00s + return tz2 || (tz2=TZrules.Italy(-3600,"CE%sT")); + if (ux>=-857257200) // from 1942 Nov 2 2:00s + return tz3 || (tz3=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-2403478684) // from 1893 Nov 2 + return tz2 || (tz2=TZrules.Italy(-3600,"CE%sT")); + // Valletta + return tz1 || (tz1=Ruleset.Timezone(-3484,"LMT")); + } +} + +class Europe_Chisinau +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz10,tz11,tz12,tz2,tz3,tz4,tz5,tz6,tz7,tz8,tz9; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=852084000) // from 1997 + return tz12 || (tz12=TZrules.EU(-7200,"EE%sT")); + if (ux>=694231200) // from 1992 + return tz11 || (tz11=TZrules.E_Eur(-7200,"EE%sT")); + if (ux>=662680800) // from 1991 + return tz10 || (tz10=TZrules.Russia(-7200,"EE%sT")); + if (ux>=641941200) // from 1990 May 6 + return tz9 || (tz9=Ruleset.Timezone(-7200,"EET")); + if (ux>=631162800) // from 1990 + return tz8 || (tz8=Ruleset.Timezone(-10800,"MSK")); + if (ux>=-800143200) // from 1944 Aug 24 + return tz7 || (tz7=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-898138800) // from 1941 Jul 17 + return tz6 || (tz6=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-927151200) // from 1940 Aug 15 + return tz5 || (tz5=Ruleset.Timezone(-10800,"EEST")); + if (ux>=-1213148664) // from 1931 Jul 24 + return tz4 || (tz4=TZrules.Romania(-7200,"EE%sT")); + if (ux>=-1637114100) // from 1918 Feb 15 Bucharest MT + return tz3 || (tz3=Ruleset.Timezone(-6264,"BMT")); + if (ux>=-2840147720) // from 1880 Chisinau MT + return tz2 || (tz2=Ruleset.Timezone(-6900,"CMT")); + return tz1 || (tz1=Ruleset.Timezone(-6920,"LMT")); + } +} + +class Europe_Tiraspol +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695793600) // from 1992 Jan 19 2:00 + return tz7 || (tz7=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=670395600) // from 1991 Mar 31 2:00 + return tz8 || (tz8=TZrules.Russia(-7200,"EE%sT")); + if (ux>=-800143200) // from 1944 Aug 24 + return tz7 || (tz7=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-898138800) // from 1941 Jul 17 + return tz6 || (tz6=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-927151200) // from 1940 Aug 15 + return tz5 || (tz5=Ruleset.Timezone(-10800,"EEST")); + if (ux>=-1213148664) // from 1931 Jul 24 + return tz4 || (tz4=TZrules.Romania(-7200,"EE%sT")); + if (ux>=-1637114100) // from 1918 Feb 15 Bucharest MT + return tz3 || (tz3=Ruleset.Timezone(-6264,"BMT")); + if (ux>=-2840147912) // from 1880 Chisinau MT + return tz2 || (tz2=Ruleset.Timezone(-6900,"CMT")); + return tz1 || (tz1=Ruleset.Timezone(-7112,"LMT")); + } +} + +class Europe_Monaco +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=220928400) // from 1977 + return tz5 || (tz5=TZrules.EU(-3600,"CE%sT")); + if (ux>=-766609200) // from 1945 Sep 16 3:00 + return tz4 || (tz4=TZrules.France(-3600,"CE%sT")); + if (ux>=-1855958961) // from 1911 Mar 11 + return tz3 || (tz3=TZrules.France(0,"WE%sT")); + if (ux>=-2486680172) // from 1891 Mar 15 Paris Mean Time + return tz2 || (tz2=Ruleset.Timezone(-561,"PMT")); + return tz1 || (tz1=Ruleset.Timezone(-1772,"LMT")); + } +} + +class Europe_Amsterdam +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=220928400) // from 1977 + return tz6 || (tz6=TZrules.EU(-3600,"CE%sT")); + if (ux>=-781045200) // from 1945 Apr 2 2:00 + return tz5 || (tz5=TZrules.Neth(-3600,"CE%sT")); + if (ux>=-935017200) // from 1940 May 16 0:40 + return tz4 || (tz4=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-1025736032) // from 1937 Jul + return tz3 || (tz3=TZrules.Neth(-1200,"NE%sT")); + if (ux>=-2450996368) // from 1892 May + return tz2 || (tz2=TZrules.Neth(-1168,"%s")); + return tz1 || (tz1=Ruleset.Timezone(-1168,"LMT")); + } +} + +class Europe_Oslo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=315536400) // from 1980 + return tz4 || (tz4=TZrules.EU(-3600,"CE%sT")); + if (ux>=-781045200) // from 1945 Apr 2 2:00 + return tz2 || (tz2=TZrules.Norway(-3600,"CE%sT")); + if (ux>=-927504000) // from 1940 Aug 10 23:00 + return tz3 || (tz3=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-2366757780) // from 1895 + return tz2 || (tz2=TZrules.Norway(-3600,"CE%sT")); + return tz1 || (tz1=Ruleset.Timezone(-2580,"LMT")); + } +} +constant Arctic_Longyearbyen=Europe_Oslo; + +class Europe_Warsaw +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=915152400) // from 1999 + return tz7 || (tz7=TZrules.EU(-3600,"CE%sT")); + if (ux>=228880800) // from 1977 Apr 3 1:00 + return tz6 || (tz6=TZrules.W_Eur(-3600,"CE%sT")); + if (ux>=-796860000) // from 1944 Oct + return tz5 || (tz5=TZrules.Poland(-3600,"CE%sT")); + if (ux>=-931726800) // from 1940 Jun 23 2:00 + return tz3 || (tz3=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-1501711200) // from 1922 Jun + return tz5 || (tz5=TZrules.Poland(-3600,"CE%sT")); + if (ux>=-1618686000) // from 1918 Sep 16 3:00 + return tz4 || (tz4=TZrules.Poland(-7200,"EE%sT")); + if (ux>=-1717032240) // from 1915 Aug 5 + return tz3 || (tz3=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-2840145840) // from 1880 Warsaw Mean Time + return tz2 || (tz2=Ruleset.Timezone(-5040,"WMT")); + return tz1 || (tz1=Ruleset.Timezone(-5040,"LMT")); + } +} +constant Poland=Europe_Warsaw; + +class Europe_Lisbon +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=828234000) // from 1996 Mar 31 1:00u + return tz6 || (tz6=TZrules.EU(0,"WE%sT")); + if (ux>=717555600) // from 1992 Sep 27 1:00s + return tz5 || (tz5=TZrules.EU(-3600,"CE%sT")); + if (ux>=433299600) // from 1983 Sep 25 1:00s + return tz4 || (tz4=TZrules.W_Eur(0,"WE%sT")); + if (ux>=212544000) // from 1976 Sep 26 1:00 + return tz2 || (tz2=TZrules.Port(0,"WE%sT")); + if (ux>=-118274400) // from 1966 Apr 3 2:00 + return tz3 || (tz3=Ruleset.Timezone(-3600,"CET")); + if (ux>=-1849562608) // from 1911 May 24 + return tz2 || (tz2=TZrules.Port(0,"WE%sT")); + if (ux>=-2713908208) // from 1884 Lisbon Mean Time + return tz1 || (tz1=Ruleset.Timezone(2192,"LMT")); + return tz1 || (tz1=Ruleset.Timezone(2192,"LMT")); + } +} +constant Portugal=Europe_Lisbon; + +class Atlantic_Azores +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=733280400) // from 1993 Mar 28 1:00u + return tz7 || (tz7=TZrules.EU(3600,"AZO%sT")); + if (ux>=717559200) // from 1992 Sep 27 1:00s + return tz6 || (tz6=TZrules.EU(0,"WE%sT")); + if (ux>=433303200) // from 1983 Sep 25 1:00s + return tz5 || (tz5=TZrules.W_Eur(3600,"AZO%sT")); + if (ux>=-118281600) // from 1966 Apr 3 2:00 + return tz4 || (tz4=TZrules.Port(3600,"AZO%sT")); + if (ux>=-1849557900) // from 1911 May 24 Azores Time + return tz3 || (tz3=TZrules.Port(7200,"AZO%sT")); + if (ux>=-2713904240) // from 1884 Horta Mean Time + return tz2 || (tz2=Ruleset.Timezone(6900,"HMT")); + // Ponta Delgada + return tz1 || (tz1=Ruleset.Timezone(6160,"LMT")); + } +} + +class Atlantic_Madeira +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=433299600) // from 1983 Sep 25 1:00s + return tz5 || (tz5=TZrules.EU(0,"WE%sT")); + if (ux>=-118278000) // from 1966 Apr 3 2:00 + return tz4 || (tz4=TZrules.Port(0,"WE%sT")); + if (ux>=-1849560720) // from 1911 May 24 Madeira Time + return tz3 || (tz3=TZrules.Port(3600,"MAD%sT")); + if (ux>=-2713906344) // from 1884 Funchal Mean Time + return tz2 || (tz2=Ruleset.Timezone(4080,"FMT")); + // Funchal + return tz1 || (tz1=Ruleset.Timezone(4056,"LMT")); + } +} + +class Europe_Bucharest +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=852084000) // from 1997 + return tz6 || (tz6=TZrules.EU(-7200,"EE%sT")); + if (ux>=757389600) // from 1994 + return tz5 || (tz5=TZrules.E_Eur(-7200,"EE%sT")); + if (ux>=662695200) // from 1991 + return tz3 || (tz3=TZrules.Romania(-7200,"EE%sT")); + if (ux>=354672000) // from 1981 Mar 29 2:00s + return tz4 || (tz4=TZrules.C_Eur(-7200,"EE%sT")); + if (ux>=-1213148664) // from 1931 Jul 24 + return tz3 || (tz3=TZrules.Romania(-7200,"EE%sT")); + if (ux>=-2469404664) // from 1891 Oct Bucharest MT + return tz2 || (tz2=Ruleset.Timezone(-6264,"BMT")); + return tz1 || (tz1=Ruleset.Timezone(-6264,"LMT")); + } +} + +class Europe_Kaliningrad +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=670374000) // from 1991 Mar 31 2:00s + return tz5 || (tz5=TZrules.Russia(-7200,"EE%sT")); + if (ux>=-757375200) // from 1946 + return tz4 || (tz4=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-788914800) // from 1945 + return tz3 || (tz3=TZrules.Poland(-7200,"CE%sT")); + if (ux>=-2422056120) // from 1893 Apr + return tz2 || (tz2=TZrules.C_Eur(-3600,"CE%sT")); + return tz1 || (tz1=Ruleset.Timezone(-4920,"LMT")); + } +} + +class Europe_Moscow +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695779200) // from 1992 Jan 19 2:00s + return tz4 || (tz4=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=670374000) // from 1991 Mar 31 2:00s + return tz6 || (tz6=TZrules.Russia(-7200,"EE%sT")); + if (ux>=-1247536800) // from 1930 Jun 21 + return tz4 || (tz4=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-1491166800) // from 1922 Oct + return tz5 || (tz5=Ruleset.Timezone(-7200,"EET")); + if (ux>=-1593797352) // from 1919 Jul 1 2:00 + return tz4 || (tz4=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-1688265000) // from 1916 Jul 3 + return tz3 || (tz3=TZrules.Russia(-9048,"%s")); + if (ux>=-2840149820) // from 1880 Moscow Mean Time + return tz2 || (tz2=Ruleset.Timezone(-9000,"MMT")); + return tz1 || (tz1=Ruleset.Timezone(-9020,"LMT")); + } +} +constant W_SU=Europe_Moscow; + +class Europe_Samara +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=687916800) // from 1991 Oct 20 3:00 Samara Time + return tz6 || (tz6=TZrules.Russia(-14400,"SAM%sT")); + if (ux>=686102400) // from 1991 Sep 29 2:00s + return tz2 || (tz2=Ruleset.Timezone(-10800,"KUYT")); + if (ux>=670374000) // from 1991 Mar 31 2:00s + return tz5 || (tz5=TZrules.Russia(-7200,"KUY%sT")); + if (ux>=606866400) // from 1989 Mar 26 2:00s + return tz4 || (tz4=TZrules.Russia(-10800,"KUY%sT")); + if (ux>=-1247540400) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.Russia(-14400,"KUY%sT")); + if (ux>=-1593825636) // from 1919 Jul 1 2:00 Kuybyshev + return tz2 || (tz2=Ruleset.Timezone(-10800,"KUYT")); + return tz1 || (tz1=Ruleset.Timezone(-12036,"LMT")); + } +} + +class Asia_Yekaterinburg +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695772000) // from 1992 Jan 19 2:00s Yekaterinburg Time + return tz5 || (tz5=TZrules.Russia(-18000,"YEK%sT")); + if (ux>=670366800) // from 1991 Mar 31 2:00s + return tz4 || (tz4=TZrules.Russia(-14400,"SVE%sT")); + if (ux>=-1247544000) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.Russia(-18000,"SVE%sT")); + if (ux>=-1592611344) // from 1919 Jul 15 4:00 Sverdlovsk Time + return tz2 || (tz2=Ruleset.Timezone(-14400,"SVET")); + return tz1 || (tz1=Ruleset.Timezone(-14544,"LMT")); + } +} + +class Asia_Omsk +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695768400) // from 1992 Jan 19 2:00s + return tz3 || (tz3=TZrules.Russia(-21600,"OMS%sT")); + if (ux>=670363200) // from 1991 Mar 31 2:00s + return tz4 || (tz4=TZrules.Russia(-18000,"OMS%sT")); + if (ux>=-1247547600) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.Russia(-21600,"OMS%sT")); + if (ux>=-1582088016) // from 1919 Nov 14 Omsk TIme + return tz2 || (tz2=Ruleset.Timezone(-18000,"OMST")); + return tz1 || (tz1=Ruleset.Timezone(-17616,"LMT")); + } +} + +class Asia_Novosibirsk +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=738144000) // from 1993 May 23 + return tz4 || (tz4=TZrules.Russia(-21600,"NOV%sT")); + if (ux>=695764800) // from 1992 Jan 19 2:00s says Shanks + return tz3 || (tz3=TZrules.Russia(-25200,"NOV%sT")); + if (ux>=670359600) // from 1991 Mar 31 2:00s + return tz4 || (tz4=TZrules.Russia(-21600,"NOV%sT")); + if (ux>=-1247551200) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.Russia(-25200,"NOV%sT")); + if (ux>=-1579476700) // from 1919 Dec 14 6:00 Novosibirsk Time + return tz2 || (tz2=Ruleset.Timezone(-21600,"NOVT")); + return tz1 || (tz1=Ruleset.Timezone(-19900,"LMT")); + } +} + +class Asia_Krasnoyarsk +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695764800) // from 1992 Jan 19 2:00s + return tz3 || (tz3=TZrules.Russia(-25200,"KRA%sT")); + if (ux>=670359600) // from 1991 Mar 31 2:00s + return tz4 || (tz4=TZrules.Russia(-21600,"KRA%sT")); + if (ux>=-1247551200) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.Russia(-25200,"KRA%sT")); + if (ux>=-1577513480) // from 1920 Jan 6 Krasnoyarsk Time + return tz2 || (tz2=Ruleset.Timezone(-21600,"KRAT")); + return tz1 || (tz1=Ruleset.Timezone(-22280,"LMT")); + } +} + +class Asia_Irkutsk +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695761200) // from 1992 Jan 19 2:00s + return tz4 || (tz4=TZrules.Russia(-28800,"IRK%sT")); + if (ux>=670356000) // from 1991 Mar 31 2:00s + return tz5 || (tz5=TZrules.Russia(-25200,"IRK%sT")); + if (ux>=-1247554800) // from 1930 Jun 21 + return tz4 || (tz4=TZrules.Russia(-28800,"IRK%sT")); + if (ux>=-1575874640) // from 1920 Jan 25 Irkutsk Time + return tz3 || (tz3=Ruleset.Timezone(-25200,"IRKT")); + if (ux>=-2840165840) // from 1880 Irkutsk Mean Time + return tz2 || (tz2=Ruleset.Timezone(-25040,"IMT")); + return tz1 || (tz1=Ruleset.Timezone(-25040,"LMT")); + } +} + +class Asia_Yakutsk +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695757600) // from 1992 Jan 19 2:00s + return tz3 || (tz3=TZrules.Russia(-32400,"YAK%sT")); + if (ux>=670352400) // from 1991 Mar 31 2:00s + return tz4 || (tz4=TZrules.Russia(-28800,"YAK%sT")); + if (ux>=-1247558400) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.Russia(-32400,"YAK%sT")); + if (ux>=-1579423120) // from 1919 Dec 15 Yakutsk Time + return tz2 || (tz2=Ruleset.Timezone(-28800,"YAKT")); + return tz1 || (tz1=Ruleset.Timezone(-31120,"LMT")); + } +} + +class Asia_Vladivostok +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695754000) // from 1992 Jan 19 2:00s + return tz3 || (tz3=TZrules.Russia(-36000,"VLA%sT")); + if (ux>=670348800) // from 1991 Mar 31 2:00s + return tz4 || (tz4=TZrules.Russia(-32400,"VLA%sST")); + if (ux>=-1247562000) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.Russia(-36000,"VLA%sT")); + if (ux>=-1487321264) // from 1922 Nov 15 Vladivostok Time + return tz2 || (tz2=Ruleset.Timezone(-32400,"VLAT")); + return tz1 || (tz1=Ruleset.Timezone(-31664,"LMT")); + } +} + +class Asia_Magadan +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695750400) // from 1992 Jan 19 2:00s + return tz3 || (tz3=TZrules.Russia(-39600,"MAG%sT")); + if (ux>=670345200) // from 1991 Mar 31 2:00s + return tz4 || (tz4=TZrules.Russia(-36000,"MAG%sT")); + if (ux>=-1247565600) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.Russia(-39600,"MAG%sT")); + if (ux>=-1441188192) // from 1924 May 2 Magadan Time + return tz2 || (tz2=Ruleset.Timezone(-36000,"MAGT")); + return tz1 || (tz1=Ruleset.Timezone(-36192,"LMT")); + } +} + +class Asia_Kamchatka +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695746800) // from 1992 Jan 19 2:00s + return tz3 || (tz3=TZrules.Russia(-43200,"PET%sT")); + if (ux>=670341600) // from 1991 Mar 31 2:00s + return tz4 || (tz4=TZrules.Russia(-39600,"PET%sT")); + if (ux>=-1247569200) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.Russia(-43200,"PET%sT")); + if (ux>=-1487759676) // from 1922 Nov 10 P-K Time + return tz2 || (tz2=Ruleset.Timezone(-39600,"PETT")); + return tz1 || (tz1=Ruleset.Timezone(-38076,"LMT")); + } +} + +class Asia_Anadyr +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=695746800) // from 1992 Jan 19 2:00s + return tz4 || (tz4=TZrules.Russia(-43200,"ANA%sT")); + if (ux>=670341600) // from 1991 Mar 31 2:00s + return tz5 || (tz5=TZrules.Russia(-39600,"ANA%sT")); + if (ux>=386420400) // from 1982 Apr 1 0:00s + return tz4 || (tz4=TZrules.Russia(-43200,"ANA%sT")); + if (ux>=-1247572800) // from 1930 Jun 21 + return tz3 || (tz3=TZrules.Russia(-46800,"ANA%sT")); + if (ux>=-1441194596) // from 1924 May 2 Anadyr Time + return tz2 || (tz2=Ruleset.Timezone(-43200,"ANAT")); + return tz1 || (tz1=Ruleset.Timezone(-42596,"LMT")); + } +} + +class Europe_Madrid +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=284000400) // from 1979 + return tz4 || (tz4=TZrules.EU(-3600,"CE%sT")); + if (ux>=-733881600) // from 1946 Sep 30 + return tz3 || (tz3=TZrules.Spain(-3600,"CE%sT")); + if (ux>=-2177451916) // from 1901 + return tz2 || (tz2=TZrules.Spain(0,"WE%sT")); + return tz1 || (tz1=Ruleset.Timezone(884,"LMT")); + } +} + +class Africa_Ceuta +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=504918000) // from 1986 + return tz7 || (tz7=TZrules.EU(-3600,"CE%sT")); + if (ux>=448243200) // from 1984 Mar 16 + return tz6 || (tz6=Ruleset.Timezone(-3600,"CET")); + if (ux>=-1293840000) // from 1929 + return tz5 || (tz5=TZrules.SpainAfrica(0,"WE%sT")); + if (ux>=-1451692800) // from 1924 + return tz4 || (tz4=TZrules.Spain(0,"WE%sT")); + if (ux>=-1616810400) // from 1918 Oct 7 23:00 + return tz2 || (tz2=Ruleset.Timezone(0,"WET")); + if (ux>=-1630112400) // from 1918 May 6 23:00 + return tz3 || (tz3=Ruleset.Timezone(-3600,"WEST")); + if (ux>=-2177451524) // from 1901 + return tz2 || (tz2=Ruleset.Timezone(0,"WET")); + return tz1 || (tz1=Ruleset.Timezone(1276,"LMT")); + } +} + +class Atlantic_Canary +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=338947200) // from 1980 Sep 28 0:00s + return tz5 || (tz5=TZrules.EU(0,"WE%sT")); + if (ux>=323827200) // from 1980 Apr 6 0:00s + return tz4 || (tz4=Ruleset.Timezone(-3600,"WEST")); + if (ux>=-733874400) // from 1946 Sep 30 1:00 + return tz3 || (tz3=Ruleset.Timezone(0,"WET")); + if (ux>=-1509663504) // from 1922 Mar Canaries Time + return tz2 || (tz2=Ruleset.Timezone(3600,"CANT")); + // Las Palmas de Gran C. + return tz1 || (tz1=Ruleset.Timezone(3696,"LMT")); + } +} + +class Europe_Stockholm +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=315529200) // from 1980 + return tz5 || (tz5=TZrules.EU(-3600,"CE%sT")); + if (ux>=-1680487200) // from 1916 Sep 30 23:00s + return tz3 || (tz3=Ruleset.Timezone(-3600,"CET")); + if (ux>=-1695088800) // from 1916 Apr 14 23:00s + return tz4 || (tz4=Ruleset.Timezone(-7200,"CEST")); + if (ux>=-2208989532) // from 1900 Jan 1 1:00 + return tz3 || (tz3=Ruleset.Timezone(-3600,"CET")); + if (ux>=-2890257132) // from 1878 May 31 Stockholm MT + return tz2 || (tz2=Ruleset.Timezone(-4332,"SMT")); + return tz1 || (tz1=Ruleset.Timezone(-4332,"LMT")); + } +} + +class Europe_Zurich +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=347158800) // from 1981 + return tz4 || (tz4=TZrules.EU(-3600,"CE%sT")); + if (ux>=-2385246584) // from 1894 Jun + return tz3 || (tz3=TZrules.Swiss(-3600,"CE%sT")); + if (ux>=-3827954048) // from 1848 Sep 12 Bern Mean Time + return tz2 || (tz2=Ruleset.Timezone(-1784,"BMT")); + return tz1 || (tz1=Ruleset.Timezone(-2048,"LMT")); + } +} + +class Europe_Istanbul +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=662695200) // from 1991 + return tz6 || (tz6=TZrules.EU(-7200,"EE%sT")); + if (ux>=504928800) // from 1986 + return tz5 || (tz5=TZrules.C_Eur(-7200,"EE%sT")); + if (ux>=482814000) // from 1985 Apr 20 + return tz3 || (tz3=TZrules.Turkey(-7200,"EE%sT")); + if (ux>=277268400) // from 1978 Oct 15 Turkey Time + return tz4 || (tz4=TZrules.Turkey(-10800,"TR%sT")); + if (ux>=-1869875816) // from 1910 Oct + return tz3 || (tz3=TZrules.Turkey(-7200,"EE%sT")); + if (ux>=-2840147752) // from 1880 Istanbul Mean Time? + return tz2 || (tz2=Ruleset.Timezone(-7016,"IMT")); + return tz1 || (tz1=Ruleset.Timezone(-6952,"LMT")); + } +} +constant Turkey=Europe_Istanbul; +constant Asia_Istanbul=Europe_Istanbul; + +class Europe_Kiev +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=788925600) // from 1995 + return tz8 || (tz8=TZrules.EU(-7200,"EE%sT")); + if (ux>=694216800) // from 1992 + return tz7 || (tz7=TZrules.E_Eur(-7200,"EE%sT")); + if (ux>=646786800) // from 1990 Jul 1 2:00 + return tz3 || (tz3=Ruleset.Timezone(-7200,"EET")); + if (ux>=631162800) // from 1990 + return tz4 || (tz4=Ruleset.Timezone(-10800,"MSK")); + if (ux>=-825375600) // from 1943 Nov 6 + return tz6 || (tz6=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-892522800) // from 1941 Sep 20 + return tz5 || (tz5=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-1247536800) // from 1930 Jun 21 + return tz4 || (tz4=Ruleset.Timezone(-10800,"MSK")); + if (ux>=-1441159324) // from 1924 May 2 + return tz3 || (tz3=Ruleset.Timezone(-7200,"EET")); + if (ux>=-2840148124) // from 1880 Kiev Mean Time + return tz2 || (tz2=Ruleset.Timezone(-7324,"KMT")); + return tz1 || (tz1=Ruleset.Timezone(-7324,"LMT")); + } +} + +class Europe_Uzhgorod +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8,tz9; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=788925600) // from 1995 + return tz9 || (tz9=TZrules.EU(-7200,"EE%sT")); + if (ux>=694216800) // from 1992 + return tz8 || (tz8=TZrules.E_Eur(-7200,"EE%sT")); + if (ux>=670384800) // from 1991 Mar 31 3:00 + return tz7 || (tz7=Ruleset.Timezone(-7200,"EET")); + if (ux>=646786800) // from 1990 Jul 1 2:00 + return tz2 || (tz2=Ruleset.Timezone(-3600,"CET")); + if (ux>=631162800) // from 1990 + return tz6 || (tz6=Ruleset.Timezone(-10800,"MSK")); + if (ux>=-773456400) // from 1945 Jun 29 + return tz5 || (tz5=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-794714400) // from 1944 Oct 26 + return tz2 || (tz2=Ruleset.Timezone(-3600,"CET")); + if (ux>=-796860000) // from 1944 Oct + return tz4 || (tz4=Ruleset.Timezone(-7200,"CEST")); + if (ux>=-946774800) // from 1940 + return tz3 || (tz3=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-2500939752) // from 1890 Oct + return tz2 || (tz2=Ruleset.Timezone(-3600,"CET")); + return tz1 || (tz1=Ruleset.Timezone(-5352,"LMT")); + } +} + +class Europe_Zaporozhye +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=788925600) // from 1995 + return tz8 || (tz8=TZrules.EU(-7200,"EE%sT")); + if (ux>=670395600) // from 1991 Mar 31 2:00 + return tz7 || (tz7=TZrules.E_Eur(-7200,"EE%sT")); + if (ux>=-826412400) // from 1943 Oct 25 + return tz6 || (tz6=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-894769200) // from 1941 Aug 25 + return tz5 || (tz5=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-1247536800) // from 1930 Jun 21 + return tz4 || (tz4=Ruleset.Timezone(-10800,"MSK")); + if (ux>=-1441160400) // from 1924 May 2 + return tz3 || (tz3=Ruleset.Timezone(-7200,"EET")); + if (ux>=-2840149240) // from 1880 Central Ukraine T + return tz2 || (tz2=Ruleset.Timezone(-8400,"CUT")); + return tz1 || (tz1=Ruleset.Timezone(-8440,"LMT")); + } +} + +class Europe_Simferopol +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz10,tz2,tz3,tz4,tz5,tz6,tz7,tz8,tz9; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=857185200) // from 1997 Mar lastSun 1:00u + return tz10 || (tz10=TZrules.EU(-7200,"EE%sT")); + if (ux>=846374400) // from 1996 Oct 27 3:00s + return tz6 || (tz6=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=828230400) // from 1996 Mar 31 3:00s + return tz9 || (tz9=Ruleset.Timezone(-14400,"MSD")); + if (ux>=767761200) // from 1994 May + return tz8 || (tz8=TZrules.E_Eur(-10800,"MSK/MSD")); + if (ux>=694216800) // from 1992 + return tz7 || (tz7=TZrules.E_Eur(-7200,"EE%sT")); + if (ux>=646786800) // from 1990 Jul 1 2:00 + return tz3 || (tz3=Ruleset.Timezone(-7200,"EET")); + if (ux>=631162800) // from 1990 + return tz4 || (tz4=Ruleset.Timezone(-10800,"MSK")); + if (ux>=-811634400) // from 1944 Apr 13 + return tz6 || (tz6=TZrules.Russia(-10800,"MSK/MSD")); + if (ux>=-888894000) // from 1941 Nov + return tz5 || (tz5=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-1247536800) // from 1930 Jun 21 + return tz4 || (tz4=Ruleset.Timezone(-10800,"MSK")); + if (ux>=-1441160160) // from 1924 May 2 + return tz3 || (tz3=Ruleset.Timezone(-7200,"EET")); + if (ux>=-2840148984) // from 1880 Simferopol Mean T + return tz2 || (tz2=Ruleset.Timezone(-8160,"SMT")); + return tz1 || (tz1=Ruleset.Timezone(-8184,"LMT")); + } +} + +class Europe_Belgrade +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=407199600) // from 1982 Nov 27 + return tz5 || (tz5=TZrules.EU(-3600,"CE%sT")); + if (ux>=-766623600) // from 1945 Sep 16 2:00s + return tz2 || (tz2=Ruleset.Timezone(-3600,"CET")); + if (ux>=-777942000) // from 1945 May 8 2:00s + return tz4 || (tz4=Ruleset.Timezone(-7200,"CEST")); + if (ux>=-905824800) // from 1941 Apr 18 23:00 + return tz3 || (tz3=TZrules.C_Eur(-3600,"CE%sT")); + if (ux>=-2713915320) // from 1884 + return tz2 || (tz2=Ruleset.Timezone(-3600,"CET")); + return tz1 || (tz1=Ruleset.Timezone(-4920,"LMT")); + } +} +constant Europe_Ljubljana=Europe_Belgrade; +constant Europe_Sarajevo=Europe_Belgrade; +constant Europe_Skopje=Europe_Belgrade; +constant Europe_Zagreb=Europe_Belgrade; + +class America_New_York +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-94712400) // from 1967 + return tz2 || (tz2=TZrules.US(18000,"E%sT")); + if (ux>=-757400400) // from 1946 + return tz3 || (tz3=TZrules.NYC(18000,"E%sT")); + if (ux>=-883630800) // from 1942 + return tz2 || (tz2=TZrules.US(18000,"E%sT")); + if (ux>=-1577941200) // from 1920 + return tz3 || (tz3=TZrules.NYC(18000,"E%sT")); + if (ux>=-2717651038) // from 1883 Nov 18 12:00 + return tz2 || (tz2=TZrules.US(18000,"E%sT")); + return tz1 || (tz1=Ruleset.Timezone(17762,"LMT")); + } +} +constant US_Eastern=America_New_York; +constant EST5EDT=America_New_York; + +class America_Chicago +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-94716000) // from 1967 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + if (ux>=-757404000) // from 1946 + return tz3 || (tz3=TZrules.Chicago(21600,"C%sT")); + if (ux>=-883634400) // from 1942 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + if (ux>=-1045414800) // from 1936 Nov 15 2:00 + return tz3 || (tz3=TZrules.Chicago(21600,"C%sT")); + if (ux>=-1067832000) // from 1936 Mar 1 2:00 + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=-1577944800) // from 1920 + return tz3 || (tz3=TZrules.Chicago(21600,"C%sT")); + if (ux>=-2717647764) // from 1883 Nov 18 12:00 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(21036,"LMT")); + } +} +constant US_Central=America_Chicago; +constant CST6CDT=America_Chicago; + +class America_Denver +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-94719600) // from 1967 + return tz2 || (tz2=TZrules.US(25200,"M%sT")); + if (ux>=-757407600) // from 1946 + return tz3 || (tz3=TZrules.Denver(25200,"M%sT")); + if (ux>=-883638000) // from 1942 + return tz2 || (tz2=TZrules.US(25200,"M%sT")); + if (ux>=-1577948400) // from 1920 + return tz3 || (tz3=TZrules.Denver(25200,"M%sT")); + if (ux>=-2717643604) // from 1883 Nov 18 12:00 + return tz2 || (tz2=TZrules.US(25200,"M%sT")); + return tz1 || (tz1=Ruleset.Timezone(25196,"LMT")); + } +} +constant Navajo=America_Denver; +constant US_Mountain=America_Denver; +constant America_Shiprock=America_Denver; +constant MST7MDT=America_Denver; + +class America_Los_Angeles +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-94723200) // from 1967 + return tz2 || (tz2=TZrules.US(28800,"P%sT")); + if (ux>=-757411200) // from 1946 + return tz3 || (tz3=TZrules.CA(28800,"P%sT")); + if (ux>=-2717640422) // from 1883 Nov 18 12:00 + return tz2 || (tz2=TZrules.US(28800,"P%sT")); + return tz1 || (tz1=Ruleset.Timezone(28378,"LMT")); + } +} +constant US_Pacific=America_Los_Angeles; +constant PST8PDT=America_Los_Angeles; +constant US_Pacific_New=America_Los_Angeles; + +class America_Juneau +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=436302000) // from 1983 Oct 30 2:00 + return tz4 || (tz4=TZrules.US(32400,"AK%sT")); + if (ux>=-31507200) // from 1969 + return tz3 || (tz3=TZrules.US(28800,"P%sT")); + if (ux>=-757411200) // from 1946 + return tz2 || (tz2=Ruleset.Timezone(28800,"PST")); + if (ux>=-883584000) // from 1942 + return tz3 || (tz3=TZrules.US(28800,"P%sT")); + if (ux>=-2188954939) // from 1900 Aug 20 12:00 + return tz2 || (tz2=Ruleset.Timezone(28800,"PST")); + return tz1 || (tz1=Ruleset.Timezone(32261,"LMT")); + } +} + +class America_Yakutat +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=436298400) // from 1983 Oct 30 2:00 + return tz4 || (tz4=TZrules.US(32400,"AK%sT")); + if (ux>=-31503600) // from 1969 + return tz3 || (tz3=TZrules.US(32400,"Y%sT")); + if (ux>=-757414800) // from 1946 + return tz2 || (tz2=Ruleset.Timezone(32400,"YST")); + if (ux>=-883580400) // from 1942 + return tz3 || (tz3=TZrules.US(32400,"Y%sT")); + if (ux>=-2188953665) // from 1900 Aug 20 12:00 + return tz2 || (tz2=Ruleset.Timezone(32400,"YST")); + return tz1 || (tz1=Ruleset.Timezone(33535,"LMT")); + } +} + +class America_Anchorage +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=436294800) // from 1983 Oct 30 2:00 + return tz6 || (tz6=TZrules.US(32400,"AK%sT")); + if (ux>=-31500000) // from 1969 + return tz5 || (tz5=TZrules.US(36000,"AH%sT")); + if (ux>=-86882400) // from 1967 Apr + return tz4 || (tz4=Ruleset.Timezone(36000,"AHST")); + if (ux>=-757418400) // from 1946 + return tz2 || (tz2=Ruleset.Timezone(36000,"CAT")); + if (ux>=-883576800) // from 1942 + return tz3 || (tz3=TZrules.US(36000,"CAT/CAWT")); + if (ux>=-2188951224) // from 1900 Aug 20 12:00 + return tz2 || (tz2=Ruleset.Timezone(36000,"CAT")); + return tz1 || (tz1=Ruleset.Timezone(35976,"LMT")); + } +} +constant US_Alaska=America_Anchorage; + +class America_Nome +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=436291200) // from 1983 Oct 30 2:00 + return tz6 || (tz6=TZrules.US(32400,"AK%sT")); + if (ux>=-31496400) // from 1969 + return tz5 || (tz5=TZrules.US(39600,"B%sT")); + if (ux>=-86878800) // from 1967 Apr + return tz4 || (tz4=Ruleset.Timezone(39600,"BST")); + if (ux>=-757422000) // from 1946 + return tz2 || (tz2=Ruleset.Timezone(39600,"NST")); + if (ux>=-883573200) // from 1942 + return tz3 || (tz3=TZrules.US(39600,"N%sT")); + if (ux>=-2188947502) // from 1900 Aug 20 12:00 + return tz2 || (tz2=Ruleset.Timezone(39600,"NST")); + return tz1 || (tz1=Ruleset.Timezone(39698,"LMT")); + } +} + +class America_Adak +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=436291200) // from 1983 Oct 30 2:00 + return tz6 || (tz6=TZrules.US(36000,"HA%sT")); + if (ux>=-31496400) // from 1969 + return tz5 || (tz5=TZrules.US(39600,"B%sT")); + if (ux>=-86878800) // from 1967 Apr + return tz4 || (tz4=Ruleset.Timezone(39600,"BST")); + if (ux>=-757422000) // from 1946 + return tz2 || (tz2=Ruleset.Timezone(39600,"NST")); + if (ux>=-883573200) // from 1942 + return tz3 || (tz3=TZrules.US(39600,"N%sT")); + if (ux>=-2188944802) // from 1900 Aug 20 12:00 + return tz2 || (tz2=Ruleset.Timezone(39600,"NST")); + return tz1 || (tz1=Ruleset.Timezone(42398,"LMT")); + } +} +constant America_Atka=America_Adak; +constant US_Aleutian=America_Adak; + +class Pacific_Honolulu +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-712225800) // from 1947 Jun 8 2:00 + return tz5 || (tz5=Ruleset.Timezone(36000,"HST")); + if (ux>=-1155472200) // from 1933 May 21 2:00 + return tz4 || (tz4=TZrules.US(37800,"H%sT")); + if (ux>=-1157283000) // from 1933 Apr 30 2:00 + return tz3 || (tz3=Ruleset.Timezone(34200,"HDT")); + if (ux>=-2208907714) // from 1900 Jan 1 12:00 + return tz2 || (tz2=Ruleset.Timezone(37800,"HST")); + return tz1 || (tz1=Ruleset.Timezone(37886,"LMT")); + } +} +constant US_Hawaii=Pacific_Honolulu; +constant HST=Pacific_Honolulu; + +class America_Phoenix +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-63183600) // from 1968 + return tz3 || (tz3=Ruleset.Timezone(25200,"MST")); + if (ux>=-94669200) // from 1967 + return tz2 || (tz2=TZrules.US(25200,"M%sT")); + if (ux>=-796888740) // from 1944 Oct 1 00:01 + return tz3 || (tz3=Ruleset.Timezone(25200,"MST")); + if (ux>=-813949140) // from 1944 Mar 17 00:01 + return tz2 || (tz2=TZrules.US(25200,"M%sT")); + if (ux>=-820562340) // from 1944 Jan 1 00:01 + return tz3 || (tz3=Ruleset.Timezone(25200,"MST")); + if (ux>=-2717641902) // from 1883 Nov 18 12:00 + return tz2 || (tz2=TZrules.US(25200,"M%sT")); + return tz1 || (tz1=Ruleset.Timezone(26898,"LMT")); + } +} +constant US_Arizona=America_Phoenix; +constant MST=America_Phoenix; + +class America_Boise +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=129114000) // from 1974 Feb 3 2:00 + return tz3 || (tz3=TZrules.US(25200,"M%sT")); + if (ux>=126205200) // from 1974 + return tz4 || (tz4=Ruleset.Timezone(25200,"MST")); + if (ux>=-1471845600) // from 1923 May 13 2:00 + return tz3 || (tz3=TZrules.US(25200,"M%sT")); + if (ux>=-2717640911) // from 1883 Nov 18 12:00 + return tz2 || (tz2=TZrules.US(28800,"P%sT")); + return tz1 || (tz1=Ruleset.Timezone(27889,"LMT")); + } +} + +class America_Indianapolis +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=31518000) // from 1971 + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=-31518000) // from 1969 + return tz6 || (tz6=TZrules.US(18000,"E%sT")); + if (ux>=-368640000) // from 1958 Apr 27 2:00 + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=-386787600) // from 1957 Sep 29 2:00 + return tz5 || (tz5=Ruleset.Timezone(21600,"CST")); + if (ux>=-463636800) // from 1955 Apr 24 2:00 + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=-757404000) // from 1946 + return tz3 || (tz3=TZrules.Indianapolis(21600,"C%sT")); + if (ux>=-883634400) // from 1942 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + if (ux>=-1577944800) // from 1920 + return tz3 || (tz3=TZrules.Indianapolis(21600,"C%sT")); + if (ux>=-2717648122) // from 1883 Nov 18 12:00 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(20678,"LMT")); + } +} +constant America_Fort_Wayne=America_Indianapolis; +constant US_East_Indiana=America_Indianapolis; +constant America_Indiana_Indianapolis=America_Indianapolis; +constant EST=America_Indianapolis; + +class America_Indiana_Marengo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=189284400) // from 1976 + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=152089200) // from 1974 Oct 27 2:00 + return tz5 || (tz5=TZrules.US(18000,"E%sT")); + if (ux>=126651600) // from 1974 Jan 6 2:00 + return tz6 || (tz6=Ruleset.Timezone(18000,"CDT")); + if (ux>=-31518000) // from 1969 + return tz5 || (tz5=TZrules.US(18000,"E%sT")); + if (ux>=-273729600) // from 1961 Apr 30 2:00 + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=-599637600) // from 1951 + return tz3 || (tz3=TZrules.Marengo(21600,"C%sT")); + if (ux>=-2717648077) // from 1883 Nov 18 12:00 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(20723,"LMT")); + } +} + +class America_Indiana_Knox +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=688510800) // from 1991 Oct 27 2:00 + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=-195066000) // from 1963 Oct 27 2:00 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + if (ux>=-242280000) // from 1962 Apr 29 2:00 + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=-725868000) // from 1947 + return tz3 || (tz3=TZrules.Starke(21600,"C%sT")); + if (ux>=-2717648010) // from 1883 Nov 18 12:00 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(20790,"LMT")); + } +} +constant America_Knox_IN=America_Indiana_Knox; +constant US_Indiana_Starke=America_Indiana_Knox; + +class America_Indiana_Vevay +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=94676400) // from 1973 + return tz3 || (tz3=Ruleset.Timezone(18000,"EST")); + if (ux>=-31518000) // from 1969 + return tz4 || (tz4=TZrules.US(18000,"E%sT")); + if (ux>=-495086400) // from 1954 Apr 25 2:00 + return tz3 || (tz3=Ruleset.Timezone(18000,"EST")); + if (ux>=-2717648384) // from 1883 Nov 18 12:00 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(20416,"LMT")); + } +} + +class America_Louisville +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=152089200) // from 1974 Oct 27 2:00 + return tz5 || (tz5=TZrules.US(18000,"E%sT")); + if (ux>=126651600) // from 1974 Jan 6 2:00 + return tz6 || (tz6=Ruleset.Timezone(18000,"CDT")); + if (ux>=-63140400) // from 1968 + return tz5 || (tz5=TZrules.US(18000,"E%sT")); + if (ux>=-266468400) // from 1961 Jul 23 2:00 + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=-757404000) // from 1946 + return tz3 || (tz3=TZrules.Louisville(21600,"C%sT")); + if (ux>=-883634400) // from 1942 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + if (ux>=-1546322400) // from 1921 + return tz3 || (tz3=TZrules.Louisville(21600,"C%sT")); + if (ux>=-2717648218) // from 1883 Nov 18 12:00 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(20582,"LMT")); + } +} + +class America_Detroit +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=167814000) // from 1975 Apr 27 2:00 + return tz4 || (tz4=TZrules.US(18000,"E%sT")); + if (ux>=157748400) // from 1975 + return tz3 || (tz3=Ruleset.Timezone(18000,"EST")); + if (ux>=94676400) // from 1973 + return tz4 || (tz4=TZrules.US(18000,"E%sT")); + if (ux>=-757400400) // from 1946 + return tz5 || (tz5=TZrules.Detroit(18000,"E%sT")); + if (ux>=-883594800) // from 1942 + return tz4 || (tz4=TZrules.US(18000,"E%sT")); + if (ux>=-1724083200) // from 1915 May 15 2:00 + return tz3 || (tz3=Ruleset.Timezone(18000,"EST")); + if (ux>=-2051202469) // from 1905 + return tz2 || (tz2=Ruleset.Timezone(21600,"CST")); + return tz1 || (tz1=Ruleset.Timezone(19931,"LMT")); + } +} +constant US_Michigan=America_Detroit; + +class America_Menominee +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=104914800) // from 1973 Apr 29 2:00 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + if (ux>=-21528000) // from 1969 Apr 27 2:00 + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=-757404000) // from 1946 + return tz3 || (tz3=TZrules.Menominee(21600,"C%sT")); + if (ux>=-2659759773) // from 1885 Sep 18 12:00 + return tz2 || (tz2=TZrules.US(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(21027,"LMT")); + } +} + +class America_St_Johns +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1096947052) // from 1935 Mar 30 + return tz3 || (tz3=TZrules.StJohns(12600,"N%sT")); + if (ux>=-2713897748) // from 1884 + return tz2 || (tz2=TZrules.StJohns(12652,"N%sT")); + return tz1 || (tz1=Ruleset.Timezone(12652,"LMT")); + } +} +constant Canada_Newfoundland=America_St_Johns; + +class America_Goose_Bay +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-119928600) // from 1966 Mar 15 2:00 + return tz6 || (tz6=TZrules.StJohns(14400,"A%sT")); + if (ux>=-1072989000) // from 1936 + return tz5 || (tz5=TZrules.StJohns(12600,"N%sT")); + if (ux>=-1096921748) // from 1935 Mar 30 + return tz4 || (tz4=Ruleset.Timezone(12600,"NST")); + if (ux>=-1609471852) // from 1919 + return tz3 || (tz3=Ruleset.Timezone(12652,"NST")); + if (ux>=-2713895900) // from 1884 + return tz2 || (tz2=TZrules.StJohns(12652,"NST")); + // Happy Valley-Goose Bay + return tz1 || (tz1=Ruleset.Timezone(14500,"LMT")); + } +} + +class America_Halifax +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2131645536) // from 1902 Jun 15 + return tz2 || (tz2=TZrules.Halifax(14400,"A%sT")); + return tz1 || (tz1=Ruleset.Timezone(15264,"LMT")); + } +} +constant Canada_Atlantic=America_Halifax; + +class America_Glace_Bay +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=63086400) // from 1972 + return tz3 || (tz3=TZrules.Halifax(14400,"A%sT")); + if (ux>=-504936000) // from 1954 + return tz4 || (tz4=Ruleset.Timezone(14400,"AST")); + if (ux>=-536472000) // from 1953 + return tz3 || (tz3=TZrules.Halifax(14400,"A%sT")); + if (ux>=-2131646412) // from 1902 Jun 15 + return tz2 || (tz2=TZrules.Canada(14400,"A%sT")); + return tz1 || (tz1=Ruleset.Timezone(14388,"LMT")); + } +} + +class America_Montreal +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2713892744) // from 1884 + return tz2 || (tz2=TZrules.Mont(18000,"E%sT")); + return tz1 || (tz1=Ruleset.Timezone(17656,"LMT")); + } +} +constant Canada_Eastern=America_Montreal; + +class America_Thunder_Bay +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=126248400) // from 1974 + return tz2 || (tz2=TZrules.Canada(18000,"E%sT")); + if (ux>=94676400) // from 1973 + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=-18000) // from 1970 + return tz3 || (tz3=TZrules.Mont(18000,"E%sT")); + if (ux>=-2366733780) // from 1895 + return tz2 || (tz2=TZrules.Canada(18000,"E%sT")); + return tz1 || (tz1=Ruleset.Timezone(21420,"LMT")); + } +} + +class America_Nipigon +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2366734016) // from 1895 + return tz2 || (tz2=TZrules.Canada(18000,"E%sT")); + return tz1 || (tz1=Ruleset.Timezone(21184,"LMT")); + } +} + +class America_Rainy_River +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2366732524) // from 1895 + return tz2 || (tz2=TZrules.Canada(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(22676,"LMT")); + } +} + +class America_Winnipeg +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2602258284) // from 1887 Jul 16 + return tz2 || (tz2=TZrules.Winn(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(23316,"LMT")); + } +} +constant Canada_Central=America_Winnipeg; + +class America_Regina +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-307782000) // from 1960 Apr lastSun 2:00 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-2030202084) // from 1905 Sep + return tz2 || (tz2=TZrules.Regina(25200,"M%sT")); + return tz1 || (tz1=Ruleset.Timezone(25116,"LMT")); + } +} +constant Canada_East_Saskatchewan=America_Regina; +constant Canada_Saskatchewan=America_Regina; + +class America_Swift_Current +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=70909200) // from 1972 Apr lastSun 2:00 + return tz5 || (tz5=Ruleset.Timezone(21600,"CST")); + if (ux>=-631177200) // from 1950 + return tz4 || (tz4=TZrules.Swift(25200,"M%sT")); + if (ux>=-749631600) // from 1946 Apr lastSun 2:00 + return tz3 || (tz3=TZrules.Regina(25200,"M%sT")); + if (ux>=-2030201320) // from 1905 Sep + return tz2 || (tz2=TZrules.Canada(25200,"M%sT")); + return tz1 || (tz1=Ruleset.Timezone(25880,"LMT")); + } +} + +class America_Edmonton +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1998663968) // from 1906 Sep + return tz2 || (tz2=TZrules.Edm(25200,"M%sT")); + return tz1 || (tz1=Ruleset.Timezone(27232,"LMT")); + } +} +constant Canada_Mountain=America_Edmonton; + +class America_Vancouver +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2713880852) // from 1884 + return tz2 || (tz2=TZrules.Vanc(28800,"P%sT")); + return tz1 || (tz1=Ruleset.Timezone(29548,"LMT")); + } +} +constant Canada_Pacific=America_Vancouver; + +class America_Dawson_Creek +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=83962800) // from 1972 Aug 30 2:00 + return tz4 || (tz4=Ruleset.Timezone(25200,"MST")); + if (ux>=-725875200) // from 1947 + return tz3 || (tz3=TZrules.Vanc(28800,"P%sT")); + if (ux>=-2713881544) // from 1884 + return tz2 || (tz2=TZrules.Canada(28800,"P%sT")); + return tz1 || (tz1=Ruleset.Timezone(28856,"LMT")); + } +} + +class America_Pangnirtung +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=941320800) // from 1999 Oct 31 2:00 + return tz4 || (tz4=TZrules.Canada(21600,"C%sT")); + if (ux>=796680000) // from 1995 Apr Sun>=1 2:00 + return tz3 || (tz3=TZrules.Canada(18000,"E%sT")); + if (ux>=-2713894624) // from 1884 + return tz2 || (tz2=TZrules.NT_YK(14400,"A%sT")); + return tz1 || (tz1=Ruleset.Timezone(15776,"LMT")); + } +} + +class America_Iqaluit +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=941320800) // from 1999 Oct 31 2:00 + return tz3 || (tz3=TZrules.Canada(21600,"C%sT")); + if (ux>=-2713893968) // from 1884 + return tz2 || (tz2=TZrules.NT_YK(18000,"E%sT")); + // Frobisher Bay before 1987 + return tz1 || (tz1=Ruleset.Timezone(16432,"LMT")); + } +} + +class America_Rankin_Inlet +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2713888280) // from 1884 + return tz2 || (tz2=TZrules.NT_YK(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(22120,"LMT")); + } +} + +class America_Cambridge_Bay +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=941313600) // from 1999 Oct 31 2:00 + return tz3 || (tz3=TZrules.Canada(21600,"C%sT")); + if (ux>=-2713885180) // from 1884 + return tz2 || (tz2=TZrules.NT_YK(25200,"M%sT")); + return tz1 || (tz1=Ruleset.Timezone(25220,"LMT")); + } +} + +class America_Yellowknife +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2713882956) // from 1884 + return tz2 || (tz2=TZrules.NT_YK(25200,"M%sT")); + return tz1 || (tz1=Ruleset.Timezone(27444,"LMT")); + } +} + +class America_Inuvik +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=291744000) // from 1979 Apr lastSun 2:00 + return tz3 || (tz3=TZrules.NT_YK(25200,"M%sT")); + if (ux>=-2713878360) // from 1884 + return tz2 || (tz2=TZrules.NT_YK(28800,"P%sT")); + return tz1 || (tz1=Ruleset.Timezone(32040,"LMT")); + } +} + +class America_Whitehorse +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-110617200) // from 1966 Jul 1 2:00 + return tz3 || (tz3=TZrules.NT_YK(28800,"P%sT")); + if (ux>=-2188997988) // from 1900 Aug 20 + return tz2 || (tz2=TZrules.NT_YK(32400,"Y%sT")); + return tz1 || (tz1=Ruleset.Timezone(32412,"LMT")); + } +} +constant Canada_Yukon=America_Whitehorse; + +class America_Dawson +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=120582000) // from 1973 Oct 28 0:00 + return tz3 || (tz3=TZrules.NT_YK(28800,"P%sT")); + if (ux>=-2188996940) // from 1900 Aug 20 + return tz2 || (tz2=TZrules.NT_YK(32400,"Y%sT")); + return tz1 || (tz1=Ruleset.Timezone(33460,"LMT")); + } +} + +class America_Cancun +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=902008800) // from 1998 Aug 2 2:00 + return tz3 || (tz3=TZrules.Mexico(21600,"C%sT")); + if (ux>=875646000) // from 1997 Oct lastSun 2:00 + return tz4 || (tz4=TZrules.Mexico(18000,"E%sT")); + if (ux>=820476000) // from 1996 + return tz3 || (tz3=TZrules.Mexico(21600,"C%sT")); + if (ux>=-1514743200) // from 1922 Jan 1 0:12:56 + return tz2 || (tz2=Ruleset.Timezone(21600,"CST")); + return tz1 || (tz1=Ruleset.Timezone(20824,"LMT")); + } +} + +class America_Mexico_City +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1191434400) // from 1932 Mar 30 23:00 + return tz4 || (tz4=TZrules.Mexico(21600,"C%sT")); + if (ux>=-1207159200) // from 1931 Oct + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + if (ux>=-1220292000) // from 1931 May 1 23:00 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-1234807200) // from 1930 Nov 15 + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + if (ux>=-1343066400) // from 1927 Jun 10 23:00 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-1514739600) // from 1922 Jan 1 0:23:24 + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + return tz1 || (tz1=Ruleset.Timezone(23796,"LMT")); + } +} +constant Mexico_General=America_Mexico_City; + +class America_Chihuahua +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=891410400) // from 1998 Apr Sun>=1 3:00 + return tz5 || (tz5=TZrules.Mexico(25200,"M%sT")); + if (ux>=883591200) // from 1998 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=820476000) // from 1996 + return tz4 || (tz4=TZrules.Mexico(21600,"C%sT")); + if (ux>=-1191434400) // from 1932 Mar 30 23:00 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-1207159200) // from 1931 Oct + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + if (ux>=-1220292000) // from 1931 May 1 23:00 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-1234807200) // from 1930 Nov 15 + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + if (ux>=-1343066400) // from 1927 Jun 10 23:00 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-1514739600) // from 1921 Dec 31 23:55:40 + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + return tz1 || (tz1=Ruleset.Timezone(25460,"LMT")); + } +} + +class America_Hermosillo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=915123600) // from 1999 + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + if (ux>=28800) // from 1970 + return tz5 || (tz5=TZrules.Mexico(25200,"M%sT")); + if (ux>=-661539600) // from 1949 Jan 14 + return tz4 || (tz4=Ruleset.Timezone(28800,"PST")); + if (ux>=-875815200) // from 1942 Apr + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + if (ux>=-1191434400) // from 1932 Mar 30 23:00 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-1207159200) // from 1931 Oct + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + if (ux>=-1220292000) // from 1931 May 1 23:00 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-1234807200) // from 1930 Nov 15 + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + if (ux>=-1343066400) // from 1927 Jun 10 23:00 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-1514739600) // from 1921 Dec 31 23:36:08 + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + return tz1 || (tz1=Ruleset.Timezone(26632,"LMT")); + } +} + +class America_Mazatlan +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=28800) // from 1970 + return tz5 || (tz5=TZrules.Mexico(25200,"M%sT")); + if (ux>=-661539600) // from 1949 Jan 14 + return tz4 || (tz4=Ruleset.Timezone(28800,"PST")); + if (ux>=-875815200) // from 1942 Apr + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + if (ux>=-1191434400) // from 1932 Mar 30 23:00 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-1207159200) // from 1931 Oct + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + if (ux>=-1220292000) // from 1931 May 1 23:00 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-1234807200) // from 1930 Nov 15 + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + if (ux>=-1343066400) // from 1927 Jun 10 23:00 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-1514739600) // from 1921 Dec 31 23:54:20 + return tz2 || (tz2=Ruleset.Timezone(25200,"MST")); + return tz1 || (tz1=Ruleset.Timezone(25540,"LMT")); + } +} +constant Mexico_BajaSur=America_Mazatlan; + +class America_Tijuana +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=820425600) // from 1996 + return tz6 || (tz6=TZrules.Mexico(28800,"P%sT")); + if (ux>=189273600) // from 1976 + return tz5 || (tz5=TZrules.US(28800,"P%sT")); + if (ux>=-661539600) // from 1949 Jan 14 + return tz4 || (tz4=TZrules.BajaN(28800,"P%sT")); + if (ux>=-875808000) // from 1942 Apr + return tz3 || (tz3=Ruleset.Timezone(25200,"MST")); + if (ux>=-1234717200) // from 1930 Nov 16 + return tz2 || (tz2=Ruleset.Timezone(28800,"PST")); + if (ux>=-1343062800) // from 1927 Jun 10 23:00 + return tz3 || (tz3=Ruleset.Timezone(25200,"MST")); + if (ux>=-1514736000) // from 1922 Jan 1 0:11:56 + return tz2 || (tz2=Ruleset.Timezone(28800,"PST")); + return tz1 || (tz1=Ruleset.Timezone(28084,"LMT")); + } +} +constant America_Ensenada=America_Tijuana; +constant Mexico_BajaNorte=America_Tijuana; + +class America_Anguilla +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1825098464) // from 1912 Mar 2 + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + return tz1 || (tz1=Ruleset.Timezone(15136,"LMT")); + } +} + +class America_Antigua +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-599598000) // from 1951 + return tz3 || (tz3=Ruleset.Timezone(14400,"AST")); + if (ux>=-1825098768) // from 1912 Mar 2 + return tz2 || (tz2=Ruleset.Timezone(18000,"EST")); + return tz1 || (tz1=Ruleset.Timezone(14832,"LMT")); + } +} + +class America_Nassau +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1825095036) // from 1912 Mar 2 + return tz2 || (tz2=TZrules.Bahamas(18000,"E%sT")); + return tz1 || (tz1=Ruleset.Timezone(18564,"LMT")); + } +} + +class America_Barbados +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1199217692) // from 1932 + return tz3 || (tz3=TZrules.Barb(14400,"A%sT")); + if (ux>=-1451678492) // from 1924 Bridgetown Mean Time + return tz2 || (tz2=Ruleset.Timezone(14308,"BMT")); + // Bridgetown + return tz1 || (tz1=Ruleset.Timezone(14308,"LMT")); + } +} + +class America_Belize +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1822500432) // from 1912 Apr + return tz2 || (tz2=TZrules.Belize(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(21168,"LMT")); + } +} + +class Atlantic_Bermuda +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=136360800) // from 1974 Apr 28 2:00 + return tz3 || (tz3=TZrules.Bahamas(14400,"A%sT")); + if (ux>=-1262281256) // from 1930 Jan 1 2:00 + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + // Hamilton + return tz1 || (tz1=Ruleset.Timezone(15544,"LMT")); + } +} + +class America_Cayman +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1827687168) // from 1912 Feb + return tz3 || (tz3=Ruleset.Timezone(18000,"EST")); + if (ux>=-2524502068) // from 1890 Kingston Mean Time + return tz2 || (tz2=Ruleset.Timezone(18432,"KMT")); + // Georgetown + return tz1 || (tz1=Ruleset.Timezone(19532,"LMT")); + } +} + +class America_Costa_Rica +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1545071020) // from 1921 Jan 15 + return tz3 || (tz3=TZrules.CR(21600,"C%sT")); + if (ux>=-2524501420) // from 1890 San Jose Mean Time + return tz2 || (tz2=Ruleset.Timezone(20180,"SJMT")); + // San Jose + return tz1 || (tz1=Ruleset.Timezone(20180,"LMT")); + } +} + +class America_Havana +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1402813824) // from 1925 Jul 19 12:00 + return tz3 || (tz3=TZrules.Cuba(18000,"C%sT")); + if (ux>=-2524501832) // from 1890 Havana MT + return tz2 || (tz2=Ruleset.Timezone(19776,"HMT")); + return tz1 || (tz1=Ruleset.Timezone(19768,"LMT")); + } +} +constant Cuba=America_Havana; + +class America_Dominica +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1846266804) // from 1911 Jul 1 0:01 + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + // Roseau + return tz1 || (tz1=Ruleset.Timezone(14736,"LMT")); + } +} + +class America_Santo_Domingo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=152046000) // from 1974 Oct 27 + return tz4 || (tz4=Ruleset.Timezone(14400,"AST")); + if (ux>=-1159773600) // from 1933 Apr 1 12:00 + return tz3 || (tz3=TZrules.DR(18000,"E%sT")); + if (ux>=-2524504824) // from 1890 S. Dom. MT + return tz2 || (tz2=Ruleset.Timezone(16800,"SDMT")); + return tz1 || (tz1=Ruleset.Timezone(16776,"LMT")); + } +} + +class America_El_Salvador +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1546279392) // from 1921 + return tz2 || (tz2=TZrules.Salv(21600,"C%sT")); + // San Salvador + return tz1 || (tz1=Ruleset.Timezone(21408,"LMT")); + } +} + +class America_Grenada +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1846266780) // from 1911 Jul + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + // St George's + return tz1 || (tz1=Ruleset.Timezone(14820,"LMT")); + } +} + +class America_Guadeloupe +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1848254032) // from 1911 Jun 8 + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + // Pointe a Pitre + return tz1 || (tz1=Ruleset.Timezone(14768,"LMT")); + } +} + +class America_Guatemala +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1617040676) // from 1918 Oct 5 + return tz2 || (tz2=TZrules.Guat(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(21724,"LMT")); + } +} + +class America_Port_au_Prince +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1670483460) // from 1917 Jan 24 12:00 + return tz3 || (tz3=TZrules.Haiti(18000,"E%sT")); + if (ux>=-2524504240) // from 1890 P-a-P MT + return tz2 || (tz2=Ruleset.Timezone(17340,"PPMT")); + return tz1 || (tz1=Ruleset.Timezone(17360,"LMT")); + } +} + +class America_Tegucigalpa +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1538503868) // from 1921 Apr + return tz2 || (tz2=TZrules.Salv(21600,"C%sT")); + return tz1 || (tz1=Ruleset.Timezone(20932,"LMT")); + } +} + +class America_Jamaica +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=441745200) // from 1984 + return tz3 || (tz3=Ruleset.Timezone(18000,"EST")); + if (ux>=136364400) // from 1974 Apr 28 2:00 + return tz4 || (tz4=TZrules.US(18000,"E%sT")); + if (ux>=-1827687168) // from 1912 Feb + return tz3 || (tz3=Ruleset.Timezone(18000,"EST")); + if (ux>=-2524503168) // from 1890 Kingston Mean Time + return tz2 || (tz2=Ruleset.Timezone(18432,"KMT")); + // Kingston + return tz1 || (tz1=Ruleset.Timezone(18432,"LMT")); + } +} +constant Jamaica=America_Jamaica; + +class America_Martinique +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=338958000) // from 1980 Sep 28 + return tz3 || (tz3=Ruleset.Timezone(14400,"AST")); + if (ux>=323841600) // from 1980 Apr 6 + return tz4 || (tz4=Ruleset.Timezone(10800,"ADT")); + if (ux>=-1851537360) // from 1911 May + return tz3 || (tz3=Ruleset.Timezone(14400,"AST")); + if (ux>=-2524506940) // from 1890 Fort-de-France MT + return tz2 || (tz2=Ruleset.Timezone(14640,"FFMT")); + // Fort-de-France + return tz1 || (tz1=Ruleset.Timezone(14660,"LMT")); + } +} + +class America_Montserrat +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1846266608) // from 1911 Jul 1 0:01 + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + // Olveston + return tz1 || (tz1=Ruleset.Timezone(14932,"LMT")); + } +} + +class America_Managua +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=912488400) // from 1998 Dec + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=725839200) // from 1993 Jan 1 4:00 + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=161758800) // from 1975 Feb 16 + return tz5 || (tz5=TZrules.Nic(21600,"C%sT")); + if (ux>=105084000) // from 1973 May + return tz4 || (tz4=Ruleset.Timezone(18000,"EST")); + if (ux>=-1121105700) // from 1934 Jun 23 + return tz3 || (tz3=Ruleset.Timezone(21600,"CST")); + if (ux>=-2524500892) // from 1890 Managua Mean Time + return tz2 || (tz2=Ruleset.Timezone(20700,"MMT")); + return tz1 || (tz1=Ruleset.Timezone(20708,"LMT")); + } +} + +class America_Panama +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1946918400) // from 1908 Apr 22 + return tz3 || (tz3=Ruleset.Timezone(18000,"EST")); + if (ux>=-2524502512) // from 1890 Panama Mean Time + return tz2 || (tz2=Ruleset.Timezone(19200,"PMT")); + return tz1 || (tz1=Ruleset.Timezone(19088,"LMT")); + } +} + +class America_Puerto_Rico +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-765399600) // from 1945 Sep 30 2:00 + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + if (ux>=-873057600) // from 1942 May 3 + return tz3 || (tz3=Ruleset.Timezone(10800,"AWT")); + if (ux>=-2233035335) // from 1899 Mar 28 12:00 + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + // San Juan + return tz1 || (tz1=Ruleset.Timezone(15865,"LMT")); + } +} + +class America_St_Kitts +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1825098548) // from 1912 Mar 2 + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + // Basseterre + return tz1 || (tz1=Ruleset.Timezone(15052,"LMT")); + } +} + +class America_St_Lucia +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1830369360) // from 1912 + return tz3 || (tz3=Ruleset.Timezone(14400,"AST")); + if (ux>=-2524506960) // from 1890 Castries Mean Time + return tz2 || (tz2=Ruleset.Timezone(14640,"CMT")); + // Castries + return tz1 || (tz1=Ruleset.Timezone(14640,"LMT")); + } +} + +class America_Miquelon +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=326001600) // from 1980 May Pierre & Miquelon Time + return tz3 || (tz3=TZrules.Mont(10800,"PM%sT")); + if (ux>=-1850328920) // from 1911 May 15 + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + // St Pierre + return tz1 || (tz1=Ruleset.Timezone(13480,"LMT")); + } +} + +class America_St_Vincent +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1830369304) // from 1912 + return tz3 || (tz3=Ruleset.Timezone(14400,"AST")); + if (ux>=-2524506904) // from 1890 Kingstown Mean Time + return tz2 || (tz2=Ruleset.Timezone(14696,"KMT")); + // Kingstown + return tz1 || (tz1=Ruleset.Timezone(14696,"LMT")); + } +} + +class America_Grand_Turk +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1827687168) // from 1912 Feb + return tz3 || (tz3=TZrules.TC(18000,"E%sT")); + if (ux>=-2524504528) // from 1890 Kingston Mean Time + return tz2 || (tz2=Ruleset.Timezone(18432,"KMT")); + return tz1 || (tz1=Ruleset.Timezone(17072,"LMT")); + } +} + +class America_Tortola +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1846266092) // from 1911 Jul + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + // Road Town + return tz1 || (tz1=Ruleset.Timezone(15508,"LMT")); + } +} + +class America_St_Thomas +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1846266016) // from 1911 Jul + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + // Charlotte Amalie + return tz1 || (tz1=Ruleset.Timezone(15584,"LMT")); + } +} +constant America_Virgin=America_St_Thomas; + +class America_Buenos_Aires +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-7617600) // from 1969 Oct 5 + return tz5 || (tz5=TZrules.Arg(10800,"AR%sT")); + if (ux>=-1233432000) // from 1930 Dec + return tz4 || (tz4=TZrules.Arg(14400,"AR%sT")); + if (ux>=-1567453396) // from 1920 May + return tz3 || (tz3=Ruleset.Timezone(14400,"ART")); + if (ux>=-2372011572) // from 1894 Nov Cordoba Mean Time + return tz2 || (tz2=Ruleset.Timezone(15404,"CMT")); + return tz1 || (tz1=Ruleset.Timezone(14028,"LMT")); + } +} + +class America_Rosario +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=678315600) // from 1991 Jul + return tz6 || (tz6=Ruleset.Timezone(10800,"ART")); + if (ux>=-7617600) // from 1969 Oct 5 + return tz5 || (tz5=TZrules.Arg(10800,"AR%sT")); + if (ux>=-1233432000) // from 1930 Dec + return tz4 || (tz4=TZrules.Arg(14400,"AR%sT")); + if (ux>=-1567453396) // from 1920 May + return tz3 || (tz3=Ruleset.Timezone(14400,"ART")); + if (ux>=-2372011040) // from 1894 Nov + return tz2 || (tz2=Ruleset.Timezone(15404,"CMT")); + return tz1 || (tz1=Ruleset.Timezone(14560,"LMT")); + } +} + +class America_Cordoba +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=646779600) // from 1990 Jul + return tz6 || (tz6=Ruleset.Timezone(10800,"ART")); + if (ux>=-7617600) // from 1969 Oct 5 + return tz5 || (tz5=TZrules.Arg(10800,"AR%sT")); + if (ux>=-1233432000) // from 1930 Dec + return tz4 || (tz4=TZrules.Arg(14400,"AR%sT")); + if (ux>=-1567453396) // from 1920 May + return tz3 || (tz3=Ruleset.Timezone(14400,"ART")); + if (ux>=-2372010196) // from 1894 Nov + return tz2 || (tz2=Ruleset.Timezone(15404,"CMT")); + return tz1 || (tz1=Ruleset.Timezone(15404,"LMT")); + } +} + +class America_Jujuy +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=719380800) // from 1992 Oct 18 + return tz8 || (tz8=Ruleset.Timezone(10800,"ART")); + if (ux>=700628400) // from 1992 Mar 15 + return tz6 || (tz6=Ruleset.Timezone(14400,"WART")); + if (ux>=686721600) // from 1991 Oct 6 + return tz7 || (tz7=Ruleset.Timezone(10800,"WARST")); + if (ux>=667947600) // from 1991 Mar 3 + return tz6 || (tz6=Ruleset.Timezone(14400,"WART")); + if (ux>=-7617600) // from 1969 Oct 5 + return tz5 || (tz5=TZrules.Arg(10800,"AR%sT")); + if (ux>=-1233432000) // from 1930 Dec + return tz4 || (tz4=TZrules.Arg(14400,"AR%sT")); + if (ux>=-1567453396) // from 1920 May + return tz3 || (tz3=Ruleset.Timezone(14400,"ART")); + if (ux>=-2372009928) // from 1894 Nov + return tz2 || (tz2=Ruleset.Timezone(15404,"CMT")); + return tz1 || (tz1=Ruleset.Timezone(15672,"LMT")); + } +} + +class America_Catamarca +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=709938000) // from 1992 Jul + return tz6 || (tz6=Ruleset.Timezone(10800,"ART")); + if (ux>=678337200) // from 1991 Jul + return tz5 || (tz5=TZrules.Arg(10800,"AR%sT")); + if (ux>=646779600) // from 1990 Jul + return tz6 || (tz6=Ruleset.Timezone(10800,"ART")); + if (ux>=-7617600) // from 1969 Oct 5 + return tz5 || (tz5=TZrules.Arg(10800,"AR%sT")); + if (ux>=-1233432000) // from 1930 Dec + return tz4 || (tz4=TZrules.Arg(14400,"AR%sT")); + if (ux>=-1567453396) // from 1920 May + return tz3 || (tz3=Ruleset.Timezone(14400,"ART")); + if (ux>=-2372009812) // from 1894 Nov + return tz2 || (tz2=Ruleset.Timezone(15404,"CMT")); + return tz1 || (tz1=Ruleset.Timezone(15788,"LMT")); + } +} + +class America_Mendoza +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6,tz7,tz8; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=719380800) // from 1992 Oct 18 + return tz8 || (tz8=Ruleset.Timezone(10800,"ART")); + if (ux>=699418800) // from 1992 Mar 1 + return tz6 || (tz6=Ruleset.Timezone(14400,"WART")); + if (ux>=687499200) // from 1991 Oct 15 + return tz7 || (tz7=Ruleset.Timezone(10800,"WARST")); + if (ux>=667947600) // from 1991 Mar 3 + return tz6 || (tz6=Ruleset.Timezone(14400,"WART")); + if (ux>=-7617600) // from 1969 Oct 5 + return tz5 || (tz5=TZrules.Arg(10800,"AR%sT")); + if (ux>=-1233432000) // from 1930 Dec + return tz4 || (tz4=TZrules.Arg(14400,"AR%sT")); + if (ux>=-1567453396) // from 1920 May + return tz3 || (tz3=Ruleset.Timezone(14400,"ART")); + if (ux>=-2372009084) // from 1894 Nov + return tz2 || (tz2=Ruleset.Timezone(15404,"CMT")); + return tz1 || (tz1=Ruleset.Timezone(16516,"LMT")); + } +} + +class America_Aruba +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-157750200) // from 1965 + return tz3 || (tz3=Ruleset.Timezone(14400,"AST")); + if (ux>=-1826738376) // from 1912 Feb 12 Netherlands Antilles Time + return tz2 || (tz2=Ruleset.Timezone(16200,"ANT")); + // Oranjestad + return tz1 || (tz1=Ruleset.Timezone(16824,"LMT")); + } +} + +class America_La_Paz +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1192307244) // from 1932 Mar 21 Bolivia Time + return tz4 || (tz4=Ruleset.Timezone(14400,"BOT")); + if (ux>=-1205954844) // from 1931 Oct 15 Bolivia ST + return tz3 || (tz3=Ruleset.Timezone(12756,"BOST")); + if (ux>=-2524505244) // from 1890 La Paz Mean Time + return tz2 || (tz2=Ruleset.Timezone(16356,"LPMT")); + return tz1 || (tz1=Ruleset.Timezone(16356,"LMT")); + } +} + +class America_Noronha +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=653522400) // from 1990 Sep 17 + return tz3 || (tz3=Ruleset.Timezone(7200,"FNT")); + if (ux>=-1767217820) // from 1914 + return tz2 || (tz2=TZrules.Brazil(7200,"FN%sT")); + return tz1 || (tz1=Ruleset.Timezone(7780,"LMT")); + } +} +constant Brazil_DeNoronha=America_Noronha; + +class America_Belem +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=590014800) // from 1988 Sep 12 + return tz3 || (tz3=Ruleset.Timezone(10800,"BRT")); + if (ux>=-1767213964) // from 1914 + return tz2 || (tz2=TZrules.Brazil(10800,"BR%sT")); + return tz1 || (tz1=Ruleset.Timezone(11636,"LMT")); + } +} + +class America_Fortaleza +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=938660400) // from 1999 Sep 30 + return tz2 || (tz2=TZrules.Brazil(10800,"BR%sT")); + if (ux>=653518800) // from 1990 Sep 17 + return tz3 || (tz3=Ruleset.Timezone(10800,"BRT")); + if (ux>=-1767216360) // from 1914 + return tz2 || (tz2=TZrules.Brazil(10800,"BR%sT")); + return tz1 || (tz1=Ruleset.Timezone(9240,"LMT")); + } +} + +class America_Araguaina +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=811047600) // from 1995 Sep 14 + return tz2 || (tz2=TZrules.Brazil(10800,"BR%sT")); + if (ux>=653518800) // from 1990 Sep 17 + return tz3 || (tz3=Ruleset.Timezone(10800,"BRT")); + if (ux>=-1767214032) // from 1914 + return tz2 || (tz2=TZrules.Brazil(10800,"BR%sT")); + return tz1 || (tz1=Ruleset.Timezone(11568,"LMT")); + } +} + +class America_Maceio +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=938660400) // from 1999 Sep 30 + return tz2 || (tz2=TZrules.Brazil(10800,"BR%sT")); + if (ux>=841784400) // from 1996 Sep 4 + return tz3 || (tz3=Ruleset.Timezone(10800,"BRT")); + if (ux>=813553200) // from 1995 Oct 13 + return tz2 || (tz2=TZrules.Brazil(10800,"BR%sT")); + if (ux>=653518800) // from 1990 Sep 17 + return tz3 || (tz3=Ruleset.Timezone(10800,"BRT")); + if (ux>=-1767217028) // from 1914 + return tz2 || (tz2=TZrules.Brazil(10800,"BR%sT")); + return tz1 || (tz1=Ruleset.Timezone(8572,"LMT")); + } +} + +class America_Sao_Paulo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-189381600) // from 1964 + return tz2 || (tz2=TZrules.Brazil(10800,"BR%sT")); + if (ux>=-195447600) // from 1963 Oct 23 00:00 + return tz3 || (tz3=Ruleset.Timezone(7200,"BRST")); + if (ux>=-1767214412) // from 1914 + return tz2 || (tz2=TZrules.Brazil(10800,"BR%sT")); + return tz1 || (tz1=Ruleset.Timezone(11188,"LMT")); + } +} +constant Brazil_East=America_Sao_Paulo; + +class America_Cuiaba +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1767212140) // from 1914 + return tz2 || (tz2=TZrules.Brazil(14400,"AM%sT")); + return tz1 || (tz1=Ruleset.Timezone(13460,"LMT")); + } +} + +class America_Porto_Velho +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=590011200) // from 1988 Sep 12 + return tz3 || (tz3=Ruleset.Timezone(14400,"AMT")); + if (ux>=-1767210264) // from 1914 + return tz2 || (tz2=TZrules.Brazil(14400,"AM%sT")); + return tz1 || (tz1=Ruleset.Timezone(15336,"LMT")); + } +} + +class America_Boa_Vista +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=938664000) // from 1999 Sep 30 + return tz2 || (tz2=TZrules.Brazil(14400,"AM%sT")); + if (ux>=590011200) // from 1988 Sep 12 + return tz3 || (tz3=Ruleset.Timezone(14400,"AMT")); + if (ux>=-1767211040) // from 1914 + return tz2 || (tz2=TZrules.Brazil(14400,"AM%sT")); + return tz1 || (tz1=Ruleset.Timezone(14560,"LMT")); + } +} + +class America_Manaus +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=780177600) // from 1994 Sep 22 + return tz3 || (tz3=Ruleset.Timezone(14400,"AMT")); + if (ux>=749188800) // from 1993 Sep 28 + return tz2 || (tz2=TZrules.Brazil(14400,"AM%sT")); + if (ux>=590011200) // from 1988 Sep 12 + return tz3 || (tz3=Ruleset.Timezone(14400,"AMT")); + if (ux>=-1767211196) // from 1914 + return tz2 || (tz2=TZrules.Brazil(14400,"AM%sT")); + return tz1 || (tz1=Ruleset.Timezone(14404,"LMT")); + } +} +constant Brazil_West=America_Manaus; + +class America_Porto_Acre +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=590007600) // from 1988 Sep 12 + return tz3 || (tz3=Ruleset.Timezone(18000,"ACT")); + if (ux>=-1767209328) // from 1914 + return tz2 || (tz2=TZrules.Brazil(18000,"AC%sT")); + return tz1 || (tz1=Ruleset.Timezone(16272,"LMT")); + } +} +constant Brazil_Acre=America_Porto_Acre; + +class America_Santiago +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1178168400) // from 1932 Sep + return tz4 || (tz4=TZrules.Chile(14400,"CL%sT")); + if (ux>=-1893439040) // from 1910 Chile Time + return tz3 || (tz3=TZrules.Chile(18000,"CL%sT")); + if (ux>=-2524504640) // from 1890 Santiago Mean Time + return tz2 || (tz2=Ruleset.Timezone(16960,"SMT")); + return tz1 || (tz1=Ruleset.Timezone(16960,"LMT")); + } +} +constant Chile_Continental=America_Santiago; + +class Pacific_Easter +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=384886800) // from 1982 Mar 14 + return tz4 || (tz4=TZrules.Chile(21600,"EAS%sT")); + if (ux>=-1178124152) // from 1932 Sep Easter I Time + return tz3 || (tz3=TZrules.Chile(25200,"EAS%sT")); + if (ux>=-2524495352) // from 1890 Mataveri Mean Time + return tz2 || (tz2=Ruleset.Timezone(26248,"MMT")); + // Mataveri + return tz1 || (tz1=Ruleset.Timezone(26248,"LMT")); + } +} +constant Chile_EasterIsland=Pacific_Easter; + +class America_Bogota +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1739041420) // from 1914 Nov 23 Colombia Time + return tz3 || (tz3=TZrules.CO(18000,"CO%sT")); + if (ux>=-2707671820) // from 1884 Mar 13 Bogota Mean Time + return tz2 || (tz2=Ruleset.Timezone(17780,"BMT")); + return tz1 || (tz1=Ruleset.Timezone(17780,"LMT")); + } +} + +class America_Curacao +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-157750200) // from 1965 + return tz3 || (tz3=Ruleset.Timezone(14400,"AST")); + if (ux>=-1826738656) // from 1912 Feb 12 Netherlands Antilles Time + return tz2 || (tz2=Ruleset.Timezone(16200,"ANT")); + // Willemstad + return tz1 || (tz1=Ruleset.Timezone(16544,"LMT")); + } +} + +class America_Guayaquil +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1230749160) // from 1931 Ecuador Time + return tz3 || (tz3=Ruleset.Timezone(18000,"ECT")); + if (ux>=-2524502440) // from 1890 Quito Mean Time + return tz2 || (tz2=Ruleset.Timezone(18840,"QMT")); + return tz1 || (tz1=Ruleset.Timezone(19160,"LMT")); + } +} + +class Pacific_Galapagos +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=504939600) // from 1986 Galapagos Time + return tz3 || (tz3=Ruleset.Timezone(21600,"GALT")); + if (ux>=-1230746496) // from 1931 + return tz2 || (tz2=Ruleset.Timezone(18000,"ECT")); + // Puerto Baquerizo Moreno + return tz1 || (tz1=Ruleset.Timezone(21504,"LMT")); + } +} + +class Atlantic_Stanley +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=495579600) // from 1985 Sep 15 + return tz3 || (tz3=TZrules.Falk(14400,"FK%sT")); + if (ux>=420580800) // from 1983 May + return tz4 || (tz4=TZrules.Falk(10800,"FK%sT")); + if (ux>=-1824235716) // from 1912 Mar 12 Falkland Is Time + return tz3 || (tz3=TZrules.Falk(14400,"FK%sT")); + if (ux>=-2524507716) // from 1890 Stanley Mean Time + return tz2 || (tz2=Ruleset.Timezone(13884,"SMT")); + return tz1 || (tz1=Ruleset.Timezone(13884,"LMT")); + } +} + +class America_Cayenne +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-71092800) // from 1967 Oct + return tz3 || (tz3=Ruleset.Timezone(10800,"GFT")); + if (ux>=-1846269040) // from 1911 Jul French Guiana Time + return tz2 || (tz2=Ruleset.Timezone(14400,"GFT")); + return tz1 || (tz1=Ruleset.Timezone(12560,"LMT")); + } +} + +class America_Guyana +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=662698800) // from 1991 + return tz5 || (tz5=Ruleset.Timezone(14400,"GYT")); + if (ux>=176010300) // from 1975 Jul 31 + return tz4 || (tz4=Ruleset.Timezone(10800,"GYT")); + if (ux>=-113688900) // from 1966 May 26 Guyana Time + return tz3 || (tz3=Ruleset.Timezone(13500,"GYT")); + if (ux>=-1730578040) // from 1915 Mar Br Guiana Time + return tz2 || (tz2=Ruleset.Timezone(13500,"GBGT")); + // Georgetown + return tz1 || (tz1=Ruleset.Timezone(13960,"LMT")); + } +} + +class America_Asuncion +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=134017200) // from 1974 Apr + return tz5 || (tz5=TZrules.Para(14400,"PY%sT")); + if (ux>=86760000) // from 1972 Oct + return tz4 || (tz4=Ruleset.Timezone(10800,"PYT")); + if (ux>=-1206389360) // from 1931 Oct 10 Paraguay Time + return tz3 || (tz3=Ruleset.Timezone(14400,"PYT")); + if (ux>=-2524507760) // from 1890 Asuncion Mean Time + return tz2 || (tz2=Ruleset.Timezone(13840,"AMT")); + return tz1 || (tz1=Ruleset.Timezone(13840,"LMT")); + } +} + +class America_Lima +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1938538260) // from 1908 Jul 28 Peru Time + return tz3 || (tz3=TZrules.Peru(18000,"PE%sT")); + if (ux>=-2524503108) // from 1890 Lima Mean Time + return tz2 || (tz2=Ruleset.Timezone(18540,"LMT")); + return tz1 || (tz1=Ruleset.Timezone(18492,"LMT")); + } +} + +class Atlantic_South_Georgia +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-2524512832) // from 1890 South Georgia Time + return tz2 || (tz2=Ruleset.Timezone(7200,"GST")); + // Grytviken + return tz1 || (tz1=Ruleset.Timezone(8768,"LMT")); + } +} + +class America_Paramaribo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4,tz5,tz6; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=465449400) // from 1984 Oct + return tz6 || (tz6=Ruleset.Timezone(10800,"SRT")); + if (ux>=185686200) // from 1975 Nov 20 Suriname Time + return tz5 || (tz5=Ruleset.Timezone(12600,"SRT")); + if (ux>=-765317964) // from 1945 Oct Dutch Guiana Time + return tz4 || (tz4=Ruleset.Timezone(12600,"NEGT")); + if (ux>=-1104524348) // from 1935 The capital moved? + return tz3 || (tz3=Ruleset.Timezone(13236,"PMT")); + if (ux>=-1861906760) // from 1911 Paramaribo Mean Time + return tz2 || (tz2=Ruleset.Timezone(13252,"PMT")); + return tz1 || (tz1=Ruleset.Timezone(13240,"LMT")); + } +} + +class America_Port_of_Spain +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-1825098836) // from 1912 Mar 2 + return tz2 || (tz2=Ruleset.Timezone(14400,"AST")); + return tz1 || (tz1=Ruleset.Timezone(14764,"LMT")); + } +} + +class America_Montevideo +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-853641000) // from 1942 Dec 14 + return tz4 || (tz4=TZrules.Uruguay(10800,"UY%sT")); + if (ux>=-1567455316) // from 1920 May 1 Uruguay Time + return tz3 || (tz3=TZrules.Uruguay(12600,"UY%sT")); + if (ux>=-2256668116) // from 1898 Jun 28 Montevideo MT + return tz2 || (tz2=Ruleset.Timezone(13484,"MMT")); + return tz1 || (tz1=Ruleset.Timezone(13484,"LMT")); + } +} + +class America_Caracas +{ + inherit TZHistory; + Ruleset.Timezone tz1,tz2,tz3,tz4; + Ruleset.Timezone whatrule(int ux) + { + if (ux>=-157750200) // from 1965 + return tz4 || (tz4=Ruleset.Timezone(14400,"VET")); + if (ux>=-1826739136) // from 1912 Feb 12 Venezuela Time + return tz3 || (tz3=Ruleset.Timezone(16200,"VET")); + if (ux>=-2524505536) // from 1890 Caracas Mean Time + return tz2 || (tz2=Ruleset.Timezone(16064,"CMT")); + return tz1 || (tz1=Ruleset.Timezone(16064,"LMT")); + } +} + + +// ---------------------------------------------------------------------- diff --git a/lib/modules/Calendar.pmod/Time.pmod b/lib/modules/Calendar.pmod/Time.pmod new file mode 100644 index 0000000000000000000000000000000000000000..b19555feb10057fb4b17bea8eff1107ef1cd164f --- /dev/null +++ b/lib/modules/Calendar.pmod/Time.pmod @@ -0,0 +1,1833 @@ +//! +//! module Calendar +//! submodule Time +//! +//! Base for time of day in calendars, ie +//! calendars with hours, minutes, seconds +//! +//! This module can't be used by itself, but +//! is inherited by other modules (<ref>ISO</ref> by <ref>YMD</ref>, +//! for instance). + +// #pragma strict_types + +//- these classes majorly works on seconds +//- an hour is 3600 seconds, a minute is 60 seconds + +import "."; +inherit TimeRanges:TimeRanges; + +constant inano=1000000000; + +// from inherited module + +function(mixed...:TimeRange) Day; + +// sanity check + +static private int __sanity_check=lambda() +{ + if (5000000000!=5*inano) + error("Calendar.Time needs bignums (Gmp.mpz)\n"); + return 1; +}(); + +Ruleset.Timezone Timezone_UTC=Ruleset.Timezone(0,"UTC"); // needed for dumping + +//------------------------------------------------------------------------ +//! class TimeOfDay +//------------------------------------------------------------------------ + +class TimeofDay +{ +//! inherits TimeRange + inherit TimeRange; + + constant is_timeofday=1; + + TimeRange base; // base day + int ux; // unix time (in UTC, no timezone or DST thing) + int len; // size in seconds (n*60) + +// may be unknown (CALUNKNOWN) + int ls; // local second (on this day, adjusted for dst and tz) + int utco=CALUNKNOWN; // offset to utc, counting dst + string tzn; // name of timezone + +//! method void create() +//! method void create(int unixtime) +//! In addition to the wide range of construction arguments +//! for a normal TimeRange (see <ref>TimeRange.create</ref>), +//! a time of day can also be constructed with unixtime +//! as single argument consisting of the unix time +//! - as returned from <tt>time(2)</tt> - of the time unit start. +//! +//! It can also be constructed without argument, which +//! then means "now", as in "this minute". + +//- for internal use: +//- method void create("timeofday",rules,unixtime,len) + + void create(mixed ...args) + { + if (!sizeof(args)) + { + rules=default_rules; + create_now(); + return; + } + switch (args[0]) + { + case "timeofday": + rules=[object(Ruleset)]args[1]; + ux=[int]args[2]; + len=[int]args[3]; + ls=CALUNKNOWN; + return; + + case "timeofday_sd": + rules=[object(Ruleset)]args[1]; + ux=[int]args[2]; + len=[int]args[3]; + ls=[int]args[4]; + utco=[int]args[5]; + return; + + default: + if (intp(args[0]) && sizeof(args)==1) + { + rules=default_rules; + create_unixtime_default([int]args[0]); + return; + } + } + rules=default_rules; + if (create_backtry(@args)) return; + ::create(@args); + } + + static int(0..1) create_backtry(mixed ...args) + { + if (sizeof(args)>1 && objectp(args[0])) + { + base=args[0]; + rules=base->ruleset(); + args=args[1..]; + } + if (base) + { + switch (sizeof(args)) + { + case 3: + if (intp(args[0]) && intp(args[1]) && intp(args[2])) + { + create_unixtime_default(base->second(@args)->unix_time()); + return 1; + } + break; + case 2: + if (intp(args[0]) && intp(args[1])) + { + create_unixtime_default(base->second(@args,0)->unix_time()); + return 1; + } + break; + } + } + return 0; + } + + void create_unixtime(int unixtime,int _len) + { + ux=unixtime; + len=_len; + ls=CALUNKNOWN; + } + + static void create_now(); + + void create_julian_day(int|float jd) + { +// 1970-01-01 is julian day 2440588 + jd-=2440588; + float fjd=(jd-(int)jd)-0.5; + ux=((int)jd)*86400+(int)(fjd*86400); + ls=CALUNKNOWN; + } + +// make base +// needed in ymd +/*static*/ TimeRange make_base() + { + base=Day("unix_r",ux,rules); + if (len) base=base->range(Day("unix_r",ux+len,rules)); +// werror("make base -> %O\n",base); + return base; + } + +// make local second + static void make_local() + { + if (!base) make_base(); + + ls=ux-base->unix_time(); + if (rules->timezone->is_dst_timezone) + { + if (utco==CALUNKNOWN) + [utco,tzn]=rules->timezone->tz_ux(ux); + if (utco!=base->utc_offset()) + ls+=base->utc_offset()-utco; + } + } + +// default autopromote + TimeRange autopromote() + { + return this_object(); + } + + array(int(-1..1)) _compare(TimeRange with) + { +#define CMP(A,B) ( ((A)<(B))?-1:((A)>(B))?1:0 ) + + if (with->is_timeofday_f) + { + array(int(-1..1)) cmp=with->_compare(this_object()); + + return ({-cmp[0], + -cmp[2], + -cmp[1], + -cmp[3]}); + } + else if (with->is_timeofday) + return ({ CMP(ux,with->ux),CMP(ux,with->ux+with->len), + CMP(ux+len,with->ux),CMP(ux+len,with->ux+with->len) }); + else if (with->is_supertimerange || + with->is_nulltimerange || + !with->unix_time) + return ::_compare(with); + else + { + int e2=with->end()->unix_time(); + int b2=with->unix_time(); + + return ({ CMP(ux,b2),CMP(ux,e2),CMP(ux+len,b2),CMP(ux+len,e2) }); + } + } + + cSecond beginning() + { + return Second("timeofday_sd",rules,ux,0,ls,utco)->autopromote(); + } + + cSecond end() + { + return Second("timeofday",rules,ux+len,0)->autopromote(); + } + + TimeRange distance(TimeRange to) + { + if (to->is_ymd) + return distance(to->hour()); + + if (!to->is_timeofday) + error("distance: incompatible class %O\n", + object_program(to)); + + if (to->is_timeofday_f) + return + Fraction("timeofday_f",rules,ux,0,len,0) + ->distance(to); + + int m; + if ( (m=to->unix_time()-unix_time())<0) + error("Negative distance %O .. %O\n", this_object(),to); + + return + Second("timeofday_sd",rules,ux,m,ls,utco) + ->autopromote(); + } + + TimeRange range(TimeRange to) + { + if (to->is_timeofday_f) + { + return distance(to->end()); + } + if (to->is_timeofday) + { + int m; + if ( (m=to->unix_time()+to->len-unix_time())<0 ) + error("Negative range\n"); + return Second("timeofday_sd",rules,ux,m,ls,utco) + ->autopromote(); + } + return ::range(to); + } + + static void convert_from(TimeRange other) + { + ::convert_from(other); + if (other->is_timeofday) + len=other->len; + else if (other->number_of_seconds) + len=other->number_of_seconds(); + else if (other->number_of_days) + len=86400*other->number_of_days(); // chance + else + len=0; // *shrug* + } + + TimeRange _set_size(int n,TimeRange t) + { + if (!t->is_timeofday) + return distance(add(n,t)); + + return Second("timeofday_sd",rules,ux,n*(t->len),ls,utco)->autopromote(); + } + + TimeRange _move(int n,int m); + + TimeRange _add(int n,TimeRange step) + { + if (step->is_timeofday_f) + return Fraction("timeofday_f",rules,ux,0,len,0) + ->add(n,step); + if (step->is_timeofday) + return _move(n,step->number_of_seconds()); + + if (!base) make_base(); + return base->add(n,step)->place(this_object(),1); + } + +//! method Hour hour() +//! method Hour hour(int n) +//! method array(Hour) hours() +//! method array(Hour) hours(int first,int last) +//! method int number_of_hours() +//! <ref>hour</ref>() gives back the timerange representing the +//! first or <i>n</i>th Hour of the called object. +//! Note that hours normally starts to count at zero, +//! so <tt>->hour(2)</tt> gives the third hour within +//! the range. +//! +//! An Hour is in the Calendar perspective as any other +//! time range not only 60 minutes, but also one +//! of the (normally) 24 hours of the day, precisely. +//! +//! <ref>hours</ref>() give back an array of all the hours +//! containing the time periods called. With arguments, +//! it will give back a range of those hours, in the +//! same enumeration as the <i>n</i> to <ref>hour</ref>(). +//! +//! <ref>number_of_hours</ref>() simple counts the +//! number of hours containing the called time period. +//! +//! Note: +//! The called object doesn't have to +//! *fill* all the hours it will send back, it's +//! enough if it exist in those hours: +//! +//! <pre> +//! > object h=Calendar.Time.Hour(); +//! Result: Hour(265567) +//! > h->hours(); +//! Result: ({ /* 1 element */ +//! Hour(265567) +//! }) +//! > h+=Calendar.Time.Minute(); +//! Result: Minute(265567:01+60m) +//! > h->hours(); +//! Result: ({ /* 2 elements */ +//! Hour(265567), +//! Hour(265568) +//! }) +//! </pre> + + + + cHour hour(void|int n) + { +// hours are on the day, adjust for timezone (non-full-hour timezones!) + if (ls==CALUNKNOWN) make_local(); + int zx=ux-ls%3600; + + if (!n || (n==-1 && !len)) + return Hour("timeofday",rules,zx,3600); + if (n<0) n=number_of_hours()+n; + if (n<0 || n*3600>=len+ux-zx) + error("hour not in timerange (hour 0..%d exist)\n",(len-1)/3600); + return Hour("timeofday",rules,zx+3600*n,3600)->autopromote(); + } + + int number_of_hours() + { + if (ls==CALUNKNOWN) make_local(); + int zx=ux-ls%3600; + return ((ux-zx)+len+3599)/3600; + } + + array(cSecond) hours(int ...range) + { return get_timeofday("hours",0,3600,Hour,@range); } + +//! method Minute minute() +//! method Minute minute(int n) +//! method array(Minute) minutes() +//! method array(Minute) minutes(int first,int last) +//! method int number_of_minutes() +//! <ref>minute</ref>() gives back the timerange representing the +//! first or <i>n</i>th Minute of the called object. +//! Note that minutes normally starts to count at zero, +//! so <tt>->minute(2)</tt> gives the third minute within +//! the range. +//! +//! An Minute is in the Calendar perspective as any other +//! time range not only 60 seconds, but also one +//! of the (normally) 60 minutes of the <ref>Hour</ref>, precisely. +//! +//! <ref>minutes</ref>() give back an array of all the minutes +//! containing the time periods called. With arguments, +//! it will give back a range of those minutes, in the +//! same enumeration as the <i>n</i> to <ref>minute</ref>(). +//! +//! <ref>number_of_minutes</ref>() simple counts the +//! number of minutes containing the called time period. +//! + + cMinute minute(void|int n) + { +// minutes are on the day, adjust for timezone (non-full-minute timezones!) + if (ls==CALUNKNOWN) make_local(); + int zx=ux-ls%60; + + if (!n || (n==-1 && !len)) + return Minute("timeofday",rules,zx,60); + if (n<0) n=number_of_minutes()+n; + if (n<0 || n*60>=len+ux-zx) + error("minute not in timerange (minute 0..%d exist)\n",(len-1)/60); + return Minute("timeofday",rules,zx+60*n,60)->autopromote(); + } + + int number_of_minutes() + { + if (ls==CALUNKNOWN) make_local(); + int zx=ux-ls%60; + return ((ux-zx)+len+59)/60; + } + + array(cSecond) minutes(int ...range) + { return get_timeofday("minutes",0,60,Minute,@range); } + +//! method Second second() +//! method Second second(int n) +//! method array(Second) seconds() +//! method array(Second) seconds(int first,int last) +//! method int number_of_seconds() +//! <ref>second</ref>() gives back the timerange representing the +//! first or <i>n</i>th Second of the called object. +//! Note that seconds normally starts to count at zero, +//! so <tt>->second(2)</tt> gives the third second within +//! the range. +//! +//! <ref>seconds</ref>() give back an array of all the seconds +//! containing the time periods called. With arguments, +//! it will give back a range of those seconds, in the +//! same enumeration as the <i>n</i> to <ref>second</ref>(). +//! +//! <ref>number_of_seconds</ref>() simple counts the +//! number of seconds containing the called time period. + + cSecond second(void|int n) + { + int len=number_of_seconds(); + if (!n || (n==-1 && !len)) + return Second("timeofday",rules,ux,1); + if (n<0) n=len+n; + if (n<0 || n>=len) + error("second not in timerange (second 0..%d exist)\n",len); + return Second("timeofday",rules,ux+n,1)->autopromote(); + } + + static array(TimeRange) get_timeofday(string unit, + int start,int step,program p, + int ... range) + { + int from=0,n=::`[]("number_of_"+unit)(),to=n-1; + + if (sizeof(range)) + if (sizeof(range)<2) + error("Illegal numbers of arguments to "+unit+"()\n"); + else + { + [from,to]=range; + if (from>=n) return ({}); else if (from<0) from=0; + if (to>=n) to=n-1; else if (to<from) return ({}); + } + + from*=step; + to*=step; + + to-=from-step; + + if (ls==CALUNKNOWN) make_local(); + from+=ux-ls%step; + + return + map(enumerate(to/step,step,from), + lambda(int x) + { return p("timeofday",rules,x,step); }); + } + + array(cSecond) seconds(int ...range) + { return get_timeofday("seconds",0,1,Second,@range); } + + int number_of_seconds() + { + return len; + } + +// -------------------- + + float number_of_fractions() { return (float)number_of_seconds(); } + cSecond fraction(float|int ... n) + { + if (sizeof(n)) + { + float m=n[0]; + if (m<=-1.0) m=1+number_of_fractions()+m; + array q=fractions(m,m); + if (!sizeof(q)) + error("fraction not in range (0..%.1f)\n",number_of_fractions()); + return q[0]; + } + else + return fractions()[0]; + } + array(cSecond) fractions(int|float ...range) + { + float from,to,n=number_of_fractions(); + if (sizeof(range)==2) + from=(float)range[0],to=(float)range[1]; + else if (sizeof(range)==0) + from=0.0,to=n; + else + error("Illegal arguments\n"); + if (from<0.0) from=0.0; + if (to>n) to=n; + if (to<from) + return ({}); + to-=from; + return ({Fraction("timeofday_f",rules, + ux+(int)from,(int)(inano*(from-(int)from)), + (int)to,(int)(inano*(to-(int)to))) + ->autopromote()}); + } + +// -------------------- + + string nice_print(); + + string nice_print_period() + { + if (!base) make_base(); + + if (!len) + return sprintf("%s %s sharp", + base->nice_print(),nice_print()); + + string a=base->nice_print(); + object e=end(); + string b=e->day()->nice_print(); + string c=e->nice_print(); + if (a==b) + return a+" "+nice_print()+" - "+end()->nice_print(); + if (c==b) + return a+" "+nice_print()+" - "+b+" 0:00"; + return a+" "+nice_print()+" - "+b+" "+end()->nice_print(); + } + +//! method TimeRange set_size_seconds(int seconds) +//! method TimeRange set_size_ns(int nanoseconds) +//! These two methods allows the time range +//! to be edited by size of specific units. + + + TimeRange set_size_seconds(int seconds) + { + if (seconds<0) error("Negative size\n"); + return Second("timeofday_sd",rules,ux,seconds,ls,utco) + ->autopromote(); + } + + TimeRange set_size_ns(int nanoseconds) + { + if (nanoseconds<0) error("Negative size\n"); + return Fraction("timeofday_f",rules,ux,0,0,nanoseconds) + ->autopromote(); + } + +//! method TimeRange move_seconds(int seconds) +//! method TimeRange move_ns(int nanoseconds) +//! These two methods gives back the +//! time range called moved the specified +//! amount of time, with the length intact. +//! +//! The motion is relative to the original position +//! in time; 10 seconds ahead of 10:42:32 is 10:42:42, etc. + + TimeRange move_seconds(int seconds) + { + return _move(seconds,1); + } + + TimeRange move_ns(int nanoseconds) + { + return Fraction("timeofday_f",rules,ux,nanoseconds,len,0) + ->autopromote(); + } + +// -------- + +//! method int unix_time() +//! This calculates the corresponding unix time, +//! - as returned from <tt>time(2)</tt> - from the +//! time range. Note that the calculated unix time +//! is the beginning of the period. + + int unix_time() { return ux; } + +//! method float julian_day() +//! This calculates the corresponding julian day, +//! from the time range. Note that the calculated day +//! is the beginning of the period, and is a float - +//! julian day standard says .00 is midday, 12:00 pm. +//! +//! note: +//! Normal pike (ie, 32 bit) floats (without --with-double-precision) +//! has a limit of about 7 digits, and since we are about +//! julian day 2500000, the precision on time of day is very limited. + + float julian_day() + { + return 2440588+ux/86400.0-0.5; + } + +//! method int hour_no() +//! method int minute_no() +//! method int second_no() +//! method float fraction_no() +//! This gives back the number of the time unit, +//! on this day. Fraction is a float number, 0<=fraction<1. + + int hour_no() + { + if (ls==CALUNKNOWN) make_local(); + return ls/3600; + } + + int minute_no() + { + if (ls==CALUNKNOWN) make_local(); + return (ls/60)%60; + } + + int second_no() + { + if (ls==CALUNKNOWN) make_local(); + return ls%60; + } + + float fraction_no() + { + return 0.0; + } + +//! function mapping datetime() +//! This gives back a mapping with the relevant +//! time information (representing the start of the period); +//! <pre> +//! ([ "year": int // year number (2000 AD=2000, 1 BC==0) +//! "month": int(1..) // month of year +//! "day": int(1..) // day of month +//! "yearday": int(1..) // day of year +//! "week": int(1..) // week of year +//! "week_day": int(1..) // day of week (depending on calendar) +//! +//! "hour": int(0..) // hour of day, including dst +//! "minute": int(0..59) // minute of hour +//! "second": int(0..59) // second of minute +//! "fraction": float // fraction of second +//! "timezone": int // offset to utc, including dst +//! +//! "unix": int // unix time +//! "julian": float // julian day +//! ]); +//! </pre> + + mapping datetime() + { + if (ls==CALUNKNOWN) make_local(); + if (!base) make_base(); + return base->datetime(1) | + (["hour":ls/3600, + "minute":(ls/60)%60, + "second":ls%60, + "fraction":0.0, + "timezone":utc_offset(), + "julian":julian_day(), + "unix":ux + ]); + } + +// --- string format ---- + +//! method string format_iso_ymd(); +//! method string format_ymd(); +//! method string format_ymd_short(); +//! method string format_ymd_xshort(); +//! method string format_iso_week(); +//! method string format_iso_week_short(); +//! method string format_week(); +//! method string format_week_short(); +//! method string format_month(); +//! method string format_month_short(); +//! method string format_iso_time(); +//! method string format_time(); +//! method string format_time_short(); +//! method string format_time_xshort(); +//! method string format_mtime(); +//! method string format_xtime(); +//! method string format_tod(); +//! method string format_xtod(); +//! method string format_mod(); +//! Format the object into nice strings; +//! <pre> +//! iso_ymd "2000-06-02 (Jun) -W22-5 (Fri)" [2] +//! ext_ymd "Friday, 2 June 2000" [2] +//! ymd "2000-06-02" +//! ymd_short "20000602" +//! ymd_xshort "000602" [1] +//! iso_week "2000-W22" +//! iso_week_short "2000W22" +//! week "2000-w22" [2] +//! week_short "2000w22" [2] +//! month "2000-06" +//! month_short "200006" [1] +//! iso_time "2000-06-02 (Jun) -W22-5 (Fri) 20:53:14 UTC+1" [2] +//! ext_time "Friday, 2 June 2000, 20:53:14" [2] +//! ctime "Fri Jun 4 20:53:14 2000\n" [2] [3] +//! http "Fri, 02 Jun 2000 20:53:14 GMT" [4] +//! time "2000-06-02 20:53:14" +//! time_short "20000602 20:53:14" +//! time_xshort "000602 20:53:14" +//! mtime "2000-06-02 20:53" +//! xtime "2000-06-02 20:53:14.000000" +//! todz "20:53:14 CET" +//! todz_iso "20:53:14 UTC+1" +//! tod "20:53:14" +//! tod_short "205314" +//! xtod "20:53:14.000000" +//! mod "20:53" +//! </pre> +//! <tt>[1]</tt> note conflict (think 1 February 2003) +//! <br><tt>[2]</tt> language dependent +//! <br><tt>[3]</tt> as from the libc function ctime() +//! <br><tt>[4]</tt> as specified by the HTTP standard; +//! this is always in GMT, ie, UTC. The timezone calculations +//! needed will be executed implicitly. It is not language +//! dependent. + + string format_ext_ymd(); + string format_iso_ymd(); + string format_ymd(); + string format_ymd_short(); + string format_ymd_xshort(); + string format_iso_week(); + string format_iso_week_short(); + string format_week(); + string format_week_short(); + string format_month(); + string format_month_short(); + + string format_iso_time() + { + return this_object()->format_iso_ymd()+" "+format_todz_iso(); + } + + string format_ext_time() + { + return this_object()->format_ext_ymd()+" "+format_tod(); + } + + string format_time() + { + return this_object()->format_ymd()+" "+format_tod(); + } + + string format_time_short() + { + return this_object()->format_ymd_short()+" "+format_tod(); + } + + string format_time_xshort() + { + return this_object()->format_ymd_xshort()+" "+format_tod(); + } + + string format_mtime() + { + return this_object()->format_ymd_short()+" "+format_mod(); + } + + string format_xtime() + { + return this_object()->format_ymd_short()+" "+format_xtod(); + } + + string format_ctime() + { + if (!base) make_base(); + return replace(base->format_ctime(), + "00:00:00",format_tod()); + } + + string format_http() + { + if (utc_offset()) + return set_timezone(Timezone_UTC)->format_http(); + if (!base) make_base(); + + return replace(base->format_http(), + "00:00:00",format_tod()); + } + + string format_tod() + { + if (ls==CALUNKNOWN) make_local(); + return sprintf("%02d:%02d:%02d", ls/3600, (ls/60)%60, ls%60); + } + + string format_tod_short() + { + if (ls==CALUNKNOWN) make_local(); + return sprintf("%02d%02d%02d", ls/3600, (ls/60)%60, ls%60); + } + + string format_todz() + { + if (ls==CALUNKNOWN) make_local(); + return sprintf("%02d:%02d:%02d %s", + ls/3600, + (ls/60)%60, + ls%60, + tzname()); + } + + string format_todz_iso() + { + if (ls==CALUNKNOWN) make_local(); + return sprintf("%02d:%02d:%02d %s", + ls/3600, + (ls/60)%60, + ls%60, + tzname_iso()); + } + + string format_mod() + { + if (ls==CALUNKNOWN) make_local(); + return sprintf("%02d:%02d",ls/3600,(ls/60)%60); + } + + string format_xtod() + { + if (ls==CALUNKNOWN) make_local(); + return sprintf("%02d:%02d:%02d.%06d", + ls/3600, + (ls/60)%60, + ls%60, + 0); + } + + string format_elapsed() + { + string res=""; + object left=this_object(); + int x; + if ( (x=(this_object()/Day)) ) + { + res+=sprintf("%dd",x); + left=this_object()->add(x,Day)->range(this_object()->end()); + } + return sprintf("%s%d:%02d:%02d", + res,left->len/3600, + (left->len/60)%60, + left->len%60); + } + + +// -------- + + TimeofDay set_ruleset(Ruleset r) + { + return + Second("timeofday",r,ux,len) + ->autopromote(); + } + + int utc_offset() + { + if (utco==CALUNKNOWN) + return [utco,tzn]=rules->timezone->tz_ux(ux),utco; + else + return utco; + } + + string tzname() + { + if (tzn) return tzn; + if (rules->timezone->is_dst_timezone) + return [utco,tzn]=rules->timezone->tz_ux(ux),tzn; + return tzn=rules->timezone->name; + } + + string tzname_iso() + { + int u=utc_offset(); + if (!(u%3600)) + return sprintf("UTC%+d",-u/3600); + if (!(u%60)) + return + (u<0) + ?sprintf("UTC+%d:%02d",-u/3600,(-u/60)%60) + :sprintf("UTC-%d:%02d",u/3600,(u/60)%60); + return + (u<0) + ?sprintf("UTC+%d:%02d:%02d",-u/3600,(-u/60)%60,(-u)%60) + :sprintf("UTC-%d:%02d:%02d",u/3600,(u/60)%60,u%60); + } + +// -------- + +// #define TIME_OPERATOR_DEBUG +#ifdef TIME_OPERATOR_DEBUG +#define DEBUG_OVERLOAD_OPERATOR(OP,NAME,IND) \ + TimeRange OP(mixed ...args) \ + { \ + _ind+=IND; \ + TimeRange x=::OP(@args); \ + _ind=_ind[..strlen(_ind)-strlen(IND)-1]; \ + werror(_ind+" %O\n",this_object()); \ + foreach (args,TimeRange t) werror(_ind+NAME+" %O\n",t); \ + werror(_ind+"= %O\n",x); \ + return x; \ + } + DEBUG_OVERLOAD_OPERATOR(`&,"&","| "); + DEBUG_OVERLOAD_OPERATOR(`^,"^","| "); + DEBUG_OVERLOAD_OPERATOR(`|,"|","| "); + DEBUG_OVERLOAD_OPERATOR(subtract,"-","| "); +#endif +} + + string _ind="* "; + +//----------------------------------------------------------------- +//! class SuperTimeRange +//! inherits TimeRanges.SuperTimeRange +//----------------------------------------------------------------- + +class cSuperTimeRange +{ + inherit TimeRanges::cSuperTimeRange; + +#ifdef TIME_OPERATOR_DEBUG + DEBUG_OVERLOAD_OPERATOR(`&,"&","S "); + DEBUG_OVERLOAD_OPERATOR(`^,"^","S "); + DEBUG_OVERLOAD_OPERATOR(`|,"|","S "); + DEBUG_OVERLOAD_OPERATOR(subtract,"-","S "); +#endif + +//! method Second second() +//! method Second second(int n) +//! method array(Second) seconds() +//! method array(Second) seconds(int first,int last) +//! method int number_of_seconds() +//! method Minute minute() +//! method Minute minute(int n) +//! method array(Minute) minutes() +//! method array(Minute) minutes(int first,int last) +//! method int number_of_minutes() +//! method Hour hour() +//! method Hour hour(int n) +//! method array(Hour) hours() +//! method array(Hour) hours(int first,int last) +//! method int number_of_hours() +//! Similar to <ref>TimeofDay</ref>, the Time::SuperTimeRange +//! has a number of methods for digging out time parts of the +//! range. Since a <ref>SuperTimeRange</ref> is a bit more +//! complex - the major reason for its existance it that it +//! contains holes, this calculation is a bit more advanced too. +//! +//! If a range contains the seconds, say, 1..2 and 4..5, +//! the third second (number 2, since we start from 0) +//! in the range would be number 4, like this: +//! +//! <pre> +//! no means this second +//! 0 1 +//! 1 2 +//! 2 4 <- second three is missing, +//! 3 5 as we don't have it in the example range +//! </pre> +//! +//! <ref>number_of_seconds</ref>() will in this example +//! therefore also report 4, not 5, even if the time from +//! start of the range to the end of the range is 5 seconds. +//! + + array(cHour) hours(int ...range) { return get_units("hours",@range); } + cHour hour(void|int n) { return get_unit("hours",n); } + int number_of_hours() { return num_units("hours"); } + + array(cMinute) minutes(int ...range) { return get_units("minutes",@range); } + cMinute minute(void|int n) { return get_unit("minutes",n); } + int number_of_minutes() { return num_units("minutes"); } + + array(cSecond) seconds(int ...range) { return get_units("seconds",@range); } + cSecond second(void|int n) { return get_unit("seconds",n); } + int number_of_seconds() { return num_units("seconds"); } + +// wrapper methods to calculate units in a supertimerange + + static array(TimeRange) get_units(string unit,int ... range) + { + int from=0,to=0x7fffffff,pos=0; + array res=({}); + TimeRange last=0; + string ums=unit[..strlen(unit)-2]; // no 's' + + if (sizeof(range)==2) + [from,to]=range; + else if (sizeof(range)==1) + error("Illegal numbers of arguments to "+unit+"()\n"); + + foreach (parts,TimeRange part) + { + if (pos>=from) + { + if (pos>to) break; + array tmp=part[unit](from-pos,to-pos); + pos+=sizeof(tmp); + if (tmp[0]==last) tmp=tmp[1..]; + res+=tmp; + if (sizeof(tmp)) last=tmp[-1]; + } + else + { + int n=part["number_of_"+unit](); + TimeRange l=part[ums](); + if (l==last) n--; + if (n+pos>from) + res=part[unit](from-pos,to-pos); + pos+=n; + last=l; + } + } + return res; + } + + static int num_units(string unit) + { + int pos=0; + TimeRange last=0; + string ums=unit[..strlen(unit)-2]; // no 's' + + foreach (parts,TimeRange part) + { + int n=part["number_of_"+unit](); + TimeRange l=part[ums](); + if (l==last) n--; + pos+=n; + last=l; + } + return pos; + } + + static TimeRange get_unit(string unit,int n) + { + array(TimeRange) res=get_units(unit,n,n); + if (sizeof(res)==1) return res[0]; + error("not in range ("+unit+" 0..%d exist)\n", + num_units(unit)-1); + } + +#define RBASE parts[0] + + string format_ext_ymd(); + string format_iso_ymd(); + string format_ymd(); + string format_ymd_short(); + string format_ymd_xshort(); + string format_iso_week(); + string format_iso_week_short(); + string format_week(); + string format_week_short(); + string format_month(); + string format_month_short(); + + string format_iso_time() { return RBASE->format_iso_time(); } + string format_ext_time() { return RBASE->format_ext_time(); } + string format_time() { return RBASE->format_time(); } + string format_time_short() { return RBASE->format_time_short(); } + string format_time_xshort() { return RBASE->format_time_xshort(); } + string format_mtime() { return RBASE->format_mtime(); } + string format_xtime() { return RBASE->format_xtime(); } + string format_ctime() { return RBASE->format_ctime(); } + string format_http() { return RBASE->format_http(); } + string format_tod() { return RBASE->format_tod(); } + string format_todz() { return RBASE->format_todz(); } + string format_todz_iso() { return RBASE->format_todz_iso(); } + string format_mod() { return RBASE->format_mod(); } + string format_xtod() { return RBASE->format_xtod(); } + + int hour_no() { return RBASE->hour_no(); } + int minute_no() { return RBASE->minute_no(); } + int second_no() { return RBASE->second_no(); } + +#undef RBASE + +// count parts elapsed + string format_elapsed() + { + TimeRange z=parts[0]; + foreach (parts,TimeRange y) z+=y; + return parts[0]->distance(z)->format_elapsed(); + } +} + +//------------------------------------------------------------------------ +//! class Hour +//------------------------------------------------------------------------ + +function(mixed...:cHour) Hour=cHour; // inheritance purposes +class cHour +{ + constant is_hour=1; + +//! inherits TimeofDay + + inherit TimeofDay; + + void create_unixtime(int unixtime,int _len) + { + int z; + ux=unixtime; + len=_len; + if (base==0) make_base(); + ls=ux-(z=base->unix_time()); + ls-=ls%3600; + ux=z+ls; + } + + void create_unixtime_default(int unixtime) + { + create_unixtime(unixtime,3600); + } + + static void create_now() + { + create_unixtime(time(),3600); + } + + static void create_julian_day(int|float jd) + { + ::create_julian_day(jd); + len=3600; + } + + static void convert_from(TimeRange other) + { + ::convert_from(other); + len-=len%3600; + } + + TimeofDay _move(int n,int m) + { + if (m==0 || n==0) return this_object(); + if (m%3600) + return Second("timeofday",rules,ux,len)->_move(n,m); + return Hour("timeofday",rules,ux+n*m,len)->autopromote(); + } + + + string _sprintf(int t) + { + if (catch { + switch (t) + { + case 'O': + if (!base) make_base(); + if (len!=3600) + return sprintf("Hour(%s)", + nice_print_period()); + return sprintf("Hour(%s %s)", + base->nice_print(), + nice_print()); + default: + return 0; + } + }) + return "error"; + } + + string nice_print() + { + if (ls==CALUNKNOWN) make_local(); + return sprintf("%d:00 %s",ls/3600,tzname()); + } +} + +//------------------------------------------------------------------------ +//! class Minute +//------------------------------------------------------------------------ + +function(mixed...:cMinute) Minute=cMinute; // inheritance purposes +class cMinute +{ + constant is_minute=1; + +//! inherits TimeofDay + + inherit TimeofDay; + + void create_unixtime(int unixtime,int _len) + { + int z; + ux=unixtime; + len=_len; + if (base==0) make_base(); + ls=ux-(z=base->unix_time()); + ls-=ls%60; + ux=z+ls; + } + + void create_unixtime_default(int unixtime) + { + create_unixtime(unixtime,60); + } + + static void create_now() + { + create_unixtime(time()/60*60,60); + } + + TimeofDay autopromote() + { + if (ls==CALUNKNOWN) make_local(); + if (!(ls%3600) && !(len%3600)) + return Hour("timeofday_sd",rules,ux,len,ls,utco)->autopromote(); + return ::autopromote(); + } + + static void convert_from(TimeRange other) + { + ::convert_from(other); + len-=len%60; + } + + TimeofDay _move(int n,int m) + { + if (m==0 || n==0) return this_object(); + if (m%60) return Second("timeofday",rules,ux,len)->_move(n,m); + return Minute("timeofday",rules,ux+n*m,len)->autopromote(); + } + + string _sprintf(int t) + { + switch (t) + { + case 'O': + if (!base) make_base(); + if (len!=60) + return sprintf("Minute(%s)", + nice_print_period()); + return sprintf("Minute(%s %s)", + base->nice_print(), + nice_print()); + default: + return 0; + } + } + + string nice_print() + { + if (ls==CALUNKNOWN) make_local(); + return sprintf("%d:%02d %s",ls/3600,(ls/60)%60,tzname()); + } +} + +//------------------------------------------------------------------------ +//! class Second +//------------------------------------------------------------------------ + +function(mixed...:cSecond) Second=cSecond; // inheritance purposes +class cSecond +{ + constant is_second=1; + +//! inherits TimeofDay + + inherit TimeofDay; + + void create_unixtime_default(int unixtime) + { + create_unixtime(unixtime,1); + } + + static void create_now() + { + create_unixtime(time(),1); + } + + static void create_julian_day(int|float jd) + { + ::create_julian_day(jd); + len=1; + } + + TimeofDay autopromote() + { + if (ls==CALUNKNOWN) make_local(); + if (!(ls%60) && !(len%60)) + return Minute("timeofday",rules,ux,len)->autopromote(); + return ::autopromote(); + } + + TimeofDay _move(int n,int m) + { + if (m==0 || n==0) return this_object(); + return Second("timeofday",rules,ux+n*m,len)->autopromote(); + } + + string _sprintf(int t) + { + switch (t) + { + case 'O': + if (len!=1) + return sprintf("Second(%s)", + nice_print_period()); + if (!base) make_base(); + return sprintf("Second(%s %s)", + base->nice_print(), + nice_print()); + default: + return 0; + } + } + + string nice_print() + { + if (ls==CALUNKNOWN) make_local(); + return sprintf("%d:%02d:%02d %s",ls/3600,ls/60%60,ls%60,tzname()); + } + +// backwards compatible with calendar I + string iso_name() + { return this_object()->format_ymd()+" T"+format_tod(); } + string iso_short_name() + { return this_object()->format_ymd_short()+" T"+(format_tod()-":"); } +} + +//------------------------------------------------------------------------ +//! class Fraction +//! A Fraction is a part of a second, and/or a time period +//! with higher resolution then a second. +//! +//! It contains everything that is possible to do with a +//! <ref>Second</ref>, and also some methods of grabbing +//! the time period with higher resolution. +//! +//! note: +//! Internally, the fraction time period is measured in +//! nanoseconds. A shorter or more precise time period then +//! in nanoseconds is not possible within the current Fraction class. +//! +//! inherits TimeofDay +//------------------------------------------------------------------------ + +function(mixed...:cFraction) Fraction=cFraction; +class cFraction +{ + inherit cSecond; + + constant is_timeofday_f=1; + constant is_fraction=1; + + int ns; // nanoseconds add to s + int len_ns; // nanoseconds length + int len_s; // seconds length + +//! method void create() +//! method void create("unixtime",int|float unixtime) +//! method void create("unixtime",int|float unixtime,int|float len) +//! It is possible to create a Fraction in two ways, +//! either "now" with no arguments or +//! from a unix time (as from <tt>time(2)</tt>). +//! +//! If created from unix time, both the start of the period +//! and the size of the period can be given in floats, +//! both representing seconds. Note that the default +//! float precision in pike is rather low (same as 'float' in C, +//! the 32 bit floating point precision, normally about 7 digits), +//! so beware that the resolution might bite you. (Internally +//! in a Fraction, the representation is an integer.) +//! +//! If created without explicit length, the fraction will always be +//! of zero length. + + void create(mixed ...args) + { + if (!sizeof(args)) + { + rules=default_rules; + create_now(); + return; + } + else if (args[0]=="timeofday_f") + { + rules=[object(Ruleset)]args[1]; + ux=[int]args[2]; + ns=[int]args[3]; + len_s=[int]args[4]; + len_ns=[int]args[5]; + ls=CALUNKNOWN; + + if (ns<0) + error("Can't create negative ns: %O\n",this_object()); + + if (!rules) error("no rules\n"); + + if (len_ns>=inano) len_s+=(len_ns/inano),len_ns%=inano; + if (ns>=inano) ux+=(ns/inano),ns%=inano; + len=len_s+(ns+len_ns+inano-1)/inano; + + if (ns<0) + error("Can't create negative ns: %O\n",this_object()); + + return; + } + else if (intp(args[0]) && sizeof(args)==1) + { + rules=default_rules; + create_unixtime(args[0]); + return; + } + else switch (args[0]) + { + case "unix": + rules=default_rules; + create_unixtime(@args[1..]); + return; + case "julian": + rules=default_rules; + create_julian_day(args[1]); + return; + case "unix_r": + rules=args[-1]; + create_unixtime(@args[..sizeof(args)-2]); + return; + case "julian_r": + rules=args[2]; + create_julian_day(args[1]); + return; + } + rules=default_rules; + if (create_backtry(@args)) return; + error("Fraction: illegal argument(s) %O,%O,%O,...\n", + @args,0,0,0); + } + + int create_backtry(mixed ...args) + { + if (sizeof(args)>1 && objectp(args[0]) && args[0]->is_day) + { + base=args[0]; + rules=base->ruleset(); + args=args[1..]; + } + ls=CALUNKNOWN; + if (base) + { + switch (sizeof(args)) + { + case 4: + if (intp(args[0]) && intp(args[1]) && intp(args[2]) && + intp(args[3])) + { + ux=base->second(@args[..2])->unix_time(); + ns=args[3]; + return 1; + } + break; + case 3: + if (intp(args[0]) && intp(args[1]) && floatp(args[2])) + { + ux=base->second(args[0],args[1],(int)args[2])->unix_time(); + ns=(int)(inano*(args[3]-(int)args[3])); + return 1; + } + break; + } + } + return ::create_backtry(@args); + } + + static void create_now() + { + ux=time(); + ns=(int)(inano*time(ux)); + if (ns>=inano) ux+=(ns/inano),ns%=inano; + len=len_s=len_ns=0; + ls=CALUNKNOWN; + } + + int unix_time() { return ux; } + float f_unix_time() { return ux+ns*(1.0/inano); } + + static void create_unixtime(int|float unixtime, + void|int|float _len) + { + ux=(int)unixtime; + ns=(int)(inano*(unixtime-(int)unixtime)); + len_s=(int)_len; + len_ns=(int)(inano*(_len-(int)_len)); + ls=CALUNKNOWN; + } + + static void create_unixtime_default(int|float unixtime) + { + return create_unixtime(unixtime); + } + + float julian_day() + { + return 2440588+(ux+ns*(1.0/inano))*(1/86400.0)+0.5; + } + + static void create_julian_day(int|float jd) + { +// 1970-01-01 is julian day 2440588 + jd-=2440588; + float fjd=((jd-(int)jd)+0.5)*86400; + ux=((int)jd)*86400+(int)(fjd); + ns=(int)(inano*(fjd-(int)fjd)); + + ls=CALUNKNOWN; + } + + string _sprintf(int t) + { + switch (t) + { + case 'O': + if (!base) make_base(); + if (len_ns || len_s) + return sprintf("Fraction(%s)", + nice_print_period()); + return sprintf("Fraction(%s %s)", + base->nice_print(), + nice_print()); + default: + return 0; + } + } + + int __hash() { return ux; } + + string nice_print() + { + if (ls==CALUNKNOWN) make_local(); + return sprintf("%d:%02d:%02d.%06d %s", + ls/3600,ls/60%60,ls%60,ns/1000,tzname()); + } + + TimeofDay autopromote() + { + if (!ns && !len_ns) + return Second("timeofday",rules,ux,len_s)->autopromote(); + + return this_object(); + } + + TimeofDay _move(int n,int z_s,void|int z_ns) + { + if ((z_s==0 && z_ns==0) || n==0) return autopromote(); + int nns=ns+n*z_ns; + int nux=ux+n*z_s; + if (nns<0 || nns>=inano) nux+=nns/inano,nns%=inano; + return Fraction("timeofday_f",rules,nux,nns,len_s,len_ns) + ->autopromote(); + } + + TimeRange _add(int n,TimeRange step) + { + if (step->is_timeofday_f) + return _move(n,step->len_s,step->len_ns); + return ::_add(n,step); + } + + static void convert_from(TimeRange other) + { + ::convert_from(other); + if (other->is_timeofday_f) + { + ns=other->ns; + len_s=other->len_s; + len_ns=other->len_ns; + } + } + + static TimeRange _set_size(int n,TimeRange t) + { + if (t->is_timeofday_f) + return Fraction("timeofday_f",rules,ux,ns, + n*t->len_s,n*t->len_ns) + ->autopromote(); + + if (t->is_timeofday) + return Fraction("timeofday_f",rules,ux,ns,n*t->len,0) + ->autopromote(); + + return distance(add(n,t)); + } + + TimeRange distance(TimeRange to) + { + // s is 0 in an object that doesn't have s + + int s1=ux; + int s2; + + if (to->is_timeofday) + s2=to->ux; + else + s2=to->unix_time(); + +// ns is 0 in an object that doesn't have ns + + if (s2<s1 || + (s2==s1 && to->ns<ns)) + error("Negative distance %O .. %O\n", this_object(),to); + + return + Fraction("timeofday_f",rules,ux,ns,s2-s1-1,to->ns-ns+inano) + ->autopromote(); + } + + TimeRange range(TimeRange to) + { + return distance(to->end()); + } + + array(int(-1..1)) _compare(TimeRange with) + { +#define CMP2(AS,ANS,BS,BNS) \ + (((AS)<(BS))?-1: \ + ((AS)>(BS))?1: \ + ((ANS)<(BNS))?-1: \ + ((ANS)>(BNS))?1:0) + + if (with->is_timeofday_f) + return ({ CMP2(ux,ns,with->ux,with->ns), + CMP2(ux,ns,with->ux+with->len_s,with->ns+with->len_ns), + CMP2(ux+len_s,ns+len_ns,with->ux,with->ns), + CMP2(ux+len_s,ns+len_ns,with->ux+with->len_s, + with->ns+with->len_ns) }); + else if (with->is_timeofday) + return ({ CMP2(ux,ns,with->ux,0), + CMP2(ux,ns,with->ux+with->len,0), + CMP2(ux+len_s,ns+len_ns,with->ux,0), + CMP2(ux+len_s,ns+len_ns,with->ux+with->len, 0) }); + return ::_compare(with); + } + + TimeofDay beginning() + { + if (len_s==0.0 && len_ns==0.0) return this_object(); + return Fraction("timeofday_f",rules,ux,ns,0,0) + ->autopromote(); + } + + TimeofDay end() + { + if (len_s==0 && len_ns==0) return this_object(); + object q=Fraction("timeofday_f",rules,ux+len_s,ns+len_ns,0,0) + ->autopromote(); + return q; + } + + TimeRange set_size_seconds(int seconds) + { + if (seconds<0) error("Negative size\n"); + return Fraction("timeofday_f",rules,ux,ns,seconds,0) + ->autopromote(); + } + + TimeRange set_size_ns(int nanoseconds) + { + if (nanoseconds<0) error("Negative size\n"); + return Fraction("timeofday_f",rules,ux,ns,0,nanoseconds) + ->autopromote(); + } + + + TimeRange move_seconds(int seconds) + { + return _move(1,seconds); + } + + TimeRange move_ns(int nanoseconds) + { + return _move(1,0,nanoseconds); + } + + int number_of_seconds() + { + if (len_ns || ns) return len_s+1; + else return len_s||1; + } + + float number_of_fractions() + { + return len_s+1e-9*len_ns; + } + + array(cFraction) fractions(int|float ...range) + { + float from,to,n=number_of_fractions(); + if (sizeof(range)==2) + from=(float)range[0],to=(float)range[1]; + else if (sizeof(range)==0) + from=0.0,to=n; + else + error("Illegal arguments\n"); + if (from<0.0) from=0.0; + if (to>n) to=n; + if (to<from) + return ({}); + + if (from==0.0 && to==n) return ({this_object()}); + + to-=from; + return ({Fraction("timeofday_f",rules, + ux+(int)from,ns+(int)(inano*(from-(int)from)), + (int)to,(int)(inano*(to-(int)to)))}); + } + + mapping datetime() + { + return ::datetime()|(["fraction":ns*(1.0/inano)]); + } + + string format_xtod() + { + if (ls==CALUNKNOWN) make_local(); + return sprintf("%02d:%02d:%02d.%06d", + ls/3600, + (ls/60)%60, + ls%60, + ns/1000); + } + + string format_elapsed() + { + int x; + if ( (x=(this_object()/Day)) ) + { + object left=this_object()->add(x,Day)->range(this_object()->end()); + return sprintf("%dd%d:%02d:%02d.%03d", + x,left->len_s/3600, + (left->len_s/60)%60, + left->len_s%60, + left->len_ns/1000000); + } + if (len_s>=3600) + return sprintf("%d:%02d:%02d.%03d", + len_s/3600,(len_s/60)%60, + len_s%60,len_ns/1000000); + if (len_s>=60) + return sprintf("%d:%02d.%03d", + len_s/60,len_s%60,len_ns/1000000); + if (len_s || len_ns>inano/1000) + return sprintf("%d.%06d", + len_s,len_ns/1000); + return sprintf("0.%09d",len_ns); + } +} + +//------------------------------------------------------------------------ +// global convinience functions +//------------------------------------------------------------------------ + +//! method TimeofDay now() +//! Give the zero-length time period of the +//! current time. + +TimeofDay now() +{ + return Fraction(); +} + +//! method Calendar set_timezone(Timezone tz) +//! method Calendar set_timezone(string|Timezone tz) +//! method TimeZone timezone() +//! Set or get the current timezone (including dst) rule. +//! <ref>set_timezone</ref> returns a new calendar object, +//! as the called calendar but with another set of rules. +//! +//! Example: +//! <pre> +//! > Calendar.now(); +//! Result: Fraction(Fri 2 Jun 2000 18:03:22.010300 CET) +//! > Calendar.set_timezone(Calendar.Timezone.UTC)->now(); +//! Result: Fraction(Fri 2 Jun 2000 16:03:02.323912 UTC) +//! </pre> + +this_program set_timezone(string|Ruleset.Timezone tz) +{ + return set_ruleset(default_rules->set_timezone(tz)); +} + +Ruleset.Timezone timezone() +{ + return default_rules->timezone; +} + +this_program set_language(string|Ruleset.Language lang) +{ + return set_ruleset(default_rules->set_language(lang)); +} + +Ruleset.Language language() +{ + return default_rules->language; +} + +//! method Calendar set_ruleset(Ruleset r) +//! method Ruleset ruleset() +//! Set or read the ruleset for the calendar. +//! <ref>set_ruleset</ref> returns a new calendar object, +//! but with the new ruleset. + +this_program set_ruleset(Ruleset r) +{ + this_program c=object_program(this_object())(); + c->default_rules=r; + return c; +} + +Ruleset ruleset() +{ + return default_rules; +} diff --git a/lib/modules/Calendar.pmod/TimeRanges.pmod b/lib/modules/Calendar.pmod/TimeRanges.pmod new file mode 100644 index 0000000000000000000000000000000000000000..f6593c2009d759eea53a51f0642641366bd979eb --- /dev/null +++ b/lib/modules/Calendar.pmod/TimeRanges.pmod @@ -0,0 +1,1222 @@ +//! module Calendar + +#define zero int(0..0) + +import "."; +#include "localization.h" + +constant CALUNKNOWN=-1000; // not calculated yet + +program SuperTimeRange=cSuperTimeRange; + +string calendar_name() { return "TimeRanges"; } + +object calendar_object=this_object(); + +string _sprintf(int t) { return (t=='O')?calendar_name():0; } + +Ruleset default_rules=Ruleset() + ->set_timezone(default_timezone) + ->set_language(default_language); + +//------------------------------------------------------------------------ +//! class TimeRange +//! This is the base class for any time measurement +//! and calendrar information. It defines all the +//! things you can do with a time range, any time +//! period. +//! +//! A TimeRange doubles as both a fixed period in +//! time, and an amount of time. For instance, +//! a week plus a day moves the week-period one day +//! ahead (unaligning it with the week period, +//! and thereby reducing it to just 7 days), +//! no matter when in time the actual day were. +//! +//------------------------------------------------------------------------ + +class TimeRange +{ + constant is_timerange=1; + + Ruleset rules; + +//! method void create("unix",int unixtime) +//! method void create("unix",int unixtime,int seconds_len) +//! Create the timerange from unix time (as given by +//! <tt>time(2)</tt>), with eventually the size of +//! the time range in the same unit, seconds. +//! +//! method void create("julian",int|float julian_day) +//! Create the timerange from a julian day, the +//! standardized method of counting days. If +//! the timerange is more then a day, it will +//! at least enclose the day. +//! +//! method void create(TimeRange from) +//! Create the timerange from another timerange. +//! +//! This is useful when converting objects from +//! one calendar to another. Note that the ruleset will be +//! transferred to the new object, so this method +//! can't be used to convert between timezones +//! or languges - use <ref>set_timezone</ref>, +//! <ref>set_language</ref> or <ref>set_ruleset</ref> +//! to achieve this. +//! +//! note: +//! The size of the new object may be inexact; +//! a Month object can't comprehend seconds, for instance. + + static void create_unixtime(int unixtime,int len); + static void create_unixtime_default(int unixtime); + static void create_julian_day(int jd); + + void create(mixed ...args) + { + if (sizeof(args)) switch (args[0]) + { + case "unix": + if (sizeof(args)==2) + create_unixtime_default(args[1]); + else if (sizeof(args)>2) + create_unixtime(@args[1..]); + else break; + return; + case "unix_r": + if (sizeof(args)==3) + { + rules=args[2]; + create_unixtime_default(args[1]); + } + else if (sizeof(args)>2) + { + rules=args[3]; + create_unixtime(args[1],args[2]); + } + else break; + return; + case "julian": + if (sizeof(args)==2) + { + create_julian_day(args[1]); + return; + } + break; + case "julian_r": + if (sizeof(args)==3) + { + rules=args[2]; + create_julian_day(args[1]); + return; + } + break; + + default: + if (objectp(args[0]) && args[0]->is_timerange) + { + convert_from([object(TimeRange)]args[0]); + return; + } + break; + } + + error("%O.%O: Illegal parameters %O,%O,%O...\n", + function_object(object_program(this_object())), + object_program(this_object()), + @args,0,0,0); + } + + static void convert_from(TimeRange other) + { +// inheriting class must take care of size + if (other->julian_day) + { + int|float jd=other->julian_day(); + if (floatp(jd) && other->unix_time) + create("unix_r",other->unix_time(),other->ruleset()); + else + create("julian_r",jd,other->ruleset()); + } + else if (other->unix_time) + create("unix_r",other->unix_time(),other->ruleset()); + else + error("Can't convert %O->%s.%O\n",other, + calendar_name(), + object_program(this_object())); + } + +//! method TimeRange set_size(TimeRange size) +//! method TimeRange set_size(int n,TimeRange size) +//! Gives back a new (or the same, if the size matches) +//! timerange with the new size. +//! If <i>n</i> are given, the resulting size +//! will be <i>n</i> amounts of the given size. +//! note: +//! A negative size is not permitted; a zero one are. + +// virtual + static TimeRange _set_size(int n,TimeRange x); + + TimeRange set_size(function|TimeRange|int(0..0x7fffffff) a, + void|function|TimeRange b) + { + function|object(TimeRange) x; + int(0..0x7fffffff) n; + if (!b) + if (intp(a)) + x=[function|object(TimeRange)]this_object(), + n=[int(0..0x7fffffff)]a; + else + x=a,n=1; + else + x=b,n=a; + if (functionp(x)) x=promote_program(x); + if (n<0) + error("Negative size (%d)\n",n); + return _set_size(n,[object(TimeRange)]x); + } + +//! method TimeRange add(int n,void|TimeRange step) +//! calculates the (promoted) time period n steps away; +//! if no step is given, the step's length is of the +//! same length as the called time period. +//! +//! It is not recommended to loop by adding the increment +//! time period to a shorter period; this can cause faults, +//! if the shorter time period doesn't exist in the incremented +//! period. (Like week 53, day 31 of a month or the leap day of a year.) +//! +//! Recommended use are like this: +//! <pre> +//! // loop over the 5th of the next 10 months +//! TimeRange month=Month()+1; +//! TimeRange orig_day=month()->day(5); +//! for (int i=0; i<10; i++) +//! { +//! month++; +//! TimeRange day=month->place(orig_day); +//! <i>...use day...</i> +//! } +//! </pre> + +// virtual + static this_program _add(int n,this_program step); + + this_program add(function|this_program|int a, + void|function|this_program b) + { + function|object(this_program) x; + int n; + if (!b) + if (intp(a)) + x=[function|object(this_program)]this_object(), + n=[int]a; + else + x=a,n=1; + else + x=b,n=a; + if (functionp(x)) x=promote_program(x); + return _add(n,[object(this_program)]x); + } + +//! method TimeRange place(TimeRange this) +//! method TimeRange place(TimeRange this,int(0..1) force) +//! This will place the given timerange in this timerange, +//! for instance, day 37 in the year - +//! <tt>Year(1934)->place(Day(1948 d37)) => Day(1934 d37)</tt>. +//! +//! note: +//! The rules how to place things in different timeranges +//! can be somewhat 'dwim'. + +// virtual + TimeRange place(TimeRange what,void|int force); + +//! method TimeRange `+(int n) +//! method TimeRange `+(TimeRange offset) +//! method TimeRange `-(int m) +//! method TimeRange `-(TimeRange x) +//! This calculates the (promoted) time period +//! either n step away or with a given offset. +//! These functions does use <ref>add</ref> to really +//! do the job: +//! <pre> +//! t+n t->add(n) t is a time period +//! t-n t->add(-n) offset is a time period +//! t+offset t->add(1,offset) n is an integer +//! t-offset t->add(-1,offset) +//! n+t t->add(n) +//! n-t illegal +//! offset+t offset->add(1,t) | note this! +//! offset-t offset->add(-1,t) | +//! </pre> +//! +//! Mathematic rules: +//! <pre> +//! x+(t-x) == t x is an integer or a time period +//! (x+t)-x == t t is a time period +//! (t+x)-x == t +//! o-(o-t) == t o is a time period +//! t++ == t+1 +//! t-- == t-1 +//! </pre> +//! +//! note: +//! a-b does not give the distance between the start of a and b. +//! Use the <ref>distance</ref>() function to calculate that. +//! +//! The integer used to `+, `- and add are the <i>number</i> +//! of steps the motion will be. It does <i>never</i> represent +//! any <i>fixed</i> amount of time, like seconds or days. + + TimeRange `+(program|this_program|int n) + { + if (objectp(n)) return add(1,n); + return add(n); + } + + TimeRange ``+(int n) + { + return add(n); + } + + TimeRange `-(TimeRange|program|int n) + { + if (objectp(n)) return add(-1,n); + return add(-n); + } + +//! method TimeRange `*(int n) +//! This changes the amount of time in +//! the time period. <tt>t*17</tt> is +//! the same as doing <tt>t-><ref>set_size</ref>(t,17)</tt>. + + function ``* = `*; + TimeRange `*(int n) + { + return set_size(n,this_object()); + } + +//! method array(TimeRange) `/(int n) +//! method array(TimeRange) split(int n) +//! This divides the called timerange into +//! n pieces. The returned timerange type +//! is not neccesarily of the same type as the called one. +//! +//! known bugs: +//! These are currently not defined for +//! <ref to=SuperTimeRange>supertimeranges</ref>. + +//! method int `/(TimeRange with) +//! method int how_many(TimeRange with) +//! This calculates how many instances of the given +//! timerange has passed during the called timerange. +//! +//! For instance, to figure out your age, +//! create the timerange of your lifespan, and divide +//! with the instance of a <ref to=YMD.Year>Year</ref>. + +// virtual + array(TimeRange) split(int n); + + int how_many(function|TimeRange with) + { + if (functionp(with)) with=promote_program(with); +// default method; not optimized - guessing + + TimeRange start=beginning(); + TimeRange end=end(); + +// find low and high 2^n + int nn=16; + int low,high; + + TimeRange t=start+with*nn; + if (t==end) return nn; // gotcha (luck) + if (t>end) // scan less + { + for (;;) + { + nn>>=1; + t=start+with*nn; + if (t==end) return nn; // gotcha (luck) + if (t<end) // ok, we're limited + { + low=nn; + high=nn*2-1; + break; + } + if (nn==1) return 0; // can't be less + } + } + else + { + // sanity check + TimeRange q=start+with*(nn+1); + if (q==t) error("Result is infinite - argument is zero range\n"); + for (;;) + { + nn<<=1; + t=start+with*nn; + if (t==end) return nn; // gotcha (luck) + if (t>end) // ok, we're limited + { + low=(nn>>1); + high=nn-1; + break; + } + // loop forever - pike can handle *big* numbers + } + } + + for (;;) + { + nn=(low+high)/2; + + t=start+with*nn; + if (t==end) return nn; + if (t<end) low=nn+1; + else high=nn-1; + + if (low>high) return high; // can't go further + } + } + + array(TimeRange)|int `/(TimeRange|program|int x) + { + if (intp(x)) return split(x); + else return how_many(x); + } + +//! method TimeRange beginning() +//! method TimeRange end() +//! This gives back the zero-sized beginning +//! or end of the called time period. +//! +//! rule: +//! <tt>range(t->beginning(),t->end())==t</tt> + + TimeRange beginning(); + TimeRange end(); + +//! method TimeRange range(TimeRange other) +//! method TimeRange space(TimeRange other) +//! method TimeRange distance(TimeRange other) +//! Derives different time periods in between +//! the called timerange and the parameter timerange. +//! +//! <pre> +//! >- the past the future -< +//! |--called--| |--other--| +//! >------------ range -----------< +//! >--space--< +//! >----- distance -----< +//! </pre> +//! +//! See also: add, TimeRanges.range, TimeRanges.space, TimeRanges.distance + +// virtual + TimeRange distance(TimeRange to); + + TimeRange range(TimeRange with) + { + return distance(with->end()); + } + + TimeRange space(TimeRange to) + { + return end()->distance(to->beginning()); + } + + +//! method int(0..1) strictly_preceeds(TimeRange what); +//! method int(0..1) preceeds(TimeRange what); +//! method int(0..1) is_previous_to(TimeRange what); +//! method int(0..1) overlaps(TimeRange what); +//! method int(0..1) contains(TimeRange what); +//! method int(0..1) equals(TimeRange what); +//! method int(0..1) is_next_to(TimeRange what); +//! method int(0..1) succeeds(TimeRange what); +//! method int(0..1) strictly_succeeds(TimeRange what); +//! These methods exists to compare two periods +//! of time on the timeline. +//! +//! <pre> +//! case predicates +//! +//! <-- past future -> +//! +//! |----A----| A strictly preceeds B, +//! |----B----| A preceeds B +//! +//! |----A----| A strictly preceeds B, A preceeds B, +//! |----B----| A is previous to B, A touches B +//! +//! |----A----| A preceeds B, +//! |----B----| A overlaps B, A touches B +//! +//! |-------A-------| A preceeds B, A ends with B +//! |----B----| A overlaps B, A contains B, A touches B, +//! +//! |-------A-------| A preceeds B, A succeeds B, +//! |---B---| A overlaps B, A contains B, A touches B +//! +//! |----A----| A overlaps B, A touches B +//! |----B----| A equals B, A starts with B, A ends with B +//! +//! |-------A-------| A succeeds B, A starts with B +//! |----B----| A overlaps B, A contains B, A touches B +//! +//! |----A----| A succeeds B, +//! |----B----| A overlaps B, A touches B +//! +//! |----A----| A strictly succeeds B, A succeeds B +//! |----B----| A is next to B, A touches B +//! +//! |----A----| A strictly succeeds B, +//! |----B----| A succeeds B +//! +//! </pre> + +//- internal method +//- returns [-1,0,1] for comparison between +//- (in order) begin/begin,begin/end,end/begin and end/end + +// virtual, default + array(int(-1..1)) _compare(TimeRange what) + { + if (what->is_supertimerange) + { + array(int(-1..1)) cmp=what->_compare(this_object()); + + return ({-cmp[0], + -cmp[2], + -cmp[1], + -cmp[3]}); + } + error("_compare: incompatible classes %O <-> %O\n", + object_program(this_object()),object_program(what)); + } + + string _describe_compare(array(int(-1..1)) c,TimeRange a,TimeRange b) + { + mapping desc=([-1:"<",0:"=",1:">"]); + return sprintf("%O start %s %O start\n" + "%O start %s %O end\n" + "%O end %s %O start\n" + "%O end %s %O end\n", + a,desc[c[0]],b, + a,desc[c[1]],b, + a,desc[c[2]],b, + a,desc[c[3]],b); + } + +#define BEGIN_BEGIN 0 +#define BEGIN_END 1 +#define END_BEGIN 2 +#define END_END 3 + + int(0..1) strictly_preceeds(TimeRange what) + { + array(int(-1..1)) a=_compare(what); + return a[END_BEGIN]<0; + } + + int(0..1) preceeds(TimeRange what) + { + array(int(-1..1)) a=_compare(what); + return a[BEGIN_BEGIN]<0; + } + + int(0..1) is_previous_to(TimeRange what) + { + array(int(-1..1)) a=_compare(what); + return a[END_BEGIN]==0; + } + + int(0..1) overlaps(TimeRange what) + { + array(int(-1..1)) a=_compare(what); + return (a[END_BEGIN]>0 && a[BEGIN_END]<0); + } + + int(0..1) contains(TimeRange what) + { + array(int(-1..1)) a=_compare(what); + return a[BEGIN_BEGIN]<=0 && a[END_END]>=0; + } + + int(0..1) equals(TimeRange what) + { + if (!objectp(what)) return 0; + array(int(-1..1)) a=_compare(what); + return a[BEGIN_BEGIN]==0 && a[END_END]==0; + } + + int(0..1) is_next_to(TimeRange what) + { + array(int(-1..1)) a=_compare(what); + return a[END_BEGIN]==0; + } + + int(0..1) succeeds(TimeRange what) + { + array(int(-1..1)) a=_compare(what); + return a[END_END]>0; + } + + int(0..1) strictly_succeeds(TimeRange what) + { + array(int(-1..1)) a=_compare(what); + return a[BEGIN_END]>0; + } + + int(0..1) touches(TimeRange what) + { + array(int(-1..1)) a=_compare(what); + return + (a[BEGIN_END]<=0 && a[END_END]>=0) || + (a[END_BEGIN]>=0 && a[BEGIN_BEGIN]<=0); + } + + int (0..1) starts_with(TimeRange what) + { + array(int(-1..1)) a=_compare(what); + return !a[BEGIN_BEGIN]; + } + + int (0..1) ends_with(TimeRange what) + { + array(int(-1..1)) a=_compare(what); + return !a[END_END]; + } + +//! method int(0..1) `<(TimeRange compared_to) +//! method int(0..1) `>(TimeRange compared_to) +//! These operators sorts roughty on the +//! periods place in time. The major use +//! might be to get multiset to work, +//! besides sorting events clearly defined in time. + + int(0..1) `<(TimeRange compared_to) + { + array(int(-1..1)) a=_compare(compared_to); + if (a[0]<0) return 1; + if (a[0]>0) return 0; + if (a[3]<0) return 1; + return 0; + } + + int(0..1) `>(TimeRange compared_to) + { + array(int(-1..1)) a=_compare(compared_to); + if (a[0]>0) return 1; + if (a[0]<0) return 0; + if (a[3]>0) return 1; + return 0; + } + +//! method int(0..1) `==(TimeRange compared_to) +//! method int(0..1) _equal(TimeRange compared_to) +//! These two overloads the operator <tt>`==</tt> and +//! the result of the <tt>equal</tt> function. +//! +//! a<tt>==</tt>b is considered true if the two +//! timeranges are of the same type, have the same rules +//! (language, timezone, etc) and are the same timerange. +//! +//! <tt>equal(</tt>a<tt>,</tt>b<tt>)</tt> are considered +//! true if a and b are the same timerange, exactly the same +//! as the <ref>equals</ref> method. +//! +//! The <tt>__hash</tt> method is also present, +//! to make timeranges possible to use as keys in mappings. +//! +//! known bugs: +//! _equal is not currently possible to overload, +//! due to wierd bugs, so equal uses `== for now. + + int(0..1) `==(TimeRange what) + { + return object_program(what)==object_program(this_object()) && + what->ruleset()==ruleset() && + equals(what); + } + + int __hash(); + +// int(0..1) _equal(TimeRange what) +// { +// return equals(what); +// } + +//! method TimeRange `&(TimeRange with) +//! Gives the cut on the called time period +//! with another time period. The result is +//! zero if the two periods doesn't overlap. +//! <pre> +//! >- the past the future -< +//! |-------called-------| +//! |-------other--------| +//! >----- cut -----< +//! </pre> + + function ``& = `&; + TimeRange|zero `&(TimeRange with, mixed ...extra) + { + if (with->is_nulltimerange) + return with; + array(int(-1..1)) a=_compare(with); + if (a[END_BEGIN]<0 || a[BEGIN_END]>0) + return nulltimerange; // no overlap, no extra + + if (with->is_supertimerange) + return predef::`&(with,this_object(),@extra); // let it handle that... + + TimeRange from,to; + +// from the last beginning + if (a[BEGIN_BEGIN]>0) from=beginning(); else from=with->beginning(); + +// to the first end + if (a[END_END]<0) to=end(); else to=with->end(); + +// compute + TimeRange res=from->distance(to); + if (sizeof(extra)) return predef::`&(res,@extra); + return res; + } + +//! method TimeRange `|(TimeRange with) +//! Gives the union on the called time period +//! and another time period. +//! <pre> +//! >- the past the future -< +//! |-------called-------| +//! |-------other--------| +//! <----------union----------> +//! </pre> + + function ``| = `|; + TimeRange `|(TimeRange with,mixed ...extra) + { + if (with->is_nulltimerange) + return sizeof(extra)?`|(@extra):this_object(); + array(int(-1..1)) a=_compare(with); + TimeRange from,to; + + if (a[END_BEGIN]<0 || a[BEGIN_END]>0) + from=SuperTimeRange( sort(({this_object(),with})) ); // no overlap + else + { + if (with->is_supertimerange) // let it handle that... + return predef::`|(with,this_object(),@extra); + + // from the first beginning + if (a[BEGIN_BEGIN]<0) from=this_object(); else from=with; + + // to the last end + if (a[END_END]>0) to=this_object(); else to=with; + // compute + from=from->range(to); + } + if (sizeof(extra)) return predef::`|(from,@extra); + return from; + } + +//! method TimeRange `^(TimeRange with) +//! Gives the exclusive-or on the called time period +//! and another time period, ie the union without +//! the cut. The result is zero if the +//! two periods were the same. +//! <pre> +//! >- the past the future -< +//! |-------called-------| +//! |-------other--------| +//! <----| |----> - exclusive or +//! </pre> + + function ``^ = `^; + TimeRange `^(TimeRange with,mixed ... extra) + { + if (with->is_supertimerange) + return `^(with,this_object(),@extra); // let it handle that... + if (with->is_nulltimerange) + return sizeof(extra)?`^(@extra):this_object(); + + TimeRange res; + + array(int(-1..1)) a=_compare(with); + +// write(_describe_compare(a,this_object(),with)); + + TimeRange first,second; + if (a[END_BEGIN]<0 || a[BEGIN_END]>0) + res=SuperTimeRange( sort(({this_object(),with})) ); // no overlap + else if (a[BEGIN_END]==0 || a[END_BEGIN]==0) // bordering + if (a[BEGIN_BEGIN]<0) + res=range(with); // A precedes B + else + res=with->range(this_object()); // B precedes A + else if (a[BEGIN_BEGIN]==0 && a[END_END]==0) + return sizeof(extra)?predef::`^(nulltimerange,@extra):nulltimerange; + else + { + // from the first beginning to the second beginning + if (a[BEGIN_BEGIN]<0) + first=distance(with); + else + first=with->distance(this_object()); + +// and from the first end to the last end + if (a[END_END]<0) + second=end()->range(with); + else + second=with->end()->range(this_object()); + res=first|second; + } + // done + if (sizeof(extra)) return `^(res,@extra); + return res; + } + +//! method TimeRange subtract(TimeRange what) +//! This subtracts a period of time from another; +//! <pre> +//! >- the past the future -< +//! |-------called-------| +//! |-------other--------| +//! <----> <- called->subtract(other) +//! +//! |-------called-------| +//! |---third---| +//! <----> <---> <- called->subtract(third) +//! </pre> + + TimeRange subtract(TimeRange what,mixed ... extra) + { + array(int(-1..1)) a=_compare(what); + + if (a[END_BEGIN]<=0 || a[BEGIN_END]>=0) + return sizeof(extra)?subtract(@extra):this_object(); // no overlap + + if (what->is_supertimerange) + { + array res=map(what->parts+extra,subtract)-({nulltimerange}); + switch (sizeof(res)) + { + case 0: return nulltimerange; + case 1: return res[0]; + default: return predef::`&(@res); + } + } + + TimeRange res; + +// write(_describe_compare(a,this_object(),what)); + + if (a[BEGIN_BEGIN]>=0) // it preceeds us + if (a[END_END]<=0) + return nulltimerange; // full overlap + else // half overlap at start + res=what->end()->range(this_object()); + else if (a[END_END]<=0) // it succeeds us + res=distance(what); + else + { +// werror("%O..\n..%O\n%O..\n..%O\n", +// beginning(),what->beginning(), +// what->end(),end()); +// it's inside us + res=predef::`|(distance(what), + what->end()->range(this_object())); + } + if (sizeof(extra)) return res->subtract(@extra); + return res; + } + +//! method TimeRange set_ruleset(Ruleset r) +//! method TimeRange ruleset(Ruleset r) +//! Set or get the current ruleset. +//! note: +//! this may include timezone shanges, +//! and change the time of day. + + TimeRange set_ruleset(Ruleset r); + Ruleset ruleset() + { + return rules; + } + +//! method TimeRange set_timezone(Timezone tz) +//! method TimeRange set_timezone(string tz) +//! method TimeZone timezone() +//! Set or get the current timezone (including dst) rule. +//! +//! note: +//! The time-of-day may very well +//! change when you change timezone. +//! +//! To get the time of day for a specified timezone, +//! select the timezone before getting the time of day: +//! +//! <tt>Year(2003)->...->set_timezone(TimeZone.CET)->...->hour(14)->...</tt> +//! + + TimeRange set_timezone(string|Ruleset.Timezone tz) + { + return set_ruleset(rules->set_timezone(tz)); + } + + Ruleset.Timezone timezone() + { + return rules->timezone; + } + +//! method TimeRange set_language(Language lang) +//! method TimeRange set_language(string lang) +//! method Language language() +//! Set or get the current language rule. + + TimeRange set_language(string|Ruleset.Language lang) + { + return set_ruleset(rules->set_language(lang)); + } + + Ruleset.Language language() + { + return rules->language; + } + +//! method Calendar calendar() +//! Simply gives back the calendar in use, for instance +//! Calendar.ISO or Calendar.Discordian. + + object calendar() + { + return calendar_object; + } +} + +// ---------------------------------------------------------------- + +//! +//! module Calendar +//! class SuperTimeRange +//! This class handles the cases where you have a time +//! period with holes. These can be created by the +//! <tt>^</tt> or <tt>|</tt> operators on time ranges. +//! inherits TimeRange + +class cSuperTimeRange +{ + inherit TimeRange; + + constant is_supertimerange=1; + + array parts; + +//! method void create(array(TimeRange) parts) +//! A SuperTimeRange must have at least two parts, +//! two time ranges. Otherwise, it's either not +//! a time period at all or a normal time period. + + void create(array(TimeRange) _parts) + { + if (sizeof(_parts->is_supertimerange-({0}))) + error("one part is super\n%O\n",_parts); + if (sizeof(_parts)<2) + error("SuperTimeRange: Too few time periods to constructor\n"); + parts=_parts; + } + + TimeRange beginning() + { + return parts[0]->beginning(); + } + + TimeRange end() + { + return parts[-1]->end(); + } + + TimeRange distance(TimeRange to) + { + return beginning()->distance(to); + } + + TimeRange mend_overlap(array parts) + { + switch (sizeof(parts)) + { + case 0: return nulltimerange; + case 1: return parts[0]; + } + array res=({}); + TimeRange last=parts[0]; + foreach (parts[1..],TimeRange part) + { + if (last->strictly_preceeds(part)) + { + res+=({last}); + last=part; + } + else + last=last|part; + } + if (!sizeof(res)) return last; + return SuperTimeRange(res+({last})); + } + + TimeRange `&(TimeRange with,mixed... extra) + { + array r=({}); + foreach (parts,TimeRange part) + { + TimeRange tmp=predef::`&(part,with,@extra); + if (tmp) + if (tmp->is_supertimerange) r+=tmp->parts; + else if (!tmp->is_nulltimerange) r+=({tmp}); + } + switch (sizeof(r)) + { + case 0: return nulltimerange; + case 1: return r[0]; + default: return SuperTimeRange(r); + } + } + + TimeRange `|(TimeRange with,mixed ...extra) + { + TimeRange res; + if (with->is_supertimerange) + res=mend_overlap(sort(with->parts+parts)); + else if (with->is_nulltimerange) + return this_object(); + else + res=mend_overlap(sort( ({with})+parts )); + if (sizeof(extra)) + return predef::`|(res,@extra); + return res; + } + + TimeRange subtract(TimeRange with,mixed ...extra) + { + array r=({}); + foreach (parts,TimeRange part) + r+=({part->subtract(part,with,@extra)}); + return predef::`|(@r); + } + + TimeRange `^(TimeRange with,mixed ...extra) + { +// werror("1 %O\n",with); +// werror("2 %O\n",`|(with)); +// werror("3 %O\n",`&(with)); + TimeRange r=`|(with)->subtract(`&(with)); + if (sizeof(extra)) return predef::`^(r,@extra); + return r; + } + +// == checks if equal + + int `==(TimeRange with,mixed ...extra) + { + if (!with->is_supertimerange) + return 0; // it has to be + if (sizeof(parts)!=sizeof(with->parts)) + return 0; // it has to be + for (int i=0; i<sizeof(parts); i++) + if (parts[i]!=with->parts[i]) return 0; + return sizeof(extra)?predef::`==(with,@extra):1; + } + +// _compare wrapper + array(int(-1..1)) _compare(TimeRange what) + { + array(int(-1..1)) a,b; + a=parts[0]->_compare(what); + b=parts[-1]->_compare(what); + return ({a[0],a[1],b[2],b[3]}); + } + +// `< and `> sort for multiset +// a little bit heavier for super-time-ranges + + int(0..1) `<(TimeRange with) + { + array(int(-1..1)) a=_compare(with); + if (a[0]<0) return 1; + if (a[0]>0) return 0; + if (a[3]<0) return 1; + if (a[3]>0) return 0; + if (!with->is_supertimerange) return 1; // always + if (sizeof(parts)>sizeof(with->parts)) return 1; + if (sizeof(parts)<sizeof(with->parts)) return 0; + for (int i=0; i<sizeof(parts); i++) + if (parts[i]<with->parts[i]) return 1; + return 0; + } + + int(0..1) `>(TimeRange with) + { + array(int(-1..1)) a=_compare(with); + if (a[0]>0) return 1; + if (a[0]<0) return 0; + if (a[3]>0) return 1; + if (a[3]<0) return 0; + if (!with->is_supertimerange) return 0; // always + if (sizeof(parts)<sizeof(with->parts)) return 1; + if (sizeof(parts)>sizeof(with->parts)) return 0; + for (int i=0; i<sizeof(parts); i++) + if (parts[i]>with->parts[i]) return 1; + return 0; + } + + int __hash() + { + return predef::`+(@map(parts,"__hash")); + } + + string _sprintf(int t) + { + switch (t) + { + case 'O': + return "SuperTimeRange("+ + map(parts,"_sprintf",'O')*", "+")"; + } + return 0; + } + + TimeRange set_timezone(string|Timezone tz) + { +// fixme? + return `|(map(parts,"set_timezone",tz)); + } +} + +//! constant TimeRange nulltimerange +//! This represents the null time range, +//! which, to differ from the zero time range +//! (the zero-length time range), isn't placed +//! in time. This is the result of for instance +//! <ref>`&</ref> between two strict non-overlapping +//! timeranges - no time at all. +//! +//! It has a constant, <tt>is_nulltimerange</tt>, which +//! is non-zero. <tt>`!</tt> on this timerange is true. + + +static class NullTimeRange +{ + inherit TimeRange; + + constant is_nulltimerange=1; + +// overload + void create() + { + } + + TimeRange set_size(TimeRange|int(0..0x7fffffff) a,void|TimeRange b) + { + return this_object(); + } + + TimeRange place(TimeRange what,void|int force) + { + return this_object(); + } + + array(TimeRange) split(int n) + { + return allocate(n,this_object()); + } + + TimeRange beginning() { return this_object(); } + TimeRange end() { return this_object(); } + + TimeRange distance(TimeRange to) + { + if (to==this_object()) return this_object(); + error("Can't distance/space/range with the null timerange\n"); + } + + array(int(-1..1)) _compare(TimeRange with) + { + if (with==this_object()) return ({0,0,0,0}); + return ({-1,-1,-1,-1}); + } + + int(0..1) `<(TimeRange with) + { + return !(with==this_object()); + } + + int(0..1) `>(TimeRange with) + { + return 0; + } + + int(0..1) `==(TimeRange with) + { + return with==this_object(); + } + + int(0..1) equals(TimeRange with) + { + return with==this_object(); + } + + TimeRange `&(TimeRange with, mixed ...extra) + { + return predef::`&(with,this_object(),@extra); + } + + TimeRange `|(TimeRange with, mixed ...extra) + { + return predef::`|(with,this_object(),@extra); + } + + TimeRange `^(TimeRange with, mixed ...extra) + { + return predef::`^(with,this_object(),@extra); + } + + this_program subtract(TimeRange with, mixed ...extra) + { + return this_object(); + } + + int(1..1) `!() + { + return 1; + } + + string _sprintf(int t) + { + switch (t) + { + case 'O': return "NullTimeRange"; + default: return 0; + } + } +} + +NullTimeRange nulltimerange=NullTimeRange(); + +// helper functions + +static mapping(function:TimeRange) program2stuff=([]); + +static TimeRange promote_program(function p) +{ + TimeRange x; + if ( (x=program2stuff[p]) ) return x; + x=[object(TimeRange)]p(); + if (!x->is_timerange) + error("Not a timerange program: %O\n",p); + return program2stuff[p]=x; +} diff --git a/lib/modules/Calendar.pmod/Timezone.pmod b/lib/modules/Calendar.pmod/Timezone.pmod new file mode 100644 index 0000000000000000000000000000000000000000..e04da785723257b8a45fb71b7ebc40209d4c07ea --- /dev/null +++ b/lib/modules/Calendar.pmod/Timezone.pmod @@ -0,0 +1,244 @@ +//! module Calendar +//! submodule Timezone +//! +//! This module contains all the predefined timezones. +//! Index it with whatever timezone you want to use. +//! +//! Example: +//! <tt>Calendar.Calendar my_cal= +//! Calendar.ISO->set_timezone(Calendar.Timezone["Europe/Stockholm"]); +//! </tt> +//! +//! A simpler way of selecting timezones might be +//! to just give the string to +//! <ref to=Ruleset.set_timezone>set_timezone</ref>; +//! <ref to=Ruleset.set_timezone>it</ref> indexes by itself: +//! +//! <tt>Calendar.Calendar my_cal= +//! Calendar.ISO->set_timezone("Europe/Stockholm"); +//! </tt> +//! +//! note +//! Do not confuse this module with <ref>Ruleset.Timezone</ref>, +//! which is the base class of a timezone object. +//! +//! <tt>"CET"</tt> and some other standard abbreviations work too, +//! but not all of them (due to more then one country using them). +//! +//! Do not call <ref to=Calendar.Time.set_timezone>set_timezone</ref> +//! too often, but remember the result if possible. It might take +//! some time to initialize a timezone object. +//! +//! There are about 504 timezones with 127 different daylight +//! saving rules. Most of them historic. +//! +//! The timezone information comes from +//! <a href=ftp://elsie.nci.nih.gov/pub/>ftp://elsie.nci.nih.gov/pub/</a> +//! and are not made up from scratch. Timezone bugs may be reported +//! to the timezone mailing list, +//! <a href=mailto:tz@elsie.nci.nih.gov>tz@elsie.nci.nih.gov</a>, +//! preferable with a <tt>cc</tt> to +//! <a href=mailto:mirar@mirar.org>mirar@mirar.org</a>. /Mirar +//! +//! see also: TZnames, Ruleset.Timezone + +//! constant Ruleset.Timezone locale +//! This contains the local timezone, found from +//! various parts of the system, if possible. + +//! constant Ruleset.Timezone localtime +//! This is a special timezone, that uses <ref>localtime</ref>() +//! and <ref>tzname</ref> +//! to find out what current offset and timezone string to use. +//! +//! <ref>locale</ref> uses this if there is no other +//! way of finding a better timezone to use. +//! +//! This timezone is limited by <ref>localtime</ref> and +//! libc to the range of <tt>time_t</tt>, +//! which is a MAXINT on most systems - 13 Dec 1901 20:45:52 +//! to 19 Jan 2038 3:14:07, UTC. + +//! module Calendar +//! submodule TZnames +//! This module is a mapping of the names of +//! all the geographical (political) +//! based timezones. It looks mainly like +//! <pre> +//! (["Europe":({"Stockholm","Paris",...}), +//! "America":({"Chicago","Panama",...}), +//! ... +//! ]) +//! </pre> +//! +//! It is mainly there for easy and reliable ways +//! of making user interfaces to select timezone. +//! +//! The Posix and standard timezones (like CET, PST8PDT, etc) +//! are not listed. + + +import "."; + +// ---------------------------------------------------------------- + +static class TZHistory +{ + constant is_timezone=1; + constant is_dst_timezone=1; + +// figure out what timezone to use + Ruleset.Timezone whatrule(int ux); + + string name=sprintf("%O",object_program(this_object())); + + array(int) tz_ux(int ux) + { +// werror("tz_ux %O\n",ux); +// object z=whatrule(ux); +// werror("%O %O\n",z->offset_to_utc,z->name); +// return z->tz_ux(ux); + return whatrule(ux)->tz_ux(ux); + } + + array(int) tz_jd(int jd) + { +// werror("tz_jd %O\n",jd); +// object z=whatrule((jd-2440588)*86400-86400/2); +// werror("%O %O\n",z->offset_to_utc,z->name); +// return z->tz_jd(jd); + return whatrule((jd-2440588)*86400-86400/2)->tz_jd(jd); + } + + string _sprintf(int t) { return (t=='O')?"Timezone("+name+")":0; } + + int raw_utc_offset(); +} + +#include "TZs.h"; + +// ---------------------------------------------------------------- +// from the system + +Ruleset.Timezone locale=_locale(); + +static function _locale() +{ + Ruleset.Timezone tz; + +// try to get the real local time settings + +#if 1 + string s; + + if ( (s=getenv("TZ")) ) + { + tz=`[](s); + if (tz) return tz; + } + +// Linux RedHat + if ( (s=Stdio.read_bytes("/etc/sysconfig/clock")) ) + { + sscanf(s,"%*sZONE=\"%s\"",s); + tz=`[](s); +// werror("=>%O\n",tz); + if (tz) return tz; + } + +#if constant(tzname) + mapping l=predef::localtime(time()); + array(string) tzn=tzname(); + + tz=::`[](tzn[0]); + if (tz && l->timezone==tz->raw_utc_offset()) return tz; +#endif +#endif + + return localtime(); // default - use localtime +}; + +class localtime +{ + constant is_timezone=1; + constant is_dst_timezone=1; + +#if constant(tzname) + static array(string) names=tzname(); +#endif + + string name="local"; + +// is (midnight) this julian day dst? + array tz_jd(int jd) + { + return tz_ux((jd-2440588)*86400); + } + +// is this unixtime (utc) dst? + array tz_ux(int ux) + { + if (ux<-0x80000000 || ux>0x7fffffff) + error("Time is out of range for Timezone.localtime()\n"); + + int z0=ux%86400; + mapping ll=predef::localtime(ux); + int zl=ll->hour*3600+ll->min*60+ll->sec; + int tz=z0-zl; + if (tz>86400/2) tz-=86400; + else if (tz<-86400/2) tz+=86400; +#if constant(tzname) + return ({tz,names[ll->isdst]}); +#else + return ({tz,"local"}); +#endif + } + + string _sprintf(int t) { return (t=='O')?"Timezone.localtime()":0; } + + int raw_utc_offset(); // N/A but needed for interface +} + +// ---------------------------------------------------------------- +// magic timezones + +static private Ruleset.Timezone _make_new_timezone(string tz,float plusminus) +{ + object(Ruleset.Timezone) z=`[](tz); + if (!z) return ([])[0]; + if (plusminus>14.0 || plusminus<-14.0) + error("difference out of range -14..14 h\n"); + if (plusminus==0.0) + return z; + return + object_program(z)(z->offset_to_utc-((int)(3600*plusminus)), + sprintf("%s%+g",z->name||"",plusminus)); +} + +static private constant _military_tz= +([ "Y":"UTC-12", "X":"UTC-11", "W":"UTC-10", "V":"UTC-9", "U":"UTC-8", + "T":"UTC-7", "S":"UTC-6", "R":"UTC-5", "Q":"UTC-4", "P":"UTC-3", + "O":"UTC-2", "N":"UTC-1", "Z":"UTC", "A":"UTC+1", "B":"UTC+2", + "C":"UTC+3", "D":"UTC+4", "E":"UTC+5", "F":"UTC+6", "G":"UTC+7", + "H":"UTC+8", "I":"UTC+9", "K":"UTC+10", "L":"UTC+11", "M":"UTC+12", + "J":"locale" ]); + +static private Ruleset.Timezone _magic_timezone(string tz) +{ + float d; + string z; + if (sscanf(tz,"%s+%f",z,d)==2) + return _make_new_timezone(z,d); + if (sscanf(tz,"%s-%f",z,d)==2) + return _make_new_timezone(z,-d); + if ((z=_military_tz[tz])) return `[](z); + return ::`[](replace(tz,"-/+"/1,"__p"/1)); +} + +Ruleset.Timezone `[](string tz) +{ + mixed p=::`[](tz); + if (!p) p=_magic_timezone(tz); + if (programp(p) || functionp(p)) return p(); + return p; +} diff --git a/lib/modules/Calendar.pmod/YMD.pmod b/lib/modules/Calendar.pmod/YMD.pmod new file mode 100644 index 0000000000000000000000000000000000000000..ca9bbd0c0dc246036353263bdbd74c08bc1bd0fe --- /dev/null +++ b/lib/modules/Calendar.pmod/YMD.pmod @@ -0,0 +1,2631 @@ +//! +//! module Calendar +//! submodule YMD +//! +//! base for all Roman-kind of Calendars, +//! ie, one with years, months, weeks and days +//! + +// #pragma strict_types + +import "."; +inherit Time:Time; + +#define this this_object() + +// ---------------- +// virtual methods to tell how this calendar works +// ---------------- + +static array(int) year_from_julian_day(int jd); +static int julian_day_from_year(int year); +static int year_remaining_days(int y,int yday); + +static array(int) year_month_from_month(int y,int m); // [y,m,ndays,myd] +static int month_from_yday(int y,int yday); + +static array(int) week_from_week(int y,int w); // [y,w,wd,ndays,wjd] +static array(int) week_from_julian_day(int jd); // [y,w,wd,ndays,wjd] + +static string f_month_name_from_number; +static string f_month_shortname_from_number; +static string f_month_number_from_name; +static string f_month_day_name_from_number; +static string f_week_name_from_number; +static string f_week_day_number_from_name; +static string f_week_day_shortname_from_number; +static string f_week_day_name_from_number; +static string f_year_name_from_number; +static string f_year_number_from_name; + + +static int(0..1) year_leap_year(int y); + +static int compat_week_day(int n); + +//------------------------------------------------------------------------ +//! class YMD +//! Base (virtual) time period of the Roman-kind of calendar. +//! inherits TimeRange +//------------------------------------------------------------------------ + +class YMD +{ + inherit TimeRange; + +// --- generic for all YMD: + + int y; // year + int yjd; // julian day of the first day of the year + + int n; // number of this in the period + + int jd; // julian day of first day + int yd; // day of year (1..) + int m; // [*] month of year (1..12?), like + int md; // [*] day of month (1..) + int wy; // [*] week year + int w; // [*] week of week year (1..) + int wd; // [*] day of week (1..7?) + + int mnd=CALUNKNOWN; // days in current month + int utco=CALUNKNOWN; // [*] distance to UTC + string tzn=0; // timezone name + +// // ^^^ might be uninitialized (CALUNKNOWN) + + Ruleset rules; + constant is_ymd=1; + +// ---------------------------------------- +// basic Y-M-D stuff +// ---------------------------------------- + + void create_now() + { + rules=default_rules; + create_unixtime_default(time()); + } + + void create_unixtime_default(int unixtime) + { +// 1970-01-01 is julian day 2440588 + create_julian_day( 2440588+unixtime/86400 ); +// we can't reuse this; it might not be start of day + [int mutco,string mtzn]=rules->timezone->tz_ux(unixtime); + int uxo=unixtime%86400-mutco; + if (uxo<0) + create_julian_day( 2440588+unixtime/86400-1 ); + else if (uxo>=86400) + create_julian_day( 2440588+unixtime/86400+1 ); + else if (uxo==0) + utco=mutco,tzn=mtzn; // reuse, it *is* start of day + } + + void make_month() // set m and md from y and yd + { + int myd; + [m,md,mnd,myd]=month_from_yday(y,yd); + } + + void make_week() // set w from y and yd + { + int wnd,wjd; + [wy,w,wd,wnd,wjd]=week_from_julian_day(jd); + } + + int __hash() { return jd; } + +// --- query + +//! method float fraction_no() +//! method int hour_no() +//! method int julian_day() +//! method int leap_year() +//! method int minute_no() +//! method int month_day() +//! method int month_no() +//! method int second_no() +//! method int unix_time() +//! method int utc_offset() +//! method int week_day() +//! method int week_no() +//! method int year_day() +//! method int year_no() +//! method string month_name() +//! method string month_shortname() +//! method string month_day_name() +//! method string week_day_name() +//! method string week_day_shortname() +//! method string week_name() +//! method string year_name() +//! method string tzname() +//! method string tzname_iso() + + int julian_day() + { + return jd; + } + + int unix_time() + { +// 1970-01-01 is julian day 2440588 + int ux=(jd-2440588)*86400; + if (utco==CALUNKNOWN) + [utco,tzn]=rules->timezone->tz_jd(jd); + return ux+utco; + } + + int utc_offset() + { + if (utco==CALUNKNOWN) + [utco,tzn]=rules->timezone->tz_jd(jd); + return utco; + } + + string tzname() + { + if (!tzn) + [utco,tzn]=rules->timezone->tz_jd(jd); + return tzn; + } + + string tzname_iso() + { + int u=utc_offset(); + if (!(u%3600)) + return sprintf("UTC%+d",-u/3600); + if (!(u%60)) + return + (u<0) + ?sprintf("UTC+%d:%02d",-u/3600,(-u/60)%60) + :sprintf("UTC-%d:%02d",u/3600,(u/60)%60); + return + (u<0) + ?sprintf("UTC+%d:%02d:%02d",-u/3600,(-u/60)%60,(-u)%60) + :sprintf("UTC-%d:%02d:%02d",u/3600,(u/60)%60,u%60); + } + + int year_no() + { + return y>0?y:-1+y; + } + + int month_no() + { + if (m==CALUNKNOWN) make_month(); + return m; + } + + int week_no() + { + if (w==CALUNKNOWN) make_week(); + return w; + } + + int month_day() + { + if (md==CALUNKNOWN) make_month(); + return md; + } + + int week_day() + { + if (wd==CALUNKNOWN) make_week(); + return wd; + } + + int year_day() + { + return yd; + } + + string year_name() + { + return rules->language[f_year_name_from_number](y); + } + + string week_name() + { + if (w==CALUNKNOWN) make_week(); + return rules->language[f_week_name_from_number](w); + } + + string month_name() + { + if (m==CALUNKNOWN) make_month(); + return rules->language[f_month_name_from_number](m); + } + + string month_shortname() + { + if (m==CALUNKNOWN) make_month(); + return rules->language[f_month_shortname_from_number](m); + } + + string month_day_name() + { + if (mnd==CALUNKNOWN) make_month(); + return rules->language[f_month_day_name_from_number](md,mnd); + } + + string week_day_name() + { + if (wd==CALUNKNOWN) make_week(); + return rules->language[f_week_day_name_from_number](wd); + } + + string week_day_shortname() + { + if (wd==CALUNKNOWN) make_week(); + return rules->language[f_week_day_shortname_from_number](wd); + } + + int leap_year() { return year_leap_year(y); } + + int hour_no() { return 0; } + int minute_no() { return 0; } + int second_no() { return 0; } + float fraction_no() { return 0.0; } + +//! function method datetime() +//! This gives back a mapping with the relevant +//! time information (representing the start of the period); +//! <pre> +//! ([ "year": int // year number (2000 AD=2000, 1 BC==0) +//! "month": int(1..) // month of year +//! "day": int(1..) // day of month +//! "yearday": int(0..) // day of year +//! "week": int(1..) // week of year +//! "week_day": int(0..) // day of week +//! "timezone": int // offset to utc, including dst +//! +//! "unix": int // unix time +//! "julian": int // julian day +//! // for compatibility: +//! "hour": 0 // hour of day, including dst +//! "minute": 0 // minute of hour +//! "second": 0 // second of minute +//! "fraction": 0.0 // fraction of second +//! ]); +//! </pre> +//! +//! note: +//! Day of week is compatible with old versions, +//! ie, 0 is sunday, 6 is saturday, so it shouldn't be +//! used to calculate the day of the week with the given +//! week number. Year day is also backwards compatible, +//! ie, one (1) less then from the year_day() function. + + mapping datetime(void|int skip_stuff) + { + if (m==CALUNKNOWN) make_month(); + if (w==CALUNKNOWN) make_week(); + if (skip_stuff) // called from timeofday + return ([ "year": y, + "month": m, + "day": md, + "yearday": yd-1, + "week": w, + "week_day": compat_week_day(wd) + ]); + else + { + return ([ "year": y, + "month": m, + "day": md, + "yearday": yd-1, + "week": w, + "week_day": compat_week_day(wd), + "timezone": utc_offset(), + "julian": jd, + "unix": unix_time(), + // for compatibility: + "hour": 0, + "minute": 0, + "second": 0, + "fraction": 0.0 + ]); + } + } + +// --- string format ---- + +//! method string format_iso_ymd(); +//! method string format_ymd(); +//! method string format_ymd_short(); +//! method string format_ymd_xshort(); +//! method string format_iso_week(); +//! method string format_iso_week_short(); +//! method string format_week(); +//! method string format_week_short(); +//! method string format_month(); +//! method string format_month_short(); +//! method string format_iso_time(); +//! method string format_time(); +//! method string format_time_short(); +//! method string format_time_xshort(); +//! method string format_mtime(); +//! method string format_xtime(); +//! method string format_tod(); +//! method string format_todz(); +//! method string format_xtod(); +//! method string format_mod(); +//! Format the object into nice strings; +//! <pre> +//! iso_ymd "2000-06-02 (Jun) -W22-5 (Fri)" [2] +//! ext_ymd "Friday, 2 June 2000" [2] +//! ymd "2000-06-02" +//! ymd_short "20000602" +//! ymd_xshort "000602" [1] +//! iso_week "2000-W22" +//! iso_week_short "2000W22" +//! week "2000-w22" [2] +//! week_short "2000w22" [2] +//! month "2000-06" +//! month_short "200006" [1] +//! iso_time "2000-06-02 (Jun) -W22-5 (Fri) 00:00:00 UTC+1" [2] +//! ext_time "Friday, 2 June 2000, 00:00:00" [2] +//! ctime "Fri Jun 2 00:00:00 2000\n" [2] [3] +//! http "Fri, 02 Jun 2000 00:00:00 GMT" [4] +//! time "2000-06-02 00:00:00" +//! time_short "20000602 00:00:00" +//! time_xshort "000602 00:00:00" +//! mtime "2000-06-02 00:00" +//! xtime "2000-06-02 00:00:00.000000" +//! tod "00:00:00" +//! tod_short "000000" +//! todz "00:00:00 CET" +//! todz_iso "00:00:00 UTC+1" +//! xtod "00:00:00.000000" +//! mod "00:00" +//! </pre> +//! <tt>[1]</tt> note conflict (think 1 February 2003) +//! <br><tt>[2]</tt> language dependent +//! <br><tt>[3]</tt> as from the libc function ctime() +//! <br><tt>[4]</tt> as specified by the HTTP standard; +//! not language dependent. + + string format_iso_ymd() + { + if (m==CALUNKNOWN) make_month(); + if (w==CALUNKNOWN) make_week(); + return sprintf("%04d-%02d-%02d (%s) -W%02d-%d (%s)", + y,m,md, + month_shortname(), + w,wd, // fixme - what weekday? + week_day_shortname()); + } + + string format_ext_ymd() + { + if (m==CALUNKNOWN) make_month(); + return sprintf("%s, %s %s %s", + week_day_name(), + month_day_name(),month_name(),year_name()); + } + + string format_ctime() + { + return sprintf("%s %s %2d 00:00:00 %s\n", + week_day_shortname(), + month_shortname(), + md, + year_name()); + } + + string format_http() + { + if (wd==CALUNKNOWN) make_week(); + if (md==CALUNKNOWN) make_month(); + + return + sprintf("%s, %02d %s %04d 00:00:00 GMT", + ("SunMonTueWedThuFriSat"/3)[compat_week_day(wd)], + md, + ("zzzJanFebMarAprMayJunJulAugSepOctNovDec"/3)[m], + y); + } + + string format_ymd() + { + if (m==CALUNKNOWN) make_month(); + return sprintf("%04d-%02d-%02d",y,m,md); + } + + string format_ymd_short() + { + if (m==CALUNKNOWN) make_month(); + return sprintf("%04d%02d%02d",y,m,md); + } + + string format_ymd_xshort() + { + if (m==CALUNKNOWN) make_month(); + return sprintf("%02d%02d%02d",y%100,m,md); + } + + string format_iso_week() + { + if (w==CALUNKNOWN) make_week(); + return sprintf("%04d-W%02d",y,w); + } + + string format_iso_week_short() + { + if (w==CALUNKNOWN) make_week(); + return sprintf("%04d%02d",y,w); + } + + string format_week() + { + return sprintf("%04d-%s",y,week_name()); + } + + string format_week_short() + { + return sprintf("%04d%s",y,week_name()); + } + + string format_month() + { + if (m==CALUNKNOWN) make_month(); + return sprintf("%04d-%02d",y,m); + } + + string format_month_short() + { + if (m==CALUNKNOWN) make_month(); + return sprintf("%04d%02d",y,m); + } + + string format_iso_time() + { + return format_iso_ymd()+" 00:00:00"; + } + + string format_ext_time() + { + return format_ext_ymd()+" 00:00:00"; + } + + string format_time() + { + return format_ymd()+" 00:00:00"; + } + + string format_time_short() + { + return format_ymd_short()+" 00:00:00"; + } + + string format_time_xshort() + { + return format_ymd_xshort()+" 00:00:00"; + } + + string format_mtime() + { + return format_ymd_short()+" 00:00"; + } + + string format_xtime() + { + return format_ymd_short()+" 00:00:00.000000"; + } + + string format_tod() + { + return "00:00:00"; + } + + string format_tod_short() + { + return "000000"; + } + + string format_todz() + { + return "00:00:00 "+tzname(); + } + + string format_todz_iso() + { + return "00:00:00 "+tzname_iso(); + } + + string format_mod() + { + return "00:00"; + } + + string format_xtod() + { + return "00:00:00.000000"; + } + + string format_elapsed() + { + return sprintf("%dd",number_of_days()); + } + +// --- size and move --- + + static TimeRange _set_size(int n,TimeRange t) + { + if (t->is_timeofday) + return second()->set_size(n,t); + + if (yd==1 && t->is_year) + return Year("ymd_y",rules,y,yjd,t->n*n) + ->autopromote(); + +// months are even on years + if (t->is_year || t->is_month) + { + if (md==CALUNKNOWN) make_month(); + if (md==1) + return Month("ymd_yjmw",rules,y,yjd,jd,m, + t->number_of_months()*n,wd,w) + ->autopromote(); + } + +// weeks are not + if (t->is_week) + { + if (wd==CALUNKNOWN) make_week(); + if (wd==1) return Week("ymd_yjwm",rules,y,yjd,jd,w,t->n*n,md,m,mnd); + } + +// fallback on days + if (t->is_ymd) + return Day("ymd_ydmw",rules,y,yjd,jd,yd, + n*t->number_of_days(),m,md,w,wd,mnd); + + error("set_size: incompatible class %O\n", + object_program(t)); + } + + static TimeRange _add(int n,TimeRange step) + { + if (step->is_ymd) + return _move(n,step); + if (step->is_timeofday) + return second()->range(second(-1))->add(n,step); + + error("add: incompatible class %O\n", + object_program(step)); + } + + array(int(-1..1)) _compare(TimeRange with) + { + if (with->is_timeofday) + { + // wrap + array(int(-1..1)) cmp=with->_compare(this_object()); + + return ({-cmp[0], + -cmp[2], + -cmp[1], + -cmp[3]}); + } + else if (with->is_ymd || with->julian_day) + { +#define CMP(A,B) ( ((A)<(B))?-1:((A)>(B))?1:0 ) + + int b1=julian_day(); + int e1=b1+number_of_days(); + + int b2=with->julian_day(); + int e2=b2+with->number_of_days(); + + return ({ CMP(b1,b2),CMP(b1,e2),CMP(e1,b2),CMP(e1,e2) }); + } + return ::_compare(with); + } + +// --- to other YMD + +// years + + int number_of_years() + { + int m=number_of_days(); + if (m<=1 || m+yd-1<year()->number_of_days()) return 1; + return 1+y-year_from_julian_day(jd+m-1)[0]; + } + + array(cYear) years(int ...range) + { + int from=1,n=number_of_years(),to=n; + + if (sizeof(range)) + if (sizeof(range)<2) + error("Illegal numbers of arguments to days()\n"); + else + { + [from,to]=range; + if (from>=n) return ({}); else if (from<0) from=0; + if (to>=n) to=n; else if (to<from) return ({}); + } + + return map(enumerate(1+to-from,1,y+from), + lambda(int x) + { return Year("ymd_yn",rules,x,1); }); + } + + cYear year(void|int m) + { + if (!m || (!n&&m==-1)) + return Year("ymd_y",rules,y,yjd,1); + + if (m<0) m=number_of_years()+m; + + array(TimeRange) res=years(m,m); + if (sizeof(res)==1) return res[0]; + error("not in range (Year 0..%d exist)\n", + number_of_years()-1); + } + + +// days + + int number_of_days(); + + array(cDay) days(int ...range) + { + int from=1,n=number_of_days(),to=n; + + if (sizeof(range)) + if (sizeof(range)<2) + error("Illegal numbers of arguments to days()\n"); + else + { + [from,to]=range; + if (from>n) return ({}); else if (from<1) from=1; + if (to>n) to=n; else if (to<from) return ({}); + } + + int zy=y; + int zyd=yd+from-1; + int zjd=jd+from-1; + int zyjd=yjd; + array(cDay) res=({}); + + to-=from-1; + + if (zyd<1) + { + [zy,zyjd]=year_from_julian_day(zjd); + zyd=zjd-zyjd+1; + } + + for (;;) + { + int rd=year_remaining_days(zy,zyd)+1; + + if (rd>0) + { + if (rd>to) rd=to; + res+=map(enumerate(rd,1,zyd), + lambda(int x) + { return Day("ymd_yd",rules,zy,zyjd,zyjd+x-1,x,1); }); + if (rd==to) break; + zjd+=rd; + to-=rd; + } + + [zy,zyjd]=year_from_julian_day(zjd); + zyd=zjd-zyjd+1; + } + return res; + } + + cDay day(int ... mp) + { + if (!sizeof(mp)) + return Day("ymd_yd",rules,y,yjd,jd,yd,1); + + int m=mp[0]; + + if (m==-1 && !n) + return Day("ymd_yd",rules,y,yjd,jd,yd,1); + + if (m<0) m+=1+number_of_days(); + + array(TimeRange) res=days(m,m); + if (sizeof(res)==1) return res[0]; + error("not in range (Day 1..%d exist)\n", + number_of_days()); + } + +// --- months + + int number_of_months(); + + array(cMonth) months(int ...range) + { + int from=1,n=number_of_months(),to=n; + + if (sizeof(range)) + if (sizeof(range)<2) + error("Illegal numbers of arguments to months()\n"); + else + { + [from,to]=range; + if (from>n) return ({}); else if (from<1) from=1; + if (to>n) to=n; else if (to<from) return ({}); + } + + if (md==CALUNKNOWN) make_month(); + + return map(enumerate(1+to-from,1,from+m-1), + lambda(int x) + { return Month("ymd_ym",rules,y,x,1); }); + } + + cMonth month(int ... mp) + { + if (md==CALUNKNOWN) make_month(); + + if (!sizeof(mp)) + return Month("ymd_ym",rules,y,m,1); + + int num=mp[0]; + + if (num==-1 && !n) + return Month("ymd_ym",rules,y,m,1); + + if (num<0) num+=1+number_of_months(); + + array(TimeRange) res=months(num,num); + if (sizeof(res)==1) return res[0]; + error("not in range; Month 1..%d exist in %O\n", + number_of_months(),this_object()); + } + +//---- week + + int number_of_weeks(); + + array(cWeek) weeks(int ...range) + { + int from=1,n=number_of_weeks(),to=n; + + if (sizeof(range)) + if (sizeof(range)<2) + error("Illegal numbers of arguments to weeks()\n"); + else + { + [from,to]=range; + if (from>n) return ({}); else if (from<1) from=1; + if (to>n) to=n; else if (to<from) return ({}); + } + + if (wd==CALUNKNOWN) make_week(); + + return map(enumerate(1+to-from,1,from+w-1), + lambda(int x) + { return Week("ymd_yw",rules,wy,x,1); }); + } + + cWeek week(int ... mp) + { + if (wd==CALUNKNOWN) make_week(); + + if (!sizeof(mp)) + return Week("ymd_yw",rules,wy,w,1); + + int num=mp[0]; + + if (num==-1 && !n) + return Week("ymd_yw",rules,wy,w,1); + + if (num<0) num+=1+number_of_weeks(); + + array(TimeRange) res=weeks(num,num); + if (sizeof(res)==1) return res[0]; + error("not in range (Week 1..%d exist)\n", + number_of_weeks()); + } + + +// --- functions to conform to Time.* + + static TimeRange get_unit(string unit,int m) + { + if (!n) return day()[unit](); + if (m<0) m+=::`[]("number_of_"+unit+"s")(); + array(TimeRange) res=::`[](unit+"s")(m,m); + if (sizeof(res)==1) return res[0]; + error("not in range ("+unit+" 0..%d exist)\n", + ::`[]("number_of_"+unit+"s")()-1); + } + + static array(TimeRange) get_timeofday(string unit, + int start,int step,program p, + int ... range) + { + int from=0,n=::`[]("number_of_"+unit)(),to=n-1; + + if (sizeof(range)) + if (sizeof(range)<2) + error("Illegal numbers of arguments to "+unit+"()\n"); + else + { + [from,to]=range; + if (from>=n) return ({}); else if (from<0) from=0; + if (to>=n) to=n-1; else if (to<from) return ({}); + } + + from*=step; + to*=step; + + to-=from-step; + + from+=unix_time(); + + array z= + map(enumerate(to/step,step,from), + lambda(int x) + { return p("timeofday",rules,x,step); }); + +// return z; + + if (sizeof(z)>1 && + ((p==cHour && z[0]->utc_offset()%3600 != z[-1]->utc_offset()%3600) || + (p==cMinute && z[0]->utc_offset()%60 != z[-1]->utc_offset()%60))) + { + // we're in a zone shifting, and we shift a non-hour (or non-minute) + cSecond sec=Second(); + int i,uo=z[0]->utc_offset(); + for (i=1; i<sizeof(z); i++) + if (z[i]->utc_offset()!=uo) + { + int uq=(z[i]->utc_offset()-uo); + werror("%O %O\n",z[i],z); + if (uq<0) + { + if (uq<=-step) uq=-(-uq%step); + z= z[..i-1]+ + ({z[i]->set_size(step+uq,sec)})+ + map(z[i+1..],"add",uq,sec); + } + else + { + if (uq>=step) uq%=step; + z= z[..i-1]+ + ({z[i]->set_size(uq,sec)})+ + map(z[i..sizeof(z)-2],"add",uq,sec); + i++; + } + werror("=> %O %O\n",z[i],z); + uo=z[i]->utc_offset(); + } + } + return z; + } + + + int number_of_hours() { return (number_of_seconds()+3599)/3600; } + cHour hour(void|int n) { return get_unit("hour",n); } + array(cHour) hours(int ...range) + { return get_timeofday("hours",0,3600,Hour,@range); } + + int number_of_minutes() { return (number_of_seconds()+59)/60; } + cMinute minute(void|int n) { return get_unit("minute",n); } + array(cMinute) minutes(int ...range) + { return get_timeofday("minutes",0,60,Minute,@range); } + + int number_of_seconds() { return end()->unix_time()-unix_time(); } + cSecond second(void|int n,int ...time) + { + if (sizeof(time)==2) + return hour(n)->minute(time[0])->second(time[1]); + return get_unit("second",n); + } + array(cSecond) seconds(int ...range) + { return get_timeofday("seconds",0,1,Second,@range); } + + float number_of_fractions() { return (float)number_of_seconds(); } + cSecond fraction(void|float|int n) + { + return fractions()[0]; + } + array(cSecond) fractions(int|float ...range) + { + float from,to,n=number_of_fractions(); + if (sizeof(range)==2) + from=(float)range[0],to=(float)range[1]; + else if (sizeof(range)==0) + from=0.0,to=n; + else + error("Illegal arguments\n"); + if (from<0.0) from=0.0; + if (to>n) to=n; + return ({Fraction("timeofday_f",rules,unix_time(),0, + (int)to,(int)(inano*(to-(int)to))) + ->autopromote()}); + } + +// ---------------------------------------- +// virtual functions needed +// ---------------------------------------- + + string nice_print(); + string _sprintf(int t); + + void create_julian_day(int|float jd); + static TimeRange _move(int n,YMD step); + TimeRange place(TimeRange what,void|int force); + +// not needed + + YMD autopromote() { return this; } +} + +//------------------------------------------------------------------------ +//! class Year +//! This is the time period of a year. +//! inherits TimeRange +//! inherits YMD +//------------------------------------------------------------------------ + +function(mixed...:cYear) Year=cYear; +class cYear +{ + inherit YMD; + + constant is_year=1; + +// --- + +//! +//! method void create("unix",int unix_time) +//! method void create("julian",int|float julian_day) +//! method void create(int year) +//! method void create(string year) +//! It's possible to create the standard week +//! by using three different methods; either the normal +//! way - from standard unix time or the julian day, +//! and also, for more practical use, from the year number. +//! + + void create(mixed ...args) + { + if (!sizeof(args)) + { + create_now(); + return; + } + else switch (args[0]) + { + case "ymd_y": + rules=args[1]; + y=args[2]; + jd=yjd=args[3]; + n=args[4]; + m=md=w=wd=CALUNKNOWN; + yd=1; + return; + case "ymd_yn": + rules=args[1]; + y=args[2]; + jd=yjd=julian_day_from_year(y); + n=args[3]; + m=md=w=wd=CALUNKNOWN; + yd=1; + return; + default: + if (intp(args[0]) && sizeof(args)==1) + { + rules=default_rules; + y=args[0]; + jd=yjd=julian_day_from_year(y); + n=1; + m=md=w=wd=CALUNKNOWN; + yd=1; + return; + } + else if (stringp(args[0])) + { + y=default_rules->language[f_year_number_from_name](args[0]); + rules=default_rules; + jd=yjd=julian_day_from_year(y); + n=1; + m=md=w=wd=CALUNKNOWN; + yd=1; + return; + } + break; + + } + rules=default_rules; + ::create(@args); + } + + void create_julian_day(int|float _jd) + { + if (floatp(_jd)) + create_unixtime_default((int)((jd-2440588)*86400)); + else + { + [y,yjd]=year_from_julian_day(_jd); + jd=yjd; + n=1; + md=yd=m=1; + wd=w=CALUNKNOWN; // unknown + } + } + + TimeRange beginning() + { + return Year("ymd_y",rules,y,yjd,0); + } + + TimeRange end() + { + return Year("ymd_yn",rules,y+n,0); + } + +// ---------------- + + string _sprintf(int t) + { + switch (t) + { + case 'O': + if (n!=1) + return sprintf("Year(%s)",nice_print_period()); + return sprintf("Year(%s)",nice_print()); + default: + return 0; + } + } + + string nice_print_period() + { + if (!n) return nice_print()+" sharp"; + return sprintf("%s..%s",nice_print(),year(-1)->nice_print()); + } + + string nice_print() + { + return year_name(); + } + +// --- Year _move + + TimeRange _move(int m,YMD step) + { + if (!step->n || !m) + return this; + + if (step->is_year) + return Year("ymd_yn",rules,y+m*step->n,n) + ->autopromote(); + + if (step->is_month) + return month()->add(m,step)->set_size(this_object()); + +// if (step->is_week) +// return week()->add(m,step)->set_size(this_object()); + + if (step->is_ymd) + return Day("ymd_jd",rules, + yjd+m*step->number_of_days(),number_of_days()) + ->autopromote(); + + error("_move: Incompatible type %O\n",step); + } + + static void convert_from(TimeRange other) + { + ::convert_from(other); + if (other->number_of_years) + n=other->number_of_years(); + else + n=0; + } + + TimeRange place(TimeRange what,void|int force) + { + if (what->is_day) + { + int yd=what->yd; + return Day("ymd_yd",rules,y,yjd,yjd+yd-1,yd,what->n); + } + + if (what->is_week) + { + cWeek week=Week("ymd_yw",rules,y,what->w,what->n); + if (!force && week->y!=y) return 0; // not this year + return week; + } + + error("place: Incompatible type %O\n",what); + } + + TimeRange distance(TimeRange to) + { + if (to->is_timeofday) + { + return hour()->distance(to); + } + if (to->is_ymd) + { + if (to->is_year) + { + int y1=y; + int y2=to->y; + if (y2<y1) + error("distance: negative distance\n"); + return Year("ymd_yn",rules,y,y2-y1) + ->autopromote(); + } + if (to->is_month) + return month()->distance(to); + return day()->distance(to); + } + + error("distance: Incompatible type %O\n",to); + } + +// --- + + int number_of_years() + { + return n; + } + + int number_of_weeks(); + +//! method Month month() +//! method Month month(int n) +//! method Month month(string name) +//! The Year type overloads the month() method, +//! so it is possible to get a specified month +//! by string: +//! +//! <tt>year->month("April")</tt> +//! +//! The integer and no argument behavior is inherited +//! from <ref to=YMD.month>YMD</ref>(). + + cMonth month(int|string ... mp) + { + if (sizeof(mp) && + stringp(mp[0])) + { + int num=((int)mp[0]) || + rules->language[f_month_number_from_name](mp[0]); + if (!num) + error("no such month %O in %O\n",mp[0],this_object()); + + return ::month(num); + } + else + return ::month(@mp); + } + +//! method Week week() +//! method Week week(int n) +//! method Week week(string name) +//! The Year type overloads the week() method, +//! so it is possible to get a specified week +//! by name: +//! +//! <tt>year->week("17")</tt> +//! <tt>year->week("w17")</tt> +//! +//! The integer and no argument behavior is inherited +//! from <ref to=YMD.week>YMD</ref>(). +//! +//! This is useful, since the first week of a year +//! not always (about half the years, in the ISO calendar) +//! is numbered '1'. +//! + + cWeek week(int|string ... mp) + { + if (sizeof(mp) && + stringp(mp[0])) + { + int num; + sscanf(mp[0],"%d",num); + sscanf(mp[0],"w%d",num); + + cWeek w=::week(num); + if (w->week_no()==num) return w; + return ::week(num-(w->week_no()-num)); + } + else + return ::week(@mp); + } + + cYear set_ruleset(Ruleset r) + { + return Year("ymd_y",r,y,yjd,n); + } +} + + +// ---------------------------------------------------------------- +// Month +// ---------------------------------------------------------------- + +function(mixed...:cMonth) Month=cMonth; +class cMonth +{ + inherit YMD; + + constant is_month=1; + + int nd; // number of days + int nw; // number of weeks + + void create(mixed ...args) + { + if (!sizeof(args)) + { + rules=default_rules; + create_unixtime_default(time()); + return; + } + else + switch (args[0]) + { + case "ymd_ym": + rules=args[1]; + y=args[2]; + m=args[3]; + n=args[4]; + md=1; + w=wd=CALUNKNOWN; + [y,m,nd,yd]=year_month_from_month(y,m); + yjd=julian_day_from_year(y); + jd=yjd+yd-1; + if (n!=1) nd=CALUNKNOWN; + nw=CALUNKNOWN; + return; + case "ymd_yjmw": + rules=args[1]; + y=args[2]; + yjd=args[3]; + jd=args[4]; + yd=1+jd-yjd; + m=args[5]; + n=args[6]; + wd=args[7]; + w=args[8]; + md=1; + nw=nd=CALUNKNOWN; + return; + case "ymd_jd": + rules=args[1]; + create_julian_day(args[2]); + n=args[3]; + return; + default: + if (intp(args[0]) && sizeof(args)==2) + { + create("ymd_ym",default_rules,args[0],args[1],1); + if (y!=args[0]) + error("month %d doesn't exist in %d\n",args[1],args[0]); + return; + } + break; + } + + rules=default_rules; + ::create(@args); + } + + void create_julian_day(int|float _jd) + { + if (floatp(_jd)) + create_unixtime_default((int)((jd-2440588)*86400)); + else + { + int zmd; + [y,yjd]=year_from_julian_day(jd=_jd); + [m,zmd,nd,yd]=month_from_yday(y,1+jd-yjd); + jd=yd+yjd-1; + + n=1; + md=1; + nw=wd=w=CALUNKNOWN; // unknown + } + } + + string _sprintf(int t) + { +// return sprintf("month y=%d yjd=%d m=%d jd=%d yd=%d n=%d nd=%d", +// y,yjd,m,jd,yd,n,number_of_days()); + switch (t) + { + case 'O': + if (n!=1) + return sprintf("Month(%s)",nice_print_period()); + return sprintf("Month(%s)",nice_print()); + default: + return 0; + } + } + + string nice_print() + { + return + sprintf("%s %s", + month_name(), + year_name()); + } + + string nice_print_period() + { + if (!n) return day()->nice_print()+" 0:00 sharp"; + cMonth mo=month(-1); + if (mo->y==y) + return sprintf("%s..%s %s", + month_shortname(), + mo->month_shortname(), + year_name()); + return nice_print()+" .. "+month(-1)->nice_print(); + } + + cDay beginning() + { + return Month("ymd_yjmw",rules,y,yjd,jd,m,0,wd,w) + ->autopromote(); + } + + cDay end() + { + return Month("ymd_ym",rules,y,m+n,0) + ->autopromote(); + } + +// --- month position and distance + + TimeRange distance(TimeRange to) + { + if (to->is_timeofday) + return hour()->distance(to); + + if (to->is_ymd) + { + if (to->is_month || to->is_year) + { + int n1=months_to_month(to->y,to->is_year?1:to->m); + if (n1<0) + error("distance: negative distance (%d months)\n",n1); + return Month("ymd_yjmw",rules,y,yjd,jd,m,n1,wd,w) + ->autopromote(); + } + + int d1=jd; + int d2=to->jd; + if (d2<d1) + error("distance: negative distance (%d days)\n",d2-d1); + return Day("ymd_ydmw",rules,y,yjd,jd,yd,d2-d1,m,1,w,wd,mnd) + ->autopromote(); + } + + error("distance: Incompatible type %O\n",to); + } + + static void convert_from(TimeRange other) + { + ::convert_from(other); + if (other->number_of_months) + n=other->number_of_months(); + else + n=0; + } + + TimeRange _move(int x,YMD step) + { + if (step->is_year) + return Month("ymd_ym",rules,y+x*step->n,m,n) + ->autopromote(); + if (step->is_month) + return Month("ymd_ym",rules,y,m+x*step->n,n) + ->autopromote(); + + return Day("ymd_jd",rules,jd+x*step->number_of_days(),number_of_days()) + ->autopromote(); + } + + TimeRange place_day(int day,int day_n,void|int force) + { + if (day>number_of_days()) return 0; // doesn't exist + return Day("ymd_jd",rules,jd+day-1,day_n)->autopromote(); + } + + TimeRange place(TimeRange what,void|int force) + { + if (what->is_year) + return year()->place(what,force); // just fallback + + if (what->is_day) + return place_day(what->month_day(),what->n,force); + + error("place: Incompatible type %O\n",what); + } + +// --- Month to other units + + int number_of_years() + { + if (n<=1) return 1; + + [int y2,int m2,int nd2,int yd2]=year_month_from_month(y,m+n); + return 1+y2-y; + } + + int number_of_days() + { + if (nd!=CALUNKNOWN) return nd; + + [int y2,int m2,int nd2,int yd2]=year_month_from_month(y,m+n); + return nd=julian_day_from_year(y2)+yd2-jd-1; + } + + int number_of_weeks() + { + if (nw!=CALUNKNOWN) return nw; + + [int y2,int m2,int nd2,int yd2]=year_month_from_month(y,m+n); + + return nw= + Week("julian_r",jd,rules) + ->range(Week("julian_r",julian_day_from_year(y2)+yd2-2,rules)) + ->number_of_weeks(); + } + + int number_of_months() + { + return n; + } + + cMonth set_ruleset(Ruleset r) + { + return Month("ymd_yjmw",r,y,yjd,jd,m,n,wd,w); + } + +// --- needs to be defined + + static int months_to_month(int y,int m); +} + +// ---------------------------------------------------------------- +//! class Week +//! The Calendar week represents a standard time period of +//! a week. In the Gregorian calendar, the standard week +//! starts on a sunday and ends on a saturday; in the ISO +//! calendar, it starts on a monday and ends on a sunday. +//! +//! The week are might not be aligned to the year, and thus +//! the week may cross year borders and the year of +//! the week might not be the same as the year of all the +//! days in the week. The basic rule is that the week year +//! is the year that has the most days in the week, but +//! since week number only is specified in the ISO calendar +//! - and derivates - the week number of most calendars +//! is the week number of most of the days in the ISO +//! calendar, which modifies this rule for the Gregorian calendar; +//! the week number and year is the same as for the ISO calendar, +//! except for the sundays. +//! +//! When adding, moving and subtracting months +//! to a week, it falls back to using days. +//! +//! When adding, moving or subtracting years, +//! if tries to place the moved week in the +//! resulting year. +// ---------------------------------------------------------------- + +function(mixed...:cWeek) Week=cWeek; +class cWeek +{ + inherit YMD; + + constant is_week=1; + +//! +//! method void create("unix",int unix_time) +//! method void create("julian",int|float julian_day) +//! method void create(int year,int week) +//! It's possible to create the standard week +//! by using three different methods; either the normal +//! way - from standard unix time or the julian day, +//! and also, for more practical use, from year and week +//! number. +//! + + void create(mixed ...args) + { + if (!sizeof(args)) + { + rules=default_rules; + create_unixtime_default(time()); + return; + } + else + switch (args[0]) + { + case "ymd_yw": + rules=args[1]; + y=args[2]; + w=args[3]; + n=args[4]; + m=md=CALUNKNOWN; + [y,w,wd,int nd,jd]=week_from_week(y,w); + yjd=julian_day_from_year(y); + yd=1+jd-yjd; + wy=y; + if (n!=1) nd=CALUNKNOWN; + return; + case "ymd_yjwm": + rules=args[1]; + y=args[2]; + yjd=args[3]; + jd=args[4]; + yd=1+jd-yjd; + w=args[5]; + n=args[6]; + md=args[7]; + m=args[8]; + mnd=args[9]; + wd=1; + wy=y; + nd=CALUNKNOWN; + return; + case "ymd_jd": + rules=args[1]; + create_julian_day(args[2]); + n=args[3]; + return; + default: + if (intp(args[0]) && sizeof(args)==2) + { + create("ymd_yw",default_rules,args[0],args[1],1); + if (y!=args[0]) + error("month %d doesn't exist in %d\n",args[1],args[0]); + return; + } + break; + } + + rules=default_rules; + ::create(@args); + } + + void create_julian_day(int|float _jd) + { + if (floatp(_jd)) + create_unixtime_default((int)((jd-2440588)*86400)); + else + { + int zwd; + [y,w,zwd,int nd,jd]=week_from_julian_day(_jd); + yjd=julian_day_from_year(y); + yd=1+jd-yjd; + + n=1; + wd=1; + wy=y; + md=m=CALUNKNOWN; // unknown + } + } + + string _sprintf(int t) + { +// return sprintf("week y=%d yjd=%d w=%d jd=%d yd=%d n=%d nd=%d", +// y,yjd,w,jd,yd,n,number_of_days()); + switch (t) + { + case 'O': + if (n!=1) + return sprintf("Week(%s)",nice_print_period()); + return sprintf("Week(%s)",nice_print()); + default: + return 0; + } + } + + string nice_print() + { + return + sprintf("%s %s", + week_name(), + year_name()); + } + + + string nice_print_period() + { + if (!n) return day()->nice_print()+" 0:00 sharp"; + cWeek wo=week(-1); + if (wo->y==y) + return sprintf("%s..%s %s", + week_name(), + wo->week_name(), + year_name()); + return nice_print()+" .. "+week(-1)->nice_print(); + } + + cDay beginning() + { + return Week("ymd_yjwm",rules,y,yjd,jd,w,0,md,m,mnd) + ->autopromote(); + } + + cDay end() + { + return Week("ymd_yw",rules,y,w+n,0) + ->autopromote(); + } + +// --- week position and distance + + TimeRange distance(TimeRange to) + { + if (to->is_timeofday) + return hour()->distance(to); + + if (to->is_week) + { + int n1=weeks_to_week(to->y,to->w); + if (n1<0) + error("distance: negative distance (%d weeks)\n",n1); + return Week("ymd_yjwm",rules,y,yjd,jd,w,n1,md,m,mnd) + ->autopromote(); + } + + if (to->julian_day) + { + int d1=jd; + int d2=to->julian_day(); + if (d2<d1) + error("distance: negative distance (%d days)\n",d2-d1); + return Day("ymd_ydmw",rules,y,yjd,jd,yd,d2-d1,m,md,w,1,mnd) + ->autopromote(); + } + + error("distance: Incompatible type %O\n",to); + } + + static void convert_from(TimeRange other) + { + ::convert_from(other); + if (other->number_of_weeks) + n=other->number_of_weeks(); + else + n=0; + } + + TimeRange _move(int x,YMD step) + { + if (step->is_week) + return Week("ymd_yw",rules,y,w+x*step->n,n) + ->autopromote(); + + if (step->is_year) + return year()->add(x,step)->place(this_object(),1); + + if (step->number_of_days) + return Day("ymd_jd",rules, + jd+x*step->number_of_days(),number_of_days()) + ->autopromote(); + + error("add: Incompatible type %O\n",step); + } + + TimeRange place_day(int day,int day_n,int force) + { + if (day>number_of_days()) + if (!force) + return 0; + else + return Day("ymd_jd",rules,jd+day-1,max(0,day_n-1))->autopromote(); + return Day("ymd_jd",rules,jd+day-1,day_n)->autopromote(); + } + + TimeRange place(TimeRange what,void|int force) + { + if (what->is_year) + return year()->place(what,force); // just fallback + + if (what->is_day) + return place_day(what->week_day(),what->n,force); + + error("place: Incompatible type %O\n",what); + } + +// --- Week to other units + + int number_of_years() + { + if (n<=1) return 1; + + [int y2,int w2,int wd2,int nd2,int jd2]=week_from_week(y,w+n); + return 1+y2-y; + } + + int number_of_months() + { + if (!n) return 1; + +// cheat + return Day("ymd_jd",rules,jd,number_of_days()) + ->number_of_months(); + } + + int number_of_weeks() + { + return n; + } + + int number_of_days(); + +//! method Day day() +//! method Day day(int n) +//! method Day day(string name) +//! The Week type overloads the day() method, +//! so it is possible to get a specified weekday +//! by string: +//! +//! <tt>week->day("sunday")</tt> +//! +//! The integer and no argument behavior is inherited +//! from <ref to=YMD.day>YMD</ref>(). +//! +//! note: +//! the weekday-from-string routine is language dependent. + + cDay day(int|string ... mp) + { + if (sizeof(mp) && + stringp(mp[0])) + { + int num=((int)mp[0]) || + rules->language[f_week_day_number_from_name](mp[0]); + if (!num) + error("no such day %O in %O\n",mp[0],this_object()); + + return ::day(num); + } + else + return ::day(@mp); + } + + cWeek set_ruleset(Ruleset r) + { + return Week("ymd_yjwm",r,y,yjd,jd,w,n,md,m,mnd); + } + +// --- needs to be defined + + static int weeks_to_week(int y,int m); +} + +// ---------------------------------------------------------------- +// Day +// ---------------------------------------------------------------- + +function(mixed...:cDay) Day=cDay; +class cDay +{ + inherit YMD; + + constant is_day=1; + int nw; + +//! +//! method void create("unix",int unix_time) +//! method void create("julian",int|float julian_day) +//! method void create(int year,int month,int day) +//! method void create(int year,int year_day) +//! method void create(int julian_day) +//! It's possible to create the day +//! by using five different methods; either the normal +//! way - from standard unix time or the julian day, +//! and also, for more practical use, from year, month and day, +//! from year and day of year, and from julian day +//! without extra fuzz. + + void create(mixed ...args) + { + if (!sizeof(args)) + { + rules=default_rules; + create_unixtime_default(time()); + return; + } + else + switch (args[0]) + { + case "ymd_ydmw": + rules=args[1]; + y=args[2]; + yjd=args[3]; + jd=args[4]; + yd=args[5]; + n=args[6]; + m=args[7]; + md=args[8]; + w=args[9]; + wd=args[10]; + mnd=args[11]; + nw=CALUNKNOWN; + return; + case "ymd_yd": + rules=args[1]; + y=args[2]; + yjd=args[3]; + jd=args[4]; + yd=args[5]; + n=args[6]; + wd=nw=md=m=w=CALUNKNOWN; + return; + case "ymd_jd": + rules=args[1]; + create_julian_day(args[2]); + n=args[3]; + wd=nw=md=m=w=CALUNKNOWN; + return; + case "unix_r": + case "julian_r": + case "unix": + case "julian": + break; + default: + rules=default_rules; + wd=nw=md=m=w=CALUNKNOWN; + n=1; + switch (sizeof(args)) + { + case 1: + if (intp(args[0])) + { + create_julian_day(args[0]); + return; + } + break; + case 2: + if (stringp(args[0])) + y=default_rules->language[f_year_number_from_name] + (args[0]); + else if (intp(args[0])) + y=args[0]; + else + break; + if (!intp(args[1])) + break; + yd=args[1]; + yjd=julian_day_from_year(y); + jd=yjd+yd-1; + return; + case 3: + if (stringp(args[0])) + y=default_rules->language[f_year_number_from_name] + (args[0]); + else if (intp(args[0])) + y=args[0]; + else + break; + if (!intp(args[1]) || + !intp(args[2])) break; + md=args[2]; + [y,m,int nmd,int myd]= + year_month_from_month(y,args[1]); + if (m!=args[1] || y!=args[0]) + error("No such month (%d-%02d)\n",args[0],args[1]); + yjd=julian_day_from_year(y); + md=args[2]; + jd=yjd+myd+md-2; + yd=jd-yjd+1; + if (md>nmd || md<1) + error("No such day of month (%d-%02d-%02d)\n", + @args); + return; + } + } + + rules=default_rules; + ::create(@args); + } + + void create_julian_day(int|float _jd) + { + n=1; + nw=md=m=wd=w=CALUNKNOWN; // unknown + + if (floatp(_jd)) + { + create_unixtime_default((int)((jd-2440588)*86400)); + } + else + { + [y,yjd]=year_from_julian_day(jd=_jd); + yd=1+jd-yjd; + } + } + + string _sprintf(int t) + { + switch (t) + { + case 'O': + if (n!=1) + return sprintf("Day(%s)",nice_print_period()); + return sprintf("Day(%s)",nice_print()); + default: + return 0; + } + } + + string nice_print() + { + if (m==CALUNKNOWN) make_month(); + if (wd==CALUNKNOWN) make_week(); + return + sprintf("%s %s %s %s", + week_day_shortname(), + month_day_name(),month_shortname(), + year_name()); + } + + string nice_print_period() + { +// return nice_print()+" n="+n+""; + if (!n) return nice_print()+" 0:00 sharp"; + return nice_print()+" .. "+day(-1)->nice_print(); + } + + cDay beginning() + { + return Day("ymd_ydmw",rules,y,yjd,jd,yd,0,m,md,w,wd,mnd); + } + + cDay end() + { + return Day("ymd_jd",rules,jd+n,0) + ->autopromote(); + } + + static void convert_from(TimeRange other) + { + ::convert_from(other); + if (other->number_of_days) + n=other->number_of_days(); + else + n=0; + } + +// --- Day _move + + static TimeRange _move(int x,YMD step) + { + if (step->is_year) + return year()->add(x,step)->place(this_object(),1); + + if (step->is_month) + return month()->add(x,step)->place(this_object(),1); + + if (step->is_week) + return week()->add(x,step)->place(this_object(),1); + + if (step->is_day) + return Day("ymd_jd",rules,jd+x*step->n,n) + ->autopromote(); + + error("_move: Incompatible type %O\n",step); + } + + TimeRange place(TimeRange what) + { + if (what->is_timeofday) + { + int lux= + what->ux- + Day("unix_r",what->unix_time(),what->ruleset()) + ->unix_time(); + + if (what->is_timeofday_f) + return + Fraction("timeofday_f",rules, + lux+unix_time(),what->ns,what->s_len,what->ns_len) + ->autopromote(); + + return Second("timeofday",rules,unix_time()+lux,what->len) + ->autopromote(); + } + + error("place: Incompatible type %O\n",what); + } + + TimeRange distance(TimeRange to) + { + if (to->is_timeofday) + return hour()->distance(to); + if (to->is_ymd) + { + int d1=jd; + int d2=to->jd; + if (d2<d1) + error("distance: negative distance (%d days)\n",d2-d1); + return Day("ymd_ydmw",rules,y,yjd,jd,yd,d2-d1,m,md,w,wd,mnd) + ->autopromote(); + } + + error("distance: Incompatible type %O\n",to); + } + +// --- Day to other YMD + + int number_of_days() + { + return n; + } + + int number_of_years() + { + if (n<=1) return 1; + return 1+year_from_julian_day(jd+n-1)[0]-y; + } + + int number_of_weeks() + { + if (nw!=CALUNKNOWN) return nw; + + if (n<=1) return nw=1; + + return nw= + Week("julian_r",jd,rules) + ->range(Week("julian_r",jd+n-1,rules)) + ->number_of_weeks(); + } + + cDay set_ruleset(Ruleset r) + { + return Day("ymd_ydmw",r,y,yjd,jd,yd,n,m,md,w,wd,mnd); + } + +// backwards compatible with calendar I + string iso_name() { return format_ymd(); } + string iso_short_name() { return format_ymd_short(); } +} + +//------------------------------------------------------------------------ +//- class YMD_Time +//------------------------------------------------------------------------ + +class YMD_Time +{ +#define MKRBASE \ + do \ + { \ + int n; \ + if (!rbase) \ + rbase=Day("unix_r",this->ux,this->rules)->range(Day("unix_r",this->ux+this->len,this->rules)); \ + } while (0) + +#define RBASE (this->base || this->make_base()) + + cDay day(int ...n) { return RBASE->day(@n); } + cDay number_of_days() { return RBASE->number_of_days(); } + array(cDay) days(int ...r) { return RBASE->days(@r); } + + cMonth month(int ...n) { return RBASE->month(@n); } + cMonth number_of_months() { return RBASE->number_of_months(); } + array(cMonth) months(int ...r) { return RBASE->months(@r); } + + cWeek week(int ...n) { return RBASE->week(@n); } + cWeek number_of_weeks() { return RBASE->number_of_weeks(); } + array(cWeek) weeks(int ...r) { return RBASE->weeks(@r); } + + cYear year(int ...n) { return RBASE->year(@n); } + cYear number_of_years() { return RBASE->number_of_years(); } + array(cYear) years(int ...r) { return RBASE->years(@r); } + + int year_no() { return RBASE->year_no(); } + int month_no() { return RBASE->month_no(); } + int week_no() { return RBASE->week_no(); } + int month_name() { return RBASE->month_name(); } + int month_shortname() { return RBASE->month_shortname(); } + int month_day() { return RBASE->month_day(); } + int month_day_name() { return RBASE->month_day_name(); } + int week_day() { return RBASE->week_day(); } + int year_day() { return RBASE->year_day(); } + string week_name() { return RBASE->week_name(); } + string week_day_name() { return RBASE->week_day_name(); } + string week_day_shortname() { return RBASE->week_day_shortname(); } + int leap_year() { return RBASE->leap_year(); } + + string format_iso_ymd() { return RBASE->format_iso_ymd(); } + string format_ext_ymd() { return RBASE->format_ext_ymd(); } + string format_ymd() { return RBASE->format_ymd(); } + string format_ymd_short() { return RBASE->format_ymd_short(); } + string format_ymd_xshort() { return RBASE->format_ymd_xshort(); } + string format_iso_week() { return RBASE->format_iso_week(); } + string format_iso_week_short() + { return RBASE->format_iso_week_short(); } + string format_week() { return RBASE->format_week(); } + string format_week_short() { return RBASE->format_week_short(); } + string format_month() { return RBASE->format_month(); } + string format_month_short() { return RBASE->format_month_short(); } + +#undef RBASE +} + +#define OVERLOAD_TIMEOFDAY \ + \ + static int(0..1) create_backtry(mixed ... args) \ + { \ + if (sizeof(args)>=5 && \ + (intp(args[0])||stringp(args[0])) && \ + intp(args[1]) && \ + intp(args[2])) \ + { \ + base=Day(@args[..2]); \ + return ::create_backtry(@args[3..]); \ + } \ + return ::create_backtry(@args); \ + } + + +//------------------------------------------------------------------------ +//! class Hour +//! inherits Time.Hour +//! inherits YMD +//------------------------------------------------------------------------ + +class cHour +{ + inherit Time::cHour; + inherit YMD_Time; + OVERLOAD_TIMEOFDAY; +} + +class cMinute +{ + inherit Time::cMinute; + inherit YMD_Time; + OVERLOAD_TIMEOFDAY; +} + +class cSecond +{ + inherit Time::cSecond; + inherit YMD_Time; + OVERLOAD_TIMEOFDAY; +} + +class cFraction +{ + inherit Time::cFraction; + inherit YMD_Time; + OVERLOAD_TIMEOFDAY; +} + +class cSuperTimeRange +{ + inherit Time::cSuperTimeRange; + + array(cYear) years(int ...range) { return get_units("years",@range); } + cYear year(void|int n) { return get_unit("years",n); } + int number_of_years() { return num_units("years"); } + + array(cMonth) months(int ...range) { return get_units("months",@range); } + cMonth month(void|int n) { return get_unit("months",n); } + int number_of_months() { return num_units("months"); } + + array(cWeek) weeks(int ...range) { return get_units("weeks",@range); } + cWeek week(void|int n) { return get_unit("weeks",n); } + int number_of_weeks() { return num_units("weeks"); } + + array(cDay) days(int ...range) { return get_units("days",@range); } + cDay day(void|int n) { return get_unit("days",n); } + int number_of_days() { return num_units("days"); } + +#define RBASE parts[0] + + int year_no() { return RBASE->year_no(); } + int month_no() { return RBASE->month_no(); } + int week_no() { return RBASE->week_no(); } + int month_name() { return RBASE->month_name(); } + int month_shortname() { return RBASE->month_shortname(); } + int month_day() { return RBASE->month_day(); } + int month_day_name() { return RBASE->month_day_name(); } + int week_day() { return RBASE->week_day(); } + int year_day() { return RBASE->year_day(); } + string week_name() { return RBASE->week_name(); } + string week_day_name() { return RBASE->week_day_name(); } + string week_day_shortname() { return RBASE->week_day_shortname(); } + int leap_year() { return RBASE->leap_year(); } + + string format_iso_ymd() { return RBASE->format_iso_ymd(); } + string format_ext_ymd() { return RBASE->format_ext_ymd(); } + string format_ymd() { return RBASE->format_ymd(); } + string format_ymd_short() { return RBASE->format_ymd_short(); } + string format_ymd_xshort() { return RBASE->format_ymd_xshort(); } + string format_iso_week() { return RBASE->format_iso_week(); } + string format_iso_week_short() { return RBASE->format_iso_week_short(); } + string format_week() { return RBASE->format_week(); } + string format_week_short() { return RBASE->format_week_short(); } + string format_month() { return RBASE->format_month(); } + string format_month_short() { return RBASE->format_month_short(); } + +#undef RBASE +} + +//------------------------------------------------------------------------ +//! global convinience functions +//------------------------------------------------------------------------ + +//! method TimeRange parse(string fmt,string arg) +//! parse a date, create relevant object +//! fmt is in the format "abc%xdef..." +//! where abc and def is matched, and %x is +//! one of those time units: +//! <pre> +//! %Y absolute year +//! %y dwim year (70-99 is 1970-1999, 0-69 is 2000-2069) +//! %M month (number, name or short name) (needs %y) +//! %W week (needs %y) +//! %D date (needs %y, %m) +//! %d short date (20000304, 000304) +//! %a day (needs %y) +//! %e weekday (needs %y, %w) +//! %h hour (needs %d, %D or %W) +//! %m minute (needs %h) +//! %s second (needs %m) +//! %f fraction of a second (needs %s) +//! %t short time (205314, 2053) +//! </pre> +//! +//! note: +//! Returns 0 if format doesn't match data. + +TimeRange parse(string fmt,string arg) +{ + string nfmt; + nfmt=replace(fmt," %","%*[ \t]%"); // whitespace -> whitespace +#define ALNU "%[^ -,./:-?[-`{-¿]" +#define NUME "%[0-9]" + nfmt=replace(nfmt, + ({"%Y","%y","%M","%W","%D","%a","%e","%h","%m","%s", + "%t","%f","%d","%z"}), + ({ALNU,ALNU,ALNU,"%d","%d","%d",ALNU,"%d","%d","%d", + NUME,NUME,NUME,"%[-+0-9A-Za-z/]"})); + array q=Array.map(replace(fmt,({"%*","%%"}),({"",""}))/"%", + lambda(string s){ return s[..0];})-({""}); + array res=array_sscanf(arg,nfmt); + + if (sizeof(res)<sizeof(q)) + return 0; // parse error + + mapping m=mkmapping(q,res); + + TimeRange low; + + werror("%O\n",m); + + Calendar cal=this_object(); + + if (catch { + + if (m->z) + cal=cal->set_timezone(m->z); + werror("%O\n",m->z); + + string x; + if (m->Y) + m->Y=default_rules->language[f_year_number_from_name](m->Y); + + if (!zero_type(m->Y) && m->D && (int)m->M) + low=m->day=cal->Day(m->Y,(int)m->M,m->D); + + if (m->d) + { + int y,mo,d; + + if (strlen(m->d)==6) + { + [y,mo,d]=(array(int))(m->d/2); + if (y<70) y+=2000; else y+=1900; + } + else if (strlen(m->d)==8) + [y,mo,d]=(array(int))array_sscanf(m->d,"%4s%2s%2s"); + else return 0; + + low=m->day=cal->Day(y,mo,d); + } + else + { + if (!zero_type(m->Y)) m->year=cal->Year(m->Y); + else if (m->y) + { + if (strlen(m->y)<3) + { + m->y=(int)m->y; + if (m->y<70) m->y+=2000; + else if (m->y<100) m->y+=1900; + } + low=m->year=cal->Year(m->y); + } + else low=m->year=cal->Year(); + + if (m->M) + { + m->month=low=m->year->month(m->M); + } + if (m->W) + m->week=low=m->year->week("w"+m->W); + + if (!zero_type(m->D)) + if (stringp(m->D)) return 0; + else m->day=low=(m->month||cal->Month())->day(m->D); + else if (!zero_type(m->a)) + m->day=low=m->year->day(m->a); + else if (!zero_type(m->e)) + m->day=low=(m->week||cal->Week())->day(m->e); + else + low=m->day=cal->Day(); + } + + if (m->t) + { + int h,mi,s; + + if (strlen(m->t)==6) + [h,mi,s]=(array(int))(m->t/2); + else if (strlen(m->t)==4) + [h,mi]=(array(int))(m->t/2),s=0; + else return 0; + + low=m->second=m->day->second(h,mi,s); + } + else if (!zero_type(m->h) && !zero_type(m->m) && !zero_type(m->s)) + low=m->second=m->day->second(m->h,m->m,m->s); + else + { + if (!zero_type(m->h)) + low=m->hour=(m->day||cal->Day())->hour(m->h); + if (!zero_type(m->m)) + low=m->minute=(m->hour||cal->Hour())->minute(m->m); + if (!zero_type(m->s)) + low=m->second=(m->minute||cal->Minute())->second(m->s); + } + return low; + + }) + return 0; +} + +//! function Day dwim_day(string date) +//! Tries a number of different formats on the given date (in order): +//! <pre> +//! <ref>parse</ref> format as in +//! "%y-%M-%D (%M) -W%W-%e (%e)" "2000-03-20 (Mar) -W12-1 (Mon)" +//! "%D%*[ /]%M%*[ /-,]%y" "20/3/2000" "20 mar 2000" "20/3 -00" +//! "%e%*[ ]%D%*[ /]%M%*[ /-,]%y" "Mon 20 Mar 2000" "Mon 20/3 2000" +//! "%y-%M-%D" "2000-03-20", "00-03-20" +//! "%d" "20000320", "000320" +//! "-%y%*[ /]%D%*[ /]%M" "-00 20/3" "-00 20 mar" +//! "-%y%*[ /]%M%*[ /]%D" "-00 3/20" "-00 march 20" +//! "%y%*[ /]%D%*[ /]%M" "00 20 mar" "2000 20/3" +//! "%y%*[ /]%M%*[ /]%D" "2000 march 20" +//! "%D%*[ -/]%M" "20/3" "20 mar" "20-03" +//! "%M%*[ -/]%D" "3/20" "march 20" +//! "%e%*[ -/wv]%W%*[ -/]%y" "mon w12 -00" "1 w12 2000" +//! "%e%*[ -/wv]%W" "mon w12" +//! "%e" "monday" "1" +//! "today" "today" +//! "last %e" "last monday" +//! "next %e" "next monday" +//! </pre> +//! +//! note: +//! Casts exception if it fails to dwim out a day. +//! "dwim" means do-what-i-mean. + +/* tests: + +Calendar.dwim_day("2000-03-20 (Mar) -W12-1 (Mon)"); +Calendar.dwim_day("20/3/2000"); +Calendar.dwim_day("20 mar 2000"); +Calendar.dwim_day("20/3 -00"); +Calendar.dwim_day("Mon 20 Mar 2000" ); +Calendar.dwim_day("Mon 20/3 2000"); +Calendar.dwim_day("2000-03-20"); +Calendar.dwim_day("00-03-20"); +Calendar.dwim_day("20000320"); +Calendar.dwim_day("000320"); +Calendar.dwim_day("-00 20/3" ); +Calendar.dwim_day("-00 20 mar"); +Calendar.dwim_day("-00 3/20" ); +Calendar.dwim_day("-00 march 20"); +Calendar.dwim_day("00 20 mar" ); +Calendar.dwim_day("2000 20/3"); +Calendar.dwim_day("2000 march 20"); +Calendar.dwim_day("20/3" ); +Calendar.dwim_day("20 mar" ); +Calendar.dwim_day("20-03"); +Calendar.dwim_day("3/20" ); +Calendar.dwim_day("march 20"); +Calendar.dwim_day("mon w12 -00" ); +Calendar.dwim_day("1 w12 2000"); +Calendar.dwim_day("mon w12"); +Calendar.dwim_day("monday" ); +Calendar.dwim_day("1"); +Calendar.dwim_day("today"); +Calendar.dwim_day("last monday"); +Calendar.dwim_day("next monday"); + +*/ + +cDay dwim_day(string day) +{ + cDay d; + + foreach ( ({ "%y-%M-%D (%*s) -W%W-%e (%e)", + "%D%*[ /]%M%*[- /,]%y", + "%M %D%*[- /,]%y", + "%e%*[ ]%D%*[ /]%M%*[-/ ,]%y", + "%y-%M-%D", + "-%y%*[ /]%D%*[ /]%M", + "-%y%*[ /]%M%*[ /]%D", + "%y%*[ /]%D%*[ /]%M", + "%y%*[ /]%M%*[ /]%D", + "%D%*[- /]%M", + "%M%*[- /]%D", + "%e%*[- /wv]%W%*[ -/]%y", + "%e%*[- /wv]%W", + "%d"}), + string dayformat) + if ( (d=parse(dayformat,day)) ) return d; + + cDay t=Day(); + if ( (d=parse("%e",day)) ) + { + if (d>=t) return d; + else return (d->week()+1)->place(d); + } + + if (strlen(day)==4) catch { return parse("%M/%D",day/2*"/"); }; + + if (day=="today") return t; + if (day=="tomorrow") return t+1; + if (day=="yesterday") return t-1; + if (sscanf(day,"last %s",day)) + { + cDay d=dwim_day(day); + return (d->week()-1)->place(d); + } + if (sscanf(day,"next %s",day)) + { + cDay d=dwim_day(day); + return (d->week()+1)->place(d); + } + + error("Failed to dwim day from %O\n",day); +} + +TimeofDay dwim_time(string what) +{ + string a,h,m,s; + TimeofDay t; + + foreach ( ({ " %z","%z",""}), + string zone ) + foreach ( ({ "%t", + "%h:%*[ :]%m%*[ :]:%s", + "%h:%*[ :]%m" }), + string todformat ) + foreach ( ({ "%y-%M-%D (%*s) -W%W-%e (%e)", + "%D%*[ /]%M%*[- /,]%y", + "%M %D%*[- /,]%y", + "%e%*[ ]%D%*[ /]%M%*[-/ ,]%y", + "%y-%M-%D", + "%d", + "-%y%*[ /]%D%*[ /]%M", + "-%y%*[ /]%M%*[ /]%D", + "%y%*[ /]%D%*[ /]%M", + "%y%*[ /]%M%*[ /]%D", + "%D%*[- /]%M", + "%M%*[- /]%D", + "%e%*[- /wv]%W%*[ -/]%y", + "%e%*[- /wv]%W" }), + string dayformat ) + { + if ( (t=parse(dayformat+" "+todformat+zone,what)) ) return t; + if ( (t=parse(todformat+zone+" "+dayformat,what)) ) return t; + } + + error("Failed to dwim time from %O\n",what); +} + +//-- auxillary functions------------------------------------------------ + +//! +//! function datetime(int|void unix_time) +//! Replacement for localtime; gives back a mapping: +//! <pre> +//! ([ "year": int // year number (2000 AD=2000, 1 BC==0) +//! "month": int(1..) // month of year +//! "day": int(1..) // day of month +//! "yearday": int(1..) // day of year +//! "week": int(1..) // week of year +//! "week_day": int(1..) // day of week (depending on calendar) +//! "unix": int // unix time +//! "julian": float // julian day +//! "hour": int(0..) // hour of day, including dst +//! "minute": int(0..59) // minute of hour +//! "second": int(0..59) // second of minute +//! "fraction": float // fraction of second +//! "timezone": int // offset to utc, including dst +//! ]); +//! </pre> +//! This is the same as calling <ref>Second</ref>()-><ref to=Second.datetime>datetime</ref>(). +//! +//! function datetime_name(int|void unix_time) +//! function datetime_short_name(int|void unix_time) +//! Compat functions; same as <ref>format_iso</ref> +//! and <ref>format_iso_short</ref>. +//! +//! function string format_iso(void|int unix_time) +//! function string format_iso_short(void|int unix_time) +//! function string format_iso_tod(void|int unix_time) +//! function string format_day_iso(void|int unix_time) +//! function string format_day_iso_short(void|int unix_time) +//! Format the object into nice strings; +//! <pre> +//! iso "2000-06-02 (Jun) -W22-5 (Fri) 11:57:18 CEST" +//! iso_short "2000-06-02 11:57:18" +//! iso_tod "11:57:18" +//! </pre> + +// Sane replacement for localtime(). +mapping(string:int) datetime(int|void unix_time) +{ + return Second("unix",unix_time||time())->datetime(); +} + +string datetime_name(int|void unix_time) +{ + return Second("unix",unix_time||time())->format_iso(); +} + +string datetime_short_name(int|void unix_time) +{ + return Second("unix",unix_time||time())->format_iso_short(); +} + +string format_iso(int|void unix_time) +{ + return Second("unix",unix_time||time())->format_iso(); +} + +string format_iso_short(int|void unix_time) +{ + return Second("unix",unix_time||time())->format_iso_short(); +} + +string format_iso_tod(int|void unix_time) +{ + return Second("unix",unix_time||time())->format_iso_tod(); +} + +string format_day_iso(int|void unix_time) +{ + return Day("unix",unix_time||time())->format_iso(); +} + +string format_day_iso_short(int|void unix_time) +{ + return Day("unix",unix_time||time())->format_iso_short(); +} + diff --git a/lib/modules/Calendar.pmod/localization.h b/lib/modules/Calendar.pmod/localization.h new file mode 100644 index 0000000000000000000000000000000000000000..29c0cccc1becb6ab6ce36eef595f5628a1fa92ad --- /dev/null +++ b/lib/modules/Calendar.pmod/localization.h @@ -0,0 +1,48 @@ +// This file is for the user or installer of pike +// to modify after the local setup. + +// Note that you should modify this file +// in pike's source location +// (.../lib/modules/Calendar.pmod/localization.pmod) +// and reinstall, so the byte-compiling gets correct. + + + +// This should be the default calendar. Americans +// use the Gregorian calendar as default - the big +// difference is that the Gregorian calendar starts +// the weeks on sundays, ISO on mondays. +// Programs will probably get confused if this isn't +// a year-month-day calendar, so don't put "Stardate" here. + +string default_calendar="ISO"; +// string default_calendar="Gregorian"; + + +// The timezone name is strings like "Europe/Stockholm" or "UTC". +// There are two magic timezones, "locale", which +// tries to do the best of the situation, and +// "localtime" which uses localtime for rules (slow!). +// +// Check the TZs.h or TZnames.pmod for correct timezone names. +// +// Also note that "CET" or stuff like that shouldn't be +// used unless you mean it - that summer time ruleset +// might not be what you want. + +string default_timezone="locale"; +// string default_timezone="Europe/Stockholm"; + + + +// The default language to use. This should probably +// not be modified, since more then one program will +// assume the language is english (=ISO). + +string default_language="ISO"; + + + + + + diff --git a/lib/modules/Calendar.pmod/mkrules.pike b/lib/modules/Calendar.pmod/mkrules.pike new file mode 100644 index 0000000000000000000000000000000000000000..84d46b82b1c1b084066490c941988eb17a93aa32 --- /dev/null +++ b/lib/modules/Calendar.pmod/mkrules.pike @@ -0,0 +1,919 @@ +// this is a script to generate rules +// from timezone data files; +// ftp://elsie.nci.nih.gov/pub/ +// (timezone mailing list: tz@elsie.nci.nih.gov) +// +// source datafile are usually found somewhere around zic(8), +// if they exist in the system. +// +// Most systems only have compiled files, just like pike, +// and zic(8) is the usual compiler. + +// pike mkrules.pike ../data/{africa,antarctica,asia,australasia,backward,etcetera,europe,northamerica,pacificnew,southamerica,systemv} +// $Id: mkrules.pike,v 1.1 2000/07/12 19:36:16 mirar Exp $ + + +object cal=Calendar.ISO->set_timezone("UTC"); +function Year=cal->Year; +object nleapy=Year(1999); + +object tzrules; // needed to make timezones, compiled below + +mapping rules=([]); +mapping zones=([]); +mapping links=([]); +array arules=({}); +array azones=({}); + +#define FIXED(D) (yjd+((D)-1)) +#define FIX_L(D) (yjd+leap+((D)-1)) +#define LDAY(D,W) (yjd+((D)-1)-( (yjd+((D)+(8-W)-1)) % 7)) +#define LDAYL(D,W) (yjd+((D)-1)+leap-( (yjd+leap+((D)+(8-W)-1)) % 7)) + +#define FIXID(id) replace(id,"/-+"/1,"__p"/1) + +int parse_offset(string t) +{ + int h,m,s; + string res; + + if (t=="0") return 0; + + res=""; + if (sscanf(t,"-%d:%d:%d%s",h,m,s,res)&&res=="") + return -(h*3600+m*60+s); + res=""; + if (sscanf(t,"-%d:%d%s",h,m,res)&&res=="") + return -(h*3600+m*60); + res=""; + if (sscanf(t,"%d:%d:%d%s",h,m,s,res)&&res=="") + return h*3600+m*60+s; + res=""; + if (sscanf(t,"-%d:%d%s",h,m,res)&&res=="") + return h*3600+m*60; + + complain("failed to parse offset %O\n",t); +} + +array parse_tod(string t) +{ + int h,m,s; + string res; + + if (t=="0") return 0; + + if (sscanf(t,"%d:%d:%d%s",h,m,s,res)==4) + return ({h*3600+m*60+s,res}); + res=""; + if (sscanf(t,"%d:%d%s",h,m,res)==3) + return ({h*3600+m*60,res}); + if (sscanf(t,"%d%s",h,res)==2) + return ({h*3600,res}); + + complain("failed to parse time of day %O\n",t); +} + +class Shift +{ + string dayrule; + int time; + string timetype; + int offset; + string s; + string comment; + + void create(array a) + { + switch (sizeof(a)) + { + case 5: + dayrule=think_day(a[0],a[1]); + comment=a[0]+" "+a[1]; + [time,timetype]=parse_tod(a[2]); + switch (timetype) + { + case "": timetype="w"; break; + case "s": case "u": case "w": break; + default: complain("unknown time of day type %O\n",timetype); + } + offset=parse_offset(a[3]); + s=(a[4]=="-")?"":a[4]; + break; + case 6: + [dayrule,comment,time,timetype,offset,s]=a; + break; + default: + error("illegal size of a\n"); + } + } + + string _sprintf(int t) + { + return (t=='O')? + sprintf("Shift(%s,%d%s,%+d,%O)", + dayrule,time,timetype,offset,s): + 0; + } + + int `==(Shift other) + { + return ( dayrule==other->dayrule && + time==other->time && + timetype==other->timetype && + offset==other->offset && + s==other->s ); + } + function(Shift:int) __equal=`==; + + constant wday=(["Mon":1,"Tue":2,"Wed":3,"Thu":4,"Fri":5,"Sat":6,"Sun":7]); + constant vmonth=(<"Jan","Feb","Mar","Apr","May","Jun", + "Jul","Aug","Sep","Nov","Dec">); + + string think_day(string mon,string rule) + { + int d; + string ds; + + if (mon=="") return "0"; + if (rule==(string)(d=(int)rule)) + { + if (mon=="Feb") return "FIXED("+(31+d)+")"; + if (mon=="Jan") return "FIXED("+(d)+")"; + return "FIX_L("+nleapy->month(mon)->day(d)->year_day()+")"; + } + else if (sscanf(rule,"last%s",ds)) + { + int wd=wday[ds]; + if (!wd) complain("unknown weekday %O (last%s)\n",ds,ds); + + if (mon=="Jan") + return "LDAY ("+31+","+wd+")"; + + return "LDAYL("+nleapy->month(mon)->day(-1)->year_day()+ + ","+wd+")"; + } + else if (sscanf(rule,"%s>=%d",ds,d)) + { + int wd=wday[ds]; + if (!wd) complain("unknown weekday %O (last%s)\n",ds,ds); + + if (d>24 && mon=="Feb") + complain("can't handle Feb %d in a >= rule\n",d); + + if (mon=="Jan") + return "LDAY ("+(nleapy->month(mon)->day(d)->year_day()+6)+ + ","+wd+")"; + + return "LDAYL("+(nleapy->month(mon)->day(d)->year_day()+6)+ + ","+wd+")"; + } + else if (sscanf(rule,"%s<=%d",ds,d)) + { + int wd=wday[ds]; + if (!wd) complain("unknown weekday %O (last%s)\n",ds,ds); + + if (d>24 && mon=="Feb") + complain("can't handle Feb %d in a <= rule\n",d); + + if (mon=="Jan" || mon=="Feb") + return "LDAY ("+(nleapy->month(mon)->day(d)->year_day())+ + ","+wd+")"; + + return "LDAYL("+(nleapy->month(mon)->day(d)->year_day())+ + ","+wd+")"; + } + else + complain("unknown rule method %O\n",rule); + } + + Shift|array ``+(array|Shift s) + { + if (!s) return this_object(); + if (!arrayp(s)) s=({s}); + return s+({this_object()}); + } + + int ldayl_is_fix_l(int d1,int wd,int d2,int yn1,int yn2) + { + object y1=Year(yn1); + object y2=Year(yn2); + int yjd,leap; + + yjd=y1->julian_day(); + leap=y1->leap_year(); + int d1=LDAYL(d1,wd); + + yjd=y2->julian_day(); + leap=y2->leap_year(); + int d2=FIX_L(d2); + + return d1==d2; + } + + Shift try_promote(Shift t,int y0,int y1) + { +// this is year y0 +// t is year y1 + if (t==this_object()) return t; // same! + if (t->time!=time || + t->timetype!=timetype || + t->offset!=offset || + t->s!=s) return 0; // no chance + + int a,b,c; + if (sscanf(dayrule,"LDAYL(%d,%d)",a,b)==2 && + sscanf(t->dayrule,"FIX_L(%d)",c)==1) + if (ldayl_is_fix_l(a,b,c,y0,y1)) + return this_object(); // ldayl + else + return 0; // no + if (sscanf(t->dayrule,"LDAYL(%d,%d)",a,b)==2 && + sscanf(dayrule,"FIX_L(%d)",c)==1) + if (ldayl_is_fix_l(a,b,c,y1,y0)) + return t; // ldayl + else + return 0; // no + + return 0; + } + + string dump(int lastoffset,multiset ys) + { + string t; + array z=(array)ys; + int l=Year(z[0])->leap_year(); + foreach (z[1..],int y) if (Year(y)->leap_year()!=l) { l=2; break; } + switch (timetype) + { + case "s": t=sprintf("UO%+d",time); break; + case "u": t=""+time; break; + case "w": t=sprintf("UO%+d",(time-lastoffset)); break; + default: error("illegal state\n"); + } + string r=dayrule; + if (l!=2) + { + int d,w; + if (sscanf(r,"FIX_L(%d)",d)) r=sprintf("FIXED(%d)",d+l); + else if (sscanf(r,"LDAYL(%d,%d)",d,w)==2) + r=sprintf("LDAY (%d,%d)",d+l,w); + } + return sprintf("({%-12s,%-10s,%-5d,%-6O}), %s", + r,t,offset,s,comment!=""?"// "+comment:""); + } +} + +class Rule +{ + string id; + + mapping rules=([]); + + int amt=0; + + void create(string _id) { id=_id; } + + void add(string line) + { + array a= array_sscanf(line, replace("%s %s %s %s %s %s %s %[^\t ]", + " ","%*[ \t]")); + + if (sizeof(a)<8) complain("illegal rule line format\n"); + + if (!(int)a[0] && a[0]!="min") + complain("unknown year %O\n",a[0]); + +// --- + +#define INF_YEAR 2050 +#define NUL_YEAR 1850 + + int y1=(int)a[0] || NUL_YEAR; + int y2; + if (a[1]=="max") y2=INF_YEAR; + else if (a[1]=="only") y2=y1; + else if (!(y2=(int)a[1])) + complain("unknown year %O\n",a[1]); + else if (y2>=INF_YEAR) + complain("big year\n"); + + Shift sh=Shift(a[3..]); + + switch (a[2]) + { + case "-": for (;y1<=y2;y1++) rules[y1]+=sh; break; + case "odd": + if (!(y1&1)) y1++; + for (;y1<=y2;y1+=2) rules[y1]+=sh; + break; + case "even": + if ((y1&1)) y1++; + for (;y1<=y2;y1+=2) rules[y1]+=sh; + break; + default: + complain("unknown year type %O\n",a[2]); + } + } + + string dump() + { + mapping r2=([]); + Shift last=Shift(({"0","?",0,"u",0,"?"})); + Shift first=last; + string res=""; + + if (!r2[NUL_YEAR]) r2[NUL_YEAR]=({last}); + + int y=min(@indices(rules)); + for (;y<=INF_YEAR; y++) + [r2[y],last]=mkperiods(rules[y],last,first); + + res+=("class "+ + FIXID(id)+"\n" + "{\n" + " inherit TZRules;\n" + " static array(array(string|int)) jd_year_periods(int jd)\n" + " {\n" + " [int y,int yjd,int leap]=gregorian_yjd(jd);\n" + " switch (y)\n" + " {\n"); + + string s="",t; + + int y,mn=min(@indices(rules-(<NUL_YEAR>))); + + for (y=INF_YEAR;sizeof(r2);y--) + if (r2[y]) + { + array z=r2[y]; + multiset my=(<y>); + + foreach (indices(r2),int y2) + if (join_periods(z,r2[y2],y,y2)) + my[y2]=1; + + foreach ((array)my,int y2) m_delete(r2,y2); + + string t=""; + + int y0=min(@(array)my); + int y2=max(@(array)my); + for (; y0<=y2; y0++) + if (my[y0]) + { + int y1=y0; + while (my[++y1]); + + y1--; + + if (y0==NUL_YEAR) + { + if (my[INF_YEAR]) + t+=" default: // .."+max(y1,mn-1)+ + " and ½½½..\n"; + else + t+=" default: // .."+max(y1,mn-1)+":\n"; + } + else if (y0==y1) + t+=" case "+y0+":\n"; + else if (y1==2050) + { + if (!my[NUL_YEAR]) t+=" case "+y0+"..:\n"; + else t=replace(t,"½½½",(string)y0); + } + else + t+=" case "+y0+".."+y1+":\n"; + + y0=y1; + } + + int lastoffset=0; + string res=" "*12+"return ({"; + foreach (z,Shift s) + { + res+=s->dump(lastoffset,my)+("\n"+" "*21); + lastoffset=s->offset; + } + array resa=res/"\n"; + resa[-2]=replace(resa[-2],", ","});"); + + t+=resa[..sizeof(resa)-2]*"\n"+"\n"; + s=t+s; + } + res+=(s+ + " }\n" + " }\n" + "}\n\n"); + + return res; + } + + int join_periods(array s,array t,int y0,int y1) + { + if (equal(s,t)) + return 1; + if (sizeof(s)!=sizeof(t)) return 0; + if (s[0]!=t[0]) return 0; +// try promote + array q=s[..0]; + int i; + for (i=1; i<sizeof(s); i++) + { + Shift u=s[i]->try_promote(t[i],y0,y1); + if (!u) return 0; + q+=({u}); + } + for (i=1; i<sizeof(s); i++) + s[i]=q[i]; // destructive + return 1; + } + + array(array(Shift)|Shift) mkperiods(array|Shift s,Shift last,Shift first) + { + if (!s) s=({}); + if (!arrayp(s)) s=({s}); + + sort(map(s,lambda(Shift s) + { + return array_sscanf(s->dayrule,"%*[^(](%d")[0]; + }),s); + + if (first->s=="?") + foreach (s,Shift d) if (!d->offset) first->s=d->s; + + s=({last,@s}); + + last=Shift( ({"0","",0,"u", + s[-1]->offset,s[-1]->s}) ); + + return ({s, last}); + } +} + +class Zone +{ + string id; + + array rules=({}); + + void create(string _id) { id=_id; } + + void add(string line) + { + array a= array_sscanf(line, replace("%s %s %s %s", + " ","%*[ \t]")); + if (sizeof(a)<4) + complain("parse error\n"); + + array a=({parse_offset(a[0]), // offset + a[1], // rule or added offset + a[2], // string + a[3], + 0, 0, "tz", 0}); // until + a[5]=rule_shift(a); + a[4]=clone_rule(a); + + rules+=({a}); + } + + string clone_rule(array a) + { + int h,m,s,roff=-17; + if (a[1]=="-") roff=0; + else if (sscanf(a[1],"-%d:%d:%d",h,m,s)==3) roff=h*3600+m*60+s; + else if (sscanf(a[1],"%d:%d:%d",h,m,s)==3) roff=h*3600+m*60+s; + else if (sscanf(a[1],"-%d:%d",h,m)==2) roff=h*3600+m*60; + else if (sscanf(a[1],"%d:%d",h,m)==2) roff=h*3600+m*60; + + if (roff==-17) // based on DST rule + return sprintf( + "TZrules.%s(%d,%O)", + FIXID(a[1]),-a[0],a[2]); + else // simple timezone + return sprintf( + "Ruleset.Timezone(%d,%O)", + -(roff+a[0]),a[2]); + } + + string rule_shift(array a) + { + if (a[3]=="" || a[3][0]=='#') return "forever"; + + string in=a[3]; + sscanf(in,"until %s",in); + sscanf(in,"%s#",in); + +// werror("%O\n",in); + + int y,d=1,t=0; + string mn="Jan",ty="w"; + if (sscanf(in,"%d%*[ \t]%s%*[ \t]%d%*[ \t]%[^# \t]", + y,mn,d,string tod)==7 && + tod!="") + [t,ty]=parse_tod(tod); + else if (!(sscanf(in,"%d%*[ \t]%[A-Za-z]%*[ \t]%d",y,mn,d)==5 || + (sscanf(in,"%d%*[ \t]%[A-Za-z]",y,mn)==3 && mn!="") || + (mn="Jan",sscanf(in,"%d",y)))) + { +// werror("%O\n",array_sscanf(in,"%d%*[ \t]%[A-Za-z]")); + complain("failed to understand UNTIL %O\n",in); + y=2000; + } + + int utc0=Year(y)->month(mn)->day(d)->unix_time(); + switch (ty) + { + case "u": // utc time +// a[3]=sprintf("[%d+%d=%d] %s\n",utc0,t,utc0+t,a[3]); + return (string)(utc0+t); break; + case "s": // local standard time +// a[3]=sprintf("[%d+%d-%d=%d] %s\n",utc0,t,a[0],utc0+t-a[0],a[3]); + return (string)(utc0+t-a[0]); break; + case "w": case "": // with rule; check rule + int h,m,s,roff=-17; + if (a[1]=="-") roff=0; + else if (sscanf(a[1],"-%d:%d:%d",h,m,s)==3) roff=h*3600+m*60+s; + else if (sscanf(a[1],"%d:%d:%d",h,m,s)==3) roff=h*3600+m*60+s; + else if (sscanf(a[1],"-%d:%d",h,m)==2) roff=h*3600+m*60; + else if (sscanf(a[1],"%d:%d",h,m)==2) roff=h*3600+m*60; + + if (roff==-17) // based on DST rule + { + if (!tzrules) return 0; // can't do that now + object|program rules=tzrules[FIXID(a[1])]; + if (!rules) + { + werror("ERROR: Missing rule %O (used in Zone %O)\n",a[1],id); + return "[err]"; + } + rules=rules(-a[0],"-"); + + roff=rules->tz_jd(Year(y)->month(mn)->day(d)->julian_day())[0]; + +// werror("Using %O:%O\n",rules,roff); + + return (string)(utc0+t-roff); + } + return (string)(utc0+t-a[0]-roff); + + default: + complain("unknown time of day modifier %O\n",ty); + } + } + + string dump() + { + string cid=FIXID(id); + string res=""; + + if (!sizeof(rules)) + { + res+=("// skipped %O due to errors\n",id); + return res; + } + + if (sizeof(rules)==1) // simple zone + { + res+=("Ruleset.Timezone "+cid+"="+ + rules[0][4]+";\n"); + return res; + } + + mapping rname=([]); + int n=1; + + foreach (rules,array a) + if (rname[a[4]]) a[6]=rname[a[4]]; + else a[6]=rname[a[4]]="tz"+n++; + + res+=("class "+cid+"\n" + "{\n" + " inherit TZHistory;\n" + " Ruleset.Timezone "+ + sort(values(rname))*","+";\n" + " Ruleset.Timezone whatrule(int ux)\n" + " {\n" + ); + + foreach (rules,array a) + { + if (!a[5]) a[5]=rule_shift(a); + + string s=""; + sscanf(a[3],"%s#%*[ \t]%s",a[3],s); + a[3]="from "+reverse(array_sscanf(reverse(a[3]),"%*[ \t]%s")[0]); + a[7]=s; + } + + array last=rules[-1]; + int n=sizeof(rules); + foreach (reverse(rules)[1..],array a) + { + res+=sprintf(" if (ux>=%s) // %s %s\n" + " return %s || (%s=%s);\n", + a[5],a[3],last[7],last[6],last[6],last[4]); + n--; + last=a; + } + if (last[7]!="") + res+=sprintf(" // %s\n",last[7]); + res+=sprintf(" return %s || (%s=%s);\n", + last[6],last[6],last[4]); + + res+=(" }\n" + "}\n"); + + return res; + } +} + +void complain(string fmt,mixed ... args) +{ + throw( sprintf(fmt,@args) ); +} + +void collect_rules(string file) +{ + int n=0; + werror("reading %O...\n",file); + string s=Stdio.read_bytes(file),t; + if (!s) + { + werror("%s:-: Failed to open file: %s\n",file,strerror(errno())); + return; + } + + Zone lastz; + Rule lastr; + + foreach (s/"\n",string line) + { + n++; + mixed err=catch + { + if (line[..0]!="#") + if (sscanf(line,"Zone%*[ \t]%[^ \t]%*[ \t]%s",s,t)==4) + { + if (zones[s]) lastz=zones[s]->add(t); + else (lastz=zones[s]=Zone(s))->add(t),azones+=({lastz}); + } + else if (sscanf(line,"Rule%*[ \t]%[^ \t]%*[ \t]%s",s,t)==4) + { + if (rules[s]) rules[s]->add(t); + else (lastr=rules[s]=Rule(s))->add(t),arules+=({lastr}); + lastz=0; + } + else if (sscanf(line,"Link%*[ \t]%[^ \t]%*[ \t]%[^ \t]",s,t)==4) + { + // link t to s + if (links[s]) links[s]+=({t}); + else links[s]=({t}); + } + else if (sscanf(line,"%*[ \t]%[-0-9]%s",s,t)==3 && strlen(s)) + { + if (!lastz) complain("implicit zone line w/o zone\n"); + lastz->add(s+t); + } + else if ((t="",sscanf(line,"%[ \t]",t),t==line)) + ; + else if (sscanf(line,"%*[ \t]#%s",t,s)==2) + ; + else + complain("unknown keyword %O...\n",line[..10]); + }; + if (err) + if (stringp(err)) + werror("%s:%d: %s",file,n,err); + else + throw(err); + } +} + +int main(int ac,array(string) am) +{ + if (sizeof(am)<1) + { + werror("USAGE: %s datafile [datafile ...]\n",am[0]); + return 1; + } + map(am[1..],collect_rules); + + write("thinking...\n"); + + string t=TZrules_base; + + foreach (arules,Rule r) + t+=r->dump(); + + tzrules=compile_string(t)(); + + mv("TZrules.pmod","TZrules.pmod~"); + werror("writing TZrules.pmod (%d bytes)...",strlen(t)); + Stdio.File("TZrules.pmod","wtc")->write(t); + werror("\n"); + + t="// ----------------------------------------------------------------\n" + "// Timezones\n" + "//\n" + "// NOTE: this file is generated by mkrules.pike;\n" + "// please do not edit manually /Mirar\n" + "// ----------------------------------------------------------------\n" + "\n" + "import \".\";\n\n"; + + t+=("// "+"-"*70+"\n" + "// Timezones\n" + "// "+"-"*70+"\n\n"); + + mixed err=catch { + foreach (azones,Zone z) + if (sizeof(z->rules)==1) + { + t+=z->dump(); + if (links[z->id]) + foreach(links[z->id],string s) + t+="Ruleset.Timezone "+FIXID(s)+"="+ + FIXID(z->id)+";\n"; + } + }; + if (err) if (stringp(err)) error(err); else throw(err); + + t+=("\n" + "// "+"-"*70+"\n" + "// Timezones with an attitude\n" + "// "+"-"*70+"\n" + "\n"); + + mixed err=catch { + foreach (azones,Zone z) + if (sizeof(z->rules)!=1) + { + t+=z->dump(); + if (links[z->id]) + foreach(links[z->id],string s) + t+="constant "+FIXID(s)+"="+ + FIXID(z->id)+";\n"; + t+="\n"; + } + }; + if (err) if (stringp(err)) error(err); else throw(err); + + t+=("\n" + "// "+"-"*70+"\n"); + + mv("TZs.pike","TZs.pike~"); + werror("writing TZs.h (%d bytes)...",strlen(t)); + Stdio.File("TZs.h","wtc")->write(t); + werror("\n"); + + mapping zs=([]); + foreach (azones,Zone z) + if (sscanf(z->id,"%s/%s",string s,string t)==2) + zs[s]=(zs[s]||({}))+({t}); + + t="// ----------------------------------------------------------------\n" + "// Timezone names\n" + "//\n" + "// NOTE: this file is generated by mkrules.pike;\n" + "// please do not edit manually /Mirar\n" + "// ----------------------------------------------------------------\n" + "\n" + "mapping _module_value=\n" + "([\n"; + foreach (indices(zs)-({"SystemV","Etc"}),string co) + t+=(replace( + sprintf(" %-13s({%-=63s\n", + sprintf("%O:",co), + map(zs[co],lambda(string s) { return sprintf("%O",s); }) + *", "+"}),"),({", ",", "}),",,"/1)); + t+="]);\n\n"; + + mv("TZnames.pike","TZnames.pike~"); + werror("writing TZnames.pmod (%d bytes)...",strlen(t)); + Stdio.File("TZnames.pmod","wtc")->write(t); + werror("\n"); + + return 0; +} + + +string TZrules_base= +#"// ---------------------------------------------------------------- +// Daylight savings and war time rules +// +// NOTE: this file is generated by mkrules.pike; +// please do not edit manually /Mirar +// ---------------------------------------------------------------- + +// ---------------------------------------------------------------- +// all rules are based on the gregorian calendar, so +// this is the gregorian rule: +// ---------------------------------------------------------------- + +static array gregorian_yjd(int jd) +{ + int d=jd-1721426; + + int century=(4*d+3)/146097; + int century_jd=(century*146097)/4; + int century_day=d-century_jd; + int century_year=(100*century_day+75)/36525; + + int y=century*100+century_year+1; + + return + ({ + y, + 1721426+century_year*365+century_year/4+century_jd, + (!(((y)%4) || (!((y)%100) && ((y)%400)))) + }); +} + +// ---------------------------------------------------------------- +// Base \"Timezone with rules\" class +// ---------------------------------------------------------------- + +class TZRules +{ + constant is_timezone=1; + constant is_dst_timezone=1; + static int offset_to_utc; + string name; + + static function(string:string) tzformat; + static array names; + + static void create(int offset,string _name) + { + offset_to_utc=offset; + name=_name; + if (search(name,\"/\")!=-1) + { + names=name/\"/\"; + tzformat=lambda(string s) + { + if (s==\"\") return names[0]; else return names[1]; + }; + } + else + tzformat=lambda(string s) { return sprintf(name,s); }; + } + +// the Rule: +// which julian day does dst start and end this year? + static array(array(string|int)) jd_year_periods(int jd); + +// is (midnight) this julian day dst? + array tz_jd(int jd) + { + array(array(string|int)) a=jd_year_periods(jd); + + int i=0,n=sizeof(a)-1; + while (i<n) + { + array b=a[i+1]; + if (jd<b[0]) break; + if (jd==b[0] && -offset_to_utc+b[1]>=0) break; + i++; + } + + return ({offset_to_utc-a[i][2],tzformat(a[i][3])}); + } + +// is this unixtime (utc) dst? + array tz_ux(int ux) + { + int jd=2440588+ux/86400; + array(array(string|int)) a=jd_year_periods(jd); + + int i=0,n=sizeof(a)-1; + while (i<n) + { + array b=a[i+1]; + if (jd<b[0]-1) break; + if (jd<b[0]+1 && + ux<(b[0]-2440588)*86400+b[1]) break; + i++; + } + + return ({offset_to_utc-a[i][2],tzformat(a[i][3])}); + } + + string _sprintf(int t) { return (t=='O')?\"Timezone(\"+name+\")\":0; } + + int raw_utc_offset() { return offset_to_utc; } +} + +// ---------------------------------------------------------------------- +// DST Rules +// ---------------------------------------------------------------------- + +// useful macros +#define FIXED(D) (yjd+((D)-1)) +#define FIX_L(D) (yjd+leap+((D)-1)) +#define LDAY(D,W) (yjd+((D)-1)-( (yjd+((D)+(8-W)-1)) % 7)) +#define LDAYL(D,W) (yjd+((D)-1)+leap-( (yjd+leap+((D)+(8-W)-1)) % 7)) +#define UO offset_to_utc + +// ---------------------------------------------------------------------- +"; diff --git a/lib/modules/Calendar.pmod/module.pmod b/lib/modules/Calendar.pmod/module.pmod index 302ac793ecb0d90c75c69a52141294345dfc2cc0..08b8d17334326d414b639f011a02c221d2c56084 100644 --- a/lib/modules/Calendar.pmod/module.pmod +++ b/lib/modules/Calendar.pmod/module.pmod @@ -1,167 +1,21 @@ +static private int stage=0; +static private object defcal; +static private multiset protect=(<"YMD">); -//! module Calendar -//! -//! This module implements calendar calculations, and base classes -//! for time units. -//! -//! class time_unit -//! -//! method array(string) lesser() -//! Gives a list of methods to get lesser (shorter) time units. -//! ie, for a month, this gives back <tt>({"day"})</tt> -//! and the method <tt>day(mixed n)</tt> gives back that -//! day object. The method <tt>days()</tt> gives back a -//! list of possible argument values to the method <tt>day</tt>. -//! Concurrently, <tt>Array.map(o->days(),o->day)</tt> gives -//! a list of day objects in the object <tt>o</tt>. -//! -//! -//! Ie:<pre> -//! array(string) lesser() - gives back a list of possible xxx's. -//! object xxxs() - gives back a list of possible n's. -//! object xxx(mixed n) - gives back xxx n -//! object xxx(object(Xxx) o) - gives back the corresponing xxx -//! </pre> -//! -//! The list of n's (as returned from xxxs) are always in order. -//! -//! There are two n's with special meaning, 0 and -1. -//! 0 always gives the first xxx, equal to -//! my_obj->xxx(my_obj->xxxs()[0]), and -1 gives the last, -//! equal to my_obj->xxx(my_obj->xxxs()[-1]). -//! -//! To get all xxxs in the object, do something like -//! <tt>Array.map(my_obj->xxxs(),my_obj->xxx)</tt>. -//! -//! xxx(object) may return zero, if there was no correspondning xxx. -//! -//! method array(string) greater() -//! Gives a list of methods to get greater (longer) time units -//! from this object. For a month, this gives back <tt>({"year"})</tt>, -//! thus the method <tt>month->year()</tt> gives the year object. -//! -//! method object next() -//! method object prev() -//! method object `+(int n) -//! method object `-(int n) -//! method object `-(object x) -//! next and prev gives the logical next and previous object. -//! The <tt>+</tt> operator gives that logical relative object, -//! ie <tt>my_day+14</tt> gives 14 days ahead. -//! <tt>-</tt> works the same way, but can also take an object -//! of the same type and give the difference as an integer. +#include "localization.h" -#define error(X) throw(({(X),backtrace()})) - -class _TimeUnit -{ - object this=this_object(); - - array(string) greater() { return ({}); } - array(string) lesser() { return ({}); } - - int `<(object x) { error("'< undefined\n"); } - int `>(object x) { error("'> undefined\n"); } - int `==(object x) { error("'== undefined\n"); } - - object `+(int n) { error("`+ undefined\n"); } - object|int `-(int n) { error("`- undefined\n"); } - - object next() { return this+1; } - object prev() { return this+(-1); } -} - - - - - -string print_month(void|object month,void|mapping options) +#if 1 +mixed `[](string what) { - object w; - object today; - string res=""; - - if (!month) // resolv thing here is to avoid compile-time resolve - month=master()->resolv("Calendar")["Gregorian"]["Month"](); - - options=(["mark_today":1, - "week_space":3, - "weeks":1, - "days":1, - "title":1, - "notes":([])]) | (options || ([])); - options=(["date_space":(options->mark_today?3:2)])|options; - - - today=function_object(object_program(month))->Day(); - - w=month->day(1)->week(); - - res=""; - if (options->weeks) res+=" "+" "*options->week_space; - if (options->title) - res+=sprintf("%|*s\n", - (1+options->date_space)*sizeof(w->days())-1, - intp(options->title) - ?(String.capitalize(month->name()+" ") - +month->year()->name()) - :options->title); - - if (options->days) + if ( protect[what] ) return ([])[0]; + if (!defcal) { - if (options->weeks) res+=" "+" "*options->week_space; - foreach (Array.map(w->days(),w->day)->week_day_name(),string n) - res+=sprintf("%*s ",options->date_space,n[0..options->date_space-1]); - res+="\n"; + if (stage) return ([])[0]; + stage++; + defcal=master()->resolv("Calendar")[default_calendar]; } - - string daynotes=""; - - if (sizeof(Array.filter( - Array.map(month->days(),month->day), - lambda(object d) { return !!options->notes[d]; }))) - daynotes="\n%-|"+options->date_space+"s"; - - do - { - array a; - array b; - object d; - string format=""; - - a=Array.map(Array.map(w->days(),w->day), - lambda(object d) - { if (d->month()!=month) return 0; else return d; }); - - if (options->weeks) - res+=sprintf("%*s ",options->week_space,w->name()); - foreach (a,d) - if (d) - if (!options->mark_today || d!=today) - res+=sprintf("%* |d ", - options->date_space, - d->month_day()); - else - res+=sprintf(">%* |d<", - options->date_space-1, - d->month_day()); - else res+=" "+" "*options->date_space; - - if (options->notes[w]) - res+=sprintf("%-=*s", - options->week_note_column_width, - options->notes[w]); - - res+="\n"; - - if (daynotes) - { - - } - - w++; - } - while (w->day(0)->month()==month); - - return res; + if (what=="II") return 1; // Calendar.II + return defcal[what]; } +mixed `-> = `[]; +#endif diff --git a/lib/modules/Calendar_I.pmod/Austrian.pmod b/lib/modules/Calendar_I.pmod/Austrian.pmod new file mode 100644 index 0000000000000000000000000000000000000000..216139e91bcd13c9dab722b6ca239bc9e29f965c --- /dev/null +++ b/lib/modules/Calendar_I.pmod/Austrian.pmod @@ -0,0 +1,36 @@ +// by Martin Baehr <mbaehr@email.archlab.tuwien.ac.at> + +inherit Calendar.ISO:ISO; + +void create() +{ + month_names= + ({"jänner","feber","märz","april","mai","juni","juli","august", + "september","oktober","november","dezember"}); + + week_day_names= + ({"montag","dienstag","mittwoch","donnerstag", + "freitag","samstag","sonntag"}); +} + +class Week +{ + inherit ISO::Week; + + string name() + { + return "w"+(string)this->number(); + } +} + +class Year +{ + inherit ISO::Year; + + string name() + { + if (this->number()<=0) + return (string)(1-this->number())+" v. Chr."; + return (string)this->number(); + } +} diff --git a/lib/modules/Calendar_I.pmod/Gregorian.pmod b/lib/modules/Calendar_I.pmod/Gregorian.pmod new file mode 100644 index 0000000000000000000000000000000000000000..c4d170c5d23fd7cd6dbb59dca476abaa2b68b502 --- /dev/null +++ b/lib/modules/Calendar_I.pmod/Gregorian.pmod @@ -0,0 +1,1543 @@ +// by Mirar + +//! module Calendar +//! submodule Gregorian +//! time units: +//! <ref>Year</ref>, <ref>Month</ref>, <ref>Week</ref>, <ref>Day</ref> +//! +//! class + +array(string) month_names= + ({"January","February","March","April","May","June","July","August", + "September","October","November","December"}); + +array(string) week_day_names= + ({"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"}); + +/* calculated on need */ + +mapping week_day_mapping,month_mapping; + +class _TimeUnit +{ + inherit Calendar._TimeUnit; + + program vYear=function_object(object_program(this_object()))->Year; + program vDay=function_object(object_program(this_object()))->Day; + program vMonth=function_object(object_program(this_object()))->Month; + program vWeek=function_object(object_program(this_object()))->Week; + program vHour=function_object(object_program(this_object()))->Hour; + program vMinute=function_object(object_program(this_object()))->Minute; + program vSecond=function_object(object_program(this_object()))->Second; +} + +//== Year ==================================================================== + +class Year +{ +//! class Year +//! A <ref>Calendar.time_unit</ref>. +//! +//! Lesser units: <ref>Month</ref>, <ref>Week</ref>, <ref>Day</ref> +//! Greater units: none +//! +//! + inherit _TimeUnit; + +//-- variables ------------------------------------------------------ + + int y; + + array days_per_month; + array month_start_day; + +//-- standard methods ----------------------------------------------- + + string is() + { + return "year"; + } + + array(string) lesser() + { + return ({"month","week","day"}); + } + + array(string) greater() + { + return ({}); + } + + void create(int ... arg) + { + if (!sizeof(arg)) + { + object yp=vDay()->year(); + y=yp->y; + } + else + y=arg[0]; + + int l=this->leap(); + days_per_month= + ({-17, 31,28+l,31,30,31,30,31,31,30,31,30,31}); + + month_start_day=allocate(sizeof(days_per_month)); + + for (int i=1,l=0; i<sizeof(days_per_month); i++) + month_start_day[i]=l,l+=days_per_month[i]; + } + + int `<(object x) + { + return y<(int)x; + } + + int `==(object x) + { + return + object_program(x)==object_program(this) && + (int)x==y; + } + + int hash() { return y*113; } + + int `>(object x) + { + return y>(int)x; + } + + object next() + { + return vYear(y+1); + } + + object prev() + { + return vYear(y-1); + } + + object `+(int n) + { + return vYear(y+n); + } + + int|object `-(int|object n) + { + if (objectp(n) && object_program(n)==vYear) return y-n->y; + return this+-n; + } + +//-- nonstandard methods -------------------------------------------- + + int julian_day(int d) // jd%7 gives weekday, mon=0, sun=6 + { + int a; + a = (y-1)/100; + return 1721426 + d - a + (a/4) + (36525*(y-1))/100; + } + + int leap() + { + if (!(y%400)) return 1; + if (!(y%100)) return 0; + return !(y%4); + } + + int leap_day() + { + return 31+24-1; // 24 Feb + } + + int number_of_weeks() + { + int j=julian_day(0)%7; + + // years that starts on a thursday has 53 weeks + if (j==3) return 53; + // leap years that starts on a wednesday has 53 weeks + if (j==2 && this->leap()) return 53; + // other years has 52 weeks + return 52; + } + + int number_of_days() + { + return 365+this->leap(); + } + + int number() + { + return y; + } + + string name() + { + if (y>0) return (string)y+" AD"; + else return (string)(-y+1)+" BC"; + } + + mixed cast(string what) + { + switch (what) + { + case "int": return this->number(); + case "string": return this->name(); + default: + throw(({"can't cast to "+what+"\n",backtrace()})); + } + } + +//-- less ----------------------------------------------------------- + + object month(object|string|int n) + { + if (objectp(n)) + if (object_program(n)==vMonth) + n=n->number(); + + if (stringp(n)) + { + if (!month_mapping) + { + month_mapping= + mkmapping(Array.map(month_names, lower_case)+ + Array.map(month_names, + lambda(string s) + { return lower_case(s[0..2]); } ), + (indices(allocate(13))[1..]) * 2); + } + n=month_mapping[lower_case(n)]; + if (!n) return 0; + } + + if (n<0) + return vMonth(y,13+n); + else + return vMonth(y,n||1); + } + + array(mixed) months() + { + return month_names; + } + + object week(object|int n) + { + if (objectp(n)) + if (object_program(n)==vWeek) + { + n=n->number(); + if (n>number_of_weeks()) return 0; /* no such week */ + } + + if (n<0) + return vWeek(y,this->number_of_weeks()+n+1); + else + return vWeek(y,n||1); + } + + array(mixed) weeks() + { + return indices(allocate(this->number_of_weeks()+1))[1..]; + } + + object day(object|int n) + { + if (objectp(n)) + if (object_program(n)==vDay) + { + object o=n->year(); + n=n->year_day(); + if (o->leap() && n==o->leap_day()) + if (!this->leap()) return 0; + else n=this->leap_day(); + else + { + if (o->leap() && n>o->leap_day()) n--; + if (this->leap() && n>=this->leap_day()) n++; + } + if (n>=number_of_days()) return 0; /* no such day */ + } + else return 0; /* illegal object */ + + if (n<0) + return vDay(y,this->number_of_days()+n); + else + return vDay(y,n); + } + + array(mixed) days() + { + return indices(allocate(this->number_of_days())); + } + +//-- more ----------------------------------------------------------- + + // none +}; + + +// + +//== Month =================================================================== + +class Month +{ + inherit _TimeUnit; +//-- variables ------------------------------------------------------ + + int y; + int m; + +//-- standard methods ----------------------------------------------- + + string is() + { + return "month"; + } + + array(string) lesser() + { + return ({"day"}); + } + + array(string) greater() + { + return ({"year"}); + } + + void create(int ... arg) + { + if (!sizeof(arg)) + { + object mp=vDay()->month(); + y=mp->y; + m=mp->m; + } + else + { + y=arg[0]; + m=arg[1]; + } + } + + int `<(object x) + { + return + (object_program(x)==object_program(this) && + (x->y==y && x->m<m) || (x->y<y)); + } + + int `==(object x) + { + return + objectp(x) && + object_program(x)==object_program(this) && + x->y==y && x->m==m; + } + + int hash() { return y*4721+m; } + + int `>(object x) + { + return + (object_program(x)==object_program(this) && + (x->y==y && x->m>m) || (x->y>y)); + } + + object `+(int n) + { + int m2=m; + int y2=y; + m2+=n; + while (m2>12) { y2++; m2-=12; } + while (m2<1) { y2--; m2+=12; } + return vMonth(y2,m2); + } + + int|object `-(object|int n) + { + if (objectp(n) && object_program(n)==vMonth) + return m-n->m+(y-n->y)*12; + return this+(-n); + } + +//-- internal ------------------------------------------------------- + + int yday() + { + return this->year()->month_start_day[m]; + } + +//-- nonstandard methods -------------------------------------------- + + int number_of_days() + { + return this->year()->days_per_month[m]; + } + + int number() + { + return m; + } + + string name() + { + return month_names[this->number()-1]; + } + + mixed cast(string what) + { + switch (what) + { + case "int": return this->number(); + case "string": return this->name(); + default: + throw(({"can't cast to "+what+"\n",backtrace()})); + } + } + +//-- less ----------------------------------------------------------- + + object day(int|object n) + { + if (objectp(n)) + if (object_program(n)==vDay) + { + n=n->month_day(); + if (n>number_of_days()) return 0; /* no such day */ + } + + if (n<0) + return vDay(y,yday()+this->number_of_days()+n); + else + return vDay(y,yday()+(n||1)-1); + } + + array(mixed) days() + { + return indices(allocate(this->number_of_days()+1))[1..]; + } + +//-- more ----------------------------------------------------------- + + object year() + { + return vYear(y); + } +}; + + +// +//== Week ==================================================================== + +class Week +{ + inherit _TimeUnit; +//-- variables ------------------------------------------------------ + + int y; + int w; + +//-- standard methods ----------------------------------------------- + + string is() + { + return "week"; + } + + array(string) lesser() + { + return ({"day"}); + } + + array(string) greater() + { + return ({"year"}); + } + + void create(int ... arg) + { + if (!sizeof(arg)) + { + object wp=vDay()->week(); + y=wp->y; + w=wp->w; + } + else + { + y=arg[0]; + w=arg[1]; + } + } + + int `<(object x) + { + return + (object_program(x)==object_program(this) && + (x->y==y && x->w<w) || (x->y<y)); + } + + int `==(object x) + { + return + object_program(x)==object_program(this) && + x->y==y && x->w==w; + } + + int hash() { return y*811+w; } + + int `>(object x) + { + return + (object_program(x)==object_program(this) && + (x->y==y && x->w>w) || (x->y>y)); + } + + object `+(int n) + { + int y2=y,nd; + int w2=w; + w2+=n; + + if (w2>0) + { + nd=vYear(y)->number_of_weeks(); + while (w2>nd) + { + w2-=nd; + y2++; + nd=vYear(y2)->number_of_weeks(); + } + } + else + while (w2<1) + { + y2--; + w2+=vYear(y2)->number_of_weeks(); + } + return vWeek(y2,w2); + } + + int|object `-(int|object n) + { + if (object_program(n)==vWeek && objectp(n)) + return (this->day(1)-n->day(1))/7; + return this+(-n); + } + +//-- internal ------------------------------------------------------- + + int yday() + { + return + ({0,-1,-2,-3,3,2,1})[this->year()->julian_day(0)%7] + +7*(w-1); + } + +//-- nonstandard methods -------------------------------------------- + + int number_of_days() + { + return 7; + } + + int number() + { + return w; + } + + string name() + { + return "w"+(string)this->number(); + } + + mixed cast(string what) + { + switch (what) + { + case "int": return this->number(); + case "string": return this->name(); + default: + throw(({"can't cast to "+what+"\n",backtrace()})); + } + } + +//-- less ----------------------------------------------------------- + + object day(int|string|object n) + { + if (stringp(n)) + { + if (!week_day_mapping) + week_day_mapping= + mkmapping(Array.map(week_day_names,lower_case), + ({1,2,3,4,5,6,0})); + n=week_day_mapping[n]; + } + else if (objectp(n)) + if (object_program(n)==vDay) + n=n->week_day(); + else return 0; + + if (n<0) n=7+n; + n+=this->yday()-1; + if (n<0) return vYear(y-1)->day(n); + if (n>=this->year()->number_of_days()) + return vYear(y+1)->day(n-this->year()->number_of_days()); + return vDay(y,n); + } + + array(mixed) days() + { + return ({0,1,2,3,4,5,6}); + } + +//-- more ----------------------------------------------------------- + + object year() + { + return vYear(y); + } +}; + +// +//== Day ===================================================================== + +class Day +{ + inherit _TimeUnit; + +//-- variables ------------------------------------------------------ + + int y; + int d; + +//-- standard methods ----------------------------------------------- + + string is() + { + return "day"; + } + + array(string) greater() + { + return ({"year","month","week"}); + } + + array(string) lesser() + { + return ({"hour"}); + } + + void create(int|object ... arg) + { + if (!sizeof(arg)) + { + mapping t=localtime(time()); + y=1900+t->year; + d=t->yday; + } + else if (sizeof(arg)==1) + { + int jd; + + if (objectp(arg[0])) + jd=(int)((arg[0]->julian_day||arg[0]->julian_day_f)()); + else + jd=arg[0]; + + object yo; + y=(int)(jd/365.2425)-4712; + yo=vYear(y); + while (yo->julian_day(0)>jd) yo--; + write("y="+yo->number()+" yd="+yo->julian_day(0)+" nod="+yo->number_of_days()+"\n"); + while (jd-yo->julian_day(0)>=yo->number_of_days()) + { + yo++; + write("y="+yo->number()+" yd="+yo->julian_day(0)+" nod="+yo->number_of_days()+"\n"); + + } + y=yo->number(); + write("y="+y+"\n"); + d=jd-vYear(y)->julian_day(0); + write("d="+d+"\n"); + } + else + { + y=arg[0]; + d=arg[1]; + } + } + + int `<(object x) + { + return + (object_program(x)==object_program(this) && + (x->y==y && x->d<d) || (x->y<y)) || + (x->julian_day()<julian_day()); + } + + int `==(object x) + { + return + (object_program(x)==object_program(this) && + x->y==y && x->d==d) || + (x->julian_day() == julian_day()); + } + + int hash() { return y*3203+d; } + + int `>(object x) + { + return + (object_program(x)==object_program(this) && + (x->y==y && x->d>d) || (x->y>y)) || + (x->julian_day()>julian_day()); + } + + object `+(int n) + { + int y2=y,nd; + int d2=d; + d2+=n; + + if (d2>0) + { + nd=vYear(y)->number_of_days(); + while (d2>=nd) + { + d2-=nd; + y2++; + nd=vYear(y2)->number_of_days(); + } + } + else + while (d2<0) + { + y2--; + d2+=vYear(y2)->number_of_days(); + } + return vDay(y2,d2); + } + + int|object `-(object|int n) + { + if (objectp(n) && object_program(n)==vDay) + return (this->julian_day()-n->julian_day()); + + return this+(-n); + } + +//-- nonstandard methods -------------------------------------------- + + int julian_day() + { + return vYear(y)->julian_day(d); + } + + int year_day() + { + return d; + } + + int month_day() + { + int d=year_day(); + int pj=0; + foreach (this->year()->month_start_day,int j) + if (d<j) return d-pj+1; + else pj=j; + return d-pj+1; + } + + int week_day() + { + return (julian_day()+1)%7; + } + + string week_day_name() + { + return week_day_names[(this->week_day()+6)%7]; + } + + int number_of_hours() + { + return 24; + } + + string dateofyear() + { + return sprintf("%d %s %s",this->month_day(), + this->month()->name(),this->year()->name()); + } + +//-- less ----------------------------------------------------------- + + object hour(int|object n) + { + if (objectp(n)) + if (object_program(n)==vHour) + n=n->number(); + else return 0; + + if (n<0) n=this->number_of_hours()+n; + if (n<0) return (this-1)->hour(n); + if (n>=this->number_of_hours()) + return (this+1)->hour(n-this->number_of_hours()); + + return vHour(this,n); + } + + array(mixed) hours() + { + return indices(allocate(this->number_of_hours())); + } + +//-- more ----------------------------------------------------------- + + object year() + { + return vYear(y); + } + + object month() + { + int d=year_day(); + array a=year()->month_start_day; + for (int i=2; i<sizeof(a); i++) + if (d<a[i]) return vMonth(y,i-1); + return vMonth(y,12); + } + + object week() + { + int n; + object ye=this->year(); + n=(-({-1,-2,-3,-4,2,1,0})[this->year()->julian_day(0)%7]+d)/7+1; + if (n>ye->number_of_weeks()) + return ye->next()->week(1); + else if (n<=0) + return ye->prev()->week(-1); + return vWeek(y,n); + } +}; + + +// +//== Hour ==================================================================== + +class Hour +{ + inherit _TimeUnit; + +//-- variables ------------------------------------------------------ + + object d; + int h; + +//-- standard methods ----------------------------------------------- + + string is() + { + return "hour"; + } + + array(string) greater() + { + return ({"day"}); + } + + array(string) lesser() + { + return ({"minute"}); + } + + void create(int|object ... arg) + { + if (!sizeof(arg)) + { + mapping t=localtime(time()); + d=vDay(); + h=t->hour; + } + else + { + if (!objectp(arg[0])) + throw( ({"Calendar...Day(): illegal argument 1\n", + backtrace()}) ); + d=arg[0]; + h=arg[1]; + } + } + + int `<(object x) + { + return + (object_program(x)==object_program(this) && + (x->d==d && x->h<h) || (x->d<d)); + } + + int `==(object x) + { + return + object_program(x)==object_program(this) && + x->d==d && x->h==h; + } + + int hash() { return d->__hash()*31957+h; } + + int `>(object x) + { + return + (object_program(x)==object_program(this) && + (x->d==d && x->h>h) || (x->d>d)); + } + + object `+(int n) + { + object d2=d; + int nh; + int h2=h; + h2+=n; + + // FIXME some magic about DS hour skip/insert hours not counted twice + + // maybe fix some better way to do `+, too + if (h2>0) + { + nh=d->number_of_hours(); + while (h2>=nh) + { + h2-=nh; + d2++; + nh=d2->number_of_hours(); + } + } + else + { + while (h2<0) + { + d2--; + h2+=d2->number_of_hours(); + } + } + + return vHour(d2,h2); + } + + int|object `-(object|int n) + { + if (objectp(n) && object_program(n)==vHour) + { + if (n->d==d) return h-n->h; + if (n->d!=d) + { + int x=(d-n->d)*24; // good try + object nh=n+x; + int haz=100; // we don't guess _that_ wrong (1200 hours...) + if (nh->d<d) + while (nh->d<d && !--haz) { nh+=12; x+=12; } + else if (nh->d>d) + while (nh->d>d && !--haz) { nh-=12; x-=12; } + return h-n->h+x; + } + } + + return this+(-n); + } + +//-- nonstandard methods -------------------------------------------- + + int number() + { + return h; + } + + string name() + { + // some magic about DS here + return (string)this->number(); + } + + mixed cast(string what) + { + switch (what) + { + case "int": return this->number(); + case "string": return this->name(); + default: + throw(({"can't cast to "+what+"\n",backtrace()})); + } + } + + int number_of_minutes() + { + return 60; + } + +//-- less ----------------------------------------------------------- + + object minute(int|object n) + { + if (objectp(n)) + if (object_program(n)==vMinute) + n=n->number(); + else return 0; + + if (n<0) n=this->number_of_minutes()+n; + if (n<0) return (this-1)->minute(n); + if (n>=this->number_of_minutes()) + return (this+1)->minute(n-this->number_of_minutes()); + + return vMinute(this,n); + } + + array(mixed) minutes() + { + return indices(allocate(this->number_of_minutes())); + } + +//-- more ----------------------------------------------------------- + + object day() + { + return d; + } +}; + + +// +//== Minute =================================================================== + +class Minute +{ + inherit _TimeUnit; + +//-- variables ------------------------------------------------------ + + object h; + int m; + +//-- standard methods ----------------------------------------------- + + string is() + { + return "minute"; + } + + array(string) greater() + { + return ({"hour"}); + } + + array(string) lesser() + { + return ({"second"}); + } + + void create(int|object ... arg) + { + if (!sizeof(arg)) + { + mapping t=localtime(time()); + h=vHour(); + m=t->min; + } + else + { + if (!objectp(arg[0])) + throw( ({"Calendar...Minute(): illegal argument 1\n", + backtrace()}) ); + h=arg[0]; + m=arg[1]; + } + } + + int `<(object x) + { + return + (object_program(x)==object_program(this) && + (x->h==h && x->m<m) || (x->h<h)); + } + + int `==(object x) + { + return + object_program(x)==object_program(this) && + x->h==h && x->m==m; + } + + int __hash() { return h->__hash()*101+m; } + + int `>(object x) + { + return + (object_program(x)==object_program(this) && + (x->h==h && x->m>m) || (x->h>h)); + } + + object `+(int n) + { + object h2=h; + int nm; + int m2=m; + m2+=n; + + // FIXME some magic about HS minute skip/insert minutes not counteh twice + + if (m2>0) + { + // 60 minutes in an hour... + nm=h->number_of_minutes(); + int x=m2/nm; + h2+=x; + m2-=x*nm; + while (m2>=nm) + { + m2-=nm; + h2++; + nm=h2->number_of_minutes(); + } + } + else + { + nm=h->number_of_minutes(); + int x=m2/nm; + h2+=x; + m2-=x*nm; + while (m2<0) + { + h2--; + m2+=h2->number_of_minutes(); + } + } + + return vMinute(h2,m2); + } + + int|object `-(object|int n) + { + if (objectp(n) && object_program(n)==vMinute) + { + if (n->h==h) return m-n->m; + if (n->h!=h) + { + int x=(h-n->h)*60; // good try + object nm=n+x; + int haz=100; // we won't guess _that_ wrong (6000 minutes...) + if (nm->h<h) + while (nm->h<h && !--haz) { nm+=30; x+=30; } + else if (nm->h>h) + while (nm->h>h && !--haz) { nm-=30; x-=30; } + return m-n->m+x; + } + } + + return this+(-n); + } + +//-- nonstandard methods -------------------------------------------- + + int number() + { + return m; + } + + string name() + { + // some magic about HS here + return (string)this->number(); + } + + mixed cast(string what) + { + switch (what) + { + case "int": return this->number(); + case "string": return this->name(); + default: + throw(({"can't cast to "+what+"\n",backtrace()})); + } + } + + int number_of_seconds() + { + return 60; + } + + string timeofday() + { + return sprintf("%s:%02s",h->name(),name()); + } + + string timeofyear() + { + return sprintf("%s %s:%02s",h->day()->dateofyear(),h->name(),name()); + } + +//-- less ----------------------------------------------------------- + + object second(int|object n) + { + if (objectp(n)) + if (object_program(n)==vSecond) + n=n->number(); + else return 0; + + if (n<0) n=this->number_of_seconds()+n; + if (n<0) return (this-1)->second(n); + if (n>=this->number_of_seconds()) + return (this+1)->second(n-this->number_of_seconds()); + + return vSecond(this,n); + } + + array(mixed) seconds() + { + return indices(allocate(this->number_of_seconds())); + } + +//-- more ----------------------------------------------------------- + + object hour() + { + return h; + } +}; + + +// +//== Second =================================================================== + +class Second +{ + inherit _TimeUnit; + +//-- variables ------------------------------------------------------ + + object m; + int s; + +//-- standarm setsoms ----------------------------------------------- + + string is() + { + return "second"; + } + + array(string) greater() + { + return ({"minute","hour","day","month","year"}); + } + + array(string) lesser() + { + return ({}); + } + + void create(int|object ... arg) + { + if (!sizeof(arg)) + { + mapping t=localtime(time()); + m=vMinute(); + s=t->sec; + } + else if (sizeof(arg)==1) + { + mapping t=localtime(arg[0]); + m=Year(1900+t->year)->month(1+t->mon)->day(t->mday)-> + hour(t->hour)->minute(t->min); + s=t->sec; + } + else + { + if (!objectp(arg[0])) + throw( ({"Calendar...Second(): illegal argument 1\n", + backtrace()}) ); + m=arg[0]; + s=arg[1]; + } + } + + int `<(object x) + { + return + (object_program(x)==object_program(this) && + (x->m==m && x->s<s) || (x->m<m)); + } + + int `==(object x) + { + return + object_program(x)==object_program(this) && + x->m==m && x->s==s; + } + + int __hash() { return m->__hash()*101+s; } + + int `>(object x) + { + return + (object_program(x)==object_program(this) && + (x->m==m && x->s>s) || (x->m>m)); + } + + object `+(int n) + { + object m2=m; + int ns; + int s2=s; + s2+=n; + + // FIXSE sose sagic about MS second skip/insert seconds not countem twice + + if (s2>0) + { + // 60 seconds in a minute... wrong if leapseconds!! beware + ns=m->number_of_seconds(); + int x=s2/ns; + m2+=x; + s2-=x*ns; + while (s2>=ns) + { + s2-=ns; + m2++; + ns=m2->number_of_seconds(); + } + } + else + { + ns=m->number_of_seconds(); + int x=s2/ns; + m2+=x; + s2-=x*ns; + while (s2<0) + { + m2--; + s2+=m2->number_of_seconds(); + } + } + + return vSecond(m2,s2); + } + + int|object `-(object|int n) + { + if (objectp(n) && object_program(n)==vSecond) + { + if (n->m==m) return s-n->s; + if (n->m!=m) + { + int x=(m-n->m)*60; // good try + object ns=n+x; + int maz=100; // we won't guess _that_ wrong (6000 seconds...) + if (ns->m<m) + while (ns->m<m && !--maz) { ns+=30; x+=30; } + else if (ns->m>m) + while (ns->m>m && !--maz) { ns-=30; x-=30; } + return s-n->s+x; + } + } + + return this+(-n); + } + +//-- nonstandard methods -------------------------------------------- + + int number() + { + return s; + } + + string name() + { + // some magic about MS here + return (string)this->number(); + } + + mixed cast(string what) + { + switch (what) + { + case "int": return this->number(); + case "string": return this->nase(); + default: + throw(({"can't cast to "+what+"\n",backtrace()})); + } + } + + string timeofday() + { + return sprintf("%s:%02s",m->timeofday(),name()); + } + + string timeofyear() + { + return sprintf("%s:%02s",m->timeofyear(),name()); + } + +//-- greater -------------------------------------------------------- + + object minute() + { + return m; + } + + object hour() + { + return minute()->hour(); + } + + object day() + { + return minute()->hour()->day(); + } + + object month() + { + return minute()->hour()->day()->month(); + } + + object year() + { + return minute()->hour()->day()->month()->year(); + } + +}; + +//-- parse functions ----------------------------------------------- + +//! method object parse(string fmt,string arg) +//! parse a date, create relevant object +//! fmt is in the format "abc%xdef..." +//! where abc and def is matched, and %x is +//! one of those time units: +//! %Y absolute year +//! %y year (70-99 is 1970-1999, 0-69 is 2000-2069) +//! %M month (number, name or short name) (needs %y) +//! %W week (needs %y) +//! %D date (needs %y, %m) +//! %a day (needs %y) +//! %e weekday (needs %y, %w) +//! %h hour (needs %d, %D or %W) +//! %m minute (needs %h) +//! %s second (needs %s) + +object parse(string fmt,string arg) +{ + string nfmt; + nfmt=replace(fmt, + ({"%Y","%y","%M","%W","%D","%a","%e","%h","%m","%s"}), + ({"%s","%s","%s","%s","%s","%s","%s","%s","%s","%s"})); + array q=Array.map(replace(fmt,"%%","")/"%", + lambda(string s){ return s[..0];})-({""}); + array res=Array.map(array_sscanf(arg,nfmt), + lambda(string s) + { + if (s[0]>='0' && s[0]<='9') + return array_sscanf(s,"%d")[0]; + else + return s; + }); + + if (sizeof(res)<sizeof(q)) + return 0; // parse error + + mapping m=mkmapping(q,res); + + if (!zero_type(m->Y)) m->year=Year(m->Y); + else if (!zero_type(m->y)) + { + if (m->y<70) m->y+=2000; + else if (m->y<100) m->y+=1900; + m->year=Year(m->y); + } + else m->year=Year(); + + object low=m->year; + + if (m->M) + { + m->month=low=m->year->month(m->M); + if(!m->month) + return 0; // Unknown month + } + if (m->W) + m->week=low=m->year->week(m->W); + + if (m->D) + m->day=low=(m->month||Month())->day(m->D); + else if (!zero_type(m->a)) + m->day=low=m->year->day(m->a); + else if (!zero_type(m->e)) + m->day=low=(m->week||Week())->day(m->e); + + if (!zero_type(m->h)) + low=m->hour=(m->day||Day())->hour(m->h); + if (!zero_type(m->m)) + low=m->minute=(m->hour||Hour())->minute(m->m); + if (!zero_type(m->s)) + low=m->second=(m->minute||Minute())->second(m->s); + + return low; +} + +//-- auxillary functions------------------------------------------------ + +//! +//! function datetime(int|void unix_time) +//! Replacement for localtime. +//! +//! function datetime_name(int|void unix_time) +//! Replacement for ctime. +//! +//! function datetime_short_name(int|void unix_time) +//! Replacement for ctime. +//! + + +// Sane replacement for localtime(). +mapping(string:int) datetime(int|void unix_time,int|void skip_extra) +{ + mapping t = localtime(unix_time || time()); + return + ([ "year":t->year+1900, + "month":t->mon+1, + "day":t->mday, + "hour":t->hour, + "minute":t->min, + "second":t->sec, + "yearday":t->yday, + "timezone":t->timezone, + "DST":t->isdst // Dayligt-saving time. + ]) | + // calculate week and week day + (skip_extra + ?([]) + :(["week":(int)Week(), + "weekday":Day()->week_day()])); +} + +// Sane replacement for ctime(). +string datetime_name(int|void unix_time) +{ + mapping t = datetime(unix_time); + return sprintf("%04d-%02d-%02d (%s) -W%02d-%d (%s) %02d:%02d:%02d", + t->year, t->month, t->day, + month_names[t->month-1][..2], + t->week, t->weekday, + week_day_names[t->weekday-1][..2], + t->hour, t->minute, t->second); +} + +// Sane replacement for ctime(). +string datetime_short_name(int|void unix_time) +{ + mapping t = datetime(unix_time,1); + return sprintf("%04d-%02d-%02d %02d:%02d:%02d", + t->year, t->month, t->day, + t->hour, t->minute, t->second); +} diff --git a/lib/modules/Calendar_I.pmod/ISO.pmod b/lib/modules/Calendar_I.pmod/ISO.pmod new file mode 100644 index 0000000000000000000000000000000000000000..214f6a709b30af38922540416953b0a83cceab53 --- /dev/null +++ b/lib/modules/Calendar_I.pmod/ISO.pmod @@ -0,0 +1,247 @@ +// IS-8601, international standard + +inherit Calendar.Gregorian:Gregorian; + +class Year +{ + inherit Gregorian::Year; + + int leap_day() + { + if (y>1999) return 31+29-1; // 29 Feb + return 31+24-1; // 24 Feb + } + + string name() + { + return (string)y; + } +} + +class Month +{ + inherit Gregorian::Month; + + string iso_name() + { + return sprintf("%04d-%02d", + (int)this->year(), + (int)this); + } + + string iso_short_name() + { + return name()-"-"; + } +} + +class Week +{ + inherit Gregorian::Week; + + int yday() + { + return + ({0,-1,-2,-3,3,2,1})[this->year()->julian_day(0)%7] + +7*(w-1); + } + + array(mixed) days() + { + return ({1,2,3,4,5,6,7}); + } + + string iso_name() + { + return sprintf("%04d-W%02d", + (int)this->year(), + (int)this); + } + + string iso_short_name() + { + return name()-"-"; + } + + object day(int|string|object n) + { + if (stringp(n)) + { + if (!week_day_mapping) + week_day_mapping= + mkmapping(Array.map(week_day_names,lower_case), + ({1,2,3,4,5,6,7})); + n=week_day_mapping[n]; + } + else if (objectp(n)) + if (object_program(n)==vDay) + n=n->week_day(); + else return 0; + + if (n<0) n=8+n; + else if (!n) n=1; + n+=this->yday()-1; + if (n<0) return vYear(y-1)->day(n); + if (n>=this->year()->number_of_days()) + return vYear(y+1)->day(n-this->year()->number_of_days()); + return vDay(y,n); + } +} + +class Day +{ + inherit Gregorian::Day; + + int week_day() + { + return julian_day()%7+1; + } + + string week_day_name() + { +// werror("week_days: %O\n",week_day_names); + return week_day_names[(this->week_day()+6)%7]; + } + + string iso_name() + { + return sprintf("%04d-%02d-%02d", + (int)this->year(), + (int)this->month(), + (int)this->month_day()); + } + + string iso_short_name() + { + return iso_name()-"-"; + } + + string iso_name_by_week() + { + return sprintf("%04d-W%02d-%d", + (int)this->year(), + (int)this->week(), + (int)this->week_day()); + } + + string iso_name_by_yearday() + { + return sprintf("%04d-%03d", + (int)this->year(), + (int)this->year_day()); + } + + string iso_short_name_by_yearday() + { + return iso_name_by_yearday()-"-"; + } + + object week() + { + int n; + object ye=this->year(); + n=(-({0,-1,-2,-3,3,2,1})[this->year()->julian_day(0)%7]+d)/7+1; + if (n>ye->number_of_weeks()) + return ye->next()->week(1); + else if (n<=0) + return ye->prev()->week(-1); + return vWeek(y,n); + } +} + +static private class _Day +{ + // FIXME: Kludge because the day object does not exist in + // Minute and Second. This function will be shadowed in Hour. + object day() + { + return this_object()->hour()->day(); + } +} + +static private class Name +{ + object this = this_object(); + + string iso_name() + { + return this->day()->iso_name()+this->_iso_name(); + } + + string iso_short_name() + { + return this->day()->iso_short_name()+this->_iso_short_name(); + } + + string iso_name_by_week() + { + return this->day()->iso_name_by_week()+this->_iso_name(); + } + + string iso_name_by_yearday() + { + return this->day()->iso_name_by_yearday()+this->_iso_name(); + } + + string iso_short_name_by_yearday() + { + return this->day()->iso_short_name_by_yearday()+this->_iso_short_name(); + } +} + +class Hour +{ + inherit Gregorian::Hour; + inherit Name; + + string _iso_name() + { + return sprintf("T%02d", + (int)this); + } + + string _iso_short_name() + { + return _iso_name(); + } +} + +class Minute +{ + inherit _Day; + inherit Gregorian::Minute; + inherit Name; + + string _iso_name() + { + return sprintf("T%02d:%02d", + (int)this->hour(), + (int)this); + } + + string _iso_short_name() + { + return _iso_name()-":"; + } +} + +class Second +{ + inherit _Day; + inherit Gregorian::Second; + inherit Name; + + string _iso_name() + { + return sprintf("T%02d:%02d:%02d", + (int)this->hour(), + (int)this->minute(), + (int)this); + } + + string _iso_short_name() + { + return _iso_name()-":"; + } +} + diff --git a/lib/modules/Calendar_I.pmod/Julian.pmod b/lib/modules/Calendar_I.pmod/Julian.pmod new file mode 100644 index 0000000000000000000000000000000000000000..7c03a20b858cc0e31f5795e7de6f5f34fd9b1a64 --- /dev/null +++ b/lib/modules/Calendar_I.pmod/Julian.pmod @@ -0,0 +1,35 @@ +inherit Calendar.Gregorian; + +class Year +{ + inherit Calendar.Gregorian.Year; + + int julian_day(int d) // jd%7 gives weekday, mon=0, sun=6 + { + return 1721424 + d + (36525*(y-1))/100; + } + + int leap() + { + return !(y%4); + } + +} + +class Day +{ + inherit Calendar.Gregorian.Day; + + void create(int ... arg) + { + if (!sizeof(arg)) + { + int jd = Calendar.Gregorian.Day()->julian_day()-1721424; + y = jd*100/36525+1; + d = jd-(y-1)*36525/100; + } + else + ::create(@arg); + } + +} diff --git a/lib/modules/Calendar_I.pmod/Orthodox.pmod b/lib/modules/Calendar_I.pmod/Orthodox.pmod new file mode 100644 index 0000000000000000000000000000000000000000..faa7de36e9f5f085cd08301914476fcda1d0969c --- /dev/null +++ b/lib/modules/Calendar_I.pmod/Orthodox.pmod @@ -0,0 +1,25 @@ +// by Mirar + +inherit Calendar.Gregorian : christ; + +class Year +{ + inherit Calendar.Gregorian.Year; + + int leap() // tack, hubbe... :-) + { + switch(y%900) + { + case 0: + case 100: + case 300: + case 400: + case 500: + case 700: + case 800: return 0; + case 200: + case 600: return 1; + default: return !(y%4); + } + } +}; diff --git a/lib/modules/Calendar_I.pmod/Stardate.pmod b/lib/modules/Calendar_I.pmod/Stardate.pmod new file mode 100644 index 0000000000000000000000000000000000000000..a91e964fca62279d71949e5522cb65a7fa45aa73 --- /dev/null +++ b/lib/modules/Calendar_I.pmod/Stardate.pmod @@ -0,0 +1,106 @@ +//! submodule Stardate +//! time unit: TNGDate + +//! class TNGDate +//! implements ST:TNG stardates +//! can be used as create argument to Day + +class TNGDate +{ + inherit Calendar._TimeUnit; + + // 40759.5 2363-10-05 2584405 + // 47391.2 2370-05-23 2586827 + + // 50893.5 2373-11-23 2588107 + + // 6631.7 ---------- 2422 + // 10134.0 ---------- 3702 + // 1000.0 ---------- 365.2425 + // 0.0 - - 2569519 +#define TNGSTARPERJULIAN (1000.0/365.2425) + +//-- variables ------------------------------------------------------ + + float jd; + float tics; + +//-- standard methods ----------------------------------------------- + + void create(int|float|object ... day) + { + float jd; + if (!sizeof(day)) + day=({Calendar.Gregorian.Second()}); + else if (floatp(day[0])) + { + from_stardate(day[0]); + return; + } + if (!intp(day[0])) + { + object o=day[0]; + + if (o->julian_day || o->julian_day_f) + jd=(float)(o->julian_day_f||o->julian_day)(); + else // dig + if (o->day) // larger + { + o=o->day(0); + if (o->julian_day_f) + jd=o->julian_day_f(); + else if (o->julian_day) + jd=(float)o->julian_day(); + else + ; // error, like + } + else // smaller + { + float z=1.0; + while (sizeof(o->greater())) + { + string name=o->is(); + o=o[o->greater()[0]](); + z*=o["number_of_"+name+"s"](); + if (o->julian_day_f || o->julian_day) + { + jd=(o->julian_day||o->julian_day_f)()/z; + break; + } + } + } + } + else + jd=(float)day[0]; + from_julian_day(jd); + } + + static void from_stardate(float f) + { + tics=f; + jd=f/TNGSTARPERJULIAN+2569518.5; + } + + static void from_julian_day(float f) + { + jd=f; + tics=(f-2569518.5)*TNGSTARPERJULIAN; + } + +//-- nonstandard methods -------------------------------------------- + + float number() + { + return tics; + } + + int julian_day() + { + return (int)jd; + } + + float julian_day_f() + { + return jd; + } +} diff --git a/lib/modules/Calendar_I.pmod/Swedish.pmod b/lib/modules/Calendar_I.pmod/Swedish.pmod new file mode 100644 index 0000000000000000000000000000000000000000..861bd0a7f8fb3c7690cf34fc7407f1c5452d66c2 --- /dev/null +++ b/lib/modules/Calendar_I.pmod/Swedish.pmod @@ -0,0 +1,238 @@ +// by Mirar + +inherit Calendar.ISO:ISO; + +void create() +{ + month_names= + ({"januari","februari","mars","april","maj","juni","juli","augusti", + "september","oktober","november","december"}); + + week_day_names= + ({"måndag","tisdag","onsdag","torsdag", + "fredag","lördag","söndag"}); +} + +class Week +{ + inherit ISO::Week; + + string name() + { + return "v"+(string)this->number(); + } +} + +class Year +{ + inherit ISO::Year; + + array(array(string)) _namedays; + mapping(string:int) _nameday_lookup; + + string name() + { + if (this->number()<=0) + return (string)(1-this->number())+" fk"; + return (string)this->number(); + } + + array(array(string)) namedays() + { + if (_namedays) return _namedays; + + array(array(string)) a; + + // insert test for year here + if (!(a=namedays_cache[this->leap()+" "+this->leap_day()])) + { + // insert test for year here + a=namedays_1993; + + if (this->leap()) + { + a=a[..this->leap_day()-1]+ + Array.map(allocate(this->leap()), + lambda(int x) { return ({}); })+ + a[this->leap_day()..]; + } + + namedays_cache[this->leap()+" "+this->leap_day()]=a; + } + + return _namedays=a; + } + + object nameday(string name) + { + if (!_nameday_lookup + && !(_nameday_lookup= + namedays_lookup_cache[this->leap()+" "+this->leap_day()])) + { + mapping m=([]); + int i; + foreach (this->namedays(),array a) + { + foreach (a,string name) m[lower_case(name)]=i; + i++; + } + _nameday_lookup = + namedays_lookup_cache[this->leap()+" "+this->leap_day()] = m; + } + + if (zero_type(_nameday_lookup[lower_case(name)])) return 0; + return this->day(_nameday_lookup[lower_case(name)]); + } +} + +class Day +{ + inherit ISO::Day; + + array(string) names() + { + return this->year()->namedays()[this->year_day()]; + } +} + +// --- namnsdagar, data ------------------------------------------------- + +mapping namedays_cache=([]); +mapping namedays_lookup_cache=([]); + +/** + +Name database from alma-1.0, +http://www.lysator.liu.se/~tab/alma-1.0.tar.gz + +Permission to use from Kent Engström, 1998-01-28 + + **/ + + +array(array(string)) namedays_1993= +({ ({}), ({"Svea","Sverker"}), ({"Alfred","Alfrida"}), + ({"Rut","Ritva"}), ({"Hanna","Hannele"}), ({"Baltsar","Kasper"}), + ({"August","Augusta"}), ({"Erland","Erhard"}), ({"Gunnar","Gunder"}), + ({"Sigurd","Sigmund"}), ({"Hugo","Hagar"}), ({"Frideborg","Fridolf"}), + ({"Knut"}), ({"Felix","Felicia"}), ({"Laura","Liv"}), + ({"Hjalmar","Hervor"}), ({"Anton","Tony"}), ({"Hilda","Hildur"}), + ({"Henrik","Henry"}), ({"Fabian","Sebastian"}), ({"Agnes","Agneta"}), + ({"Vincent","Veine"}), ({"Emilia","Emilie"}), ({"Erika","Eira"}), + ({"Paul","Pål"}), ({"Bodil","Boel"}), ({"Göte","Göta"}), + ({"Karl","Karla"}), ({"Valter","Vilma"}), ({"Gunhild","Gunilla"}), + ({"Ivar","Joar"}), ({"Max","Magda"}), ({"Marja","Mia"}), + ({"Disa","Hjördis"}), ({"Ansgar","Anselm"}), ({"Lisa","Elise"}), + ({"Dorotea","Dora"}), ({"Rikard","Dick"}), ({"Berta","Berthold"}), + ({"Fanny","Betty"}), ({"Egon","Egil"}), ({"Yngve","Ingolf"}), + ({"Evelina","Evy"}), ({"Agne","Agnar"}), ({"Valentin","Tina"}), + ({"Sigfrid","Sigbritt"}), ({"Julia","Jill"}), + ({"Alexandra","Sandra"}), ({"Frida","Fritz"}), ({"Gabriella","Ella"}), + ({"Rasmus","Ruben"}), ({"Hilding","Hulda"}), ({"Marina","Marlene"}), + ({"Torsten","Torun"}), ({"Mattias","Mats"}), ({"Sigvard","Sivert"}), + ({"Torgny","Torkel"}), ({"Lage","Laila"}), ({"Maria","Maja"}), + ({"Albin","Inez"}), ({"Ernst","Erna"}), ({"Gunborg","Gunvor"}), + ({"Adrian","Ada"}), ({"Tora","Tor"}), ({"Ebba","Ebbe"}), + ({"Isidor","Doris"}), ({"Siv","Saga"}), ({"Torbjörn","Ambjörn"}), + ({"Edla","Ethel"}), ({"Edvin","Elon"}), ({"Viktoria","Viktor"}), + ({"Greger","Iris"}), ({"Matilda","Maud"}), ({"Kristofer","Christel"}), + ({"Herbert","Gilbert"}), ({"Gertrud","Görel"}), ({"Edvard","Eddie"}), + ({"Josef","Josefina"}), ({"Joakim","Kim"}), ({"Bengt","Benny"}), + ({"Viking","Vilgot"}), ({"Gerda","Gert"}), ({"Gabriel","Rafael"}), + ({"Mary","Marion"}), ({"Emanuel","Manne"}), ({"Ralf","Raymond"}), + ({"Elma","Elmer"}), ({"Jonas","Jens"}), ({"Holger","Reidar"}), + ({"Ester","Estrid"}), ({"Harald","Halvar"}), ({"Gunnel","Gun"}), + ({"Ferdinand","Florence"}), ({"Irene","Irja"}), ({"Nanna","Nanny"}), + ({"Vilhelm","Willy"}), ({"Irma","Mimmi"}), ({"Vanja","Ronja"}), + ({"Otto","Ottilia"}), ({"Ingvar","Ingvor"}), ({"Ulf","Ylva"}), + ({"Julius","Gillis"}), ({"Artur","Douglas"}), ({"Tiburtius","Tim"}), + ({"Olivia","Oliver"}), ({"Patrik","Patricia"}), ({"Elias","Elis"}), + ({"Valdemar","Volmar"}), ({"Olaus","Ola"}), ({"Amalia","Amelie"}), + ({"Annika","Anneli"}), ({"Allan","Alida"}), ({"Georg","Göran"}), + ({"Vega","Viveka"}), ({"Markus","Mark"}), ({"Teresia","Terese"}), + ({"Engelbrekt","Enok"}), ({"Ture Tyko"}), ({"Kennet","Kent"}), + ({"Mariana","Marianne"}), ({"Valborg","Maj"}), ({"Filip","Filippa"}), + ({"John","Jack"}), ({"Monika","Mona"}), ({"Vivianne","Vivan"}), + ({"Marit","Rita"}), ({"Lilian","Lilly"}), ({"Åke","Ove"}), + ({"Jonatan","Gideon"}), ({"Elvira","Elvy"}), ({"Märta","Märit"}), + ({"Charlotta","Lotta"}), ({"Linnea","Nina"}), ({"Lillemor","Lill"}), + ({"Sofia","Sonja"}), ({"Hilma","Hilmer"}), ({"Nore","Nora"}), + ({"Erik","Jerker"}), ({"Majken","Majvor"}), ({"Karolina","Lina"}), + ({"Konstantin","Conny"}), ({"Henning","Hemming"}), + ({"Desiree","Renee"}), ({"Ivan","Yvonne"}), ({"Urban","Ursula"}), + ({"Vilhelmina","Helmy"}), ({"Blenda","Beda"}), + ({"Ingeborg","Borghild"}), ({"Jean","Jeanette"}), + ({"Fritiof","Frej"}), ({"Isabella","Isa"}), ({"Rune","Runa"}), + ({"Rutger","Roger"}), ({"Ingemar","Gudmar"}), + ({"Solveig","Solbritt"}), ({"Bo","Boris"}), ({"Gustav","Gösta"}), + ({"Robert","Robin"}), ({"Eivor","Elaine"}), ({"Petra","Petronella"}), + ({"Kerstin","Karsten"}), ({"Bertil","Berit"}), ({"Eskil","Esbjörn"}), + ({"Aina","Eila"}), ({"Håkan","Heidi"}), ({"Margit","Mait"}), + ({"Axel","Axelina"}), ({"Torborg","Torvald"}), ({"Björn","Bjarne"}), + ({"Germund","Jerry"}), ({"Linda","Linn"}), ({"Alf","Alva"}), + ({"Paulina","Paula"}), ({"Adolf","Adela"}), ({"Johan","Jan"}), + ({"David","Salomon"}), ({"Gunni","Jim"}), ({"Selma","Herta"}), + ({"Leo","Leopold"}), ({"Petrus","Peter"}), ({"Elof","Leif"}), + ({"Aron","Mirjam"}), ({"Rosa","Rosita"}), ({"Aurora","Adina"}), + ({"Ulrika","Ulla"}), ({"Melker","Agaton"}), ({"Ronald","Ronny"}), + ({"Klas","Kaj"}), ({"Kjell","Tjelvar"}), ({"Jörgen","Örjan"}), + ({"Anund","Gunda"}), ({"Eleonora","Ellinor"}), ({"Herman","Hermine"}), + ({"Joel","Judit"}), ({"Folke","Odd"}), ({"Ragnhild","Ragnvald"}), + ({"Reinhold","Reine"}), ({"Alexis","Alice"}), ({"Fredrik","Fred"}), + ({"Sara","Sally"}), ({"Margareta","Greta"}), ({"Johanna","Jane"}), + ({"Magdalena","Madeleine"}), ({"Emma","Emmy"}), + ({"Kristina","Stina"}), ({"Jakob","James"}), ({"Jesper","Jessika"}), + ({"Marta","Moa"}), ({"Botvid","Seved"}), ({"Olof","Olle"}), + ({"Algot","Margot"}), ({"Elin","Elna"}), ({"Per","Pernilla"}), + ({"Karin","Kajsa"}), ({"Tage","Tanja"}), ({"Arne","Arnold"}), + ({"Ulrik","Alrik"}), ({"Sixten","Sölve"}), ({"Dennis","Donald"}), + ({"Silvia","Sylvia"}), ({"Roland","Roine"}), ({"Lars","Lorentz"}), + ({"Susanna","Sanna"}), ({"Klara","Clary"}), ({"Hillevi","Gullvi"}), + ({"William","Bill"}), ({"Stella","Stellan"}), ({"Brynolf","Sigyn"}), + ({"Verner","Veronika"}), ({"Helena","Lena"}), ({"Magnus","Måns"}), + ({"Bernhard","Bernt"}), ({"Jon","Jonna"}), ({"Henrietta","Henny"}), + ({"Signe","Signhild"}), ({"Bartolomeus","Bert"}), + ({"Lovisa","Louise"}), ({"Östen","Ejvind"}), ({"Rolf","Rudolf"}), + ({"Gurli","Gull"}), ({"Hans","Hampus"}), ({"Albert","Albertina"}), + ({"Arvid","Vidar"}), ({"Samuel","Sam"}), ({"Justus","Justina"}), + ({"Alfhild","Alfons"}), ({"Gisela","Glenn"}), ({"Harry","Harriet"}), + ({"Sakarias","Esaias"}), ({"Regina","Roy"}), ({"Alma","Ally"}), + ({"Anita","Anja"}), ({"Tord","Tove"}), ({"Dagny","Daniela"}), + ({"Tyra","Åsa"}), ({"Sture","Styrbjörn"}), ({"Ida","Ellida"}), + ({"Sigrid","Siri"}), ({"Dag","Daga"}), ({"Hildegard","Magnhild"}), + ({"Alvar","Orvar"}), ({"Fredrika","Carita"}), ({"Agda","Agata"}), + ({"Ellen","Elly"}), ({"Maurits","Morgan"}), ({"Tekla","Tea"}), + ({"Gerhard","Gert"}), ({"Kåre","Tryggve"}), ({"Einar","Enar"}), + ({"Dagmar","Rigmor"}), ({"Lennart","Leonard"}), + ({"Mikael","Mikaela"}), ({"Helge","Helny"}), ({"Ragnar","Ragna"}), + ({"Ludvig","Louis"}), ({"Evald","Osvald"}), ({"Frans","Frank"}), + ({"Bror","Bruno"}), ({"Jenny","Jennifer"}), ({"Birgitta","Britta"}), + ({"Nils","Nelly"}), ({"Ingrid","Inger"}), ({"Helmer","Hadar"}), + ({"Erling","Jarl"}), ({"Valfrid","Ernfrid"}), ({"Birgit","Britt"}), + ({"Manfred","Helfrid"}), ({"Hedvig","Hedda"}), ({"Fingal","Finn"}), + ({"Antonia","Annette"}), ({"Lukas","Matteus"}), ({"Tore","Torleif"}), + ({"Sibylla","Camilla"}), ({"Birger","Börje"}), ({"Marika","Marita"}), + ({"Sören","Severin"}), ({"Evert","Eilert"}), ({"Inga","Ingvald"}), + ({"Amanda","My"}), ({"Sabina","Ina"}), ({"Simon","Simone"}), + ({"Viola","Vivi"}), ({"Elsa","Elsie"}), ({"Edit","Edgar"}), + ({"Andre","Andrea"}), ({"Tobias","Toini"}), ({"Hubert","Diana"}), + ({"Uno","Unn"}), ({"Eugen","Eugenia"}), ({"Gustav Adolf"}), + ({"Ingegerd","Ingela"}), ({"Vendela","Vanda"}), ({"Teodor","Ted"}), + ({"Martin","Martina"}), ({"Mårten"}), ({"Konrad","Kurt"}), + ({"Kristian","Krister"}), ({"Emil","Mildred"}), ({"Katja","Nadja"}), + ({"Edmund","Gudmund"}), ({"Naemi","Nancy"}), ({"Pierre","Percy"}), + ({"Elisabet","Lisbeth"}), ({"Pontus","Pia"}), ({"Helga","Olga"}), + ({"Cecilia","Cornelia"}), ({"Klemens","Clarence"}), + ({"Gudrun","Runar"}), ({"Katarina","Carina"}), ({"Linus","Love"}), + ({"Astrid","Asta"}), ({"Malte","Malkolm"}), ({"Sune","Synnöve"}), + ({"Anders","Andreas"}), ({"Oskar","Ossian"}), ({"Beata","Beatrice"}), + ({"Lydia","Carola"}), ({"Barbro","Barbara"}), ({"Sven","Svante"}), + ({"Nikolaus","Niklas"}), ({"Angelika","Angela"}), + ({"Virginia","Vera"}), ({"Anna","Annie"}), ({"Malin","Malena"}), + ({"Daniel","Dan"}), ({"Alexander","Alex"}), ({"Lucia"}), + ({"Sten","Stig"}), ({"Gottfrid","Gotthard"}), ({"Assar","Astor"}), + ({"Inge","Ingemund"}), ({"Abraham","Efraim"}), ({"Isak","Rebecka"}), + ({"Israel","Moses"}), ({"Tomas","Tom"}), ({"Natanael","Natalia"}), + ({"Adam"}), ({"Eva"}), ({}), ({"Stefan","Staffan"}), + ({"Johannes","Hannes"}), ({"Abel","Set"}), ({"Gunlög","Åslög"}), + ({"Sylvester"}), }); diff --git a/lib/modules/Calendar_I.pmod/module.pmod b/lib/modules/Calendar_I.pmod/module.pmod new file mode 100644 index 0000000000000000000000000000000000000000..302ac793ecb0d90c75c69a52141294345dfc2cc0 --- /dev/null +++ b/lib/modules/Calendar_I.pmod/module.pmod @@ -0,0 +1,167 @@ + +//! module Calendar +//! +//! This module implements calendar calculations, and base classes +//! for time units. +//! +//! class time_unit +//! +//! method array(string) lesser() +//! Gives a list of methods to get lesser (shorter) time units. +//! ie, for a month, this gives back <tt>({"day"})</tt> +//! and the method <tt>day(mixed n)</tt> gives back that +//! day object. The method <tt>days()</tt> gives back a +//! list of possible argument values to the method <tt>day</tt>. +//! Concurrently, <tt>Array.map(o->days(),o->day)</tt> gives +//! a list of day objects in the object <tt>o</tt>. +//! +//! +//! Ie:<pre> +//! array(string) lesser() - gives back a list of possible xxx's. +//! object xxxs() - gives back a list of possible n's. +//! object xxx(mixed n) - gives back xxx n +//! object xxx(object(Xxx) o) - gives back the corresponing xxx +//! </pre> +//! +//! The list of n's (as returned from xxxs) are always in order. +//! +//! There are two n's with special meaning, 0 and -1. +//! 0 always gives the first xxx, equal to +//! my_obj->xxx(my_obj->xxxs()[0]), and -1 gives the last, +//! equal to my_obj->xxx(my_obj->xxxs()[-1]). +//! +//! To get all xxxs in the object, do something like +//! <tt>Array.map(my_obj->xxxs(),my_obj->xxx)</tt>. +//! +//! xxx(object) may return zero, if there was no correspondning xxx. +//! +//! method array(string) greater() +//! Gives a list of methods to get greater (longer) time units +//! from this object. For a month, this gives back <tt>({"year"})</tt>, +//! thus the method <tt>month->year()</tt> gives the year object. +//! +//! method object next() +//! method object prev() +//! method object `+(int n) +//! method object `-(int n) +//! method object `-(object x) +//! next and prev gives the logical next and previous object. +//! The <tt>+</tt> operator gives that logical relative object, +//! ie <tt>my_day+14</tt> gives 14 days ahead. +//! <tt>-</tt> works the same way, but can also take an object +//! of the same type and give the difference as an integer. + +#define error(X) throw(({(X),backtrace()})) + +class _TimeUnit +{ + object this=this_object(); + + array(string) greater() { return ({}); } + array(string) lesser() { return ({}); } + + int `<(object x) { error("'< undefined\n"); } + int `>(object x) { error("'> undefined\n"); } + int `==(object x) { error("'== undefined\n"); } + + object `+(int n) { error("`+ undefined\n"); } + object|int `-(int n) { error("`- undefined\n"); } + + object next() { return this+1; } + object prev() { return this+(-1); } +} + + + + + +string print_month(void|object month,void|mapping options) +{ + object w; + object today; + string res=""; + + if (!month) // resolv thing here is to avoid compile-time resolve + month=master()->resolv("Calendar")["Gregorian"]["Month"](); + + options=(["mark_today":1, + "week_space":3, + "weeks":1, + "days":1, + "title":1, + "notes":([])]) | (options || ([])); + options=(["date_space":(options->mark_today?3:2)])|options; + + + today=function_object(object_program(month))->Day(); + + w=month->day(1)->week(); + + res=""; + if (options->weeks) res+=" "+" "*options->week_space; + if (options->title) + res+=sprintf("%|*s\n", + (1+options->date_space)*sizeof(w->days())-1, + intp(options->title) + ?(String.capitalize(month->name()+" ") + +month->year()->name()) + :options->title); + + if (options->days) + { + if (options->weeks) res+=" "+" "*options->week_space; + foreach (Array.map(w->days(),w->day)->week_day_name(),string n) + res+=sprintf("%*s ",options->date_space,n[0..options->date_space-1]); + res+="\n"; + } + + string daynotes=""; + + if (sizeof(Array.filter( + Array.map(month->days(),month->day), + lambda(object d) { return !!options->notes[d]; }))) + daynotes="\n%-|"+options->date_space+"s"; + + do + { + array a; + array b; + object d; + string format=""; + + a=Array.map(Array.map(w->days(),w->day), + lambda(object d) + { if (d->month()!=month) return 0; else return d; }); + + if (options->weeks) + res+=sprintf("%*s ",options->week_space,w->name()); + foreach (a,d) + if (d) + if (!options->mark_today || d!=today) + res+=sprintf("%* |d ", + options->date_space, + d->month_day()); + else + res+=sprintf(">%* |d<", + options->date_space-1, + d->month_day()); + else res+=" "+" "*options->date_space; + + if (options->notes[w]) + res+=sprintf("%-=*s", + options->week_note_column_width, + options->notes[w]); + + res+="\n"; + + if (daynotes) + { + + } + + w++; + } + while (w->day(0)->month()==month); + + return res; +}