forked from Mirrors/freeswitch
add mod_timezone from CtRiX thanks
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9175 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
03cc800f0c
commit
505e326de1
|
@ -0,0 +1,551 @@
|
|||
<configuration name="timezones.conf" description="Timezones">
|
||||
<timezones>
|
||||
<zone name="Africa/Abidjan" value="GMT0" />
|
||||
<zone name="Africa/Accra" value="GMT0" />
|
||||
<zone name="Africa/Addis_Ababa" value="EAT-3" />
|
||||
<zone name="Africa/Algiers" value="CET-1" />
|
||||
<zone name="Africa/Asmara" value="EAT-3" />
|
||||
<zone name="Africa/Asmera" value="EAT-3" />
|
||||
<zone name="Africa/Bamako" value="GMT0" />
|
||||
<zone name="Africa/Bangui" value="WAT-1" />
|
||||
<zone name="Africa/Banjul" value="GMT0" />
|
||||
<zone name="Africa/Bissau" value="GMT0" />
|
||||
<zone name="Africa/Blantyre" value="CAT-2" />
|
||||
<zone name="Africa/Brazzaville" value="WAT-1" />
|
||||
<zone name="Africa/Bujumbura" value="CAT-2" />
|
||||
<zone name="Africa/Cairo" value="EEST" />
|
||||
<zone name="Africa/Casablanca" value="WET0" />
|
||||
<zone name="Africa/Ceuta" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Africa/Conakry" value="GMT0" />
|
||||
<zone name="Africa/Dakar" value="GMT0" />
|
||||
<zone name="Africa/Dar_es_Salaam" value="EAT-3" />
|
||||
<zone name="Africa/Djibouti" value="EAT-3" />
|
||||
<zone name="Africa/Douala" value="WAT-1" />
|
||||
<zone name="Africa/El_Aaiun" value="WET0" />
|
||||
<zone name="Africa/Freetown" value="GMT0" />
|
||||
<zone name="Africa/Gaborone" value="CAT-2" />
|
||||
<zone name="Africa/Harare" value="CAT-2" />
|
||||
<zone name="Africa/Johannesburg" value="SAST-2" />
|
||||
<zone name="Africa/Kampala" value="EAT-3" />
|
||||
<zone name="Africa/Khartoum" value="EAT-3" />
|
||||
<zone name="Africa/Kigali" value="CAT-2" />
|
||||
<zone name="Africa/Kinshasa" value="WAT-1" />
|
||||
<zone name="Africa/Lagos" value="WAT-1" />
|
||||
<zone name="Africa/Libreville" value="WAT-1" />
|
||||
<zone name="Africa/Lome" value="GMT0" />
|
||||
<zone name="Africa/Luanda" value="WAT-1" />
|
||||
<zone name="Africa/Lubumbashi" value="CAT-2" />
|
||||
<zone name="Africa/Lusaka" value="CAT-2" />
|
||||
<zone name="Africa/Malabo" value="WAT-1" />
|
||||
<zone name="Africa/Maputo" value="CAT-2" />
|
||||
<zone name="Africa/Maseru" value="SAST-2" />
|
||||
<zone name="Africa/Mbabane" value="SAST-2" />
|
||||
<zone name="Africa/Mogadishu" value="EAT-3" />
|
||||
<zone name="Africa/Monrovia" value="GMT0" />
|
||||
<zone name="Africa/Nairobi" value="EAT-3" />
|
||||
<zone name="Africa/Ndjamena" value="WAT-1" />
|
||||
<zone name="Africa/Niamey" value="WAT-1" />
|
||||
<zone name="Africa/Nouakchott" value="GMT0" />
|
||||
<zone name="Africa/Ouagadougou" value="GMT0" />
|
||||
<zone name="Africa/Porto-Novo" value="WAT-1" />
|
||||
<zone name="Africa/Sao_Tome" value="GMT0" />
|
||||
<zone name="Africa/Timbuktu" value="GMT0" />
|
||||
<zone name="Africa/Tripoli" value="EET-2" />
|
||||
<zone name="Africa/Tunis" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Africa/Windhoek" value="WAT-1WAST,M9.1.0,M4.1.0" />
|
||||
|
||||
<zone name="America/Adak" value="HAST10HADT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Anchorage" value="AKST9AKDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Anguilla" value="AST4" />
|
||||
<zone name="America/Antigua" value="AST4" />
|
||||
<zone name="America/Araguaina" value="BRT3" />
|
||||
<zone name="America/Argentina/Buenos_Aires" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Argentina/Catamarca" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Argentina/ComodRivadavia" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Argentina/Cordoba" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Argentina/Jujuy" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Argentina/La_Rioja" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Argentina/Mendoza" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Argentina/Rio_Gallegos" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Argentina/San_Juan" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Argentina/San_Luis" value="ART3" />
|
||||
<zone name="America/Argentina/Tucuman" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Argentina/Ushuaia" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Aruba" value="AST4" />
|
||||
<zone name="America/Asuncion" value="PYT4PYST,M10.3.0/0,M3.2.0/0" />
|
||||
<zone name="America/Atikokan" value="EST5" />
|
||||
<zone name="America/Atka" value="HAST10HADT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Bahia" value="BRT3" />
|
||||
<zone name="America/Barbados" value="AST4" />
|
||||
<zone name="America/Belem" value="BRT3" />
|
||||
<zone name="America/Belize" value="CST6" />
|
||||
<zone name="America/Blanc-Sablon" value="AST4" />
|
||||
<zone name="America/Boa_Vista" value="AMT4" />
|
||||
<zone name="America/Bogota" value="COT5" />
|
||||
<zone name="America/Boise" value="MST7MDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Buenos_Aires" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Cambridge_Bay" value="MST7MDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Campo_Grande" value="AMT4AMST,M10.2.0/0,M2.3.0/0" />
|
||||
<zone name="America/Cancun" value="CST6CDT,M4.1.0,M10.5.0" />
|
||||
<zone name="America/Caracas" value="VET4:30" />
|
||||
<zone name="America/Catamarca" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Cayenne" value="GFT3" />
|
||||
<zone name="America/Cayman" value="EST5" />
|
||||
<zone name="America/Chicago" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Chihuahua" value="MST7MDT,M4.1.0,M10.5.0" />
|
||||
<zone name="America/Coral_Harbour" value="EST5" />
|
||||
<zone name="America/Cordoba" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Costa_Rica" value="CST6" />
|
||||
<zone name="America/Cuiaba" value="AMT4AMST,M10.2.0/0,M2.3.0/0" />
|
||||
<zone name="America/Curacao" value="AST4" />
|
||||
<zone name="America/Danmarkshavn" value="GMT0" />
|
||||
<zone name="America/Dawson" value="PST8PDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Dawson_Creek" value="MST7" />
|
||||
<zone name="America/Denver" value="MST7MDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Detroit" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Dominica" value="AST4" />
|
||||
<zone name="America/Edmonton" value="MST7MDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Eirunepe" value="ACT5" />
|
||||
<zone name="America/El_Salvador" value="CST6" />
|
||||
<zone name="America/Ensenada" value="PST8PDT,M4.1.0,M10.5.0" />
|
||||
<zone name="America/Fortaleza" value="BRT3" />
|
||||
<zone name="America/Fort_Wayne" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Glace_Bay" value="AST4ADT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Godthab" value="WGST" />
|
||||
<zone name="America/Goose_Bay" value="AST4ADT,M3.2.0/0:01,M11.1.0/0:01" />
|
||||
<zone name="America/Grand_Turk" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Grenada" value="AST4" />
|
||||
<zone name="America/Guadeloupe" value="AST4" />
|
||||
<zone name="America/Guatemala" value="CST6" />
|
||||
<zone name="America/Guayaquil" value="ECT5" />
|
||||
<zone name="America/Guyana" value="GYT4" />
|
||||
<zone name="America/Halifax" value="AST4ADT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Havana" value="CST5CDT,M3.3.0/0,M10.5.0/1" />
|
||||
<zone name="America/Hermosillo" value="MST7" />
|
||||
<zone name="America/Indiana/Indianapolis" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Indiana/Knox" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Indiana/Marengo" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Indiana/Petersburg" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Indianapolis" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Indiana/Tell_City" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Indiana/Vevay" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Indiana/Vincennes" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Indiana/Winamac" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Inuvik" value="MST7MDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Iqaluit" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Jamaica" value="EST5" />
|
||||
<zone name="America/Jujuy" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Juneau" value="AKST9AKDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Kentucky/Louisville" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Kentucky/Monticello" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Knox_IN" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/La_Paz" value="BOT4" />
|
||||
<zone name="America/Lima" value="PET5" />
|
||||
<zone name="America/Los_Angeles" value="PST8PDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Louisville" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Maceio" value="BRT3" />
|
||||
<zone name="America/Managua" value="CST6" />
|
||||
<zone name="America/Manaus" value="AMT4" />
|
||||
<zone name="America/Marigot" value="AST4" />
|
||||
<zone name="America/Martinique" value="AST4" />
|
||||
<zone name="America/Mazatlan" value="MST7MDT,M4.1.0,M10.5.0" />
|
||||
<zone name="America/Mendoza" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Menominee" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Merida" value="CST6CDT,M4.1.0,M10.5.0" />
|
||||
<zone name="America/Mexico_City" value="CST6CDT,M4.1.0,M10.5.0" />
|
||||
<zone name="America/Miquelon" value="PMST3PMDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Moncton" value="AST4ADT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Monterrey" value="CST6CDT,M4.1.0,M10.5.0" />
|
||||
<zone name="America/Montevideo" value="UYT3UYST,M10.1.0,M3.2.0" />
|
||||
<zone name="America/Montreal" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Montserrat" value="AST4" />
|
||||
<zone name="America/Nassau" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/New_York" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Nipigon" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Nome" value="AKST9AKDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Noronha" value="FNT2" />
|
||||
<zone name="America/North_Dakota/Center" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/North_Dakota/New_Salem" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Panama" value="EST5" />
|
||||
<zone name="America/Pangnirtung" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Paramaribo" value="SRT3" />
|
||||
<zone name="America/Phoenix" value="MST7" />
|
||||
<zone name="America/Port-au-Prince" value="EST5" />
|
||||
<zone name="America/Porto_Acre" value="ACT5" />
|
||||
<zone name="America/Port_of_Spain" value="AST4" />
|
||||
<zone name="America/Porto_Velho" value="AMT4" />
|
||||
<zone name="America/Puerto_Rico" value="AST4" />
|
||||
<zone name="America/Rainy_River" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Rankin_Inlet" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Recife" value="BRT3" />
|
||||
<zone name="America/Regina" value="CST6" />
|
||||
<zone name="America/Resolute" value="EST5" />
|
||||
<zone name="America/Rio_Branco" value="ACT5" />
|
||||
<zone name="America/Rosario" value="ART3ARST,M10.1.0/0,M3.3.0/0" />
|
||||
<zone name="America/Santiago" value="CLST" />
|
||||
<zone name="America/Santo_Domingo" value="AST4" />
|
||||
<zone name="America/Sao_Paulo" value="BRT3BRST,M10.2.0/0,M2.3.0/0" />
|
||||
<zone name="America/Scoresbysund" value="EGT1EGST,M3.5.0/0,M10.5.0/1" />
|
||||
<zone name="America/Shiprock" value="MST7MDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/St_Barthelemy" value="AST4" />
|
||||
<zone name="America/St_Johns" value="NST3:30NDT,M3.2.0/0:01,M11.1.0/0:01" />
|
||||
<zone name="America/St_Kitts" value="AST4" />
|
||||
<zone name="America/St_Lucia" value="AST4" />
|
||||
<zone name="America/St_Thomas" value="AST4" />
|
||||
<zone name="America/St_Vincent" value="AST4" />
|
||||
<zone name="America/Swift_Current" value="CST6" />
|
||||
<zone name="America/Tegucigalpa" value="CST6" />
|
||||
<zone name="America/Thule" value="AST4ADT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Thunder_Bay" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Tijuana" value="PST8PDT,M4.1.0,M10.5.0" />
|
||||
<zone name="America/Toronto" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Tortola" value="AST4" />
|
||||
<zone name="America/Vancouver" value="PST8PDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Virgin" value="AST4" />
|
||||
<zone name="America/Whitehorse" value="PST8PDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Winnipeg" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Yakutat" value="AKST9AKDT,M3.2.0,M11.1.0" />
|
||||
<zone name="America/Yellowknife" value="MST7MDT,M3.2.0,M11.1.0" />
|
||||
|
||||
<zone name="Antarctica/Casey" value="WST-8" />
|
||||
<zone name="Antarctica/Davis" value="DAVT-7" />
|
||||
<zone name="Antarctica/DumontDUrville" value="DDUT-10" />
|
||||
<zone name="Antarctica/Mawson" value="MAWT-6" />
|
||||
<zone name="Antarctica/McMurdo" value="NZST-12NZDT,M9.5.0,M4.1.0/3" />
|
||||
<zone name="Antarctica/Palmer" value="CLST" />
|
||||
<zone name="Antarctica/Rothera" value="ROTT3" />
|
||||
<zone name="Antarctica/South_Pole" value="NZST-12NZDT,M9.5.0,M4.1.0/3" />
|
||||
<zone name="Antarctica/Syowa" value="SYOT-3" />
|
||||
<zone name="Antarctica/Vostok" value="VOST-6" />
|
||||
|
||||
<zone name="Arctic/Longyearbyen" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
|
||||
<zone name="Asia/Aden" value="AST-3" />
|
||||
<zone name="Asia/Almaty" value="ALMT-6" />
|
||||
<zone name="Asia/Amman" value="EET-2EEST,M3.5.4/0,M10.5.5/1" />
|
||||
<zone name="Asia/Anadyr" value="ANAT-12ANAST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Asia/Aqtau" value="AQTT-5" />
|
||||
<zone name="Asia/Aqtobe" value="AQTT-5" />
|
||||
<zone name="Asia/Ashgabat" value="TMT-5" />
|
||||
<zone name="Asia/Ashkhabad" value="TMT-5" />
|
||||
<zone name="Asia/Baghdad" value="AST-3" />
|
||||
<zone name="Asia/Bahrain" value="AST-3" />
|
||||
<zone name="Asia/Baku" value="AZT-4AZST,M3.5.0/4,M10.5.0/5" />
|
||||
<zone name="Asia/Bangkok" value="ICT-7" />
|
||||
<zone name="Asia/Beirut" value="EET-2EEST,M3.5.0/0,M10.5.0/0" />
|
||||
<zone name="Asia/Bishkek" value="KGT-6" />
|
||||
<zone name="Asia/Brunei" value="BNT-8" />
|
||||
<zone name="Asia/Calcutta" value="IST-5:30" />
|
||||
<zone name="Asia/Choibalsan" value="CHOT-9" />
|
||||
<zone name="Asia/Chongqing" value="CST-8" />
|
||||
<zone name="Asia/Chungking" value="CST-8" />
|
||||
<zone name="Asia/Colombo" value="IST-5:30" />
|
||||
<zone name="Asia/Dacca" value="BDT-6" />
|
||||
<zone name="Asia/Damascus" value="EET-2EEST,M4.1.5/0,J274/0" />
|
||||
<zone name="Asia/Dhaka" value="BDT-6" />
|
||||
<zone name="Asia/Dili" value="TLT-9" />
|
||||
<zone name="Asia/Dubai" value="GST-4" />
|
||||
<zone name="Asia/Dushanbe" value="TJT-5" />
|
||||
<zone name="Asia/Gaza" value="EET-2EEST,J91/0,M9.2.4" />
|
||||
<zone name="Asia/Harbin" value="CST-8" />
|
||||
<zone name="Asia/Ho_Chi_Minh" value="ICT-7" />
|
||||
<zone name="Asia/Hong_Kong" value="HKT-8" />
|
||||
<zone name="Asia/Hovd" value="HOVT-7" />
|
||||
<zone name="Asia/Irkutsk" value="IRKT-8IRKST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Asia/Istanbul" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Asia/Jakarta" value="WIT-7" />
|
||||
<zone name="Asia/Jayapura" value="EIT-9" />
|
||||
<zone name="Asia/Jerusalem" value="IDDT" />
|
||||
<zone name="Asia/Kabul" value="AFT-4:30" />
|
||||
<zone name="Asia/Kamchatka" value="PETT-12PETST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Asia/Karachi" value="PKT-5" />
|
||||
<zone name="Asia/Kashgar" value="CST-8" />
|
||||
<zone name="Asia/Katmandu" value="NPT-5:45" />
|
||||
<zone name="Asia/Kolkata" value="IST-5:30" />
|
||||
<zone name="Asia/Krasnoyarsk" value="KRAT-7KRAST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Asia/Kuala_Lumpur" value="MYT-8" />
|
||||
<zone name="Asia/Kuching" value="MYT-8" />
|
||||
<zone name="Asia/Kuwait" value="AST-3" />
|
||||
<zone name="Asia/Macao" value="CST-8" />
|
||||
<zone name="Asia/Macau" value="CST-8" />
|
||||
<zone name="Asia/Magadan" value="MAGT-11MAGST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Asia/Makassar" value="CIT-8" />
|
||||
<zone name="Asia/Manila" value="PHT-8" />
|
||||
<zone name="Asia/Muscat" value="GST-4" />
|
||||
<zone name="Asia/Nicosia" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Asia/Novosibirsk" value="NOVT-6NOVST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Asia/Omsk" value="OMST-6OMSST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Asia/Oral" value="ORAT-5" />
|
||||
<zone name="Asia/Phnom_Penh" value="ICT-7" />
|
||||
<zone name="Asia/Pontianak" value="WIT-7" />
|
||||
<zone name="Asia/Pyongyang" value="KST-9" />
|
||||
<zone name="Asia/Qatar" value="AST-3" />
|
||||
<zone name="Asia/Qyzylorda" value="QYZT-6" />
|
||||
<zone name="Asia/Rangoon" value="MMT-6:30" />
|
||||
<zone name="Asia/Riyadh" value="AST-3" />
|
||||
<zone name="Asia/Riyadh87" value="zzz-3:07:04" />
|
||||
<zone name="Asia/Riyadh88" value="zzz-3:07:04" />
|
||||
<zone name="Asia/Riyadh89" value="zzz-3:07:04" />
|
||||
<zone name="Asia/Saigon" value="ICT-7" />
|
||||
<zone name="Asia/Sakhalin" value="SAKT-10SAKST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Asia/Samarkand" value="UZT-5" />
|
||||
<zone name="Asia/Seoul" value="KST-9" />
|
||||
<zone name="Asia/Shanghai" value="CST-8" />
|
||||
<zone name="Asia/Singapore" value="SGT-8" />
|
||||
<zone name="Asia/Taipei" value="CST-8" />
|
||||
<zone name="Asia/Tashkent" value="UZT-5" />
|
||||
<zone name="Asia/Tbilisi" value="GET-4" />
|
||||
<zone name="Asia/Tehran" value="IRDT" />
|
||||
<zone name="Asia/Tel_Aviv" value="IDDT" />
|
||||
<zone name="Asia/Thimbu" value="BTT-6" />
|
||||
<zone name="Asia/Thimphu" value="BTT-6" />
|
||||
<zone name="Asia/Tokyo" value="JST-9" />
|
||||
<zone name="Asia/Ujung_Pandang" value="CIT-8" />
|
||||
<zone name="Asia/Ulaanbaatar" value="ULAT-8" />
|
||||
<zone name="Asia/Ulan_Bator" value="ULAT-8" />
|
||||
<zone name="Asia/Urumqi" value="CST-8" />
|
||||
<zone name="Asia/Vientiane" value="ICT-7" />
|
||||
<zone name="Asia/Vladivostok" value="VLAT-10VLAST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Asia/Yakutsk" value="YAKT-9YAKST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Asia/Yekaterinburg" value="YEKT-5YEKST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Asia/Yerevan" value="AMT-4AMST,M3.5.0,M10.5.0/3" />
|
||||
|
||||
<zone name="Atlantic/Azores" value="AZOT1AZOST,M3.5.0/0,M10.5.0/1" />
|
||||
<zone name="Atlantic/Bermuda" value="AST4ADT,M3.2.0,M11.1.0" />
|
||||
<zone name="Atlantic/Canary" value="WET0WEST,M3.5.0/1,M10.5.0" />
|
||||
<zone name="Atlantic/Cape_Verde" value="CVT1" />
|
||||
<zone name="Atlantic/Faeroe" value="WET0WEST,M3.5.0/1,M10.5.0" />
|
||||
<zone name="Atlantic/Faroe" value="WET0WEST,M3.5.0/1,M10.5.0" />
|
||||
<zone name="Atlantic/Jan_Mayen" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Atlantic/Madeira" value="WET0WEST,M3.5.0/1,M10.5.0" />
|
||||
<zone name="Atlantic/Reykjavik" value="GMT0" />
|
||||
<zone name="Atlantic/South_Georgia" value="GST2" />
|
||||
<zone name="Atlantic/Stanley" value="FKT4FKST,M9.1.0,M4.3.0" />
|
||||
<zone name="Atlantic/St_Helena" value="GMT0" />
|
||||
|
||||
<zone name="Australia/ACT" value="EST-10EST,M10.1.0,M4.1.0/3" />
|
||||
<zone name="Australia/Adelaide" value="CST-9:30CST,M10.1.0,M4.1.0/3" />
|
||||
<zone name="Australia/Brisbane" value="EST-10" />
|
||||
<zone name="Australia/Broken_Hill" value="CST-9:30CST,M10.1.0,M4.1.0/3" />
|
||||
<zone name="Australia/Canberra" value="EST-10EST,M10.1.0,M4.1.0/3" />
|
||||
<zone name="Australia/Currie" value="EST-10EST,M10.1.0,M4.1.0/3" />
|
||||
<zone name="Australia/Darwin" value="CST-9:30" />
|
||||
<zone name="Australia/Eucla" value="CWST-8:45" />
|
||||
<zone name="Australia/Hobart" value="EST-10EST,M10.1.0,M4.1.0/3" />
|
||||
<zone name="Australia/LHI" value="LHST-10:30LHST-11,M10.1.0,M4.1.0" />
|
||||
<zone name="Australia/Lindeman" value="EST-10" />
|
||||
<zone name="Australia/Lord_Howe" value="LHST-10:30LHST-11,M10.1.0,M4.1.0" />
|
||||
<zone name="Australia/Melbourne" value="EST-10EST,M10.1.0,M4.1.0/3" />
|
||||
<zone name="Australia/North" value="CST-9:30" />
|
||||
<zone name="Australia/NSW" value="EST-10EST,M10.1.0,M4.1.0/3" />
|
||||
<zone name="Australia/Perth" value="WST-8" />
|
||||
<zone name="Australia/Queensland" value="EST-10" />
|
||||
<zone name="Australia/South" value="CST-9:30CST,M10.1.0,M4.1.0/3" />
|
||||
<zone name="Australia/Sydney" value="EST-10EST,M10.1.0,M4.1.0/3" />
|
||||
<zone name="Australia/Tasmania" value="EST-10EST,M10.1.0,M4.1.0/3" />
|
||||
<zone name="Australia/Victoria" value="EST-10EST,M10.1.0,M4.1.0/3" />
|
||||
<zone name="Australia/West" value="WST-8" />
|
||||
<zone name="Australia/Yancowinna" value="CST-9:30CST,M10.1.0,M4.1.0/3" />
|
||||
|
||||
<zone name="Brazil/Acre" value="ACT5" />
|
||||
<zone name="Brazil/DeNoronha" value="FNT2" />
|
||||
<zone name="Brazil/East" value="BRT3BRST,M10.2.0/0,M2.3.0/0" />
|
||||
<zone name="Brazil/West" value="AMT4" />
|
||||
|
||||
<zone name="Canada/Atlantic" value="AST4ADT,M3.2.0,M11.1.0" />
|
||||
<zone name="Canada/Central" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="Canada/Eastern" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="Canada/East-Saskatchewan" value="CST6" />
|
||||
<zone name="Canada/Mountain" value="MST7MDT,M3.2.0,M11.1.0" />
|
||||
<zone name="Canada/Newfoundland" value="NST3:30NDT,M3.2.0/0:01,M11.1.0/0:01" />
|
||||
<zone name="Canada/Pacific" value="PST8PDT,M3.2.0,M11.1.0" />
|
||||
<zone name="Canada/Saskatchewan" value="CST6" />
|
||||
<zone name="Canada/Yukon" value="PST8PDT,M3.2.0,M11.1.0" />
|
||||
|
||||
<zone name="Chile/Continental" value="CLST" />
|
||||
<zone name="Chile/EasterIsland" value="EASST" />
|
||||
|
||||
<zone name="Etc/GMT" value="GMT0" />
|
||||
<zone name="Etc/GMT0" value="GMT0" />
|
||||
<zone name="Etc/GMT-0" value="GMT0" />
|
||||
<zone name="Etc/GMT+0" value="GMT0" />
|
||||
<zone name="Etc/GMT-1" value="GMT-1" />
|
||||
<zone name="Etc/GMT+1" value="GMT+1" />
|
||||
<zone name="Etc/GMT-10" value="GMT-10" />
|
||||
<zone name="Etc/GMT+10" value="GMT+10" />
|
||||
<zone name="Etc/GMT-11" value="GMT-11" />
|
||||
<zone name="Etc/GMT+11" value="GMT+11" />
|
||||
<zone name="Etc/GMT-12" value="GMT-12" />
|
||||
<zone name="Etc/GMT+12" value="GMT+12" />
|
||||
<zone name="Etc/GMT-13" value="GMT-13" />
|
||||
<zone name="Etc/GMT-14" value="GMT-14" />
|
||||
<zone name="Etc/GMT-2" value="GMT-2" />
|
||||
<zone name="Etc/GMT+2" value="GMT+2" />
|
||||
<zone name="Etc/GMT-3" value="GMT-3" />
|
||||
<zone name="Etc/GMT+3" value="GMT+3" />
|
||||
<zone name="Etc/GMT-4" value="GMT-4" />
|
||||
<zone name="Etc/GMT+4" value="GMT+4" />
|
||||
<zone name="Etc/GMT-5" value="GMT-5" />
|
||||
<zone name="Etc/GMT+5" value="GMT+5" />
|
||||
<zone name="Etc/GMT-6" value="GMT-6" />
|
||||
<zone name="Etc/GMT+6" value="GMT+6" />
|
||||
<zone name="Etc/GMT-7" value="GMT-7" />
|
||||
<zone name="Etc/GMT+7" value="GMT+7" />
|
||||
<zone name="Etc/GMT-8" value="GMT-8" />
|
||||
<zone name="Etc/GMT+8" value="GMT+8" />
|
||||
<zone name="Etc/GMT-9" value="GMT-9" />
|
||||
<zone name="Etc/GMT+9" value="GMT+9" />
|
||||
<zone name="Etc/Greenwich" value="GMT0" />
|
||||
<zone name="Etc/UCT" value="UCT0" />
|
||||
<zone name="Etc/Universal" value="UTC0" />
|
||||
<zone name="Etc/UTC" value="UTC0" />
|
||||
<zone name="Etc/Zulu" value="UTC0" />
|
||||
|
||||
<zone name="Europe/Amsterdam" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Andorra" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Athens" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Belfast" value="GMT0BST,M3.5.0/1,M10.5.0" />
|
||||
<zone name="Europe/Belgrade" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Berlin" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Bratislava" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Brussels" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Bucharest" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Budapest" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Chisinau" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Copenhagen" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Dublin" value="GMT0IST,M3.5.0/1,M10.5.0" />
|
||||
<zone name="Europe/Gibraltar" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Guernsey" value="GMT0BST,M3.5.0/1,M10.5.0" />
|
||||
<zone name="Europe/Helsinki" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Isle_of_Man" value="GMT0BST,M3.5.0/1,M10.5.0" />
|
||||
<zone name="Europe/Istanbul" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Jersey" value="GMT0BST,M3.5.0/1,M10.5.0" />
|
||||
<zone name="Europe/Kaliningrad" value="EET-2EEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Kiev" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Lisbon" value="WET0WEST,M3.5.0/1,M10.5.0" />
|
||||
<zone name="Europe/Ljubljana" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/London" value="GMT0BST,M3.5.0/1,M10.5.0" />
|
||||
<zone name="Europe/Luxembourg" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Madrid" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Malta" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Mariehamn" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Minsk" value="EET-2EEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Monaco" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Moscow" value="MSK-3MSD,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Nicosia" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Oslo" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Paris" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Podgorica" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Prague" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Riga" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Rome" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Samara" value="SAMT-4SAMST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/San_Marino" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Sarajevo" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Simferopol" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Skopje" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Sofia" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Stockholm" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Tallinn" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Tirane" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Tiraspol" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Uzhgorod" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Vaduz" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Vatican" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Vienna" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Vilnius" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Volgograd" value="VOLT-3VOLST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Warsaw" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Zagreb" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
<zone name="Europe/Zaporozhye" value="EET-2EEST,M3.5.0/3,M10.5.0/4" />
|
||||
<zone name="Europe/Zurich" value="CET-1CEST,M3.5.0,M10.5.0/3" />
|
||||
|
||||
<zone name="Indian/Antananarivo" value="EAT-3" />
|
||||
<zone name="Indian/Chagos" value="IOT-6" />
|
||||
<zone name="Indian/Christmas" value="CXT-7" />
|
||||
<zone name="Indian/Cocos" value="CCT-6:30" />
|
||||
<zone name="Indian/Comoro" value="EAT-3" />
|
||||
<zone name="Indian/Kerguelen" value="TFT-5" />
|
||||
<zone name="Indian/Mahe" value="SCT-4" />
|
||||
<zone name="Indian/Maldives" value="MVT-5" />
|
||||
<zone name="Indian/Mauritius" value="MUT-4" />
|
||||
<zone name="Indian/Mayotte" value="EAT-3" />
|
||||
<zone name="Indian/Reunion" value="RET-4" />
|
||||
|
||||
<zone name="Mexico/BajaNorte" value="PST8PDT,M4.1.0,M10.5.0" />
|
||||
<zone name="Mexico/BajaSur" value="MST7MDT,M4.1.0,M10.5.0" />
|
||||
<zone name="Mexico/General" value="CST6CDT,M4.1.0,M10.5.0" />
|
||||
|
||||
<zone name="Mideast/Riyadh87" value="zzz-3:07:04" />
|
||||
<zone name="Mideast/Riyadh88" value="zzz-3:07:04" />
|
||||
<zone name="Mideast/Riyadh89" value="zzz-3:07:04" />
|
||||
|
||||
<zone name="Pacific/Apia" value="WST11" />
|
||||
<zone name="Pacific/Auckland" value="NZST-12NZDT,M9.5.0,M4.1.0/3" />
|
||||
<zone name="Pacific/Chatham" value="CHAST-12:45CHADT,M9.5.0/2:45,M4.1.0/3:45" />
|
||||
<zone name="Pacific/Easter" value="EASST" />
|
||||
<zone name="Pacific/Efate" value="VUT-11" />
|
||||
<zone name="Pacific/Enderbury" value="PHOT-13" />
|
||||
<zone name="Pacific/Fakaofo" value="TKT10" />
|
||||
<zone name="Pacific/Fiji" value="FJT-12" />
|
||||
<zone name="Pacific/Funafuti" value="TVT-12" />
|
||||
<zone name="Pacific/Galapagos" value="GALT6" />
|
||||
<zone name="Pacific/Gambier" value="GAMT9" />
|
||||
<zone name="Pacific/Guadalcanal" value="SBT-11" />
|
||||
<zone name="Pacific/Guam" value="ChST-10" />
|
||||
<zone name="Pacific/Honolulu" value="HST10" />
|
||||
<zone name="Pacific/Johnston" value="HST10" />
|
||||
<zone name="Pacific/Kiritimati" value="LINT-14" />
|
||||
<zone name="Pacific/Kosrae" value="KOST-11" />
|
||||
<zone name="Pacific/Kwajalein" value="MHT-12" />
|
||||
<zone name="Pacific/Majuro" value="MHT-12" />
|
||||
<zone name="Pacific/Marquesas" value="MART9:30" />
|
||||
<zone name="Pacific/Midway" value="SST11" />
|
||||
<zone name="Pacific/Nauru" value="NRT-12" />
|
||||
<zone name="Pacific/Niue" value="NUT11" />
|
||||
<zone name="Pacific/Norfolk" value="NFT-11:30" />
|
||||
<zone name="Pacific/Noumea" value="NCT-11" />
|
||||
<zone name="Pacific/Pago_Pago" value="SST11" />
|
||||
<zone name="Pacific/Palau" value="PWT-9" />
|
||||
<zone name="Pacific/Pitcairn" value="PST8" />
|
||||
<zone name="Pacific/Ponape" value="PONT-11" />
|
||||
<zone name="Pacific/Port_Moresby" value="PGT-10" />
|
||||
<zone name="Pacific/Rarotonga" value="CKT10" />
|
||||
<zone name="Pacific/Saipan" value="ChST-10" />
|
||||
<zone name="Pacific/Samoa" value="SST11" />
|
||||
<zone name="Pacific/Tahiti" value="TAHT10" />
|
||||
<zone name="Pacific/Tarawa" value="GILT-12" />
|
||||
<zone name="Pacific/Tongatapu" value="TOT-13" />
|
||||
<zone name="Pacific/Truk" value="TRUT-10" />
|
||||
<zone name="Pacific/Wake" value="WAKT-12" />
|
||||
<zone name="Pacific/Wallis" value="WFT-12" />
|
||||
<zone name="Pacific/Yap" value="TRUT-10" />
|
||||
|
||||
<zone name="SystemV/AST4" value="AST4" />
|
||||
<zone name="SystemV/AST4ADT" value="AST4ADT,M3.2.0,M11.1.0" />
|
||||
<zone name="SystemV/CST6" value="CST6" />
|
||||
<zone name="SystemV/CST6CDT" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="SystemV/EST5" value="EST5" />
|
||||
<zone name="SystemV/EST5EDT" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="SystemV/HST10" value="HST10" />
|
||||
<zone name="SystemV/MST7" value="MST7" />
|
||||
<zone name="SystemV/MST7MDT" value="MST7MDT,M3.2.0,M11.1.0" />
|
||||
<zone name="SystemV/PST8" value="PST8" />
|
||||
<zone name="SystemV/PST8PDT" value="PST8PDT,M3.2.0,M11.1.0" />
|
||||
<zone name="SystemV/YST9" value="GAMT9" />
|
||||
<zone name="SystemV/YST9YDT" value="AKST9AKDT,M3.2.0,M11.1.0" />
|
||||
|
||||
<zone name="US/Alaska" value="AKST9AKDT,M3.2.0,M11.1.0" />
|
||||
<zone name="US/Aleutian" value="HAST10HADT,M3.2.0,M11.1.0" />
|
||||
<zone name="US/Arizona" value="MST7" />
|
||||
<zone name="US/Central" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="US/Eastern" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="US/East-Indiana" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="US/Hawaii" value="HST10" />
|
||||
<zone name="US/Indiana-Starke" value="CST6CDT,M3.2.0,M11.1.0" />
|
||||
<zone name="US/Michigan" value="EST5EDT,M3.2.0,M11.1.0" />
|
||||
<zone name="US/Mountain" value="MST7MDT,M3.2.0,M11.1.0" />
|
||||
<zone name="US/Pacific" value="PST8PDT,M3.2.0,M11.1.0" />
|
||||
<zone name="US/Samoa" value="SST11" />
|
||||
</timezones>
|
||||
</configuration>
|
|
@ -0,0 +1,4 @@
|
|||
BASE=../../../..
|
||||
LOCAL_SOURCES=localtime_find.c
|
||||
LOCAL_OBJS=localtime_find.o
|
||||
include $(BASE)/build/modmake.rules
|
|
@ -0,0 +1,968 @@
|
|||
/*
|
||||
* This file was originally written for NetBSD and is in the public domain,
|
||||
* so clarified as of 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov).
|
||||
*
|
||||
* Iw was modified by Massimo Cetra in order to be used with Callweaver and Freeswitch.
|
||||
*/
|
||||
|
||||
//#define TESTING_IT 1
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#ifdef TESTING_IT
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif /* !defined TRUE */
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif /* !defined FALSE */
|
||||
|
||||
|
||||
|
||||
#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
|
||||
|
||||
#ifndef NOSOLAR
|
||||
#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
|
||||
#endif /* !defined NOSOLAR */
|
||||
|
||||
#ifdef NOSOLAR
|
||||
/*
|
||||
** Must be at least 14 for Europe/Riga as of Jan 12 1995,
|
||||
** as noted by Earl Chew <earl@hpato.aus.hp.com>.
|
||||
*/
|
||||
#define TZ_MAX_TYPES 20 /* Maximum number of local time types */
|
||||
#endif /* !defined NOSOLAR */
|
||||
|
||||
#endif /* !defined TZ_MAX_TYPES */
|
||||
|
||||
#ifndef TZ_MAX_CHARS
|
||||
#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */
|
||||
/* (limited by what unsigned chars can hold) */
|
||||
#endif /* !defined TZ_MAX_CHARS */
|
||||
|
||||
#ifndef TZ_MAX_LEAPS
|
||||
#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */
|
||||
#endif /* !defined TZ_MAX_LEAPS */
|
||||
|
||||
#ifdef TZNAME_MAX
|
||||
#define MY_TZNAME_MAX TZNAME_MAX
|
||||
#endif /* defined TZNAME_MAX */
|
||||
|
||||
#ifndef TZNAME_MAX
|
||||
#define MY_TZNAME_MAX 255
|
||||
#endif /* !defined TZNAME_MAX */
|
||||
|
||||
|
||||
#define SECSPERMIN 60
|
||||
#define MINSPERHOUR 60
|
||||
#define HOURSPERDAY 24
|
||||
#define DAYSPERWEEK 7
|
||||
#define DAYSPERNYEAR 365
|
||||
#define DAYSPERLYEAR 366
|
||||
#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR)
|
||||
#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY)
|
||||
#define MONSPERYEAR 12
|
||||
|
||||
#define JULIAN_DAY 0 /* Jn - Julian day */
|
||||
#define DAY_OF_YEAR 1 /* n - day of year */
|
||||
#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */
|
||||
|
||||
#define EPOCH_YEAR 1970
|
||||
#define EPOCH_WDAY TM_THURSDAY
|
||||
|
||||
|
||||
#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 TZDEFRULES
|
||||
#define TZDEFRULES "posixrules"
|
||||
#endif /* !defined TZDEFRULES */
|
||||
|
||||
/*
|
||||
** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
|
||||
** We default to US rules as of 1999-08-17.
|
||||
** POSIX 1003.1 section 8.1.1 says that the default DST rules are
|
||||
** implementation dependent; for historical reasons, US rules are a
|
||||
** common default.
|
||||
*/
|
||||
#ifndef TZDEFRULESTRING
|
||||
#define TZDEFRULESTRING ",M4.1.0,M10.5.0"
|
||||
#endif /* !defined TZDEFDST */
|
||||
|
||||
/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */
|
||||
#define is_digit(c) ((unsigned)(c) - '0' <= 9)
|
||||
|
||||
#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** INITIALIZE(x)
|
||||
*/
|
||||
|
||||
#ifndef GNUC_or_lint
|
||||
#ifdef lint
|
||||
#define GNUC_or_lint
|
||||
#endif /* defined lint */
|
||||
#ifndef lint
|
||||
#ifdef __GNUC__
|
||||
#define GNUC_or_lint
|
||||
#endif /* defined __GNUC__ */
|
||||
#endif /* !defined lint */
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
|
||||
#ifndef INITIALIZE
|
||||
#ifdef GNUC_or_lint
|
||||
#define INITIALIZE(x) ((x) = 0)
|
||||
#endif /* defined GNUC_or_lint */
|
||||
#ifndef GNUC_or_lint
|
||||
#define INITIALIZE(x)
|
||||
#endif /* !defined GNUC_or_lint */
|
||||
#endif /* !defined INITIALIZE */
|
||||
|
||||
|
||||
#define TM_SUNDAY 0
|
||||
#define TM_MONDAY 1
|
||||
#define TM_TUESDAY 2
|
||||
#define TM_WEDNESDAY 3
|
||||
#define TM_THURSDAY 4
|
||||
#define TM_FRIDAY 5
|
||||
#define TM_SATURDAY 6
|
||||
|
||||
#define TM_JANUARY 0
|
||||
#define TM_FEBRUARY 1
|
||||
#define TM_MARCH 2
|
||||
#define TM_APRIL 3
|
||||
#define TM_MAY 4
|
||||
#define TM_JUNE 5
|
||||
#define TM_JULY 6
|
||||
#define TM_AUGUST 7
|
||||
#define TM_SEPTEMBER 8
|
||||
#define TM_OCTOBER 9
|
||||
#define TM_NOVEMBER 10
|
||||
#define TM_DECEMBER 11
|
||||
|
||||
#define TM_YEAR_BASE 1900
|
||||
|
||||
#define EPOCH_YEAR 1970
|
||||
#define EPOCH_WDAY TM_THURSDAY
|
||||
|
||||
|
||||
/* **************************************************************************
|
||||
|
||||
************************************************************************** */
|
||||
|
||||
static const char gmt[] = "GMT";
|
||||
|
||||
#define CHARS_DEF BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), (2 * (MY_TZNAME_MAX + 1)))
|
||||
|
||||
struct rule {
|
||||
int r_type; /* type of rule--see below */
|
||||
int r_day; /* day number of rule */
|
||||
int r_week; /* week number of rule */
|
||||
int r_mon; /* month number of rule */
|
||||
long r_time; /* transition time of rule */
|
||||
};
|
||||
|
||||
struct ttinfo { /* time type information */
|
||||
long tt_gmtoff; /* UTC offset in seconds */
|
||||
int tt_isdst; /* used to set tm_isdst */
|
||||
int tt_abbrind; /* abbreviation list index */
|
||||
int tt_ttisstd; /* TRUE if transition is std time */
|
||||
int tt_ttisgmt; /* TRUE if transition is UTC */
|
||||
};
|
||||
|
||||
struct lsinfo { /* leap second information */
|
||||
time_t ls_trans; /* transition time */
|
||||
long ls_corr; /* correction to apply */
|
||||
};
|
||||
|
||||
|
||||
struct state {
|
||||
int leapcnt;
|
||||
int timecnt;
|
||||
int typecnt;
|
||||
int charcnt;
|
||||
time_t ats[TZ_MAX_TIMES];
|
||||
unsigned char types[TZ_MAX_TIMES];
|
||||
struct ttinfo ttis[TZ_MAX_TYPES];
|
||||
char chars[/* LINTED constant */CHARS_DEF];
|
||||
struct lsinfo lsis[TZ_MAX_LEAPS];
|
||||
};
|
||||
|
||||
|
||||
static const int mon_lengths[2][MONSPERYEAR] = {
|
||||
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
||||
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
||||
};
|
||||
|
||||
static const int year_lengths[2] = {
|
||||
DAYSPERNYEAR, DAYSPERLYEAR
|
||||
};
|
||||
|
||||
|
||||
/* **************************************************************************
|
||||
|
||||
************************************************************************** */
|
||||
|
||||
|
||||
/*
|
||||
Given a pointer into a time zone string, scan until a character that is not
|
||||
a valid character in a zone name is found. Return a pointer to that
|
||||
character.
|
||||
*/
|
||||
|
||||
static const char *getzname(strp)
|
||||
register const char * strp;
|
||||
{
|
||||
register char c;
|
||||
|
||||
while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
|
||||
c != '+')
|
||||
++strp;
|
||||
return strp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Given a pointer into a time zone string, extract a number from that string.
|
||||
Check that the number is within a specified range; if it is not, return
|
||||
NULL.
|
||||
Otherwise, return a pointer to the first character not part of the number.
|
||||
*/
|
||||
|
||||
static const char *getnum(strp, nump, min, max)
|
||||
register const char * strp;
|
||||
int * const nump;
|
||||
const int min;
|
||||
const int max;
|
||||
{
|
||||
register char c;
|
||||
register int num;
|
||||
|
||||
if (strp == NULL || !is_digit(c = *strp))
|
||||
return NULL;
|
||||
num = 0;
|
||||
do {
|
||||
num = num * 10 + (c - '0');
|
||||
if (num > max)
|
||||
return NULL; /* illegal value */
|
||||
c = *++strp;
|
||||
} while (is_digit(c));
|
||||
if (num < min)
|
||||
return NULL; /* illegal value */
|
||||
*nump = num;
|
||||
return strp;
|
||||
}
|
||||
|
||||
/*
|
||||
Given a pointer into a time zone string, extract a number of seconds,
|
||||
in hh[:mm[:ss]] form, from the string.
|
||||
If any error occurs, return NULL.
|
||||
Otherwise, return a pointer to the first character not part of the number
|
||||
of seconds.
|
||||
*/
|
||||
|
||||
static const char *getsecs(strp, secsp)
|
||||
register const char * strp;
|
||||
long * const secsp;
|
||||
{
|
||||
int num;
|
||||
|
||||
/*
|
||||
** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
|
||||
** "M10.4.6/26", which does not conform to Posix,
|
||||
** but which specifies the equivalent of
|
||||
** ``02:00 on the first Sunday on or after 23 Oct''.
|
||||
*/
|
||||
strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1);
|
||||
if (strp == NULL)
|
||||
return NULL;
|
||||
*secsp = num * (long) SECSPERHOUR;
|
||||
if (*strp == ':') {
|
||||
++strp;
|
||||
strp = getnum(strp, &num, 0, MINSPERHOUR - 1);
|
||||
if (strp == NULL)
|
||||
return NULL;
|
||||
*secsp += num * SECSPERMIN;
|
||||
if (*strp == ':') {
|
||||
++strp;
|
||||
/* `SECSPERMIN' allows for leap seconds. */
|
||||
strp = getnum(strp, &num, 0, SECSPERMIN);
|
||||
if (strp == NULL)
|
||||
return NULL;
|
||||
*secsp += num;
|
||||
}
|
||||
}
|
||||
return strp;
|
||||
}
|
||||
|
||||
/*
|
||||
Given a pointer into a time zone string, extract an offset, in
|
||||
[+-]hh[:mm[:ss]] form, from the string.
|
||||
If any error occurs, return NULL.
|
||||
Otherwise, return a pointer to the first character not part of the time.
|
||||
*/
|
||||
|
||||
static const char *getoffset(strp, offsetp)
|
||||
register const char * strp;
|
||||
long * const offsetp;
|
||||
{
|
||||
register int neg = 0;
|
||||
|
||||
if (*strp == '-') {
|
||||
neg = 1;
|
||||
++strp;
|
||||
} else if (*strp == '+')
|
||||
++strp;
|
||||
strp = getsecs(strp, offsetp);
|
||||
if (strp == NULL)
|
||||
return NULL; /* illegal time */
|
||||
if (neg)
|
||||
*offsetp = -*offsetp;
|
||||
return strp;
|
||||
}
|
||||
|
||||
/*
|
||||
Given a pointer into a time zone string, extract a rule in the form
|
||||
date[/time]. See POSIX section 8 for the format of "date" and "time".
|
||||
If a valid rule is not found, return NULL.
|
||||
Otherwise, return a pointer to the first character not part of the rule.
|
||||
*/
|
||||
|
||||
static const char *getrule(strp, rulep)
|
||||
const char * strp;
|
||||
register struct rule * const rulep;
|
||||
{
|
||||
if (*strp == 'J') {
|
||||
/*
|
||||
** Julian day.
|
||||
*/
|
||||
rulep->r_type = JULIAN_DAY;
|
||||
++strp;
|
||||
strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR);
|
||||
} else if (*strp == 'M') {
|
||||
/*
|
||||
** Month, week, day.
|
||||
*/
|
||||
rulep->r_type = MONTH_NTH_DAY_OF_WEEK;
|
||||
++strp;
|
||||
strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR);
|
||||
if (strp == NULL)
|
||||
return NULL;
|
||||
if (*strp++ != '.')
|
||||
return NULL;
|
||||
strp = getnum(strp, &rulep->r_week, 1, 5);
|
||||
if (strp == NULL)
|
||||
return NULL;
|
||||
if (*strp++ != '.')
|
||||
return NULL;
|
||||
strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1);
|
||||
} else if (is_digit(*strp)) {
|
||||
/*
|
||||
** Day of year.
|
||||
*/
|
||||
rulep->r_type = DAY_OF_YEAR;
|
||||
strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1);
|
||||
} else return NULL; /* invalid format */
|
||||
if (strp == NULL)
|
||||
return NULL;
|
||||
if (*strp == '/') {
|
||||
/*
|
||||
** Time specified.
|
||||
*/
|
||||
++strp;
|
||||
strp = getsecs(strp, &rulep->r_time);
|
||||
} else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */
|
||||
return strp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the
|
||||
year, a rule, and the offset from UTC at the time that rule takes effect,
|
||||
calculate the Epoch-relative time that rule takes effect.
|
||||
*/
|
||||
|
||||
static time_t transtime(janfirst, year, rulep, offset)
|
||||
const time_t janfirst;
|
||||
const int year;
|
||||
register const struct rule * const rulep;
|
||||
const long offset;
|
||||
{
|
||||
register int leapyear;
|
||||
register time_t value;
|
||||
register int i;
|
||||
int d, m1, yy0, yy1, yy2, dow;
|
||||
|
||||
INITIALIZE(value);
|
||||
leapyear = isleap(year);
|
||||
switch (rulep->r_type) {
|
||||
|
||||
case JULIAN_DAY:
|
||||
/*
|
||||
** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
|
||||
** years.
|
||||
** In non-leap years, or if the day number is 59 or less, just
|
||||
** add SECSPERDAY times the day number-1 to the time of
|
||||
** January 1, midnight, to get the day.
|
||||
*/
|
||||
value = janfirst + (rulep->r_day - 1) * SECSPERDAY;
|
||||
if (leapyear && rulep->r_day >= 60)
|
||||
value += SECSPERDAY;
|
||||
break;
|
||||
|
||||
case DAY_OF_YEAR:
|
||||
/*
|
||||
** n - day of year.
|
||||
** Just add SECSPERDAY times the day number to the time of
|
||||
** January 1, midnight, to get the day.
|
||||
*/
|
||||
value = janfirst + rulep->r_day * SECSPERDAY;
|
||||
break;
|
||||
|
||||
case MONTH_NTH_DAY_OF_WEEK:
|
||||
/*
|
||||
** Mm.n.d - nth "dth day" of month m.
|
||||
*/
|
||||
value = janfirst;
|
||||
for (i = 0; i < rulep->r_mon - 1; ++i)
|
||||
value += mon_lengths[leapyear][i] * SECSPERDAY;
|
||||
|
||||
/*
|
||||
** Use Zeller's Congruence to get day-of-week of first day of
|
||||
** month.
|
||||
*/
|
||||
m1 = (rulep->r_mon + 9) % 12 + 1;
|
||||
yy0 = (rulep->r_mon <= 2) ? (year - 1) : year;
|
||||
yy1 = yy0 / 100;
|
||||
yy2 = yy0 % 100;
|
||||
dow = ((26 * m1 - 2) / 10 +
|
||||
1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7;
|
||||
if (dow < 0)
|
||||
dow += DAYSPERWEEK;
|
||||
|
||||
/*
|
||||
** "dow" is the day-of-week of the first day of the month. Get
|
||||
** the day-of-month (zero-origin) of the first "dow" day of the
|
||||
** month.
|
||||
*/
|
||||
d = rulep->r_day - dow;
|
||||
if (d < 0)
|
||||
d += DAYSPERWEEK;
|
||||
for (i = 1; i < rulep->r_week; ++i) {
|
||||
if (d + DAYSPERWEEK >=
|
||||
mon_lengths[leapyear][rulep->r_mon - 1])
|
||||
break;
|
||||
d += DAYSPERWEEK;
|
||||
}
|
||||
|
||||
/*
|
||||
** "d" is the day-of-month (zero-origin) of the day we want.
|
||||
*/
|
||||
value += d * SECSPERDAY;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
** "value" is the Epoch-relative time of 00:00:00 UTC on the day in
|
||||
** question. To get the Epoch-relative time of the specified local
|
||||
** time on that day, add the transition time and the current offset
|
||||
** from UTC.
|
||||
*/
|
||||
return value + rulep->r_time + offset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Given a POSIX section 8-style TZ string, fill in the rule tables as
|
||||
appropriate.
|
||||
*/
|
||||
|
||||
static int tzparse(name, sp, lastditch)
|
||||
const char * name;
|
||||
register struct state * const sp;
|
||||
const int lastditch;
|
||||
{
|
||||
const char * stdname;
|
||||
const char * dstname;
|
||||
size_t stdlen;
|
||||
size_t dstlen;
|
||||
long stdoffset;
|
||||
long dstoffset;
|
||||
register time_t * atp;
|
||||
register unsigned char * typep;
|
||||
register char * cp;
|
||||
|
||||
|
||||
INITIALIZE(dstname);
|
||||
stdname = name;
|
||||
|
||||
if (lastditch) {
|
||||
stdlen = strlen(name); /* length of standard zone name */
|
||||
name += stdlen;
|
||||
if (stdlen >= sizeof sp->chars)
|
||||
stdlen = (sizeof sp->chars) - 1;
|
||||
stdoffset = 0;
|
||||
} else {
|
||||
name = getzname(name);
|
||||
stdlen = name - stdname;
|
||||
if (stdlen < 3)
|
||||
return -1;
|
||||
if (*name == '\0')
|
||||
return -1;
|
||||
name = getoffset(name, &stdoffset);
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
sp->leapcnt = 0; /* so, we're off a little */
|
||||
|
||||
if (*name != '\0') {
|
||||
dstname = name;
|
||||
name = getzname(name);
|
||||
dstlen = name - dstname; /* length of DST zone name */
|
||||
if (dstlen < 3)
|
||||
return -1;
|
||||
if (*name != '\0' && *name != ',' && *name != ';')
|
||||
{
|
||||
name = getoffset(name, &dstoffset);
|
||||
if (name == NULL)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
dstoffset = stdoffset - SECSPERHOUR;
|
||||
|
||||
/* Go parsing the daylight saving stuff */
|
||||
if (*name == ',' || *name == ';')
|
||||
{
|
||||
struct rule start;
|
||||
struct rule end;
|
||||
register int year;
|
||||
register time_t janfirst;
|
||||
time_t starttime;
|
||||
time_t endtime;
|
||||
|
||||
++name;
|
||||
if ((name = getrule(name, &start)) == NULL)
|
||||
return -1;
|
||||
if (*name++ != ',')
|
||||
return -1;
|
||||
if ((name = getrule(name, &end)) == NULL)
|
||||
return -1;
|
||||
if (*name != '\0')
|
||||
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;
|
||||
sp->ttis[1].tt_gmtoff = -stdoffset;
|
||||
sp->ttis[1].tt_isdst = 0;
|
||||
sp->ttis[1].tt_abbrind = 0;
|
||||
|
||||
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,
|
||||
dstoffset);
|
||||
if (starttime > endtime) {
|
||||
*atp++ = endtime;
|
||||
*typep++ = 1; /* DST ends */
|
||||
*atp++ = starttime;
|
||||
*typep++ = 0; /* DST begins */
|
||||
} else {
|
||||
*atp++ = starttime;
|
||||
*typep++ = 0; /* DST begins */
|
||||
*atp++ = endtime;
|
||||
*typep++ = 1; /* DST ends */
|
||||
}
|
||||
|
||||
janfirst += year_lengths[isleap(year)] * SECSPERDAY;
|
||||
}
|
||||
|
||||
} else {
|
||||
register long theirstdoffset;
|
||||
register long theirdstoffset;
|
||||
register long theiroffset;
|
||||
register int isdst;
|
||||
register int i;
|
||||
register int j;
|
||||
|
||||
if (*name != '\0')
|
||||
return -1;
|
||||
/*
|
||||
Initial values of theirstdoffset and theirdstoffset.
|
||||
*/
|
||||
theirstdoffset = 0;
|
||||
for (i = 0; i < sp->timecnt; ++i) {
|
||||
j = sp->types[i];
|
||||
if (!sp->ttis[j].tt_isdst) {
|
||||
theirstdoffset =
|
||||
-sp->ttis[j].tt_gmtoff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
theirdstoffset = 0;
|
||||
for (i = 0; i < sp->timecnt; ++i) {
|
||||
j = sp->types[i];
|
||||
if (sp->ttis[j].tt_isdst) {
|
||||
theirdstoffset =
|
||||
-sp->ttis[j].tt_gmtoff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
** Initially we're assumed to be in standard time.
|
||||
*/
|
||||
isdst = FALSE;
|
||||
theiroffset = theirstdoffset;
|
||||
/*
|
||||
** Now juggle transition times and types
|
||||
** tracking offsets as you do.
|
||||
*/
|
||||
for (i = 0; i < sp->timecnt; ++i) {
|
||||
j = sp->types[i];
|
||||
sp->types[i] = sp->ttis[j].tt_isdst;
|
||||
if (sp->ttis[j].tt_ttisgmt) {
|
||||
/* No adjustment to transition time */
|
||||
} else {
|
||||
/*
|
||||
** If summer time is in effect, and the
|
||||
** transition time was not specified as
|
||||
** standard time, add the summer time
|
||||
** offset to the transition time;
|
||||
** otherwise, add the standard time
|
||||
** offset to the transition time.
|
||||
*/
|
||||
/*
|
||||
** Transitions from DST to DDST
|
||||
** will effectively disappear since
|
||||
** POSIX provides for only one DST
|
||||
** offset.
|
||||
*/
|
||||
if (isdst && !sp->ttis[j].tt_ttisstd) {
|
||||
sp->ats[i] += dstoffset -
|
||||
theirdstoffset;
|
||||
} else {
|
||||
sp->ats[i] += stdoffset -
|
||||
theirstdoffset;
|
||||
}
|
||||
}
|
||||
theiroffset = -sp->ttis[j].tt_gmtoff;
|
||||
if (sp->ttis[j].tt_isdst)
|
||||
theirdstoffset = theiroffset;
|
||||
else theirstdoffset = theiroffset;
|
||||
}
|
||||
/*
|
||||
** Finally, fill in ttis.
|
||||
** ttisstd and ttisgmt need not be handled.
|
||||
*/
|
||||
sp->ttis[0].tt_gmtoff = -stdoffset;
|
||||
sp->ttis[0].tt_isdst = FALSE;
|
||||
sp->ttis[0].tt_abbrind = 0;
|
||||
sp->ttis[1].tt_gmtoff = -dstoffset;
|
||||
sp->ttis[1].tt_isdst = TRUE;
|
||||
sp->ttis[1].tt_abbrind = stdlen + 1;
|
||||
sp->typecnt = 2;
|
||||
}
|
||||
} else {
|
||||
dstlen = 0;
|
||||
sp->typecnt = 1; /* only standard time */
|
||||
sp->timecnt = 0;
|
||||
sp->ttis[0].tt_gmtoff = -stdoffset;
|
||||
sp->ttis[0].tt_isdst = 0;
|
||||
sp->ttis[0].tt_abbrind = 0;
|
||||
}
|
||||
|
||||
sp->charcnt = stdlen + 1;
|
||||
if (dstlen != 0)
|
||||
sp->charcnt += dstlen + 1;
|
||||
if ((size_t) sp->charcnt > sizeof sp->chars)
|
||||
return -1;
|
||||
cp = sp->chars;
|
||||
(void) strncpy(cp, stdname, stdlen);
|
||||
cp += stdlen;
|
||||
*cp++ = '\0';
|
||||
if (dstlen != 0) {
|
||||
(void) strncpy(cp, dstname, dstlen);
|
||||
*(cp + dstlen) = '\0';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* **************************************************************************
|
||||
|
||||
************************************************************************** */
|
||||
|
||||
static void timesub(timep, offset, sp, tmp)
|
||||
const time_t * const timep;
|
||||
const long offset;
|
||||
register const struct state * const sp;
|
||||
register struct tm * const tmp;
|
||||
{
|
||||
register const struct lsinfo * lp;
|
||||
register long days;
|
||||
register long rem;
|
||||
register int y;
|
||||
register int yleap;
|
||||
register const int * ip;
|
||||
register long corr;
|
||||
register int hit;
|
||||
register int i;
|
||||
|
||||
assert(timep != NULL);
|
||||
assert(sp != NULL);
|
||||
assert(tmp != NULL);
|
||||
|
||||
corr = 0;
|
||||
hit = 0;
|
||||
i = (sp == NULL) ? 0 : sp->leapcnt;
|
||||
|
||||
while (--i >= 0) {
|
||||
lp = &sp->lsis[i];
|
||||
if (*timep >= lp->ls_trans) {
|
||||
if (*timep == lp->ls_trans) {
|
||||
hit = ((i == 0 && lp->ls_corr > 0) ||
|
||||
lp->ls_corr > sp->lsis[i - 1].ls_corr);
|
||||
if (hit)
|
||||
while (i > 0 &&
|
||||
sp->lsis[i].ls_trans ==
|
||||
sp->lsis[i - 1].ls_trans + 1 &&
|
||||
sp->lsis[i].ls_corr ==
|
||||
sp->lsis[i - 1].ls_corr + 1) {
|
||||
++hit;
|
||||
--i;
|
||||
}
|
||||
}
|
||||
corr = lp->ls_corr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
days = *timep / SECSPERDAY;
|
||||
rem = *timep % SECSPERDAY;
|
||||
|
||||
|
||||
#ifdef mc68k
|
||||
/* If this is for CPU bugs workarounds, i would remove this anyway. Who would use it on an old mc68k ? */
|
||||
if (*timep == 0x80000000) {
|
||||
/*
|
||||
** A 3B1 muffs the division on the most negative number.
|
||||
*/
|
||||
days = -24855;
|
||||
rem = -11648;
|
||||
}
|
||||
#endif
|
||||
|
||||
rem += (offset - corr);
|
||||
while (rem < 0) {
|
||||
rem += SECSPERDAY;
|
||||
--days;
|
||||
}
|
||||
while (rem >= SECSPERDAY) {
|
||||
rem -= SECSPERDAY;
|
||||
++days;
|
||||
}
|
||||
tmp->tm_hour = (int) (rem / SECSPERHOUR);
|
||||
rem = rem % SECSPERHOUR;
|
||||
tmp->tm_min = (int) (rem / SECSPERMIN);
|
||||
|
||||
/*
|
||||
** A positive leap second requires a special
|
||||
** representation. This uses "... ??:59:60" et seq.
|
||||
*/
|
||||
tmp->tm_sec = (int) (rem % SECSPERMIN) + hit;
|
||||
tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK);
|
||||
|
||||
if (tmp->tm_wday < 0)
|
||||
tmp->tm_wday += DAYSPERWEEK;
|
||||
|
||||
y = EPOCH_YEAR;
|
||||
|
||||
#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
|
||||
|
||||
while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) {
|
||||
register int newy;
|
||||
|
||||
newy = (int)(y + days / DAYSPERNYEAR);
|
||||
if (days < 0)
|
||||
--newy;
|
||||
days -= (newy - y) * DAYSPERNYEAR +
|
||||
LEAPS_THRU_END_OF(newy - 1) -
|
||||
LEAPS_THRU_END_OF(y - 1);
|
||||
y = newy;
|
||||
}
|
||||
|
||||
tmp->tm_year = y - TM_YEAR_BASE;
|
||||
tmp->tm_yday = (int) days;
|
||||
|
||||
ip = mon_lengths[yleap];
|
||||
|
||||
for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon))
|
||||
days = days - (long) ip[tmp->tm_mon];
|
||||
|
||||
tmp->tm_mday = (int) (days + 1);
|
||||
tmp->tm_isdst = 0;
|
||||
tmp->tm_gmtoff = offset;
|
||||
}
|
||||
|
||||
/* **************************************************************************
|
||||
|
||||
************************************************************************** */
|
||||
|
||||
void tztime( timep, tzstring, tmp )
|
||||
const time_t * const timep;
|
||||
const char *tzstring;
|
||||
struct tm * const tmp;
|
||||
{
|
||||
struct state *tzptr,
|
||||
*sp;
|
||||
const time_t t = *timep;
|
||||
register int i;
|
||||
register const struct ttinfo *ttisp;
|
||||
|
||||
if ( tzstring == NULL )
|
||||
tzstring = gmt;
|
||||
|
||||
tzptr = (struct state *) malloc(sizeof (struct state));
|
||||
sp = tzptr;
|
||||
|
||||
if (tzptr != NULL)
|
||||
{
|
||||
|
||||
memset(tzptr, 0, sizeof(struct state));
|
||||
|
||||
(void) tzparse(tzstring, tzptr, FALSE);
|
||||
|
||||
if (sp->timecnt == 0 || t < sp->ats[0])
|
||||
{
|
||||
i = 0;
|
||||
while (sp->ttis[i].tt_isdst)
|
||||
if (++i >= sp->typecnt) {
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
for (i = 1; i < sp->timecnt; ++i)
|
||||
if (t < sp->ats[i])
|
||||
break;
|
||||
i = sp->types[i - 1]; // DST begin or DST end
|
||||
}
|
||||
ttisp = &sp->ttis[i];
|
||||
|
||||
/*
|
||||
To get (wrong) behavior that's compatible with System V Release 2.0
|
||||
you'd replace the statement below with
|
||||
t += ttisp->tt_gmtoff;
|
||||
timesub(&t, 0L, sp, tmp);
|
||||
*/
|
||||
if ( tmp != NULL ) /* Just a check not to assert */
|
||||
{
|
||||
timesub( &t, ttisp->tt_gmtoff, sp, tmp);
|
||||
tmp->tm_isdst = ttisp->tt_isdst;
|
||||
tmp->tm_zone = &sp->chars[ttisp->tt_abbrind];
|
||||
}
|
||||
|
||||
free(tzptr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* **************************************************************************
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
The following part is used for testing-
|
||||
Not even usually compiled.
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
************************************************************************** */
|
||||
|
||||
#ifdef TESTING_IT
|
||||
|
||||
#define TESTSTRING_1 "CET-1CEST,M3.5.0,M10.5.0/3" // Rome
|
||||
#define TESTSTRING_2 "MST7" // Arizona
|
||||
#define TESTSTRING_3 "EST5EDT,M3.2.0,M11.1.0" // Toronto
|
||||
#define TESTSTRING_4 "NZST-12NZDT,M9.5.0,M4.1.0/3" // Auckland
|
||||
#define TESTSTRING_5 "GMT" // GMT
|
||||
#define TESTSTRING_6 ""
|
||||
|
||||
|
||||
void tztest( const char *tzstring, time_t *timep)
|
||||
{
|
||||
struct tm tm;
|
||||
memset( &tm, 0, sizeof(struct tm));
|
||||
|
||||
printf("\n\n >>>>>>>>>>> Testing this: %s <<<<<<<<<<<< \n\n", tzstring);
|
||||
|
||||
tztime( timep, tzstring , &tm);
|
||||
|
||||
printf("RESULT: \n");
|
||||
printf(" tm->tm_isdst %d \n", tm.tm_isdst);
|
||||
printf(" tm->tm_zone %s \n", tm.tm_zone);
|
||||
printf(" tm->(day) %02d/%02d/%d \n", tm.tm_mday, tm.tm_mon, tm.tm_year + 1900 );
|
||||
printf(" tm->(hour) %02d:%02d:%02d \n", tm.tm_hour, tm.tm_min, tm.tm_sec );
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
time_t timep;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
timep = tv.tv_sec;
|
||||
|
||||
tztest( TESTSTRING_1, &timep);
|
||||
tztest( TESTSTRING_2, &timep);
|
||||
tztest( TESTSTRING_3, &timep);
|
||||
tztest( TESTSTRING_4, &timep);
|
||||
tztest( TESTSTRING_5, &timep);
|
||||
tztest( TESTSTRING_6, &timep);
|
||||
tztest( NULL, &timep);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH mod_timezone.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Massimo Cetra <devel@navynet.it>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* mod_timezone.c -- Access to timezone informations and time string formatting
|
||||
*
|
||||
*/
|
||||
|
||||
#include <switch.h>
|
||||
#include "mod_timezone.h"
|
||||
|
||||
/*
|
||||
This converts a struct tm to a switch_time_exp_t
|
||||
We have to use UNIX structures to do our exams
|
||||
and use switch_* functions for the output.
|
||||
*/
|
||||
|
||||
static void tm2switchtime( tm, xt )
|
||||
struct tm *tm;
|
||||
switch_time_exp_t *xt;
|
||||
{
|
||||
|
||||
if (!xt || !tm) {
|
||||
return;
|
||||
}
|
||||
memset( xt, 0, sizeof(xt) );
|
||||
|
||||
xt->tm_sec = tm->tm_sec;
|
||||
xt->tm_min = tm->tm_min;
|
||||
xt->tm_hour = tm->tm_hour;
|
||||
xt->tm_mday = tm->tm_mday;
|
||||
xt->tm_mon = tm->tm_mon;
|
||||
xt->tm_year = tm->tm_year;
|
||||
xt->tm_wday = tm->tm_wday;
|
||||
xt->tm_yday = tm->tm_yday;
|
||||
xt->tm_isdst = tm->tm_isdst;
|
||||
xt->tm_gmtoff = tm->tm_gmtoff;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* **************************************************************************
|
||||
LOADING OF THE XML DATA - HASH TABLE & MEMORY POOL MANAGEMENT
|
||||
************************************************************************** */
|
||||
|
||||
typedef struct {
|
||||
switch_memory_pool_t *pool;
|
||||
switch_hash_t *hash;
|
||||
} switch_timezones_list_t;
|
||||
|
||||
static switch_timezones_list_t TIMEZONES_LIST = { 0 };
|
||||
static switch_event_node_t *NODE = NULL;
|
||||
|
||||
const char *switch_lookup_timezone( const char *tzname )
|
||||
{
|
||||
char *value = NULL;
|
||||
|
||||
if ( tzname && (value = switch_core_hash_find(TIMEZONES_LIST.hash, tzname))==NULL ) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Timezone '%s' not found!\n", tzname);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void switch_load_timezones(switch_bool_t reload)
|
||||
{
|
||||
switch_xml_t xml = NULL, x_lists = NULL, x_list = NULL, cfg = NULL;
|
||||
unsigned total = 0;
|
||||
|
||||
if (TIMEZONES_LIST.hash) {
|
||||
switch_core_hash_destroy(&TIMEZONES_LIST.hash);
|
||||
}
|
||||
|
||||
if (TIMEZONES_LIST.pool) {
|
||||
switch_core_destroy_memory_pool(&TIMEZONES_LIST.pool);
|
||||
}
|
||||
|
||||
memset(&TIMEZONES_LIST, 0, sizeof(TIMEZONES_LIST));
|
||||
switch_core_new_memory_pool(&TIMEZONES_LIST.pool);
|
||||
switch_core_hash_init(&TIMEZONES_LIST.hash, TIMEZONES_LIST.pool);
|
||||
|
||||
if ((xml = switch_xml_open_cfg("timezones.conf", &cfg, NULL))) {
|
||||
if ((x_lists = switch_xml_child(cfg, "timezones"))) {
|
||||
for (x_list = switch_xml_child(x_lists, "zone"); x_list; x_list = x_list->next) {
|
||||
const char *name = switch_xml_attr(x_list, "name");
|
||||
const char *value= switch_xml_attr(x_list, "value");
|
||||
|
||||
if (switch_strlen_zero(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (switch_strlen_zero(value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch_core_hash_insert(TIMEZONES_LIST.hash,
|
||||
name,
|
||||
switch_core_strdup(TIMEZONES_LIST.pool, value) );
|
||||
total++;
|
||||
}
|
||||
}
|
||||
|
||||
switch_xml_free(xml);
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Timezone %sloaded %d definitions\n", reload ? "re" : "", total);
|
||||
}
|
||||
|
||||
/* **************************************************************************
|
||||
API FUNCTIONS AND COMMANDS
|
||||
************************************************************************** */
|
||||
|
||||
SWITCH_STANDARD_API(strftime_tz_api_function)
|
||||
{
|
||||
switch_time_t thetime;
|
||||
time_t timep;
|
||||
|
||||
char *format = NULL;
|
||||
const char *tzname;
|
||||
const char *tzdef;
|
||||
|
||||
switch_size_t retsize;
|
||||
char date[80] = "";
|
||||
|
||||
struct tm tm;
|
||||
switch_time_exp_t stm;
|
||||
|
||||
thetime = switch_timestamp_now();
|
||||
|
||||
timep = (thetime) / (int64_t) (1000000);
|
||||
|
||||
if (!switch_strlen_zero(cmd)) {
|
||||
format = strchr(cmd, ' ');
|
||||
tzname = cmd;
|
||||
if (format) {
|
||||
*format++ = '\0';
|
||||
}
|
||||
|
||||
tzdef = switch_lookup_timezone( tzname );
|
||||
} else {
|
||||
/* We set the default timezone to GMT. */
|
||||
tzname="GMT";
|
||||
tzdef="GMT";
|
||||
}
|
||||
|
||||
if (tzdef) { /* The lookup of the zone may fail. */
|
||||
tztime( &timep, tzdef, &tm );
|
||||
tm2switchtime( &tm, &stm );
|
||||
switch_strftime(date, &retsize, sizeof(date), switch_strlen_zero(format) ? "%Y-%m-%d %T" : format, &stm);
|
||||
stream->write_function(stream, "%s", date);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR Invalid Timezone\n");
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* **************************************************************************
|
||||
|
||||
************************************************************************** */
|
||||
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_timezone_load);
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_timezone_shutdown);
|
||||
SWITCH_MODULE_DEFINITION(mod_timezone, mod_timezone_load, mod_timezone_shutdown, NULL);
|
||||
|
||||
static void event_handler(switch_event_t *event)
|
||||
{
|
||||
switch_load_timezones(1);
|
||||
}
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_timezone_load)
|
||||
{
|
||||
switch_api_interface_t *api_interface;
|
||||
|
||||
if ((switch_event_bind_removable(modname, SWITCH_EVENT_RELOADXML, NULL, event_handler, NULL, &NODE) != SWITCH_STATUS_SUCCESS)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
||||
}
|
||||
switch_load_timezones(0);
|
||||
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
|
||||
SWITCH_ADD_API(api_interface, "strftime_tz", "strftime_tz", strftime_tz_api_function, "<Timezone name>,<format string>");
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Called when the system shuts down
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_timezone_shutdown)
|
||||
{
|
||||
|
||||
if (TIMEZONES_LIST.hash) {
|
||||
switch_core_hash_destroy(&TIMEZONES_LIST.hash);
|
||||
}
|
||||
|
||||
if (TIMEZONES_LIST.pool) {
|
||||
switch_core_destroy_memory_pool(&TIMEZONES_LIST.pool);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_UNLOAD;
|
||||
}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||
*/
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
|
||||
*
|
||||
* Version: MPL 1.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is FreeSWITCH mod_timezone.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Massimo Cetra <devel@navynet.it>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* mod_timezone.c -- Access to timezone informations and time string formatting
|
||||
*
|
||||
*/
|
||||
|
||||
void tztime (
|
||||
const time_t * const timep,
|
||||
const char *tzstring,
|
||||
struct tm * const tmp
|
||||
);
|
Loading…
Reference in New Issue