tz
Threads by month
- ----- 2024 -----
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1999 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1998 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1997 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1996 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1995 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1994 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1993 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1992 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1991 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1990 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1989 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1988 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1987 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 1986 -----
- December
- November
June 2005
- 21 participants
- 21 discussions
It's March Madness time for daylight-saving rule changes.
Here's a proposed change to the tz database to keep up with the latest
political development, which affects time stamps starting March 29:
* Latvia and Lithuania will not observe DST, starting this year.
Thanks to Andrei Ivanov for this info.
===================================================================
RCS file: RCS/europe,v
retrieving revision 2000.3
retrieving revision 2000.3.0.1
diff -pu -r2000.3 -r2000.3.0.1
--- europe 2000/03/04 15:31:08 2000.3
+++ europe 2000/03/08 17:48:59 2000.3.0.1
@@ -1135,6 +1135,12 @@ Link Europe/Rome Europe/San_Marino
# 1997-01-21 on transition to Summer time ... established the same order of
# daylight savings time settings as in the States of the European Union.
+# From Andrei Ivanov (2000-03-06):
+# This year Latvia will not switch to Daylight Savings Time (as specified in
+# <a href="http://www.lv-laiks.lv/wwwraksti/2000/071072/vd4.htm">
+# The Regulations of the Cabinet of Ministers of the Rep. of Latvia of
+# 29-Feb-2000 (#79)</a>, in Latvian for subscribers only).
+
# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S
Rule Latvia 1989 1996 - Mar lastSun 2:00s 1:00 S
Rule Latvia 1989 1996 - Sep lastSun 2:00s 0 -
@@ -1151,7 +1157,8 @@ Zone Europe/Riga 1:36:24 - LMT 1880
3:00 Russia MSK/MSD 1989 Mar lastSun 2:00s
2:00 1:00 EEST 1989 Sep lastSun 2:00s
2:00 Latvia EE%sT 1997 Jan 21
- 2:00 EU EE%sT
+ 2:00 EU EE%sT 2000 Feb 29
+ 2:00 - EET
# Liechtenstein
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
@@ -1178,6 +1185,11 @@ Zone Europe/Vaduz 0:38:04 - LMT 1894 Jun
# motion to give up shifting to summer time in spring, as it was
# already done by Estonia.
+# From Andrei Ivanov (2000-03-06):
+# I've heard that Ministers of three Baltic countries on their summit
+# somewhere in February decided not to switch to summer time starting from
+# this spring.
+
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Europe/Vilnius 1:41:16 - LMT 1880
1:24:00 - WMT 1917 # Warsaw Mean Time
@@ -1192,7 +1204,8 @@ Zone Europe/Vilnius 1:41:16 - LMT 1880
2:00 C-Eur EE%sT 1998
2:00 - EET 1998 Mar 29 1:00u
1:00 EU CE%sT 1999 Oct 31 1:00u
- 2:00 EU EE%sT
+ 2:00 EU EE%sT 2000 Feb
+ 2:00 - EET
# Luxembourg
# Whitman disagrees with most of these dates in minor ways; go with Shanks.
5
5
Broken Hill, or more precise, the whole county of Yancowinna, differs from
the rest of New South Wales, as clearly stated in the TZ database.
Problem is: what is the "county of Yancowinna"?
The Australian Standard Time Act 1987 mentions this county, but doesn't
mention the county boundaries. Once they were known, but they have
disappeared from recent maps.
Finally I found a scan of an old map from the Land Registry, showing the
Yancowinna county. Found on the website of The Sydney Morning Herald:
<http://www.smh.com.au/articles/2003/08/29/1062050651816.html?oneclick=true>
Click on field number 2 or download the map directly:
<http://www.smh.com.au/specials/leases/pdf/map2.pdf>
The following places are within the county boundaries:
Broken Hill, The Gorge, Mount Gipps, Silverton, Stephens Creek, Wahratta,
Yanco Glen.
The name "Wahratta" is not perfectly readable from the map, but I've checked
the name and location against the Australia file from the GEOnet Names
Server
<http://earth-info.nga.mil/gns/>
Oscar van Vlijmen
2005-04-23
4
8
Below find the results of "tail -1" applied to the files output by my last
message's version of "zic".
--ado
Africa/Algiers: CET-1
Africa/Luanda: WAT-1
Africa/Porto-Novo: WAT-1
Africa/Gaborone: CAT-2
Africa/Ouagadougou: GMT0
Africa/Bujumbura: CAT-2
Africa/Douala: WAT-1
Africa/Bangui: WAT-1
Africa/Ndjamena: WAT-1
Africa/Kinshasa: WAT-1
Africa/Lubumbashi: CAT-2
Africa/Brazzaville: WAT-1
Africa/Abidjan: GMT0
Africa/Djibouti: EAT-3
Africa/Cairo: EET-2<EEST>,M4.5.5/0,M9.5.4/24
Africa/Malabo: WAT-1
Africa/Asmera: EAT-3
Africa/Addis_Ababa: EAT-3
Africa/Libreville: WAT-1
Africa/Banjul: GMT0
Africa/Accra: GMT0
Africa/Conakry: GMT0
Africa/Bissau: GMT0
Africa/Nairobi: EAT-3
Africa/Maseru: <SAST>-2
Africa/Monrovia: GMT0
Africa/Tripoli: EET-2
Africa/Blantyre: CAT-2
Africa/Bamako: GMT0
Africa/Timbuktu: GMT0
Africa/Nouakchott: GMT0
Africa/Casablanca: WET0
Africa/El_Aaiun: WET0
Africa/Maputo: CAT-2
Africa/Windhoek: WAT-1<WAST>,M9.1.0,M4.1.0
Africa/Niamey: WAT-1
Africa/Lagos: WAT-1
Africa/Kigali: CAT-2
Africa/Sao_Tome: GMT0
Africa/Dakar: GMT0
Africa/Freetown: GMT0
Africa/Mogadishu: EAT-3
Africa/Johannesburg: <SAST>-2
Africa/Khartoum: EAT-3
Africa/Mbabane: <SAST>-2
Africa/Dar_es_Salaam: EAT-3
Africa/Lome: GMT0
Africa/Tunis: CET-1
Africa/Kampala: EAT-3
Africa/Lusaka: CAT-2
Africa/Harare: CAT-2
Africa/Ceuta: CET-1<CEST>,M3.5.0,M10.5.0
America/Danmarkshavn: GMT0
America/Scoresbysund: EGT1<EGST>,M3.5.0/0,M10.5.0/0
America/Godthab:
America/Thule: AST4ADT,M4.1.0,M10.5.0
America/New_York: EST5EDT,M4.1.0,M10.5.0
America/Chicago: CST6CDT,M4.1.0,M10.5.0
America/North_Dakota/Center: CST6CDT,M4.1.0,M10.5.0
America/Denver: MST7MDT,M4.1.0,M10.5.0
America/Los_Angeles: PST8PDT,M4.1.0,M10.5.0
America/Juneau: <AKST>9<AKDT>,M4.1.0,M10.5.0
America/Yakutat: <AKST>9<AKDT>,M4.1.0,M10.5.0
America/Anchorage: <AKST>9<AKDT>,M4.1.0,M10.5.0
America/Nome: <AKST>9<AKDT>,M4.1.0,M10.5.0
America/Adak: <HAST>10<HADT>,M4.1.0,M10.5.0
America/Phoenix: MST7
America/Boise: MST7MDT,M4.1.0,M10.5.0
America/Indianapolis: EST5
America/Indiana/Marengo: EST5
America/Indiana/Knox: EST5
America/Indiana/Vevay: EST5
America/Indiana/Indianapolis: EST5
America/Louisville: EST5EDT,M4.1.0,M10.5.0
America/Kentucky/Monticello: EST5EDT,M4.1.0,M10.5.0
America/Kentucky/Louisville: EST5EDT,M4.1.0,M10.5.0
America/Detroit: EST5EDT,M4.1.0,M10.5.0
America/Menominee: CST6CDT,M4.1.0,M10.5.0
America/St_Johns: NST3:30NDT,M4.1.0/0:01,M10.5.0/0:01
America/Goose_Bay: AST4ADT,M4.1.0/0:01,M10.5.0/0:01
America/Halifax: AST4ADT,M4.1.0,M10.5.0
America/Glace_Bay: AST4ADT,M4.1.0,M10.5.0
America/Montreal: EST5EDT,M4.1.0,M10.5.0
America/Toronto: EST5EDT,M4.1.0,M10.5.0
America/Thunder_Bay: EST5EDT,M4.1.0,M10.5.0
America/Nipigon: EST5EDT,M4.1.0,M10.5.0
America/Rainy_River: CST6CDT,M4.1.0,M10.5.0
America/Winnipeg: CST6CDT,M4.1.0,M10.5.0/3
America/Regina: CST6
America/Swift_Current: CST6
America/Edmonton: MST7MDT,M4.1.0,M10.5.0
America/Vancouver: PST8PDT,M4.1.0,M10.5.0
America/Dawson_Creek: MST7
America/Pangnirtung: EST5EDT,M4.1.0,M10.5.0
America/Iqaluit: EST5EDT,M4.1.0,M10.5.0
America/Rankin_Inlet: CST6CDT,M4.1.0,M10.5.0
America/Cambridge_Bay: MST7MDT,M4.1.0,M10.5.0
America/Yellowknife: MST7MDT,M4.1.0,M10.5.0
America/Inuvik: MST7MDT,M4.1.0,M10.5.0
America/Whitehorse: PST8PDT,M4.1.0,M10.5.0
America/Dawson: PST8PDT,M4.1.0,M10.5.0
America/Cancun: CST6CDT,M4.1.0,M10.5.0
America/Merida: CST6CDT,M4.1.0,M10.5.0
America/Monterrey: CST6CDT,M4.1.0,M10.5.0
America/Mexico_City: CST6CDT,M4.1.0,M10.5.0
America/Chihuahua: MST7MDT,M4.1.0,M10.5.0
America/Hermosillo: MST7
America/Mazatlan: MST7MDT,M4.1.0,M10.5.0
America/Tijuana: PST8PDT,M4.1.0,M10.5.0
America/Anguilla: AST4
America/Antigua: AST4
America/Nassau: EST5EDT,M4.1.0,M10.5.0
America/Barbados: AST4
America/Belize: CST6
America/Cayman: EST5
America/Costa_Rica: CST6
America/Havana: CST5CDT,M4.1.0/0,M10.5.0/1
America/Dominica: AST4
America/Santo_Domingo: AST4
America/El_Salvador: CST6
America/Grenada: AST4
America/Guadeloupe: AST4
America/Guatemala: CST6
America/Port-au-Prince: EST5
America/Tegucigalpa: CST6
America/Jamaica: EST5
America/Martinique: AST4
America/Montserrat: AST4
America/Managua: CST6
America/Panama: EST5
America/Puerto_Rico: AST4
America/St_Kitts: AST4
America/St_Lucia: AST4
America/Miquelon: <PMST>3<PMDT>,M4.1.0,M10.5.0
America/St_Vincent: AST4
America/Grand_Turk: EST5EDT,M4.1.0/0,M10.5.0/0
America/Tortola: AST4
America/St_Thomas: AST4
America/Argentina/Buenos_Aires: ART3
America/Argentina/Cordoba: ART3
America/Argentina/Tucuman: ART3
America/Argentina/La_Rioja: ART3
America/Argentina/San_Juan: ART3
America/Argentina/Jujuy: ART3
America/Argentina/Catamarca: ART3
America/Argentina/Mendoza: ART3
America/Argentina/ComodRivadavia: ART3
America/Argentina/Rio_Gallegos: ART3
America/Argentina/Ushuaia: ART3
America/Aruba: AST4
America/La_Paz: BOT4
America/Noronha: FNT2
America/Belem: BRT3
America/Fortaleza: BRT3
America/Recife: BRT3
America/Araguaina: BRT3
America/Maceio: BRT3
America/Bahia: BRT3
America/Sao_Paulo: BRT3<BRST>,M10.3.0/0,M2.3.0/0
America/Campo_Grande: AMT4<AMST>,M10.3.0/0,M2.3.0/0
America/Cuiaba: AMT4<AMST>,M10.3.0/0,M2.3.0/0
America/Porto_Velho: AMT4
America/Boa_Vista: AMT4
America/Manaus: AMT4
America/Eirunepe: ACT5
America/Rio_Branco: ACT5
America/Santiago:
America/Bogota: COT5
America/Curacao: AST4
America/Guayaquil: ECT5
America/Cayenne: GFT3
America/Guyana: GYT4
America/Asuncion: PYT4<PYST>,M10.3.0/0,M3.2.0/0
America/Lima: PET5
America/Paramaribo: SRT3
America/Port_of_Spain: AST4
America/Montevideo: UYT3
America/Caracas: VET4
America/Shiprock: MST7MDT,M4.1.0,M10.5.0
America/Atka: <HAST>10<HADT>,M4.1.0,M10.5.0
America/Buenos_Aires: ART3
America/Catamarca: ART3
America/Cordoba: ART3
America/Ensenada: PST8PDT,M4.1.0,M10.5.0
America/Fort_Wayne: EST5
America/Jujuy: ART3
America/Knox_IN: EST5
America/Mendoza: ART3
America/Porto_Acre: ACT5
America/Rosario: ART3
America/Virgin: AST4
Antarctica/Casey: WST-8
Antarctica/Davis: <DAVT>-7
Antarctica/Mawson: <MAWT>-6
Antarctica/DumontDUrville: <DDUT>-10
Antarctica/Syowa: <SYOT>-3
Antarctica/Vostok: <VOST>-6
Antarctica/Rothera: <ROTT>3
Antarctica/Palmer:
Antarctica/McMurdo: <NZST>-12<NZDT>,M10.1.0,M3.3.0/3
Antarctica/South_Pole: <NZST>-12<NZDT>,M10.1.0,M3.3.0/3
Arctic/Longyearbyen: CET-1<CEST>,M3.5.0,M10.5.0
Asia/Kabul: AFT-4:30
Asia/Yerevan: AMT-4<AMST>,M3.5.0,M10.5.0/3
Asia/Baku: AZT-4<AZST>,M3.5.0/1,M10.5.0/1
Asia/Bahrain: AST-3
Asia/Dhaka: BDT-6
Asia/Thimphu: BTT-6
Asia/Brunei: BNT-8
Asia/Rangoon: MMT-6:30
Asia/Phnom_Penh: ICT-7
Asia/Harbin: CST-8
Asia/Shanghai: CST-8
Asia/Chongqing: CST-8
Asia/Urumqi: CST-8
Asia/Kashgar: CST-8
Asia/Hong_Kong: HKT-8
Asia/Taipei: CST-8
Asia/Macau: CST-8
Asia/Nicosia: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Asia/Tbilisi: GET-3<GEST>,M3.5.0,M10.5.0/3
Asia/Dili: TPT-9
Asia/Calcutta: IST-5:30
Asia/Jakarta: WIT-7
Asia/Pontianak: WIT-7
Asia/Makassar: CIT-8
Asia/Jayapura: EIT-9
Asia/Tehran:
Asia/Baghdad: AST-3ADT,J91/3,J274/4
Asia/Jerusalem:
Asia/Tokyo: JST-9
Asia/Amman: EET-2<EEST>,M3.5.4/0,M9.5.4/1
Asia/Almaty: <ALMT>-6
Asia/Qyzylorda: <QYZT>-6
Asia/Aqtobe: <AQTT>-5
Asia/Aqtau: <AQTT>-4
Asia/Oral: <ORAT>-4
Asia/Bishkek: KGT-5<KGST>,M3.5.0/2:30,M10.5.0/2:30
Asia/Seoul: KST-9
Asia/Pyongyang: KST-9
Asia/Kuwait: AST-3
Asia/Vientiane: ICT-7
Asia/Beirut: EET-2<EEST>,M3.5.0/0,M10.5.0/0
Asia/Kuala_Lumpur: MYT-8
Asia/Kuching: MYT-8
Asia/Hovd: <HOVT>-7<HOVST>,M3.5.6,M9.5.6
Asia/Ulaanbaatar: <ULAT>-8<ULAST>,M3.5.6,M9.5.6
Asia/Choibalsan: <CHOT>-9<CHOST>,M3.5.6,M9.5.6
Asia/Katmandu: NPT-5:45
Asia/Muscat: GST-4
Asia/Karachi: PKT-5
Asia/Gaza: EET-2<EEST>,M4.3.5/0,M10.3.5/0
Asia/Manila: PHT-8
Asia/Qatar: AST-3
Asia/Riyadh: AST-3
Asia/Singapore: SGT-8
Asia/Colombo: LKT-6
Asia/Damascus: EET-2<EEST>,J91/0,J274/0
Asia/Dushanbe: TJT-5
Asia/Bangkok: ICT-7
Asia/Ashgabat: TMT-5
Asia/Dubai: GST-4
Asia/Samarkand: UZT-5
Asia/Tashkent: UZT-5
Asia/Saigon: ICT-7
Asia/Aden: AST-3
Asia/Yekaterinburg: <YEKT>-5<YEKST>,M3.5.0,M10.5.0/3
Asia/Omsk: <OMST>-6<OMSST>,M3.5.0,M10.5.0/3
Asia/Novosibirsk: <NOVT>-6<NOVST>,M3.5.0,M10.5.0/3
Asia/Krasnoyarsk: <KRAT>-7<KRAST>,M3.5.0,M10.5.0/3
Asia/Irkutsk: <IRKT>-8<IRKST>,M3.5.0,M10.5.0/3
Asia/Yakutsk: <YAKT>-9<YAKST>,M3.5.0,M10.5.0/3
Asia/Vladivostok: <VLAT>-10<VLAST>,M3.5.0,M10.5.0/3
Asia/Sakhalin: <SAKT>-10<SAKST>,M3.5.0,M10.5.0/3
Asia/Magadan: <MAGT>-11<MAGST>,M3.5.0,M10.5.0/3
Asia/Kamchatka: <PETT>-12<PETST>,M3.5.0,M10.5.0/3
Asia/Anadyr: <ANAT>-12<ANAST>,M3.5.0,M10.5.0/3
Asia/Riyadh87: zzz-3:07:04
Asia/Riyadh88: zzz-3:07:04
Asia/Riyadh89: zzz-3:07:04
Asia/Istanbul: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Asia/Ashkhabad: TMT-5
Asia/Chungking: CST-8
Asia/Dacca: BDT-6
Asia/Macao: CST-8
Asia/Ujung_Pandang: CIT-8
Asia/Tel_Aviv:
Asia/Thimbu: BTT-6
Asia/Ulan_Bator: <ULAT>-8<ULAST>,M3.5.6,M9.5.6
Atlantic/Cape_Verde: CVT1
Atlantic/St_Helena: GMT0
Atlantic/Faeroe: WET0<WEST>,M3.5.0/1,M10.5.0/1
Atlantic/Reykjavik: GMT0
Atlantic/Azores: <AZOT>1<AZOST>,M3.5.0/0,M10.5.0/0
Atlantic/Madeira: WET0<WEST>,M3.5.0/1,M10.5.0/1
Atlantic/Canary: WET0<WEST>,M3.5.0/1,M10.5.0/1
Atlantic/Bermuda: AST4ADT,M4.1.0,M10.5.0
Atlantic/Stanley: FKT4<FKST>,M9.1.0,M4.3.0
Atlantic/South_Georgia: GST2
Atlantic/Jan_Mayen: CET-1<CEST>,M3.5.0,M10.5.0
Australia/Darwin: CST-9:30
Australia/Perth: WST-8
Australia/Brisbane: EST-10
Australia/Lindeman: EST-10
Australia/Adelaide: CST-9:30CST,M10.5.0,M3.5.0/3
Australia/Hobart: EST-10EST,M10.1.0,M3.5.0/3
Australia/Melbourne: EST-10EST,M10.5.0,M3.5.0/3
Australia/Sydney: EST-10EST,M10.5.0,M3.5.0/3
Australia/Broken_Hill: CST-9:30CST,M10.5.0,M3.5.0/3
Australia/Lord_Howe: <LHST>-10:30<LHST>-11,M10.5.0,M3.5.0
Australia/ACT: EST-10EST,M10.5.0,M3.5.0/3
Australia/Canberra: EST-10EST,M10.5.0,M3.5.0/3
Australia/LHI: <LHST>-10:30<LHST>-11,M10.5.0,M3.5.0
Australia/NSW: EST-10EST,M10.5.0,M3.5.0/3
Australia/North: CST-9:30
Australia/Queensland: EST-10
Australia/South: CST-9:30CST,M10.5.0,M3.5.0/3
Australia/Tasmania: EST-10EST,M10.1.0,M3.5.0/3
Australia/Victoria: EST-10EST,M10.5.0,M3.5.0/3
Australia/West: WST-8
Australia/Yancowinna: CST-9:30CST,M10.5.0,M3.5.0/3
Brazil/Acre: ACT5
Brazil/DeNoronha: FNT2
Brazil/East: BRT3<BRST>,M10.3.0/0,M2.3.0/0
Brazil/West: AMT4
CET: CET-1<CEST>,M3.5.0,M10.5.0/3
CST6CDT: CST6CDT,M4.1.0,M10.5.0
Canada/Atlantic: AST4ADT,M4.1.0,M10.5.0
Canada/Central: CST6CDT,M4.1.0,M10.5.0/3
Canada/East-Saskatchewan: CST6
Canada/Eastern: EST5EDT,M4.1.0,M10.5.0
Canada/Mountain: MST7MDT,M4.1.0,M10.5.0
Canada/Newfoundland: NST3:30NDT,M4.1.0/0:01,M10.5.0/0:01
Canada/Pacific: PST8PDT,M4.1.0,M10.5.0
Canada/Saskatchewan: CST6
Canada/Yukon: PST8PDT,M4.1.0,M10.5.0
Chile/Continental:
Chile/EasterIsland:
Cuba: CST5CDT,M4.1.0/0,M10.5.0/1
EET: EET-2<EEST>,M3.5.0/3,M10.5.0/3
EST: EST5
EST5EDT: EST5EDT,M4.1.0,M10.5.0
Egypt: EET-2<EEST>,M4.5.5/0,M9.5.4/24
Eire: GMT0IST,M3.5.0/1,M10.5.0/1
Etc/GMT: GMT0
Etc/UTC: UTC0
Etc/UCT: UCT0
Etc/GMT-14: <GMT-14>-14
Etc/GMT-13: <GMT-13>-13
Etc/GMT-12: <GMT-12>-12
Etc/GMT-11: <GMT-11>-11
Etc/GMT-10: <GMT-10>-10
Etc/GMT-9: <GMT-9>-9
Etc/GMT-8: <GMT-8>-8
Etc/GMT-7: <GMT-7>-7
Etc/GMT-6: <GMT-6>-6
Etc/GMT-5: <GMT-5>-5
Etc/GMT-4: <GMT-4>-4
Etc/GMT-3: <GMT-3>-3
Etc/GMT-2: <GMT-2>-2
Etc/GMT-1: <GMT-1>-1
Etc/GMT+1: <GMT+1>1
Etc/GMT+2: <GMT+2>2
Etc/GMT+3: <GMT+3>3
Etc/GMT+4: <GMT+4>4
Etc/GMT+5: <GMT+5>5
Etc/GMT+6: <GMT+6>6
Etc/GMT+7: <GMT+7>7
Etc/GMT+8: <GMT+8>8
Etc/GMT+9: <GMT+9>9
Etc/GMT+10: <GMT+10>10
Etc/GMT+11: <GMT+11>11
Etc/GMT+12: <GMT+12>12
Etc/Universal: UTC0
Etc/Zulu: UTC0
Etc/Greenwich: GMT0
Etc/GMT-0: GMT0
Etc/GMT+0: GMT0
Etc/GMT0: GMT0
Europe/London: GMT0BST,M3.5.0/1,M10.5.0/1
Europe/Belfast: GMT0BST,M3.5.0/1,M10.5.0/1
Europe/Dublin: GMT0IST,M3.5.0/1,M10.5.0/1
Europe/Tirane: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Andorra: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Vienna: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Minsk: EET-2<EEST>,M3.5.0,M10.5.0/3
Europe/Brussels: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Sofia: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Prague: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Copenhagen: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Tallinn: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Helsinki: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Paris: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Berlin: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Gibraltar: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Athens: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Budapest: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Rome: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Riga: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Vaduz: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Vilnius: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Luxembourg: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Malta: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Chisinau: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Monaco: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Amsterdam: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Oslo: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Warsaw: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Lisbon: WET0<WEST>,M3.5.0/1,M10.5.0/1
Europe/Bucharest: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Kaliningrad: EET-2<EEST>,M3.5.0,M10.5.0/3
Europe/Moscow: MSK-3MSD,M3.5.0,M10.5.0/3
Europe/Samara: <SAMT>-4<SAMST>,M3.5.0,M10.5.0/3
Europe/Belgrade: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Madrid: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Stockholm: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Zurich: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Istanbul: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Kiev: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Uzhgorod: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Zaporozhye: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Simferopol: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Nicosia: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Mariehamn: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Europe/Vatican: CET-1<CEST>,M3.5.0,M10.5.0
Europe/San_Marino: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Ljubljana: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Sarajevo: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Skopje: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Zagreb: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Bratislava: CET-1<CEST>,M3.5.0,M10.5.0
Europe/Tiraspol: EET-2<EEST>,M3.5.0/3,M10.5.0/3
Factory: <Local time zone must be set--see zic manual page>0
GB: GMT0BST,M3.5.0/1,M10.5.0/1
GB-Eire: GMT0BST,M3.5.0/1,M10.5.0/1
GMT: GMT0
GMT+0: GMT0
GMT-0: GMT0
GMT0: GMT0
Greenwich: GMT0
HST: HST10
Hongkong: HKT-8
Iceland: GMT0
Indian/Comoro: EAT-3
Indian/Antananarivo: EAT-3
Indian/Mauritius: MUT-4
Indian/Mayotte: EAT-3
Indian/Reunion: RET-4
Indian/Mahe: SCT-4
Indian/Kerguelen: TFT-5
Indian/Chagos: IOT-6
Indian/Maldives: MVT-5
Indian/Christmas: CXT-7
Indian/Cocos: CCT-6:30
Iran:
Israel:
Jamaica: EST5
Japan: JST-9
Kwajalein: MHT-12
Libya: EET-2
MET: MET-1<MEST>,M3.5.0,M10.5.0/3
MST: MST7
MST7MDT: MST7MDT,M4.1.0,M10.5.0
Mexico/BajaNorte: PST8PDT,M4.1.0,M10.5.0
Mexico/BajaSur: MST7MDT,M4.1.0,M10.5.0
Mexico/General: CST6CDT,M4.1.0,M10.5.0
Mideast/Riyadh87: zzz-3:07:04
Mideast/Riyadh88: zzz-3:07:04
Mideast/Riyadh89: zzz-3:07:04
NZ: <NZST>-12<NZDT>,M10.1.0,M3.3.0/3
NZ-CHAT: <CHAST>-12:45<CHADT>,M10.1.0/2:45,M3.3.0/3:45
Navajo: MST7MDT,M4.1.0,M10.5.0
PRC: CST-8
PST8PDT: PST8PDT,M4.1.0,M10.5.0
Pacific/Rarotonga: CKT10
Pacific/Fiji: FJT-12
Pacific/Gambier: <GAMT>9
Pacific/Marquesas: <MART>9:30
Pacific/Tahiti: <TAHT>10
Pacific/Guam: <ChST>-10
Pacific/Tarawa: <GILT>-12
Pacific/Enderbury: <PHOT>-13
Pacific/Kiritimati: <LINT>-14
Pacific/Saipan: <ChST>-10
Pacific/Majuro: MHT-12
Pacific/Kwajalein: MHT-12
Pacific/Yap: <YAPT>-10
Pacific/Truk: <TRUT>-10
Pacific/Ponape: <PONT>-11
Pacific/Kosrae: <KOST>-11
Pacific/Nauru: NRT-12
Pacific/Noumea: NCT-11
Pacific/Auckland: <NZST>-12<NZDT>,M10.1.0,M3.3.0/3
Pacific/Chatham: <CHAST>-12:45<CHADT>,M10.1.0/2:45,M3.3.0/3:45
Pacific/Niue: NUT11
Pacific/Norfolk: NFT-11:30
Pacific/Palau: PWT-9
Pacific/Port_Moresby: PGT-10
Pacific/Pitcairn: PST8
Pacific/Pago_Pago: SST11
Pacific/Apia: WST11
Pacific/Guadalcanal: SBT-11
Pacific/Fakaofo: TKT10
Pacific/Tongatapu: TOT-13
Pacific/Funafuti: TVT-12
Pacific/Johnston: HST10
Pacific/Midway: SST11
Pacific/Wake: <WAKT>-12
Pacific/Efate: VUT-11
Pacific/Wallis: WFT-12
Pacific/Honolulu: HST10
Pacific/Easter:
Pacific/Galapagos: <GALT>6
Pacific/Samoa: SST11
Poland: CET-1<CEST>,M3.5.0,M10.5.0
Portugal: WET0<WEST>,M3.5.0/1,M10.5.0/1
ROC: CST-8
ROK: KST-9
Singapore: SGT-8
SystemV/AST4ADT: AST4ADT,M4.1.0,M10.5.0
SystemV/EST5EDT: EST5EDT,M4.1.0,M10.5.0
SystemV/CST6CDT: CST6CDT,M4.1.0,M10.5.0
SystemV/MST7MDT: MST7MDT,M4.1.0,M10.5.0
SystemV/PST8PDT: PST8PDT,M4.1.0,M10.5.0
SystemV/YST9YDT: <AKST>9<AKDT>,M4.1.0,M10.5.0
SystemV/AST4: AST4
SystemV/EST5: EST5
SystemV/CST6: CST6
SystemV/MST7: MST7
SystemV/PST8: PST8
SystemV/YST9: <GAMT>9
SystemV/HST10: HST10
Turkey: EET-2<EEST>,M3.5.0/3,M10.5.0/3
UCT: UCT0
US/Pacific-New: PST8PDT,M4.1.0,M10.5.0
US/Alaska: <AKST>9<AKDT>,M4.1.0,M10.5.0
US/Aleutian: <HAST>10<HADT>,M4.1.0,M10.5.0
US/Arizona: MST7
US/Central: CST6CDT,M4.1.0,M10.5.0
US/East-Indiana: EST5
US/Eastern: EST5EDT,M4.1.0,M10.5.0
US/Hawaii: HST10
US/Indiana-Starke: EST5
US/Michigan: EST5EDT,M4.1.0,M10.5.0
US/Mountain: MST7MDT,M4.1.0,M10.5.0
US/Pacific: PST8PDT,M4.1.0,M10.5.0
US/Samoa: SST11
UTC: UTC0
Universal: UTC0
W-SU: MSK-3MSD,M3.5.0,M10.5.0/3
WET: WET0<WEST>,M3.5.0/1,M10.5.0/1
Zulu: UTC0
localtime: <Local time zone must be set--see zic manual page>0
posixrules: EST5EDT,M4.1.0,M10.5.0
3
2
Below find the next try at 64-bit changes.
As before, zic writes a second instance of headers and data to time zone files;
the second instance has eight-byte transition times to cover far-future
(and far past) cases. Zic also puts a newline-enclosed POSIX-style time zone
string at the end of the file when possible (or, when a zone can't be
represented using POSIX, puts a newline-enclode empty string at the end of the
file). (Enclosing the string in newlines makes for meaningful output from the
"tail -1" command applied to time zone files.) When a POSIX-style string is
available, zic does *not* write 400 years worth of data.
The files that don't have a POSIX string at the end are:
America/Godthab
America/Santiago
Antarctica/Palmer
Asia/Tehran
Asia/Jerusalem
Asia/Tel_Aviv
Chile/Continental
Chile/EasterIsland
Iran
Israel
Pacific/Easter
For zones such as America/Godthab, we use the previous dodge of writing 400
years worth of data to the time zone data file and then working modulo 400
in localtime.
Comparing current (tz) and proposed (tzexp2) disk usage:
Script started on Thu 30 Jun 2005 10:51:51 AM EDT
lecserver$ du -s -k ~/src/tz/tmp/etc/zoneinfo ~/src/tzexp2/tmp/etc/zoneinfo
489 /mnt/olsona/src/tz/tmp/etc/zoneinfo
779 /mnt/olsona/src/tzexp2/tmp/etc/zoneinfo
lecserver$ exit
script done on Thu 30 Jun 2005 10:52:06 AM EDT
There's still an increase; the increase is substantially less than without
the POSIX string dodge.
--ado
diff -c old/Makefile new/Makefile
*** old/Makefile Thu Jun 30 10:42:57 2005
--- new/Makefile Thu Jun 30 10:42:58 2005
***************
*** 95,100 ****
--- 95,101 ----
# -DHAVE_SETTIMEOFDAY=1 if settimeofday has just 1 arg (SVR4)
# -DHAVE_SETTIMEOFDAY=2 if settimeofday uses 2nd arg (4.3BSD)
# -DHAVE_SETTIMEOFDAY=3 if settimeofday ignores 2nd arg (4.4BSD)
+ # -DHAVE_STDINT_H=1 if you have a pre-C99 compiler with "stdint.h"
# -DHAVE_STRERROR=0 if your system lacks the strerror function
# -DHAVE_SYMLINK=0 if your system lacks the symlink function
# -DHAVE_SYS_STAT_H=0 if your compiler lacks a "sys/stat.h"
diff -c old/localtime.c new/localtime.c
*** old/localtime.c Thu Jun 30 10:42:57 2005
--- new/localtime.c Thu Jun 30 10:42:59 2005
***************
*** 111,116 ****
--- 111,118 ----
int timecnt;
int typecnt;
int charcnt;
+ int goback;
+ int goahead;
time_t ats[TZ_MAX_TIMES];
unsigned char types[TZ_MAX_TIMES];
struct ttinfo ttis[TZ_MAX_TYPES];
***************
*** 136,143 ****
*/
static long detzcode P((const char * codep));
static const char * getzname P((const char * strp));
! static const char * getqzname P((const char * strp, const char delim));
static const char * getnum P((const char * strp, int * nump, int min,
int max));
static const char * getsecs P((const char * strp, long * secsp));
--- 138,147 ----
*/
static long detzcode P((const char * codep));
+ static time_t detzcode64 P((const char * codep));
+ static int differ_by_repeat P((time_t t1, time_t t0));
static const char * getzname P((const char * strp));
! static const char * getqzname P((const char * strp, const int delim));
static const char * getnum P((const char * strp, int * nump, int min,
int max));
static const char * getsecs P((const char * strp, long * secsp));
***************
*** 174,180 ****
const struct tm * btmp));
static time_t transtime P((time_t janfirst, int year,
const struct rule * rulep, long offset));
! static int tzload P((const char * name, struct state * sp));
static int tzparse P((const char * name, struct state * sp,
int lastditch));
--- 178,185 ----
const struct tm * btmp));
static time_t transtime P((time_t janfirst, int year,
const struct rule * rulep, long offset));
! static int tzload P((const char * name, struct state * sp,
! int doextend));
static int tzparse P((const char * name, struct state * sp,
int lastditch));
***************
*** 235,240 ****
--- 240,258 ----
return result;
}
+ static time_t
+ detzcode64(codep)
+ const char * const codep;
+ {
+ register time_t result;
+ register int i;
+
+ result = (codep[0] & 0x80) ? ~0L : 0L;
+ for (i = 0; i < 8; ++i)
+ result = result * 256 + (codep[i] & 0xff);
+ return result;
+ }
+
static void
settzname P((void))
{
***************
*** 304,316 ****
}
static int
! tzload(name, sp)
register const char * name;
register struct state * const sp;
{
! register const char * p;
! register int i;
! register int fid;
if (name == NULL && (name = TZDEFAULT) == NULL)
return -1;
--- 322,354 ----
}
static int
! differ_by_repeat(t1, t0)
! const time_t t1;
! const time_t t0;
! {
! if (TYPE_INTEGRAL(time_t) &&
! TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
! return 0;
! return t1 - t0 == SECSPERREPEAT;
! }
!
! static int
! tzload(name, sp, doextend)
register const char * name;
register struct state * const sp;
+ register const int doextend;
{
! register const char * p;
! register int i;
! register int fid;
! register int stored;
! register int nread;
! union {
! struct tzhead tzhead;
! char buf[2 * sizeof(struct tzhead) +
! 2 * sizeof *sp +
! 4 * TZ_MAX_TIMES];
! } u;
if (name == NULL && (name = TZDEFAULT) == NULL)
return -1;
***************
*** 348,365 ****
if ((fid = open(name, OPEN_MODE)) == -1)
return -1;
}
! {
! struct tzhead * tzhp;
! union {
! struct tzhead tzhead;
! char buf[sizeof *sp + sizeof *tzhp];
! } u;
int ttisstdcnt;
int ttisgmtcnt;
- i = read(fid, u.buf, sizeof u.buf);
- if (close(fid) != 0)
- return -1;
ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
--- 386,398 ----
if ((fid = open(name, OPEN_MODE)) == -1)
return -1;
}
! nread = read(fid, u.buf, sizeof u.buf);
! if (close(fid) < 0 || nread <= 0)
! return -1;
! for (stored = 4; stored <= 8; stored *= 2) {
int ttisstdcnt;
int ttisgmtcnt;
ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt);
ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt);
sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt);
***************
*** 374,390 ****
(ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
(ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
return -1;
! if (i - (p - u.buf) < sp->timecnt * 4 + /* ats */
sp->timecnt + /* types */
! sp->typecnt * (4 + 2) + /* ttinfos */
sp->charcnt + /* chars */
! sp->leapcnt * (4 + 4) + /* lsinfos */
ttisstdcnt + /* ttisstds */
ttisgmtcnt) /* ttisgmts */
return -1;
for (i = 0; i < sp->timecnt; ++i) {
! sp->ats[i] = detzcode(p);
! p += 4;
}
for (i = 0; i < sp->timecnt; ++i) {
sp->types[i] = (unsigned char) *p++;
--- 407,425 ----
(ttisstdcnt != sp->typecnt && ttisstdcnt != 0) ||
(ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0))
return -1;
! if (nread - (p - u.buf) <
! sp->timecnt * stored + /* ats */
sp->timecnt + /* types */
! sp->typecnt * 6 + /* ttinfos */
sp->charcnt + /* chars */
! sp->leapcnt * (stored + 4) + /* lsinfos */
ttisstdcnt + /* ttisstds */
ttisgmtcnt) /* ttisgmts */
return -1;
for (i = 0; i < sp->timecnt; ++i) {
! sp->ats[i] = (stored == 4) ?
! detzcode(p) : detzcode64(p);
! p += stored;
}
for (i = 0; i < sp->timecnt; ++i) {
sp->types[i] = (unsigned char) *p++;
***************
*** 412,419 ****
register struct lsinfo * lsisp;
lsisp = &sp->lsis[i];
! lsisp->ls_trans = detzcode(p);
! p += 4;
lsisp->ls_corr = detzcode(p);
p += 4;
}
--- 447,455 ----
register struct lsinfo * lsisp;
lsisp = &sp->lsis[i];
! lsisp->ls_trans = (stored == 4) ?
! detzcode(p) : detzcode64(p);
! p += stored;
lsisp->ls_corr = detzcode(p);
p += 4;
}
***************
*** 470,476 ****
--- 506,568 ----
}
break;
}
+ /*
+ ** If this is an old file, we're done.
+ */
+ if (u.tzhead.tzh_version[0] == '\0')
+ break;
+ nread -= p - u.buf;
+ for (i = 0; i < nread; ++i)
+ u.buf[i] = p[i];
+ /*
+ ** If this is a narrow integer time_t system, we're done.
+ */
+ if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t))
+ break;
}
+ if (doextend && nread > 2 &&
+ u.buf[0] == '\n' && u.buf[nread - 1] == '\n' &&
+ sp->typecnt + 2 <= TZ_MAX_TYPES) {
+ struct state ts;
+ register int result;
+
+ u.buf[nread - 1] = '\0';
+ result = tzparse(&u.buf[1], &ts, FALSE);
+ if (result == 0 && ts.typecnt == 2 &&
+ sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
+ for (i = 0; i < 2; ++i)
+ ts.ttis[i].tt_abbrind +=
+ sp->charcnt;
+ for (i = 0; i < ts.charcnt; ++i)
+ sp->chars[sp->charcnt++] =
+ ts.chars[i];
+ i = 0;
+ while (i < ts.timecnt &&
+ ts.ats[i] <=
+ sp->ats[sp->timecnt - 1])
+ ++i;
+ while (i < ts.timecnt &&
+ sp->timecnt < TZ_MAX_TIMES) {
+ sp->ats[sp->timecnt] =
+ ts.ats[i];
+ sp->types[sp->timecnt] =
+ sp->typecnt +
+ ts.types[i];
+ ++sp->timecnt;
+ ++i;
+ }
+ sp->ttis[sp->typecnt++] = ts.ttis[0];
+ sp->ttis[sp->typecnt++] = ts.ttis[1];
+ }
+ }
+ i = 2 * YEARSPERREPEAT;
+ sp->goback = sp->goahead = sp->timecnt > i;
+ sp->goback &= sp->types[i] == sp->types[0] &&
+ differ_by_repeat(sp->ats[i], sp->ats[0]);
+ sp->goahead &=
+ sp->types[sp->timecnt - 1] == sp->types[sp->timecnt - 1 - i] &&
+ differ_by_repeat(sp->ats[sp->timecnt - 1],
+ sp->ats[sp->timecnt - 1 - i]);
return 0;
}
***************
*** 503,521 ****
/*
** Given a pointer into an extended time zone string, scan until the ending
! ** delimiter of the zone name is located. Return a pointer to the delimiter.
**
** As with getzname above, the legal character set is actually quite
** restricted, with other characters producing undefined results.
! ** We choose not to care - allowing almost anything to be in the zone abbrev.
*/
static const char *
getqzname(strp, delim)
register const char * strp;
! const char delim;
{
! register char c;
while ((c = *strp) != '\0' && c != delim)
++strp;
--- 595,613 ----
/*
** Given a pointer into an extended time zone string, scan until the ending
! ** delimiter of the zone name is located. Return a pointer to the delimiter.
**
** As with getzname above, the legal character set is actually quite
** restricted, with other characters producing undefined results.
! ** We don't do any checking here; checking is done later in common-case code.
*/
static const char *
getqzname(strp, delim)
register const char * strp;
! const int delim;
{
! register int c;
while ((c = *strp) != '\0' && c != delim)
++strp;
***************
*** 824,832 ****
if (name == NULL)
return -1;
}
! load_result = tzload(TZDEFRULES, sp);
if (load_result != 0)
sp->leapcnt = 0; /* so, we're off a little */
if (*name != '\0') {
if (*name == '<') {
dstname = ++name;
--- 916,925 ----
if (name == NULL)
return -1;
}
! load_result = tzload(TZDEFRULES, sp, FALSE);
if (load_result != 0)
sp->leapcnt = 0; /* so, we're off a little */
+ sp->timecnt = 0;
if (*name != '\0') {
if (*name == '<') {
dstname = ++name;
***************
*** 866,876 ****
return -1;
sp->typecnt = 2; /* standard time and DST */
/*
! ** Two transitions per year, from EPOCH_YEAR to 2037.
*/
- sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1);
- if (sp->timecnt > TZ_MAX_TIMES)
- return -1;
sp->ttis[0].tt_gmtoff = -dstoffset;
sp->ttis[0].tt_isdst = 1;
sp->ttis[0].tt_abbrind = stdlen + 1;
--- 959,966 ----
return -1;
sp->typecnt = 2; /* standard time and DST */
/*
! ** Two transitions per year, from EPOCH_YEAR forward.
*/
sp->ttis[0].tt_gmtoff = -dstoffset;
sp->ttis[0].tt_isdst = 1;
sp->ttis[0].tt_abbrind = stdlen + 1;
***************
*** 880,886 ****
atp = sp->ats;
typep = sp->types;
janfirst = 0;
! for (year = EPOCH_YEAR; year <= 2037; ++year) {
starttime = transtime(janfirst, year, &start,
stdoffset);
endtime = transtime(janfirst, year, &end,
--- 970,980 ----
atp = sp->ats;
typep = sp->types;
janfirst = 0;
! for (year = EPOCH_YEAR;
! sp->timecnt + 2 <= TZ_MAX_TIMES;
! ++year) {
! time_t newfirst;
!
starttime = transtime(janfirst, year, &start,
stdoffset);
endtime = transtime(janfirst, year, &end,
***************
*** 896,903 ****
*atp++ = endtime;
*typep++ = 1; /* DST ends */
}
! janfirst += year_lengths[isleap(year)] *
SECSPERDAY;
}
} else {
register long theirstdoffset;
--- 990,1002 ----
*atp++ = endtime;
*typep++ = 1; /* DST ends */
}
! sp->timecnt += 2;
! newfirst = janfirst;
! newfirst += year_lengths[isleap(year)] *
SECSPERDAY;
+ if (newfirst <= janfirst)
+ break;
+ janfirst = newfirst;
}
} else {
register long theirstdoffset;
***************
*** 1012,1018 ****
gmtload(sp)
struct state * const sp;
{
! if (tzload(gmt, sp) != 0)
(void) tzparse(gmt, sp, TRUE);
}
--- 1111,1117 ----
gmtload(sp)
struct state * const sp;
{
! if (tzload(gmt, sp, TRUE) != 0)
(void) tzparse(gmt, sp, TRUE);
}
***************
*** 1039,1045 ****
}
}
#endif /* defined ALL_STATE */
! if (tzload((char *) NULL, lclptr) != 0)
gmtload(lclptr);
settzname();
}
--- 1138,1144 ----
}
}
#endif /* defined ALL_STATE */
! if (tzload((char *) NULL, lclptr, TRUE) != 0)
gmtload(lclptr);
settzname();
}
***************
*** 1081,1087 ****
lclptr->ttis[0].tt_gmtoff = 0;
lclptr->ttis[0].tt_abbrind = 0;
(void) strcpy(lclptr->chars, gmt);
! } else if (tzload(name, lclptr) != 0)
if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
(void) gmtload(lclptr);
settzname();
--- 1180,1186 ----
lclptr->ttis[0].tt_gmtoff = 0;
lclptr->ttis[0].tt_abbrind = 0;
(void) strcpy(lclptr->chars, gmt);
! } else if (tzload(name, lclptr, TRUE) != 0)
if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
(void) gmtload(lclptr);
settzname();
***************
*** 1114,1119 ****
--- 1213,1257 ----
if (sp == NULL)
return gmtsub(timep, offset, tmp);
#endif /* defined ALL_STATE */
+ if ((sp->goback && t < sp->ats[0]) ||
+ (sp->goahead && t > sp->ats[sp->timecnt - 1])) {
+ time_t newt = t;
+ register time_t seconds;
+ register time_t tcycles;
+ register int_fast64_t icycles;
+
+ if (t < sp->ats[0])
+ seconds = sp->ats[0] - t;
+ else seconds = t - sp->ats[sp->timecnt - 1];
+ --seconds;
+ tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR;
+ ++tcycles;
+ icycles = tcycles;
+ if (tcycles - icycles >= 1 || icycles - tcycles >= 1)
+ return NULL;
+ seconds = icycles;
+ seconds *= YEARSPERREPEAT;
+ seconds *= AVGSECSPERYEAR;
+ if (t < sp->ats[0])
+ newt += seconds;
+ else newt -= seconds;
+ if (newt < sp->ats[0] ||
+ newt > sp->ats[sp->timecnt - 1])
+ return NULL; /* "cannot happen" */
+ result = localsub(&newt, offset, tmp);
+ if (result == tmp) {
+ register time_t newy;
+
+ newy = tmp->tm_year;
+ if (t < sp->ats[0])
+ newy -= icycles * YEARSPERREPEAT;
+ else newy += icycles * YEARSPERREPEAT;
+ tmp->tm_year = newy;
+ if (tmp->tm_year != newy)
+ return NULL;
+ }
+ return result;
+ }
if (sp->timecnt == 0 || t < sp->ats[0]) {
i = 0;
while (sp->ttis[i].tt_isdst)
diff -c old/private.h new/private.h
*** old/private.h Thu Jun 30 10:42:58 2005
--- new/private.h Thu Jun 30 10:42:59 2005
***************
*** 48,53 ****
--- 48,57 ----
#define HAVE_SETTIMEOFDAY 3
#endif /* !defined HAVE_SETTIMEOFDAY */
+ #ifndef HAVE_STDINT_H
+ #define HAVE_STDINT_H (199901 <= __STDC_VERSION__)
+ #endif /* !defined HAVE_STDINT_H */
+
#ifndef HAVE_STRERROR
#define HAVE_STRERROR 1
#endif /* !defined HAVE_STRERROR */
***************
*** 89,95 ****
#include "stdio.h"
#include "errno.h"
#include "string.h"
! #include "limits.h" /* for CHAR_BIT */
#include "time.h"
#include "stdlib.h"
--- 93,99 ----
#include "stdio.h"
#include "errno.h"
#include "string.h"
! #include "limits.h" /* for CHAR_BIT et al. */
#include "time.h"
#include "stdlib.h"
***************
*** 124,129 ****
--- 128,152 ----
/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
#define is_digit(c) ((unsigned)(c) - '0' <= 9)
+ #if HAVE_STDINT_H
+ #include <stdint.h>
+ #endif /* !HAVE_STDINT_H */
+
+ #ifndef INT_FAST64_MAX
+ #ifdef LLONG_MAX
+ typedef long long int_fast64_t;
+ #else /* !defined LLONG_MAX */
+ typedef long int_fast64_t;
+ #endif /* !defined LLONG_MAX */
+ #endif /* !defined INT_FAST64_MAX */
+
+ #ifndef INT32_MAX
+ #define INT32_MAX 0x7fffffff
+ #endif /* !defined INT32_MAX */
+ #ifndef INT32_MIN
+ #define INT32_MIN (-1 - INT32_MAX)
+ #endif /* !defined INT32_MIN */
+
/*
** Workarounds for compilers/systems.
*/
***************
*** 310,316 ****
--- 333,359 ----
char *ctime_r P((time_t const *, char *));
#endif /* HAVE_INCOMPATIBLE_CTIME_R */
+ #ifndef YEARSPERREPEAT
+ #define YEARSPERREPEAT 400 /* years before a Gregorian repeat */
+ #endif /* !defined YEARSPERREPEAT */
+
/*
+ ** The Gregorian year averages 365.2425 days, which is 31556952 seconds.
+ */
+
+ #ifndef AVGSECSPERYEAR
+ #define AVGSECSPERYEAR 31556952
+ #endif /* !defined AVGSECSPERYEAR */
+
+ #ifndef SECSPERREPEAT
+ #define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
+ #endif /* !defined SECSPERREPEAT */
+
+ #ifndef SECSPERREPEAT_BITS
+ #define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */
+ #endif /* !defined SECSPERREPEAT_BITS */
+
+ /*
** UNIX was a registered trademark of The Open Group in 2003.
*/
diff -c old/tzfile.5 new/tzfile.5
*** old/tzfile.5 Thu Jun 30 10:42:58 2005
--- new/tzfile.5 Thu Jun 30 10:42:59 2005
***************
*** 9,15 ****
.IR tzset (3)
begin with the magic characters "TZif" to identify then as
time zone information files,
! followed by sixteen bytes reserved for future use,
followed by six four-byte values of type
.BR long ,
written in a ``standard'' byte order
--- 9,17 ----
.IR tzset (3)
begin with the magic characters "TZif" to identify then as
time zone information files,
! followed by a character identifying the version of the file's format
! (as of 2005, either an ASCII NUL or a '2')
! followed by fifteen bytes containing zeroes reserved for future use,
followed by six four-byte values of type
.BR long ,
written in a ``standard'' byte order
***************
*** 131,136 ****
--- 133,148 ----
.I tzh_timecnt
is zero or the time argument is less than the first transition time recorded
in the file.
+ .PP
+ For version-2-format time zone files,
+ the above header and data is followed by a second header and data,
+ identical in format except that
+ eight bytes are used for each transition time or leap second time.
+ After the second header and data comes a newline-encloded,
+ POSIX-TZ-environment-variable-style string for use in handling instants
+ after the last transition time stored in the file
+ (with nothing between the newlines if there is no POSIX representation for
+ such instants).
.SH SEE ALSO
newctime(3)
.\" %W%
diff -c old/tzfile.h new/tzfile.h
*** old/tzfile.h Thu Jun 30 10:42:58 2005
--- new/tzfile.h Thu Jun 30 10:42:59 2005
***************
*** 49,55 ****
struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */
! char tzh_reserved[16]; /* reserved for future use */
char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
char tzh_leapcnt[4]; /* coded number of leap seconds */
--- 49,56 ----
struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */
! char tzh_version[1]; /* '\0' or '2' as of 2005 */
! char tzh_reserved[15]; /* reserved--must be zero */
char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */
char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */
char tzh_leapcnt[4]; /* coded number of leap seconds */
***************
*** 84,101 ****
*/
/*
** In the current implementation, "tzset()" refuses to deal with files that
** exceed any of the limits below.
*/
#ifndef TZ_MAX_TIMES
! /*
! ** The TZ_MAX_TIMES value below is enough to handle a bit more than a
! ** year's worth of solar time (corrected daily to the nearest second) or
! ** 138 years of Pacific Presidential Election time
! ** (where there are three time zone transitions every fourth year).
! */
! #define TZ_MAX_TIMES 370
#endif /* !defined TZ_MAX_TIMES */
#ifndef TZ_MAX_TYPES
--- 85,106 ----
*/
/*
+ ** If tzh_version is '2' or greater, the above is followed by a second instance
+ ** of tzhead and a second instance of the data in which each coded transition
+ ** time uses 8 rather than 4 chars,
+ ** then a POSIX-TZ-environment-variable-style string for use in handling
+ ** instants after the last transition time stored in the file
+ ** (with nothing between the newlines if there is no POSIX representation for
+ ** such instants).
+ */
+
+ /*
** In the current implementation, "tzset()" refuses to deal with files that
** exceed any of the limits below.
*/
#ifndef TZ_MAX_TIMES
! #define TZ_MAX_TIMES 1200
#endif /* !defined TZ_MAX_TIMES */
#ifndef TZ_MAX_TYPES
diff -c old/zdump.c new/zdump.c
*** old/zdump.c Thu Jun 30 10:42:57 2005
--- new/zdump.c Thu Jun 30 10:42:59 2005
***************
*** 12,17 ****
--- 12,18 ----
#include "time.h" /* for struct tm */
#include "stdlib.h" /* for exit, malloc, atoi */
#include "float.h" /* for FLT_MAX and DBL_MAX */
+ #include "ctype.h" /* for isascii et al. */
#ifndef ZDUMP_LO_YEAR
#define ZDUMP_LO_YEAR (-500)
***************
*** 147,153 ****
static int warned;
static char * abbr P((struct tm * tmp));
! static void abbrok P((const char * abbr, const char * zone));
static long delta P((struct tm * newp, struct tm * oldp));
static void dumptime P((const struct tm * tmp));
static time_t hunt P((char * name, time_t lot, time_t hit));
--- 148,154 ----
static int warned;
static char * abbr P((struct tm * tmp));
! static void abbrok P((const char * abbrp, const char * zone));
static long delta P((struct tm * newp, struct tm * oldp));
static void dumptime P((const struct tm * tmp));
static time_t hunt P((char * name, time_t lot, time_t hit));
***************
*** 194,222 ****
#endif /* !defined TYPECHECK */
static void
! abbrok(abbr, zone)
! const char * const abbr;
const char * const zone;
{
- register int i;
register const char * cp;
register char * wp;
if (warned)
return;
! cp = abbr;
wp = NULL;
! while (isascii(*cp) && isalpha(*cp))
++cp;
! if (cp - abbr == 0)
wp = _("lacks alphabetic at start");
! if (cp - abbr < 3)
wp = _("has fewer than 3 alphabetics");
! if (cp - abbr > 6)
wp = _("has more than 6 alphabetics");
if (wp == NULL && (*cp == '+' || *cp == '-')) {
++cp;
! if (isascii(*cp) && isdigit(*cp))
if (*cp++ == '1' && *cp >= '0' && *cp <= '4')
++cp;
}
--- 195,222 ----
#endif /* !defined TYPECHECK */
static void
! abbrok(abbrp, zone)
! const char * const abbrp;
const char * const zone;
{
register const char * cp;
register char * wp;
if (warned)
return;
! cp = abbrp;
wp = NULL;
! while (isascii((int) *cp) && isalpha((int) *cp))
++cp;
! if (cp - abbrp == 0)
wp = _("lacks alphabetic at start");
! if (cp - abbrp < 3)
wp = _("has fewer than 3 alphabetics");
! if (cp - abbrp > 6)
wp = _("has more than 6 alphabetics");
if (wp == NULL && (*cp == '+' || *cp == '-')) {
++cp;
! if (isascii((int) *cp) && isdigit((int) *cp))
if (*cp++ == '1' && *cp >= '0' && *cp <= '4')
++cp;
}
***************
*** 227,233 ****
(void) fflush(stdout);
(void) fprintf(stderr,
"%s: warning: zone \"%s\" abbreviation \"%s\" %s\n",
! progname, zone, abbr, wp);
warned = TRUE;
}
--- 227,233 ----
(void) fflush(stdout);
(void) fprintf(stderr,
"%s: warning: zone \"%s\" abbreviation \"%s\" %s\n",
! progname, zone, abbrp, wp);
warned = TRUE;
}
diff -c old/zic.c new/zic.c
*** old/zic.c Thu Jun 30 10:42:57 2005
--- new/zic.c Thu Jun 30 10:42:59 2005
***************
*** 1,15 ****
static char elsieid[] = "%W%";
- /*
- ** Regardless of the type of time_t, we do our work using this type.
- */
-
- typedef int zic_t;
-
#include "private.h"
#include "locale.h"
#include "tzfile.h"
#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
#define ZIC_MAX_ABBR_LEN_WO_WARN 6
#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
--- 1,13 ----
static char elsieid[] = "%W%";
#include "private.h"
#include "locale.h"
#include "tzfile.h"
+ #define ZIC_VERSION '2'
+
+ typedef int_fast64_t zic_t;
+
#ifndef ZIC_MAX_ABBR_LEN_WO_WARN
#define ZIC_MAX_ABBR_LEN_WO_WARN 6
#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */
***************
*** 36,41 ****
--- 34,44 ----
#define isascii(x) 1
#endif
+ #define OFFSET_STRLEN_MAXIMUM (7 + INT_STRLEN_MAXIMUM(long))
+ #define RULE_STRLEN_MAXIMUM 8 /* "Mdd.dd.d" */
+
+ #define end(cp) (strchr((cp), '\0'))
+
struct rule {
const char * r_filename;
int r_linenum;
***************
*** 44,49 ****
--- 47,54 ----
int r_loyear; /* for example, 1986 */
int r_hiyear; /* for example, 1986 */
const char * r_yrtype;
+ int r_lowasnum;
+ int r_hiwasnum;
int r_month; /* 0..11 */
***************
*** 103,111 ****
static void associate P((void));
static int ciequal P((const char * ap, const char * bp));
static void convert P((long val, char * buf));
static void dolink P((const char * fromfile, const char * tofile));
static void doabbr P((char * abbr, const char * format,
! const char * letters, int isdst));
static void eat P((const char * name, int num));
static void eats P((const char * name, int num,
const char * rname, int rnum));
--- 108,117 ----
static void associate P((void));
static int ciequal P((const char * ap, const char * bp));
static void convert P((long val, char * buf));
+ static void convert64 P((zic_t val, char * buf));
static void dolink P((const char * fromfile, const char * tofile));
static void doabbr P((char * abbr, const char * format,
! const char * letters, int isdst, int doquotes));
static void eat P((const char * name, int num));
static void eats P((const char * name, int num,
const char * rname, int rnum));
***************
*** 121,126 ****
--- 127,133 ----
static int inzcont P((char ** fields, int nfields));
static int inzone P((char ** fields, int nfields));
static int inzsub P((char ** fields, int nfields, int iscont));
+ static int is32 P((zic_t x));
static int itsabbr P((const char * abbr, const char * word));
static int itsdir P((const char * name));
static int lowerit P((int c));
***************
*** 130,135 ****
--- 137,143 ----
static long oadd P((long t1, long t2));
static void outzone P((const struct zone * zp, int ntzones));
static void puttzcode P((long code, FILE * fp));
+ static void puttzcode64 P((zic_t code, FILE * fp));
static int rcomp P((const void * leftp, const void * rightp));
static zic_t rpytime P((const struct rule * rp, int wantedy));
static void rulesub P((struct rule * rp,
***************
*** 136,145 ****
const char * loyearp, const char * hiyearp,
const char * typep, const char * monthp,
const char * dayp, const char * timep));
static void setboundaries P((void));
static zic_t tadd P((zic_t t1, long t2));
static void usage P((void));
! static void writezone P((const char * name));
static int yearistype P((int year, const char * type));
#if !HAVE_STRERROR
--- 144,158 ----
const char * loyearp, const char * hiyearp,
const char * typep, const char * monthp,
const char * dayp, const char * timep));
+ static int stringoffset P((char * result, long offset));
+ static int stringrule P((char * result, const struct rule * rp,
+ long dstoff, long gmtoff));
+ static void stringzone P((char * result,
+ const struct zone * zp, int ntzones));
static void setboundaries P((void));
static zic_t tadd P((zic_t t1, long t2));
static void usage P((void));
! static void writezone P((const char * name, const char * string));
static int yearistype P((int year, const char * type));
#if !HAVE_STRERROR
***************
*** 150,162 ****
static int errors;
static const char * filename;
static int leapcnt;
static int linenum;
static zic_t max_time;
static int max_year;
- static int max_year_representable;
static zic_t min_time;
static int min_year;
- static int min_year_representable;
static int noise;
static const char * rfilename;
static int rlinenum;
--- 163,178 ----
static int errors;
static const char * filename;
static int leapcnt;
+ static int leapseen;
+ static int leapminyear;
+ static int leapmaxyear;
static int linenum;
+ static int max_abbrvar_len;
+ static int max_format_len;
static zic_t max_time;
static int max_year;
static zic_t min_time;
static int min_year;
static int noise;
static const char * rfilename;
static int rlinenum;
***************
*** 453,459 ****
usage P((void))
{
(void) fprintf(stderr, _("%s: usage is %s \
! [ --version ] [ -s ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\
\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"),
progname, progname);
(void) exit(EXIT_FAILURE);
--- 469,475 ----
usage P((void))
{
(void) fprintf(stderr, _("%s: usage is %s \
! [ --version ] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\
\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n"),
progname, progname);
(void) exit(EXIT_FAILURE);
***************
*** 464,470 ****
static const char * directory;
static const char * leapsec;
static const char * yitcommand;
- static int sflag = FALSE;
int
main(argc, argv)
--- 480,485 ----
***************
*** 486,491 ****
--- 501,511 ----
(void) textdomain(TZ_DOMAIN);
#endif /* HAVE_GETTEXT */
progname = argv[0];
+ if (TYPE_BIT(zic_t) < 64) {
+ (void) fprintf(stderr, "%s: %s\n", progname,
+ _("wild compilation-time specification of zic_t"));
+ exit(EXIT_FAILURE);
+ }
for (i = 1; i < argc; ++i)
if (strcmp(argv[i], "--version") == 0) {
(void) printf("%s\n", elsieid);
***************
*** 549,555 ****
noise = TRUE;
break;
case 's':
! sflag = TRUE;
break;
}
if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
--- 569,575 ----
noise = TRUE;
break;
case 's':
! (void) printf("%s: -s ignored\n", progname);
break;
}
if (optind == argc - 1 && strcmp(argv[optind], "=") == 0)
***************
*** 671,724 ****
ifree(toname);
}
! #ifndef INT_MAX
! #define INT_MAX ((int) (((unsigned)~0)>>1))
! #endif /* !defined INT_MAX */
- #ifndef INT_MIN
- #define INT_MIN ((int) ~(((unsigned)~0)>>1))
- #endif /* !defined INT_MIN */
-
- /*
- ** The tz file format currently allows at most 32-bit quantities.
- ** This restriction should be removed before signed 32-bit values
- ** wrap around in 2038, but unfortunately this will require a
- ** change to the tz file format.
- */
-
- #define MAX_BITS_IN_FILE 32
- #define TIME_T_BITS_IN_FILE ((TYPE_BIT(zic_t) < MAX_BITS_IN_FILE) ? \
- TYPE_BIT(zic_t) : MAX_BITS_IN_FILE)
-
static void
setboundaries P((void))
{
register int i;
! if (TYPE_SIGNED(zic_t)) {
! min_time = -1;
! for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i)
! min_time *= 2;
! max_time = -(min_time + 1);
! if (sflag)
! min_time = 0;
! } else {
! min_time = 0;
! max_time = 2 - sflag;
! for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i)
! max_time *= 2;
! --max_time;
! }
! {
! time_t t;
!
! t = (time_t) min_time;
! min_year = TM_YEAR_BASE + gmtime(&t)->tm_year;
! t = (time_t) max_time;
! max_year = TM_YEAR_BASE + gmtime(&t)->tm_year;
! }
! min_year_representable = min_year;
! max_year_representable = max_year;
}
static int
--- 691,707 ----
ifree(toname);
}
! #define TIME_T_BITS_IN_FILE 64
static void
setboundaries P((void))
{
register int i;
! min_time = -1;
! for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i)
! min_time *= 2;
! max_time = -(min_time + 1);
}
static int
***************
*** 993,998 ****
--- 976,983 ----
fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]);
r.r_name = ecpyalloc(fields[RF_NAME]);
r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]);
+ if (max_abbrvar_len < strlen(r.r_abbrvar))
+ max_abbrvar_len = strlen(r.r_abbrvar);
rules = (struct rule *) (void *) erealloc((char *) rules,
(int) ((nrules + 1) * sizeof *rules));
rules[nrules++] = r;
***************
*** 1098,1103 ****
--- 1083,1090 ----
}
z.z_rule = ecpyalloc(fields[i_rule]);
z.z_format = ecpyalloc(fields[i_format]);
+ if (max_format_len < strlen(z.z_format))
+ max_format_len = strlen(z.z_format);
hasuntil = nfields > i_untilyear;
if (hasuntil) {
z.z_untilrule.r_filename = filename;
***************
*** 1159,1164 ****
--- 1146,1156 ----
error(_("invalid leaping year"));
return;
}
+ if (!leapseen || leapmaxyear < year)
+ leapmaxyear = year;
+ if (!leapseen || leapminyear < year)
+ leapminyear = year;
+ leapseen = TRUE;
j = EPOCH_YEAR;
while (j != year) {
if (year > j) {
***************
*** 1313,1319 ****
*/
cp = loyearp;
lp = byword(cp, begin_years);
! if (lp != NULL) switch ((int) lp->l_value) {
case YR_MINIMUM:
rp->r_loyear = INT_MIN;
break;
--- 1305,1312 ----
*/
cp = loyearp;
lp = byword(cp, begin_years);
! rp->r_lowasnum = lp == NULL;
! if (!rp->r_lowasnum) switch ((int) lp->l_value) {
case YR_MINIMUM:
rp->r_loyear = INT_MIN;
break;
***************
*** 1328,1341 ****
} else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) {
error(_("invalid starting year"));
return;
- } else if (noise) {
- if (rp->r_loyear < min_year_representable)
- warning(_("starting year too low to be represented"));
- else if (rp->r_loyear > max_year_representable)
- warning(_("starting year too high to be represented"));
}
cp = hiyearp;
! if ((lp = byword(cp, end_years)) != NULL) switch ((int) lp->l_value) {
case YR_MINIMUM:
rp->r_hiyear = INT_MIN;
break;
--- 1321,1331 ----
} else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) {
error(_("invalid starting year"));
return;
}
cp = hiyearp;
! lp = byword(cp, end_years);
! rp->r_hiwasnum = lp == NULL;
! if (!rp->r_hiwasnum) switch ((int) lp->l_value) {
case YR_MINIMUM:
rp->r_hiyear = INT_MIN;
break;
***************
*** 1353,1363 ****
} else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) {
error(_("invalid ending year"));
return;
- } else if (noise) {
- if (rp->r_loyear < min_year_representable)
- warning(_("ending year too low to be represented"));
- else if (rp->r_loyear > max_year_representable)
- warning(_("ending year too high to be represented"));
}
if (rp->r_loyear > rp->r_hiyear) {
error(_("starting year greater than ending year"));
--- 1343,1348 ----
***************
*** 1372,1379 ****
}
rp->r_yrtype = ecpyalloc(typep);
}
- if (rp->r_loyear < min_year && rp->r_loyear > 0)
- min_year = rp->r_loyear;
/*
** Day work.
** Accept things such as:
--- 1357,1362 ----
***************
*** 1427,1433 ****
char * const buf;
{
register int i;
! register long shift;
for (i = 0, shift = 24; i < 4; ++i, shift -= 8)
buf[i] = val >> shift;
--- 1410,1416 ----
char * const buf;
{
register int i;
! register int shift;
for (i = 0, shift = 24; i < 4; ++i, shift -= 8)
buf[i] = val >> shift;
***************
*** 1434,1439 ****
--- 1417,1434 ----
}
static void
+ convert64(val, buf)
+ const zic_t val;
+ char * const buf;
+ {
+ register int i;
+ register int shift;
+
+ for (i = 0, shift = 56; i < 8; ++i, shift -= 8)
+ buf[i] = val >> shift;
+ }
+
+ static void
puttzcode(val, fp)
const long val;
FILE * const fp;
***************
*** 1444,1471 ****
(void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
}
static int
atcomp(avp, bvp)
! void * avp;
! void * bvp;
{
! if (((struct attype *) avp)->at < ((struct attype *) bvp)->at)
! return -1;
! else if (((struct attype *) avp)->at > ((struct attype *) bvp)->at)
! return 1;
! else return 0;
}
static void
! writezone(name)
const char * const name;
{
! register FILE * fp;
! register int i, j;
! static char * fullname;
! static struct tzhead tzh;
! zic_t ats[TZ_MAX_TIMES];
! unsigned char types[TZ_MAX_TIMES];
/*
** Sort.
--- 1439,1488 ----
(void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
}
+ static void
+ puttzcode64(val, fp)
+ const zic_t val;
+ FILE * const fp;
+ {
+ char buf[8];
+
+ convert64(val, buf);
+ (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp);
+ }
+
static int
atcomp(avp, bvp)
! const void * avp;
! const void * bvp;
{
! const zic_t a = ((const struct attype *) avp)->at;
! const zic_t b = ((const struct attype *) bvp)->at;
!
! return (a < b) ? -1 : (a > b);
}
+ static int
+ is32(x)
+ const zic_t x;
+ {
+ return INT32_MIN <= x && x <= INT32_MAX;
+ }
+
static void
! writezone(name, string)
const char * const name;
+ const char * const string;
{
! register FILE * fp;
! register int i, j;
! register int leapcnt32, leapi32;
! register int timecnt32, timei32;
! register int pass;
! static char * fullname;
! static const struct tzhead tzh0;
! static struct tzhead tzh;
! zic_t ats[TZ_MAX_TIMES];
! unsigned char types[TZ_MAX_TIMES];
/*
** Sort.
***************
*** 1509,1514 ****
--- 1526,1561 ----
ats[i] = attypes[i].at;
types[i] = attypes[i].type;
}
+ /*
+ ** Correct for leap seconds.
+ */
+ for (i = 0; i < timecnt; ++i) {
+ j = leapcnt;
+ while (--j >= 0)
+ if (ats[i] >= trans[j]) {
+ ats[i] = tadd(ats[i], corr[j]);
+ break;
+ }
+ }
+ /*
+ ** Figure out 32-bit-limited starts and counts.
+ */
+ timecnt32 = timecnt;
+ timei32 = 0;
+ leapcnt32 = leapcnt;
+ leapi32 = 0;
+ while (timecnt32 > 0 && !is32(ats[timecnt32 - 1]))
+ --timecnt32;
+ while (timecnt32 > 0 && !is32(ats[timei32])) {
+ --timecnt32;
+ ++timei32;
+ }
+ while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1]))
+ --leapcnt32;
+ while (leapcnt32 > 0 && !is32(trans[leapi32])) {
+ --leapcnt32;
+ ++leapi32;
+ }
fullname = erealloc(fullname,
(int) (strlen(directory) + 1 + strlen(name) + 1));
(void) sprintf(fullname, "%s/%s", directory, name);
***************
*** 1533,1599 ****
(void) exit(EXIT_FAILURE);
}
}
! convert(eitol(typecnt), tzh.tzh_ttisgmtcnt);
! convert(eitol(typecnt), tzh.tzh_ttisstdcnt);
! convert(eitol(leapcnt), tzh.tzh_leapcnt);
! convert(eitol(timecnt), tzh.tzh_timecnt);
! convert(eitol(typecnt), tzh.tzh_typecnt);
! convert(eitol(charcnt), tzh.tzh_charcnt);
! (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
#define DO(field) (void) fwrite((void *) tzh.field, \
(size_t) sizeof tzh.field, (size_t) 1, fp)
! DO(tzh_magic);
! DO(tzh_reserved);
! DO(tzh_ttisgmtcnt);
! DO(tzh_ttisstdcnt);
! DO(tzh_leapcnt);
! DO(tzh_timecnt);
! DO(tzh_typecnt);
! DO(tzh_charcnt);
#undef DO
! for (i = 0; i < timecnt; ++i) {
! j = leapcnt;
! while (--j >= 0)
! if (ats[i] >= trans[j]) {
! ats[i] = tadd(ats[i], corr[j]);
! break;
! }
! puttzcode((long) ats[i], fp);
}
! if (timecnt > 0)
! (void) fwrite((void *) types, (size_t) sizeof types[0],
! (size_t) timecnt, fp);
! for (i = 0; i < typecnt; ++i) {
! puttzcode((long) gmtoffs[i], fp);
! (void) putc(isdsts[i], fp);
! (void) putc(abbrinds[i], fp);
! }
! if (charcnt != 0)
! (void) fwrite((void *) chars, (size_t) sizeof chars[0],
! (size_t) charcnt, fp);
! for (i = 0; i < leapcnt; ++i) {
! if (roll[i]) {
! if (timecnt == 0 || trans[i] < ats[0]) {
! j = 0;
! while (isdsts[j])
! if (++j >= typecnt) {
! j = 0;
! break;
! }
! } else {
! j = 1;
! while (j < timecnt && trans[i] >= ats[j])
! ++j;
! j = types[j - 1];
! }
! puttzcode((long) tadd(trans[i], -gmtoffs[j]), fp);
! } else puttzcode((long) trans[i], fp);
! puttzcode((long) corr[i], fp);
! }
! for (i = 0; i < typecnt; ++i)
! (void) putc(ttisstds[i], fp);
! for (i = 0; i < typecnt; ++i)
! (void) putc(ttisgmts[i], fp);
if (ferror(fp) || fclose(fp)) {
(void) fprintf(stderr, _("%s: Error writing %s\n"),
progname, fullname);
--- 1580,1672 ----
(void) exit(EXIT_FAILURE);
}
}
! for (pass = 1; pass <= 2; ++pass) {
! register int thistimei, thistimecnt;
! register int thisleapi, thisleapcnt;
! register int thistimelim, thisleaplim;
!
! if (pass == 1) {
! thistimei = timei32;
! thistimecnt = timecnt32;
! thisleapi = leapi32;
! thisleapcnt = leapcnt32;
! } else {
! thistimei = 0;
! thistimecnt = timecnt;
! thisleapi = 0;
! thisleapcnt = leapcnt;
! }
! thistimelim = thistimei + thistimecnt;
! thisleaplim = thisleapi + thisleapcnt;
#define DO(field) (void) fwrite((void *) tzh.field, \
(size_t) sizeof tzh.field, (size_t) 1, fp)
! tzh = tzh0;
! (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic);
! tzh.tzh_version[0] = ZIC_VERSION;
! convert(eitol(typecnt), tzh.tzh_ttisgmtcnt);
! convert(eitol(typecnt), tzh.tzh_ttisstdcnt);
! convert(eitol(thisleapcnt), tzh.tzh_leapcnt);
! convert(eitol(thistimecnt), tzh.tzh_timecnt);
! convert(eitol(typecnt), tzh.tzh_typecnt);
! convert(eitol(charcnt), tzh.tzh_charcnt);
! DO(tzh_magic);
! DO(tzh_version);
! DO(tzh_reserved);
! DO(tzh_ttisgmtcnt);
! DO(tzh_ttisstdcnt);
! DO(tzh_leapcnt);
! DO(tzh_timecnt);
! DO(tzh_typecnt);
! DO(tzh_charcnt);
#undef DO
! for (i = thistimei; i < thistimelim; ++i)
! if (pass == 1)
! puttzcode((long) ats[i], fp);
! else puttzcode64(ats[i], fp);
! if (thistimecnt > 0)
! (void) fwrite((void *) &types[thistimei],
! (size_t) sizeof types[0],
! (size_t) thistimecnt,
! fp);
! for (i = 0; i < typecnt; ++i) {
! puttzcode(gmtoffs[i], fp);
! (void) putc(isdsts[i], fp);
! (void) putc(abbrinds[i], fp);
! }
! if (charcnt != 0)
! (void) fwrite((void *) chars, (size_t) sizeof chars[0],
! (size_t) charcnt, fp);
! for (i = thisleapi; i < thisleaplim; ++i) {
! register zic_t todo;
!
! if (roll[i]) {
! if (timecnt == 0 || trans[i] < ats[0]) {
! j = 0;
! while (isdsts[j])
! if (++j >= typecnt) {
! j = 0;
! break;
! }
! } else {
! j = 1;
! while (j < timecnt &&
! trans[i] >= ats[j])
! ++j;
! j = types[j - 1];
! }
! todo = tadd(trans[i], -gmtoffs[j]);
! } else todo = trans[i];
! if (pass == 1)
! puttzcode((long) todo, fp);
! else puttzcode64(todo, fp);
! puttzcode(corr[i], fp);
! }
! for (i = 0; i < typecnt; ++i)
! (void) putc(ttisstds[i], fp);
! for (i = 0; i < typecnt; ++i)
! (void) putc(ttisgmts[i], fp);
}
! (void) fprintf(fp, "\n%s\n", string);
if (ferror(fp) || fclose(fp)) {
(void) fprintf(stderr, _("%s: Error writing %s\n"),
progname, fullname);
***************
*** 1602,1626 ****
}
static void
! doabbr(abbr, format, letters, isdst)
char * const abbr;
const char * const format;
const char * const letters;
const int isdst;
{
! if (strchr(format, '/') == NULL) {
if (letters == NULL)
(void) strcpy(abbr, format);
else (void) sprintf(abbr, format, letters);
! } else if (isdst)
! (void) strcpy(abbr, strchr(format, '/') + 1);
! else {
! (void) strcpy(abbr, format);
! *strchr(abbr, '/') = '\0';
}
}
static void
outzone(zpfirst, zonecount)
const struct zone * const zpfirst;
const int zonecount;
--- 1675,1901 ----
}
static void
! doabbr(abbr, format, letters, isdst, doquotes)
char * const abbr;
const char * const format;
const char * const letters;
const int isdst;
+ const int doquotes;
{
! register char * cp;
! register char * slashp;
! register int len;
!
! slashp = strchr(format, '/');
! if (slashp == NULL) {
if (letters == NULL)
(void) strcpy(abbr, format);
else (void) sprintf(abbr, format, letters);
! } else if (isdst) {
! (void) strcpy(abbr, slashp + 1);
! } else {
! if (slashp > format)
! (void) strncpy(abbr, format,
! (unsigned) (slashp - format));
! abbr[slashp - format] = '\0';
}
+ if (!doquotes)
+ return;
+ for (cp = abbr; *cp != '\0'; ++cp)
+ if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", *cp) == NULL &&
+ strchr("abcdefghijklmnopqrstuvwxyz", *cp) == NULL)
+ break;
+ len = strlen(abbr);
+ if (len == 3 && *cp == '\0')
+ return;
+ abbr[len + 2] = '\0';
+ abbr[len + 1] = '>';
+ for ( ; len > 0; --len)
+ abbr[len] = abbr[len - 1];
+ abbr[0] = '<';
}
static void
+ updateminmax(x)
+ const int x;
+ {
+ if (min_year > x)
+ min_year = x;
+ if (max_year < x)
+ max_year = x;
+ }
+
+ static int
+ stringoffset(result, offset)
+ char * result;
+ long offset;
+ {
+ register int hours;
+ register int minutes;
+ register int seconds;
+
+ result[0] = '\0';
+ if (offset < 0) {
+ (void) strcpy(result, "-");
+ offset = -offset;
+ }
+ seconds = offset % SECSPERMIN;
+ offset /= SECSPERMIN;
+ minutes = offset % MINSPERHOUR;
+ offset /= MINSPERHOUR;
+ hours = offset;
+ if (hours > 99) {
+ result[0] = '\0';
+ return -1;
+ }
+ (void) sprintf(end(result), "%d", hours);
+ if (minutes != 0 || seconds != 0) {
+ (void) sprintf(end(result), ":%02d", minutes);
+ if (seconds != 0)
+ (void) sprintf(end(result), ":%02d", seconds);
+ }
+ return 0;
+ }
+
+ static int
+ stringrule(result, rp, dstoff, gmtoff)
+ char * result;
+ const struct rule * const rp;
+ const long dstoff;
+ const long gmtoff;
+ {
+ register long tod;
+
+ result = end(result);
+ if (rp->r_dycode == DC_DOM) {
+ register int month, total;
+
+ if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY)
+ return -1;
+ total = 0;
+ for (month = 0; month < rp->r_month; ++month)
+ total += len_months[0][month];
+ (void) sprintf(result, "J%d", total + rp->r_dayofmonth);
+ } else {
+ register int week;
+
+ if (rp->r_dycode == DC_DOWGEQ) {
+ week = 1 + rp->r_dayofmonth / DAYSPERWEEK;
+ if ((week - 1) * DAYSPERWEEK + 1 != rp->r_dayofmonth)
+ return -1;
+ } else if (rp->r_dycode == DC_DOWLEQ) {
+ if (rp->r_dayofmonth == len_months[1][rp->r_month])
+ week = 5;
+ else {
+ week = 1 + rp->r_dayofmonth / DAYSPERWEEK;
+ if (week * DAYSPERWEEK - 1 != rp->r_dayofmonth)
+ return -1;
+ }
+ } else return -1; /* "cannot happen" */
+ (void) sprintf(result, "M%d.%d.%d",
+ rp->r_month + 1, week, rp->r_wday);
+ }
+ tod = rp->r_tod;
+ if (rp->r_todisgmt)
+ tod += gmtoff;
+ else if (rp->r_todisstd && rp->r_stdoff == 0)
+ tod += dstoff;
+ if (tod < 0) {
+ result[0] = '\0';
+ return -1;
+ }
+ if (tod != 2 * SECSPERMIN * MINSPERHOUR) {
+ (void) strcat(result, "/");
+ if (stringoffset(end(result), tod) != 0)
+ return -1;
+ }
+ return 0;
+ }
+
+ static void
+ stringzone(result, zpfirst, zonecount)
+ char * result;
+ const struct zone * const zpfirst;
+ const int zonecount;
+ {
+ register const struct zone * zp;
+ register struct rule * rp;
+ register struct rule * stdrp;
+ register struct rule * dstrp;
+ register int i;
+ register const char * abbrvar;
+
+ result[0] = '\0';
+ zp = zpfirst + zonecount - 1;
+ stdrp = dstrp = NULL;
+ for (i = 0; i < zp->z_nrules; ++i) {
+ rp = &zp->z_rules[i];
+ if (rp->r_hiwasnum || rp->r_hiyear != INT_MAX)
+ continue;
+ if (rp->r_yrtype != NULL)
+ continue;
+ if (rp->r_stdoff == 0) {
+ if (stdrp == NULL)
+ stdrp = rp;
+ else return;
+ } else {
+ if (dstrp == NULL)
+ dstrp = rp;
+ else return;
+ }
+ }
+ if (stdrp == NULL && dstrp == NULL) {
+ /*
+ ** There are no rules running through "max".
+ ** Let's find the latest rule.
+ */
+ for (i = 0; i < zp->z_nrules; ++i) {
+ rp = &zp->z_rules[i];
+ if (stdrp == NULL || rp->r_hiyear > stdrp->r_hiyear ||
+ (rp->r_hiyear == stdrp->r_hiyear &&
+ rp->r_month > stdrp->r_month))
+ stdrp = rp;
+ }
+ if (stdrp != NULL && stdrp->r_stdoff != 0)
+ return; /* We end up in DST (a POSIX no-no). */
+ /*
+ ** Horrid special case: if year is 2037,
+ ** presume this is a zone handled on a year-by-year basis;
+ ** do not try to apply a rule to the zone.
+ */
+ if (stdrp != NULL && stdrp->r_hiyear == 2037)
+ return;
+ }
+ if (stdrp == NULL && zp->z_nrules != 0)
+ return;
+ abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar;
+ doabbr(result, zp->z_format, abbrvar, FALSE, TRUE);
+ if (stringoffset(end(result), -zp->z_gmtoff) != 0) {
+ result[0] = '\0';
+ return;
+ }
+ if (dstrp == NULL)
+ return;
+ doabbr(end(result), zp->z_format, dstrp->r_abbrvar, TRUE, TRUE);
+ if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR)
+ if (stringoffset(end(result),
+ -(zp->z_gmtoff + dstrp->r_stdoff)) != 0) {
+ result[0] = '\0';
+ return;
+ }
+ (void) strcat(result, ",");
+ if (stringrule(result, dstrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) {
+ result[0] = '\0';
+ return;
+ }
+ (void) strcat(result, ",");
+ if (stringrule(result, stdrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) {
+ result[0] = '\0';
+ return;
+ }
+ }
+
+ static void
outzone(zpfirst, zonecount)
const struct zone * const zpfirst;
const int zonecount;
***************
*** 1637,1644 ****
register int startttisstd;
register int startttisgmt;
register int type;
! char startbuf[BUFSIZ];
INITIALIZE(untiltime);
INITIALIZE(starttime);
/*
--- 1912,1928 ----
register int startttisstd;
register int startttisgmt;
register int type;
! register char * startbuf;
! register char * ab;
! register char * envvar;
! register int max_abbr_len;
! register int max_envvar_len;
+ max_abbr_len = 2 + max_format_len + max_abbrvar_len;
+ max_envvar_len = 2 * max_abbr_len + 5 * 9;
+ startbuf = emalloc(max_abbr_len + 1);
+ ab = emalloc(max_abbr_len + 1);
+ envvar = emalloc(max_envvar_len + 1);
INITIALIZE(untiltime);
INITIALIZE(starttime);
/*
***************
*** 1653,1659 ****
--- 1937,1985 ----
*/
startttisstd = FALSE;
startttisgmt = FALSE;
+ min_year = max_year = EPOCH_YEAR;
+ if (leapseen) {
+ updateminmax(leapminyear);
+ updateminmax(leapmaxyear);
+ }
for (i = 0; i < zonecount; ++i) {
+ zp = &zpfirst[i];
+ updateminmax(zp->z_untilrule.r_loyear);
+ for (j = 0; j < zp->z_nrules; ++j) {
+ rp = &zp->z_rules[j];
+ if (rp->r_lowasnum)
+ updateminmax(rp->r_loyear);
+ if (rp->r_hiwasnum)
+ updateminmax(rp->r_hiyear);
+ }
+ }
+ /*
+ ** Generate lots of data if a rule can't cover all future times.
+ */
+ stringzone(envvar, zpfirst, zonecount);
+ if (noise && envvar[0] == '\0') {
+ register char * wp;
+
+ wp = ecpyalloc(_("no POSIX environment variable for zone"));
+ wp = ecatalloc(wp, " ");
+ wp = ecatalloc(wp, zpfirst->z_name);
+ warning(wp);
+ ifree(wp);
+ }
+ if (envvar[0] == '\0') {
+ if (min_year >= INT_MIN + YEARSPERREPEAT)
+ min_year -= YEARSPERREPEAT;
+ else min_year = INT_MIN;
+ if (max_year <= INT_MAX - YEARSPERREPEAT)
+ max_year += YEARSPERREPEAT;
+ else max_year = INT_MAX;
+ }
+ /*
+ ** For the benefit of older systems, generate data through 2037.
+ */
+ if (max_year < 2037)
+ max_year = 2037;
+ for (i = 0; i < zonecount; ++i) {
/*
** A guess that may well be corrected later.
*/
***************
*** 1670,1676 ****
if (zp->z_nrules == 0) {
stdoff = zp->z_stdoff;
doabbr(startbuf, zp->z_format,
! (char *) NULL, stdoff != 0);
type = addtype(oadd(zp->z_gmtoff, stdoff),
startbuf, stdoff != 0, startttisstd,
startttisgmt);
--- 1996,2002 ----
if (zp->z_nrules == 0) {
stdoff = zp->z_stdoff;
doabbr(startbuf, zp->z_format,
! (char *) NULL, stdoff != 0, FALSE);
type = addtype(oadd(zp->z_gmtoff, stdoff),
startbuf, stdoff != 0, startttisstd,
startttisgmt);
***************
*** 1700,1706 ****
register int k;
register zic_t jtime, ktime;
register long offset;
- char buf[BUFSIZ];
INITIALIZE(ktime);
if (useuntil) {
--- 2026,2031 ----
***************
*** 1756,1779 ****
stdoff);
doabbr(startbuf, zp->z_format,
rp->r_abbrvar,
! rp->r_stdoff != 0);
continue;
}
if (*startbuf == '\0' &&
startoff == oadd(zp->z_gmtoff,
! stdoff))
doabbr(startbuf,
zp->z_format,
rp->r_abbrvar,
rp->r_stdoff !=
! 0);
}
eats(zp->z_filename, zp->z_linenum,
rp->r_filename, rp->r_linenum);
! doabbr(buf, zp->z_format, rp->r_abbrvar,
! rp->r_stdoff != 0);
offset = oadd(zp->z_gmtoff, rp->r_stdoff);
! type = addtype(offset, buf, rp->r_stdoff != 0,
rp->r_todisstd, rp->r_todisgmt);
addtt(ktime, type);
}
--- 2081,2107 ----
stdoff);
doabbr(startbuf, zp->z_format,
rp->r_abbrvar,
! rp->r_stdoff != 0,
! FALSE);
continue;
}
if (*startbuf == '\0' &&
startoff == oadd(zp->z_gmtoff,
! stdoff)) {
doabbr(startbuf,
zp->z_format,
rp->r_abbrvar,
rp->r_stdoff !=
! 0,
! FALSE);
! }
}
eats(zp->z_filename, zp->z_linenum,
rp->r_filename, rp->r_linenum);
! doabbr(ab, zp->z_format, rp->r_abbrvar,
! rp->r_stdoff != 0, FALSE);
offset = oadd(zp->z_gmtoff, rp->r_stdoff);
! type = addtype(offset, ab, rp->r_stdoff != 0,
rp->r_todisstd, rp->r_todisgmt);
addtt(ktime, type);
}
***************
*** 1806,1812 ****
starttime = tadd(starttime, -gmtoff);
}
}
! writezone(zpfirst->z_name);
}
static void
--- 2134,2143 ----
starttime = tadd(starttime, -gmtoff);
}
}
! writezone(zpfirst->z_name, envvar);
! ifree(startbuf);
! ifree(ab);
! ifree(envvar);
}
static void
***************
*** 2184,2191 ****
will not work with pre-2004 versions of zic"));
}
}
- if (dayoff < 0 && !TYPE_SIGNED(zic_t))
- return min_time;
if (dayoff < min_time / SECSPERDAY)
return min_time;
if (dayoff > max_time / SECSPERDAY)
--- 2515,2520 ----
***************
*** 2210,2216 ****
*/
cp = string;
wp = NULL;
! while (isascii(*cp) && isalpha(*cp))
++cp;
if (cp - string == 0)
wp = _("time zone abbreviation lacks alphabetic at start");
--- 2539,2545 ----
*/
cp = string;
wp = NULL;
! while (isascii((int) *cp) && isalpha((int) *cp))
++cp;
if (cp - string == 0)
wp = _("time zone abbreviation lacks alphabetic at start");
***************
*** 2220,2226 ****
wp = _("time zone abbreviation has too many alphabetics");
if (wp == NULL && (*cp == '+' || *cp == '-')) {
++cp;
! if (isascii(*cp) && isdigit(*cp))
if (*cp++ == '1' && *cp >= '0' && *cp <= '4')
++cp;
}
--- 2549,2555 ----
wp = _("time zone abbreviation has too many alphabetics");
if (wp == NULL && (*cp == '+' || *cp == '-')) {
++cp;
! if (isascii((int) *cp) && isdigit((int) *cp))
if (*cp++ == '1' && *cp >= '0' && *cp <= '4')
++cp;
}
1
0
The time zones of Kazakhstan have changed recently. I sent an e-mail to the
tz list on May 20, summarizing the evidence then available, which was
contradictory. I received an e-mail today from an informant in Astana,
Branislav Kojic, explaining the current time zone situation in Kazakhstan.
If he is right, Asia/Aqtau and Asia/Oral should be on UTC+5. The tz
database still shows them in UTC+4. He has given me permission to quote
him. He writes:
"I read your page on the time zones in Kazakhstan, and
also your invitation to suggest improvements. I have
been living in Kazakhstan for over a year now, and I
can sympathize with the feeling of confusion that
Kazakhstani government can cause among the members of
diplomatic community and other foreigners with their
lousily translated and contradicting information.
Rather than losing myself in analyzing the meaning of
their decisions on changes in the DST policy and
related issues, I wish to inform you of the situation
as it actually is now, as advised by my local
colleagues and friends.
"In reality, what happened was that the former
Kazakhstan Eastern time zone was "blended" with the
Central zone. Therefore, Kazakhstan now has two time
zones, and difference between them is one hour. The
zone closer to UTC is the former Western zone
(probably still called the same), encompassing four
provinces in the west: Aqtöbe, Atyrau, Mangghystau,
and West Kazakhstan. The other zone encompasses
everything else. This is pretty much how you describe
it in the end, except that the difference is one hour,
not two.
"Regarding the actual time zones (in reference with
UTC), I can tell you that we are now 3 and 4 hours
ahead of Central European Time (CET) in our two time
zones in Kazakhstan respectively. I am making that
reference because CET is my native time zone, here in
Astana I am now 4 hours ahead of my HQ in Geneva,
Switzerland, and my home in Belgrade,
Serbia&Montenegro. If the government here does not
make more changes, we will fall back to 4 and 5 hours
ahead of CET respectively when the DST switches in
Europe (in October, if I'm not mistaking). I guess
that would make Kazakhstan time zones de jure UTC+5
and UTC+6 respectively.
"Hope I got all this right, and hope it was of some
help.
"Best regards
Branko
Astana, Kazakhstan"
-- Gwillim Law
1
0
As it's been fairly quiet here recently I thought I would mention
that Lord Tanlaw, the UK peer who tried and failed to have the UK's
legal time changed from GMT to UTC, has been in the news again.
He has been complaining about the inaccuracy of the time signal
broadcast by the BBC (the "pips") due to the delays introduced by
various sorts of digital processing, either by digital radios or
Internet streaming. These pips used to be called the Greenwich Time
Signal as they were produced by the observatory, but responsibilty
for them passed to the BBC some years ago.
He was interviewed on the BBC Radio 4 Today programme yesterday
morning and he asked a question in the House of Lords later in
the day. There was more about it on the Radio 4 PM programme
in the evening, during which a BBC statement was read saying
roughly `we know it's a problem and we will probably have to
do something about it'. The statement made the interesting point
that for DAB digital radios at least, the delay is no worse than
that suffered by someone setting their watch by the chimes of
Big Ben when standing on the other side of Parliament Square.
Lord Tanlaw mentioned that he was a member of the British Horological
Institute on the radio in the morning, and declared this interest
before asking his question in the Lords. That's presumably why
he tried for the change to UTC.
Lord Tanlaw's question is in the Lords Hansard at
<http://www.publications.parliament.uk/pa/ld199900/ldhansrd/pdvn/
lds05/text/50622-02.htm#50622-02_star0>.
If you have Real Player you can probably listen to the radio pieces
by starting at <http://www.bbc.co.uk/radio4/>. I don't, so I can't
be more specific than that.
Peter Ilieve peter(a)aldie.co.uk
1
0
I've sent Philippe some basic information in answer to his questions.
--ado
1
0
Hello,
could someone please tell me:
- why the TZ environment variable is empty before you set it
- why setting it does not seem to affect the system's internal timezone
- what the zoneinfo daemon, if there is such a thing, is called
- how zoneinfo knows that the TZ variable has been set
- if you can query the daemon directly
- if you can retrieve data, such as a city's coordinates, from it
- if there is a way to retrieve the list of values you can set TZ to,
apart from going through the directories in /usr/share/zoneinfo and
using the file names as values
I am using Macosx 10.3.
Many thanks.
Philippe
1
0
As I mentioned - but somehow my messages aren't making it through
to the list - I use the Windows time zone information values, rather
than the keys when I'm doing the translation for the Tcl 'clock'
subsystem. The keys are indeed localized, which renders them
useless.
--
73 de ke9tv/2, Kevin KENNY GE Corporate Research & Development
kennykb(a)crd.ge.com P. O. Box 8, Bldg. K-1, Rm. 5B36A
Schenectady, New York 12301-0008 USA
2
1
The time zone names, offsets, and begin/end rules for summer time
are stored in the system registry, in the path
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\\Time Zones
The keys under that path are the time zone names; within each key
are the values Display (the name to display in the Control Panel)
Std (the name to use for standard time), Dlt (the name to use for
summer time), Index (a number of the zone, but not terribly useful),
MapID (a map location of the zone, again not useful since that
functionality was removed from the Control Panel), and TZI.
The TZI value is an encoded version of a TIME_ZONE_INFORMATION
structure.
http://msdn.microsoft.com/library/en-us/sysinfo/base/time_zone_information_…
The two WCHAR arrays are removed, so there are
- bias (minutes west) - 32 bits
- standard bias (adjustment as of 0 January) - 32 bits
- daylight bias (adjustment in Northern summer) - 32 bits
- the fields of the two SYSTEMTIME structures, in order.
--
73 de ke9tv/2, Kevin KENNY GE Corporate Research & Development
kennykb(a)crd.ge.com P. O. Box 8, Bldg. K-1, Rm. 5B36A
Schenectady, New York 12301-0008 USA
1
0