tzinfo 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of tzinfo might be problematic. Click here for more details.
- data/README +87 -0
- data/lib/tzinfo.rb +25 -0
- data/lib/tzinfo/countries/AD.rb +18 -0
- data/lib/tzinfo/countries/AE.rb +18 -0
- data/lib/tzinfo/countries/AF.rb +18 -0
- data/lib/tzinfo/countries/AG.rb +18 -0
- data/lib/tzinfo/countries/AI.rb +18 -0
- data/lib/tzinfo/countries/AL.rb +18 -0
- data/lib/tzinfo/countries/AM.rb +18 -0
- data/lib/tzinfo/countries/AN.rb +18 -0
- data/lib/tzinfo/countries/AO.rb +18 -0
- data/lib/tzinfo/countries/AQ.rb +27 -0
- data/lib/tzinfo/countries/AR.rb +27 -0
- data/lib/tzinfo/countries/AS.rb +18 -0
- data/lib/tzinfo/countries/AT.rb +18 -0
- data/lib/tzinfo/countries/AU.rb +28 -0
- data/lib/tzinfo/countries/AW.rb +18 -0
- data/lib/tzinfo/countries/AX.rb +18 -0
- data/lib/tzinfo/countries/AZ.rb +18 -0
- data/lib/tzinfo/countries/BA.rb +18 -0
- data/lib/tzinfo/countries/BB.rb +18 -0
- data/lib/tzinfo/countries/BD.rb +18 -0
- data/lib/tzinfo/countries/BE.rb +18 -0
- data/lib/tzinfo/countries/BF.rb +18 -0
- data/lib/tzinfo/countries/BG.rb +18 -0
- data/lib/tzinfo/countries/BH.rb +18 -0
- data/lib/tzinfo/countries/BI.rb +18 -0
- data/lib/tzinfo/countries/BJ.rb +18 -0
- data/lib/tzinfo/countries/BM.rb +18 -0
- data/lib/tzinfo/countries/BN.rb +18 -0
- data/lib/tzinfo/countries/BO.rb +18 -0
- data/lib/tzinfo/countries/BR.rb +32 -0
- data/lib/tzinfo/countries/BS.rb +18 -0
- data/lib/tzinfo/countries/BT.rb +18 -0
- data/lib/tzinfo/countries/BV.rb +17 -0
- data/lib/tzinfo/countries/BW.rb +18 -0
- data/lib/tzinfo/countries/BY.rb +18 -0
- data/lib/tzinfo/countries/BZ.rb +18 -0
- data/lib/tzinfo/countries/CA.rb +41 -0
- data/lib/tzinfo/countries/CC.rb +18 -0
- data/lib/tzinfo/countries/CD.rb +19 -0
- data/lib/tzinfo/countries/CF.rb +18 -0
- data/lib/tzinfo/countries/CG.rb +18 -0
- data/lib/tzinfo/countries/CH.rb +18 -0
- data/lib/tzinfo/countries/CI.rb +18 -0
- data/lib/tzinfo/countries/CK.rb +18 -0
- data/lib/tzinfo/countries/CL.rb +19 -0
- data/lib/tzinfo/countries/CM.rb +18 -0
- data/lib/tzinfo/countries/CN.rb +22 -0
- data/lib/tzinfo/countries/CO.rb +18 -0
- data/lib/tzinfo/countries/CR.rb +18 -0
- data/lib/tzinfo/countries/CS.rb +18 -0
- data/lib/tzinfo/countries/CU.rb +18 -0
- data/lib/tzinfo/countries/CV.rb +18 -0
- data/lib/tzinfo/countries/CX.rb +18 -0
- data/lib/tzinfo/countries/CY.rb +18 -0
- data/lib/tzinfo/countries/CZ.rb +18 -0
- data/lib/tzinfo/countries/DE.rb +18 -0
- data/lib/tzinfo/countries/DJ.rb +18 -0
- data/lib/tzinfo/countries/DK.rb +18 -0
- data/lib/tzinfo/countries/DM.rb +18 -0
- data/lib/tzinfo/countries/DO.rb +18 -0
- data/lib/tzinfo/countries/DZ.rb +18 -0
- data/lib/tzinfo/countries/EC.rb +19 -0
- data/lib/tzinfo/countries/EE.rb +18 -0
- data/lib/tzinfo/countries/EG.rb +18 -0
- data/lib/tzinfo/countries/EH.rb +18 -0
- data/lib/tzinfo/countries/ER.rb +18 -0
- data/lib/tzinfo/countries/ES.rb +20 -0
- data/lib/tzinfo/countries/ET.rb +18 -0
- data/lib/tzinfo/countries/FI.rb +18 -0
- data/lib/tzinfo/countries/FJ.rb +18 -0
- data/lib/tzinfo/countries/FK.rb +18 -0
- data/lib/tzinfo/countries/FM.rb +20 -0
- data/lib/tzinfo/countries/FO.rb +18 -0
- data/lib/tzinfo/countries/FR.rb +18 -0
- data/lib/tzinfo/countries/GA.rb +18 -0
- data/lib/tzinfo/countries/GB.rb +18 -0
- data/lib/tzinfo/countries/GD.rb +18 -0
- data/lib/tzinfo/countries/GE.rb +18 -0
- data/lib/tzinfo/countries/GF.rb +18 -0
- data/lib/tzinfo/countries/GH.rb +18 -0
- data/lib/tzinfo/countries/GI.rb +18 -0
- data/lib/tzinfo/countries/GL.rb +21 -0
- data/lib/tzinfo/countries/GM.rb +18 -0
- data/lib/tzinfo/countries/GN.rb +18 -0
- data/lib/tzinfo/countries/GP.rb +18 -0
- data/lib/tzinfo/countries/GQ.rb +18 -0
- data/lib/tzinfo/countries/GR.rb +18 -0
- data/lib/tzinfo/countries/GS.rb +18 -0
- data/lib/tzinfo/countries/GT.rb +18 -0
- data/lib/tzinfo/countries/GU.rb +18 -0
- data/lib/tzinfo/countries/GW.rb +18 -0
- data/lib/tzinfo/countries/GY.rb +18 -0
- data/lib/tzinfo/countries/HK.rb +18 -0
- data/lib/tzinfo/countries/HM.rb +17 -0
- data/lib/tzinfo/countries/HN.rb +18 -0
- data/lib/tzinfo/countries/HR.rb +18 -0
- data/lib/tzinfo/countries/HT.rb +18 -0
- data/lib/tzinfo/countries/HU.rb +18 -0
- data/lib/tzinfo/countries/ID.rb +21 -0
- data/lib/tzinfo/countries/IE.rb +18 -0
- data/lib/tzinfo/countries/IL.rb +18 -0
- data/lib/tzinfo/countries/IN.rb +18 -0
- data/lib/tzinfo/countries/IO.rb +18 -0
- data/lib/tzinfo/countries/IQ.rb +18 -0
- data/lib/tzinfo/countries/IR.rb +18 -0
- data/lib/tzinfo/countries/IS.rb +18 -0
- data/lib/tzinfo/countries/IT.rb +18 -0
- data/lib/tzinfo/countries/Index.rb +253 -0
- data/lib/tzinfo/countries/JM.rb +18 -0
- data/lib/tzinfo/countries/JO.rb +18 -0
- data/lib/tzinfo/countries/JP.rb +18 -0
- data/lib/tzinfo/countries/KE.rb +18 -0
- data/lib/tzinfo/countries/KG.rb +18 -0
- data/lib/tzinfo/countries/KH.rb +18 -0
- data/lib/tzinfo/countries/KI.rb +20 -0
- data/lib/tzinfo/countries/KM.rb +18 -0
- data/lib/tzinfo/countries/KN.rb +18 -0
- data/lib/tzinfo/countries/KP.rb +18 -0
- data/lib/tzinfo/countries/KR.rb +18 -0
- data/lib/tzinfo/countries/KW.rb +18 -0
- data/lib/tzinfo/countries/KY.rb +18 -0
- data/lib/tzinfo/countries/KZ.rb +22 -0
- data/lib/tzinfo/countries/LA.rb +18 -0
- data/lib/tzinfo/countries/LB.rb +18 -0
- data/lib/tzinfo/countries/LC.rb +18 -0
- data/lib/tzinfo/countries/LI.rb +18 -0
- data/lib/tzinfo/countries/LK.rb +18 -0
- data/lib/tzinfo/countries/LR.rb +18 -0
- data/lib/tzinfo/countries/LS.rb +18 -0
- data/lib/tzinfo/countries/LT.rb +18 -0
- data/lib/tzinfo/countries/LU.rb +18 -0
- data/lib/tzinfo/countries/LV.rb +18 -0
- data/lib/tzinfo/countries/LY.rb +18 -0
- data/lib/tzinfo/countries/MA.rb +18 -0
- data/lib/tzinfo/countries/MC.rb +18 -0
- data/lib/tzinfo/countries/MD.rb +18 -0
- data/lib/tzinfo/countries/MG.rb +18 -0
- data/lib/tzinfo/countries/MH.rb +19 -0
- data/lib/tzinfo/countries/MK.rb +18 -0
- data/lib/tzinfo/countries/ML.rb +18 -0
- data/lib/tzinfo/countries/MM.rb +18 -0
- data/lib/tzinfo/countries/MN.rb +20 -0
- data/lib/tzinfo/countries/MO.rb +18 -0
- data/lib/tzinfo/countries/MP.rb +18 -0
- data/lib/tzinfo/countries/MQ.rb +18 -0
- data/lib/tzinfo/countries/MR.rb +18 -0
- data/lib/tzinfo/countries/MS.rb +18 -0
- data/lib/tzinfo/countries/MT.rb +18 -0
- data/lib/tzinfo/countries/MU.rb +18 -0
- data/lib/tzinfo/countries/MV.rb +18 -0
- data/lib/tzinfo/countries/MW.rb +18 -0
- data/lib/tzinfo/countries/MX.rb +25 -0
- data/lib/tzinfo/countries/MY.rb +19 -0
- data/lib/tzinfo/countries/MZ.rb +18 -0
- data/lib/tzinfo/countries/NA.rb +18 -0
- data/lib/tzinfo/countries/NC.rb +18 -0
- data/lib/tzinfo/countries/NE.rb +18 -0
- data/lib/tzinfo/countries/NF.rb +18 -0
- data/lib/tzinfo/countries/NG.rb +18 -0
- data/lib/tzinfo/countries/NI.rb +18 -0
- data/lib/tzinfo/countries/NL.rb +18 -0
- data/lib/tzinfo/countries/NO.rb +18 -0
- data/lib/tzinfo/countries/NP.rb +18 -0
- data/lib/tzinfo/countries/NR.rb +18 -0
- data/lib/tzinfo/countries/NU.rb +18 -0
- data/lib/tzinfo/countries/NZ.rb +19 -0
- data/lib/tzinfo/countries/OM.rb +18 -0
- data/lib/tzinfo/countries/PA.rb +18 -0
- data/lib/tzinfo/countries/PE.rb +18 -0
- data/lib/tzinfo/countries/PF.rb +20 -0
- data/lib/tzinfo/countries/PG.rb +18 -0
- data/lib/tzinfo/countries/PH.rb +18 -0
- data/lib/tzinfo/countries/PK.rb +18 -0
- data/lib/tzinfo/countries/PL.rb +18 -0
- data/lib/tzinfo/countries/PM.rb +18 -0
- data/lib/tzinfo/countries/PN.rb +18 -0
- data/lib/tzinfo/countries/PR.rb +18 -0
- data/lib/tzinfo/countries/PS.rb +18 -0
- data/lib/tzinfo/countries/PT.rb +20 -0
- data/lib/tzinfo/countries/PW.rb +18 -0
- data/lib/tzinfo/countries/PY.rb +18 -0
- data/lib/tzinfo/countries/QA.rb +18 -0
- data/lib/tzinfo/countries/RE.rb +18 -0
- data/lib/tzinfo/countries/RO.rb +18 -0
- data/lib/tzinfo/countries/RU.rb +31 -0
- data/lib/tzinfo/countries/RW.rb +18 -0
- data/lib/tzinfo/countries/SA.rb +18 -0
- data/lib/tzinfo/countries/SB.rb +18 -0
- data/lib/tzinfo/countries/SC.rb +18 -0
- data/lib/tzinfo/countries/SD.rb +18 -0
- data/lib/tzinfo/countries/SE.rb +18 -0
- data/lib/tzinfo/countries/SG.rb +18 -0
- data/lib/tzinfo/countries/SH.rb +18 -0
- data/lib/tzinfo/countries/SI.rb +18 -0
- data/lib/tzinfo/countries/SJ.rb +19 -0
- data/lib/tzinfo/countries/SK.rb +18 -0
- data/lib/tzinfo/countries/SL.rb +18 -0
- data/lib/tzinfo/countries/SM.rb +18 -0
- data/lib/tzinfo/countries/SN.rb +18 -0
- data/lib/tzinfo/countries/SO.rb +18 -0
- data/lib/tzinfo/countries/SR.rb +18 -0
- data/lib/tzinfo/countries/ST.rb +18 -0
- data/lib/tzinfo/countries/SV.rb +18 -0
- data/lib/tzinfo/countries/SY.rb +18 -0
- data/lib/tzinfo/countries/SZ.rb +18 -0
- data/lib/tzinfo/countries/TC.rb +18 -0
- data/lib/tzinfo/countries/TD.rb +18 -0
- data/lib/tzinfo/countries/TF.rb +18 -0
- data/lib/tzinfo/countries/TG.rb +18 -0
- data/lib/tzinfo/countries/TH.rb +18 -0
- data/lib/tzinfo/countries/TJ.rb +18 -0
- data/lib/tzinfo/countries/TK.rb +18 -0
- data/lib/tzinfo/countries/TL.rb +18 -0
- data/lib/tzinfo/countries/TM.rb +18 -0
- data/lib/tzinfo/countries/TN.rb +18 -0
- data/lib/tzinfo/countries/TO.rb +18 -0
- data/lib/tzinfo/countries/TR.rb +18 -0
- data/lib/tzinfo/countries/TT.rb +18 -0
- data/lib/tzinfo/countries/TV.rb +18 -0
- data/lib/tzinfo/countries/TW.rb +18 -0
- data/lib/tzinfo/countries/TZ.rb +18 -0
- data/lib/tzinfo/countries/UA.rb +21 -0
- data/lib/tzinfo/countries/UG.rb +18 -0
- data/lib/tzinfo/countries/UM.rb +20 -0
- data/lib/tzinfo/countries/US.rb +39 -0
- data/lib/tzinfo/countries/UY.rb +18 -0
- data/lib/tzinfo/countries/UZ.rb +19 -0
- data/lib/tzinfo/countries/VA.rb +18 -0
- data/lib/tzinfo/countries/VC.rb +18 -0
- data/lib/tzinfo/countries/VE.rb +18 -0
- data/lib/tzinfo/countries/VG.rb +18 -0
- data/lib/tzinfo/countries/VI.rb +18 -0
- data/lib/tzinfo/countries/VN.rb +18 -0
- data/lib/tzinfo/countries/VU.rb +18 -0
- data/lib/tzinfo/countries/WF.rb +18 -0
- data/lib/tzinfo/countries/WS.rb +18 -0
- data/lib/tzinfo/countries/YE.rb +18 -0
- data/lib/tzinfo/countries/YT.rb +18 -0
- data/lib/tzinfo/countries/ZA.rb +18 -0
- data/lib/tzinfo/countries/ZM.rb +18 -0
- data/lib/tzinfo/countries/ZW.rb +18 -0
- data/lib/tzinfo/country.rb +82 -0
- data/lib/tzinfo/definitions/Africa/Abidjan.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Accra.rb +33 -0
- data/lib/tzinfo/definitions/Africa/Addis_Ababa.rb +20 -0
- data/lib/tzinfo/definitions/Africa/Algiers.rb +52 -0
- data/lib/tzinfo/definitions/Africa/Asmera.rb +21 -0
- data/lib/tzinfo/definitions/Africa/Bamako.rb +21 -0
- data/lib/tzinfo/definitions/Africa/Bangui.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Banjul.rb +21 -0
- data/lib/tzinfo/definitions/Africa/Bissau.rb +20 -0
- data/lib/tzinfo/definitions/Africa/Blantyre.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Brazzaville.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Bujumbura.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Cairo.rb +208 -0
- data/lib/tzinfo/definitions/Africa/Casablanca.rb +37 -0
- data/lib/tzinfo/definitions/Africa/Ceuta.rb +162 -0
- data/lib/tzinfo/definitions/Africa/Conakry.rb +21 -0
- data/lib/tzinfo/definitions/Africa/Dakar.rb +20 -0
- data/lib/tzinfo/definitions/Africa/Dar_es_Salaam.rb +21 -0
- data/lib/tzinfo/definitions/Africa/Djibouti.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Douala.rb +19 -0
- data/lib/tzinfo/definitions/Africa/El_Aaiun.rb +20 -0
- data/lib/tzinfo/definitions/Africa/Freetown.rb +49 -0
- data/lib/tzinfo/definitions/Africa/Gaborone.rb +21 -0
- data/lib/tzinfo/definitions/Africa/Harare.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Johannesburg.rb +24 -0
- data/lib/tzinfo/definitions/Africa/Kampala.rb +22 -0
- data/lib/tzinfo/definitions/Africa/Khartoum.rb +52 -0
- data/lib/tzinfo/definitions/Africa/Kigali.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Kinshasa.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Lagos.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Libreville.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Lome.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Luanda.rb +20 -0
- data/lib/tzinfo/definitions/Africa/Lubumbashi.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Lusaka.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Malabo.rb +20 -0
- data/lib/tzinfo/definitions/Africa/Maputo.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Maseru.rb +21 -0
- data/lib/tzinfo/definitions/Africa/Mbabane.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Mogadishu.rb +21 -0
- data/lib/tzinfo/definitions/Africa/Monrovia.rb +21 -0
- data/lib/tzinfo/definitions/Africa/Nairobi.rb +22 -0
- data/lib/tzinfo/definitions/Africa/Ndjamena.rb +21 -0
- data/lib/tzinfo/definitions/Africa/Niamey.rb +21 -0
- data/lib/tzinfo/definitions/Africa/Nouakchott.rb +21 -0
- data/lib/tzinfo/definitions/Africa/Ouagadougou.rb +19 -0
- data/lib/tzinfo/definitions/Africa/Porto__m__Novo.rb +20 -0
- data/lib/tzinfo/definitions/Africa/Sao_Tome.rb +20 -0
- data/lib/tzinfo/definitions/Africa/Timbuktu.rb +14 -0
- data/lib/tzinfo/definitions/Africa/Tripoli.rb +47 -0
- data/lib/tzinfo/definitions/Africa/Tunis.rb +46 -0
- data/lib/tzinfo/definitions/Africa/Windhoek.rb +126 -0
- data/lib/tzinfo/definitions/America/Adak.rb +180 -0
- data/lib/tzinfo/definitions/America/Anchorage.rb +180 -0
- data/lib/tzinfo/definitions/America/Anguilla.rb +19 -0
- data/lib/tzinfo/definitions/America/Antigua.rb +20 -0
- data/lib/tzinfo/definitions/America/Araguaina.rb +70 -0
- data/lib/tzinfo/definitions/America/Argentina/Buenos_Aires.rb +77 -0
- data/lib/tzinfo/definitions/America/Argentina/Catamarca.rb +79 -0
- data/lib/tzinfo/definitions/America/Argentina/ComodRivadavia.rb +16 -0
- data/lib/tzinfo/definitions/America/Argentina/Cordoba.rb +77 -0
- data/lib/tzinfo/definitions/America/Argentina/Jujuy.rb +78 -0
- data/lib/tzinfo/definitions/America/Argentina/La_Rioja.rb +80 -0
- data/lib/tzinfo/definitions/America/Argentina/Mendoza.rb +79 -0
- data/lib/tzinfo/definitions/America/Argentina/Rio_Gallegos.rb +79 -0
- data/lib/tzinfo/definitions/America/Argentina/San_Juan.rb +80 -0
- data/lib/tzinfo/definitions/America/Argentina/Tucuman.rb +79 -0
- data/lib/tzinfo/definitions/America/Argentina/Ushuaia.rb +79 -0
- data/lib/tzinfo/definitions/America/Aruba.rb +20 -0
- data/lib/tzinfo/definitions/America/Asuncion.rb +162 -0
- data/lib/tzinfo/definitions/America/Atka.rb +14 -0
- data/lib/tzinfo/definitions/America/Bahia.rb +78 -0
- data/lib/tzinfo/definitions/America/Barbados.rb +28 -0
- data/lib/tzinfo/definitions/America/Belem.rb +48 -0
- data/lib/tzinfo/definitions/America/Belize.rb +73 -0
- data/lib/tzinfo/definitions/America/Boa_Vista.rb +53 -0
- data/lib/tzinfo/definitions/America/Bogota.rb +22 -0
- data/lib/tzinfo/definitions/America/Boise.rb +183 -0
- data/lib/tzinfo/definitions/America/Buenos_Aires.rb +14 -0
- data/lib/tzinfo/definitions/America/Cambridge_Bay.rb +159 -0
- data/lib/tzinfo/definitions/America/Campo_Grande.rb +161 -0
- data/lib/tzinfo/definitions/America/Cancun.rb +120 -0
- data/lib/tzinfo/definitions/America/Caracas.rb +21 -0
- data/lib/tzinfo/definitions/America/Catamarca.rb +14 -0
- data/lib/tzinfo/definitions/America/Cayenne.rb +20 -0
- data/lib/tzinfo/definitions/America/Cayman.rb +20 -0
- data/lib/tzinfo/definitions/America/Chicago.rb +272 -0
- data/lib/tzinfo/definitions/America/Chihuahua.rb +125 -0
- data/lib/tzinfo/definitions/America/Coral_Harbour.rb +26 -0
- data/lib/tzinfo/definitions/America/Cordoba.rb +14 -0
- data/lib/tzinfo/definitions/America/Costa_Rica.rb +28 -0
- data/lib/tzinfo/definitions/America/Cuiaba.rb +161 -0
- data/lib/tzinfo/definitions/America/Curacao.rb +20 -0
- data/lib/tzinfo/definitions/America/Danmarkshavn.rb +52 -0
- data/lib/tzinfo/definitions/America/Dawson.rb +159 -0
- data/lib/tzinfo/definitions/America/Dawson_Creek.rb +76 -0
- data/lib/tzinfo/definitions/America/Denver.rb +194 -0
- data/lib/tzinfo/definitions/America/Detroit.rb +174 -0
- data/lib/tzinfo/definitions/America/Dominica.rb +19 -0
- data/lib/tzinfo/definitions/America/Edmonton.rb +186 -0
- data/lib/tzinfo/definitions/America/Eirunepe.rb +52 -0
- data/lib/tzinfo/definitions/America/El_Salvador.rb +23 -0
- data/lib/tzinfo/definitions/America/Ensenada.rb +14 -0
- data/lib/tzinfo/definitions/America/Fort_Wayne.rb +14 -0
- data/lib/tzinfo/definitions/America/Fortaleza.rb +61 -0
- data/lib/tzinfo/definitions/America/Glace_Bay.rb +176 -0
- data/lib/tzinfo/definitions/America/Godthab.rb +150 -0
- data/lib/tzinfo/definitions/America/Goose_Bay.rb +241 -0
- data/lib/tzinfo/definitions/America/Grand_Turk.rb +153 -0
- data/lib/tzinfo/definitions/America/Grenada.rb +19 -0
- data/lib/tzinfo/definitions/America/Guadeloupe.rb +19 -0
- data/lib/tzinfo/definitions/America/Guatemala.rb +25 -0
- data/lib/tzinfo/definitions/America/Guayaquil.rb +20 -0
- data/lib/tzinfo/definitions/America/Guyana.rb +22 -0
- data/lib/tzinfo/definitions/America/Halifax.rb +264 -0
- data/lib/tzinfo/definitions/America/Havana.rb +191 -0
- data/lib/tzinfo/definitions/America/Hermosillo.rb +34 -0
- data/lib/tzinfo/definitions/America/Indiana/Indianapolis.rb +139 -0
- data/lib/tzinfo/definitions/America/Indiana/Knox.rb +190 -0
- data/lib/tzinfo/definitions/America/Indiana/Marengo.rb +141 -0
- data/lib/tzinfo/definitions/America/Indiana/Vevay.rb +118 -0
- data/lib/tzinfo/definitions/America/Indianapolis.rb +14 -0
- data/lib/tzinfo/definitions/America/Inuvik.rb +159 -0
- data/lib/tzinfo/definitions/America/Iqaluit.rb +158 -0
- data/lib/tzinfo/definitions/America/Jamaica.rb +40 -0
- data/lib/tzinfo/definitions/America/Jujuy.rb +14 -0
- data/lib/tzinfo/definitions/America/Juneau.rb +179 -0
- data/lib/tzinfo/definitions/America/Kentucky/Louisville.rb +216 -0
- data/lib/tzinfo/definitions/America/Kentucky/Monticello.rb +184 -0
- data/lib/tzinfo/definitions/America/Knox_IN.rb +14 -0
- data/lib/tzinfo/definitions/America/La_Paz.rb +21 -0
- data/lib/tzinfo/definitions/America/Lima.rb +34 -0
- data/lib/tzinfo/definitions/America/Los_Angeles.rb +220 -0
- data/lib/tzinfo/definitions/America/Louisville.rb +14 -0
- data/lib/tzinfo/definitions/America/Maceio.rb +65 -0
- data/lib/tzinfo/definitions/America/Managua.rb +32 -0
- data/lib/tzinfo/definitions/America/Manaus.rb +52 -0
- data/lib/tzinfo/definitions/America/Martinique.rb +22 -0
- data/lib/tzinfo/definitions/America/Mazatlan.rb +126 -0
- data/lib/tzinfo/definitions/America/Mendoza.rb +14 -0
- data/lib/tzinfo/definitions/America/Menominee.rb +176 -0
- data/lib/tzinfo/definitions/America/Merida.rb +120 -0
- data/lib/tzinfo/definitions/America/Mexico_City.rb +132 -0
- data/lib/tzinfo/definitions/America/Miquelon.rb +138 -0
- data/lib/tzinfo/definitions/America/Monterrey.rb +122 -0
- data/lib/tzinfo/definitions/America/Montevideo.rb +84 -0
- data/lib/tzinfo/definitions/America/Montreal.rb +269 -0
- data/lib/tzinfo/definitions/America/Montserrat.rb +19 -0
- data/lib/tzinfo/definitions/America/Nassau.rb +182 -0
- data/lib/tzinfo/definitions/America/New_York.rb +272 -0
- data/lib/tzinfo/definitions/America/Nipigon.rb +167 -0
- data/lib/tzinfo/definitions/America/Nome.rb +180 -0
- data/lib/tzinfo/definitions/America/Noronha.rb +61 -0
- data/lib/tzinfo/definitions/America/North_Dakota/Center.rb +184 -0
- data/lib/tzinfo/definitions/America/Panama.rb +20 -0
- data/lib/tzinfo/definitions/America/Pangnirtung.rb +158 -0
- data/lib/tzinfo/definitions/America/Paramaribo.rb +23 -0
- data/lib/tzinfo/definitions/America/Phoenix.rb +31 -0
- data/lib/tzinfo/definitions/America/Port__m__au__m__Prince.rb +52 -0
- data/lib/tzinfo/definitions/America/Port_of_Spain.rb +19 -0
- data/lib/tzinfo/definitions/America/Porto_Acre.rb +14 -0
- data/lib/tzinfo/definitions/America/Porto_Velho.rb +48 -0
- data/lib/tzinfo/definitions/America/Puerto_Rico.rb +21 -0
- data/lib/tzinfo/definitions/America/Rainy_River.rb +167 -0
- data/lib/tzinfo/definitions/America/Rankin_Inlet.rb +158 -0
- data/lib/tzinfo/definitions/America/Recife.rb +61 -0
- data/lib/tzinfo/definitions/America/Regina.rb +70 -0
- data/lib/tzinfo/definitions/America/Rio_Branco.rb +48 -0
- data/lib/tzinfo/definitions/America/Rosario.rb +14 -0
- data/lib/tzinfo/definitions/America/Santiago.rb +191 -0
- data/lib/tzinfo/definitions/America/Santo_Domingo.rb +35 -0
- data/lib/tzinfo/definitions/America/Sao_Paulo.rb +162 -0
- data/lib/tzinfo/definitions/America/Scoresbysund.rb +150 -0
- data/lib/tzinfo/definitions/America/Shiprock.rb +14 -0
- data/lib/tzinfo/definitions/America/St_Johns.rb +275 -0
- data/lib/tzinfo/definitions/America/St_Kitts.rb +19 -0
- data/lib/tzinfo/definitions/America/St_Lucia.rb +20 -0
- data/lib/tzinfo/definitions/America/St_Thomas.rb +19 -0
- data/lib/tzinfo/definitions/America/St_Vincent.rb +20 -0
- data/lib/tzinfo/definitions/America/Swift_Current.rb +40 -0
- data/lib/tzinfo/definitions/America/Tegucigalpa.rb +23 -0
- data/lib/tzinfo/definitions/America/Thule.rb +128 -0
- data/lib/tzinfo/definitions/America/Thunder_Bay.rb +175 -0
- data/lib/tzinfo/definitions/America/Tijuana.rb +187 -0
- data/lib/tzinfo/definitions/America/Toronto.rb +268 -0
- data/lib/tzinfo/definitions/America/Tortola.rb +19 -0
- data/lib/tzinfo/definitions/America/Vancouver.rb +222 -0
- data/lib/tzinfo/definitions/America/Virgin.rb +14 -0
- data/lib/tzinfo/definitions/America/Whitehorse.rb +159 -0
- data/lib/tzinfo/definitions/America/Winnipeg.rb +218 -0
- data/lib/tzinfo/definitions/America/Yakutat.rb +179 -0
- data/lib/tzinfo/definitions/America/Yellowknife.rb +158 -0
- data/lib/tzinfo/definitions/Antarctica/Casey.rb +19 -0
- data/lib/tzinfo/definitions/Antarctica/Davis.rb +21 -0
- data/lib/tzinfo/definitions/Antarctica/DumontDUrville.rb +21 -0
- data/lib/tzinfo/definitions/Antarctica/Mawson.rb +19 -0
- data/lib/tzinfo/definitions/Antarctica/McMurdo.rb +161 -0
- data/lib/tzinfo/definitions/Antarctica/Palmer.rb +163 -0
- data/lib/tzinfo/definitions/Antarctica/Rothera.rb +19 -0
- data/lib/tzinfo/definitions/Antarctica/South_Pole.rb +14 -0
- data/lib/tzinfo/definitions/Antarctica/Syowa.rb +19 -0
- data/lib/tzinfo/definitions/Antarctica/Vostok.rb +19 -0
- data/lib/tzinfo/definitions/Arctic/Longyearbyen.rb +14 -0
- data/lib/tzinfo/definitions/Asia/Aden.rb +19 -0
- data/lib/tzinfo/definitions/Asia/Almaty.rb +69 -0
- data/lib/tzinfo/definitions/Asia/Amman.rb +152 -0
- data/lib/tzinfo/definitions/Asia/Anadyr.rb +150 -0
- data/lib/tzinfo/definitions/Asia/Aqtau.rb +69 -0
- data/lib/tzinfo/definitions/Asia/Aqtobe.rb +69 -0
- data/lib/tzinfo/definitions/Asia/Ashgabat.rb +44 -0
- data/lib/tzinfo/definitions/Asia/Ashkhabad.rb +14 -0
- data/lib/tzinfo/definitions/Asia/Baghdad.rb +147 -0
- data/lib/tzinfo/definitions/Asia/Bahrain.rb +20 -0
- data/lib/tzinfo/definitions/Asia/Baku.rb +146 -0
- data/lib/tzinfo/definitions/Asia/Bangkok.rb +20 -0
- data/lib/tzinfo/definitions/Asia/Beirut.rb +174 -0
- data/lib/tzinfo/definitions/Asia/Bishkek.rb +148 -0
- data/lib/tzinfo/definitions/Asia/Brunei.rb +20 -0
- data/lib/tzinfo/definitions/Asia/Calcutta.rb +23 -0
- data/lib/tzinfo/definitions/Asia/Choibalsan.rb +141 -0
- data/lib/tzinfo/definitions/Asia/Chongqing.rb +32 -0
- data/lib/tzinfo/definitions/Asia/Chungking.rb +14 -0
- data/lib/tzinfo/definitions/Asia/Colombo.rb +25 -0
- data/lib/tzinfo/definitions/Asia/Dacca.rb +14 -0
- data/lib/tzinfo/definitions/Asia/Damascus.rb +184 -0
- data/lib/tzinfo/definitions/Asia/Dhaka.rb +24 -0
- data/lib/tzinfo/definitions/Asia/Dili.rb +23 -0
- data/lib/tzinfo/definitions/Asia/Dubai.rb +19 -0
- data/lib/tzinfo/definitions/Asia/Dushanbe.rb +42 -0
- data/lib/tzinfo/definitions/Asia/Gaza.rb +178 -0
- data/lib/tzinfo/definitions/Asia/Harbin.rb +35 -0
- data/lib/tzinfo/definitions/Asia/Hong_Kong.rb +87 -0
- data/lib/tzinfo/definitions/Asia/Hovd.rb +141 -0
- data/lib/tzinfo/definitions/Asia/Irkutsk.rb +151 -0
- data/lib/tzinfo/definitions/Asia/Istanbul.rb +14 -0
- data/lib/tzinfo/definitions/Asia/Jakarta.rb +26 -0
- data/lib/tzinfo/definitions/Asia/Jayapura.rb +21 -0
- data/lib/tzinfo/definitions/Asia/Jerusalem.rb +161 -0
- data/lib/tzinfo/definitions/Asia/Kabul.rb +20 -0
- data/lib/tzinfo/definitions/Asia/Kamchatka.rb +150 -0
- data/lib/tzinfo/definitions/Asia/Karachi.rb +25 -0
- data/lib/tzinfo/definitions/Asia/Kashgar.rb +33 -0
- data/lib/tzinfo/definitions/Asia/Katmandu.rb +20 -0
- data/lib/tzinfo/definitions/Asia/Krasnoyarsk.rb +150 -0
- data/lib/tzinfo/definitions/Asia/Kuala_Lumpur.rb +26 -0
- data/lib/tzinfo/definitions/Asia/Kuching.rb +37 -0
- data/lib/tzinfo/definitions/Asia/Kuwait.rb +19 -0
- data/lib/tzinfo/definitions/Asia/Macao.rb +14 -0
- data/lib/tzinfo/definitions/Asia/Macau.rb +60 -0
- data/lib/tzinfo/definitions/Asia/Magadan.rb +150 -0
- data/lib/tzinfo/definitions/Asia/Makassar.rb +22 -0
- data/lib/tzinfo/definitions/Asia/Manila.rb +28 -0
- data/lib/tzinfo/definitions/Asia/Muscat.rb +19 -0
- data/lib/tzinfo/definitions/Asia/Nicosia.rb +161 -0
- data/lib/tzinfo/definitions/Asia/Novosibirsk.rb +151 -0
- data/lib/tzinfo/definitions/Asia/Omsk.rb +150 -0
- data/lib/tzinfo/definitions/Asia/Oral.rb +69 -0
- data/lib/tzinfo/definitions/Asia/Phnom_Penh.rb +22 -0
- data/lib/tzinfo/definitions/Asia/Pontianak.rb +26 -0
- data/lib/tzinfo/definitions/Asia/Pyongyang.rb +24 -0
- data/lib/tzinfo/definitions/Asia/Qatar.rb +20 -0
- data/lib/tzinfo/definitions/Asia/Qyzylorda.rb +70 -0
- data/lib/tzinfo/definitions/Asia/Rangoon.rb +22 -0
- data/lib/tzinfo/definitions/Asia/Riyadh.rb +19 -0
- data/lib/tzinfo/definitions/Asia/Riyadh87.rb +355 -0
- data/lib/tzinfo/definitions/Asia/Riyadh88.rb +356 -0
- data/lib/tzinfo/definitions/Asia/Riyadh89.rb +356 -0
- data/lib/tzinfo/definitions/Asia/Saigon.rb +22 -0
- data/lib/tzinfo/definitions/Asia/Sakhalin.rb +151 -0
- data/lib/tzinfo/definitions/Asia/Samarkand.rb +47 -0
- data/lib/tzinfo/definitions/Asia/Seoul.rb +31 -0
- data/lib/tzinfo/definitions/Asia/Shanghai.rb +36 -0
- data/lib/tzinfo/definitions/Asia/Singapore.rb +27 -0
- data/lib/tzinfo/definitions/Asia/Taipei.rb +59 -0
- data/lib/tzinfo/definitions/Asia/Tashkent.rb +47 -0
- data/lib/tzinfo/definitions/Asia/Tbilisi.rb +153 -0
- data/lib/tzinfo/definitions/Asia/Tehran.rb +122 -0
- data/lib/tzinfo/definitions/Asia/Tel_Aviv.rb +14 -0
- data/lib/tzinfo/definitions/Asia/Thimbu.rb +14 -0
- data/lib/tzinfo/definitions/Asia/Thimphu.rb +20 -0
- data/lib/tzinfo/definitions/Asia/Tokyo.rb +29 -0
- data/lib/tzinfo/definitions/Asia/Ujung_Pandang.rb +14 -0
- data/lib/tzinfo/definitions/Asia/Ulaanbaatar.rb +141 -0
- data/lib/tzinfo/definitions/Asia/Ulan_Bator.rb +14 -0
- data/lib/tzinfo/definitions/Asia/Urumqi.rb +32 -0
- data/lib/tzinfo/definitions/Asia/Vientiane.rb +22 -0
- data/lib/tzinfo/definitions/Asia/Vladivostok.rb +150 -0
- data/lib/tzinfo/definitions/Asia/Yakutsk.rb +150 -0
- data/lib/tzinfo/definitions/Asia/Yekaterinburg.rb +150 -0
- data/lib/tzinfo/definitions/Asia/Yerevan.rb +149 -0
- data/lib/tzinfo/definitions/Atlantic/Azores.rb +254 -0
- data/lib/tzinfo/definitions/Atlantic/Bermuda.rb +162 -0
- data/lib/tzinfo/definitions/Atlantic/Canary.rb +152 -0
- data/lib/tzinfo/definitions/Atlantic/Cape_Verde.rb +22 -0
- data/lib/tzinfo/definitions/Atlantic/Faeroe.rb +149 -0
- data/lib/tzinfo/definitions/Atlantic/Jan_Mayen.rb +14 -0
- data/lib/tzinfo/definitions/Atlantic/Madeira.rb +254 -0
- data/lib/tzinfo/definitions/Atlantic/Reykjavik.rb +83 -0
- data/lib/tzinfo/definitions/Atlantic/South_Georgia.rb +19 -0
- data/lib/tzinfo/definitions/Atlantic/St_Helena.rb +20 -0
- data/lib/tzinfo/definitions/Atlantic/Stanley.rb +157 -0
- data/lib/tzinfo/definitions/Australia/ACT.rb +14 -0
- data/lib/tzinfo/definitions/Australia/Adelaide.rb +177 -0
- data/lib/tzinfo/definitions/Australia/Brisbane.rb +36 -0
- data/lib/tzinfo/definitions/Australia/Broken_Hill.rb +179 -0
- data/lib/tzinfo/definitions/Australia/Canberra.rb +14 -0
- data/lib/tzinfo/definitions/Australia/Currie.rb +177 -0
- data/lib/tzinfo/definitions/Australia/Darwin.rb +28 -0
- data/lib/tzinfo/definitions/Australia/Hobart.rb +185 -0
- data/lib/tzinfo/definitions/Australia/LHI.rb +14 -0
- data/lib/tzinfo/definitions/Australia/Lindeman.rb +41 -0
- data/lib/tzinfo/definitions/Australia/Lord_Howe.rb +148 -0
- data/lib/tzinfo/definitions/Australia/Melbourne.rb +176 -0
- data/lib/tzinfo/definitions/Australia/NSW.rb +14 -0
- data/lib/tzinfo/definitions/Australia/North.rb +14 -0
- data/lib/tzinfo/definitions/Australia/Perth.rb +32 -0
- data/lib/tzinfo/definitions/Australia/Queensland.rb +14 -0
- data/lib/tzinfo/definitions/Australia/South.rb +14 -0
- data/lib/tzinfo/definitions/Australia/Sydney.rb +176 -0
- data/lib/tzinfo/definitions/Australia/Tasmania.rb +14 -0
- data/lib/tzinfo/definitions/Australia/Victoria.rb +14 -0
- data/lib/tzinfo/definitions/Australia/West.rb +14 -0
- data/lib/tzinfo/definitions/Australia/Yancowinna.rb +14 -0
- data/lib/tzinfo/definitions/Brazil/Acre.rb +14 -0
- data/lib/tzinfo/definitions/Brazil/DeNoronha.rb +14 -0
- data/lib/tzinfo/definitions/Brazil/East.rb +14 -0
- data/lib/tzinfo/definitions/Brazil/West.rb +14 -0
- data/lib/tzinfo/definitions/CET.rb +165 -0
- data/lib/tzinfo/definitions/CST6CDT.rb +12 -0
- data/lib/tzinfo/definitions/Canada/Atlantic.rb +14 -0
- data/lib/tzinfo/definitions/Canada/Central.rb +14 -0
- data/lib/tzinfo/definitions/Canada/East__m__Saskatchewan.rb +14 -0
- data/lib/tzinfo/definitions/Canada/Eastern.rb +14 -0
- data/lib/tzinfo/definitions/Canada/Mountain.rb +14 -0
- data/lib/tzinfo/definitions/Canada/Newfoundland.rb +14 -0
- data/lib/tzinfo/definitions/Canada/Pacific.rb +14 -0
- data/lib/tzinfo/definitions/Canada/Saskatchewan.rb +14 -0
- data/lib/tzinfo/definitions/Canada/Yukon.rb +14 -0
- data/lib/tzinfo/definitions/Chile/Continental.rb +14 -0
- data/lib/tzinfo/definitions/Chile/EasterIsland.rb +14 -0
- data/lib/tzinfo/definitions/Cuba.rb +12 -0
- data/lib/tzinfo/definitions/EET.rb +153 -0
- data/lib/tzinfo/definitions/EST.rb +12 -0
- data/lib/tzinfo/definitions/EST5EDT.rb +12 -0
- data/lib/tzinfo/definitions/Egypt.rb +12 -0
- data/lib/tzinfo/definitions/Eire.rb +12 -0
- data/lib/tzinfo/definitions/Etc/GMT.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT0.rb +14 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__0.rb +14 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__1.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__10.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__11.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__12.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__13.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__14.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__2.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__3.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__4.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__5.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__6.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__7.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__8.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__m__9.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__0.rb +14 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__1.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__10.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__11.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__12.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__2.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__3.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__4.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__5.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__6.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__7.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__8.rb +18 -0
- data/lib/tzinfo/definitions/Etc/GMT__p__9.rb +18 -0
- data/lib/tzinfo/definitions/Etc/Greenwich.rb +14 -0
- data/lib/tzinfo/definitions/Etc/UCT.rb +18 -0
- data/lib/tzinfo/definitions/Etc/UTC.rb +18 -0
- data/lib/tzinfo/definitions/Etc/Universal.rb +14 -0
- data/lib/tzinfo/definitions/Etc/Zulu.rb +14 -0
- data/lib/tzinfo/definitions/Europe/Amsterdam.rb +213 -0
- data/lib/tzinfo/definitions/Europe/Andorra.rb +141 -0
- data/lib/tzinfo/definitions/Europe/Athens.rb +172 -0
- data/lib/tzinfo/definitions/Europe/Belfast.rb +14 -0
- data/lib/tzinfo/definitions/Europe/Belgrade.rb +152 -0
- data/lib/tzinfo/definitions/Europe/Berlin.rb +177 -0
- data/lib/tzinfo/definitions/Europe/Bratislava.rb +14 -0
- data/lib/tzinfo/definitions/Europe/Brussels.rb +219 -0
- data/lib/tzinfo/definitions/Europe/Bucharest.rb +172 -0
- data/lib/tzinfo/definitions/Europe/Budapest.rb +186 -0
- data/lib/tzinfo/definitions/Europe/Chisinau.rb +175 -0
- data/lib/tzinfo/definitions/Europe/Copenhagen.rb +168 -0
- data/lib/tzinfo/definitions/Europe/Dublin.rb +262 -0
- data/lib/tzinfo/definitions/Europe/Gibraltar.rb +232 -0
- data/lib/tzinfo/definitions/Europe/Helsinki.rb +152 -0
- data/lib/tzinfo/definitions/Europe/Istanbul.rb +206 -0
- data/lib/tzinfo/definitions/Europe/Kaliningrad.rb +164 -0
- data/lib/tzinfo/definitions/Europe/Kiev.rb +154 -0
- data/lib/tzinfo/definitions/Europe/Lisbon.rb +255 -0
- data/lib/tzinfo/definitions/Europe/Ljubljana.rb +14 -0
- data/lib/tzinfo/definitions/Europe/London.rb +276 -0
- data/lib/tzinfo/definitions/Europe/Luxembourg.rb +216 -0
- data/lib/tzinfo/definitions/Europe/Madrid.rb +198 -0
- data/lib/tzinfo/definitions/Europe/Malta.rb +203 -0
- data/lib/tzinfo/definitions/Europe/Mariehamn.rb +14 -0
- data/lib/tzinfo/definitions/Europe/Minsk.rb +152 -0
- data/lib/tzinfo/definitions/Europe/Monaco.rb +219 -0
- data/lib/tzinfo/definitions/Europe/Moscow.rb +163 -0
- data/lib/tzinfo/definitions/Europe/Nicosia.rb +14 -0
- data/lib/tzinfo/definitions/Europe/Oslo.rb +174 -0
- data/lib/tzinfo/definitions/Europe/Paris.rb +217 -0
- data/lib/tzinfo/definitions/Europe/Prague.rb +175 -0
- data/lib/tzinfo/definitions/Europe/Riga.rb +161 -0
- data/lib/tzinfo/definitions/Europe/Rome.rb +205 -0
- data/lib/tzinfo/definitions/Europe/Samara.rb +150 -0
- data/lib/tzinfo/definitions/Europe/San_Marino.rb +14 -0
- data/lib/tzinfo/definitions/Europe/Sarajevo.rb +14 -0
- data/lib/tzinfo/definitions/Europe/Simferopol.rb +156 -0
- data/lib/tzinfo/definitions/Europe/Skopje.rb +14 -0
- data/lib/tzinfo/definitions/Europe/Sofia.rb +162 -0
- data/lib/tzinfo/definitions/Europe/Stockholm.rb +154 -0
- data/lib/tzinfo/definitions/Europe/Tallinn.rb +157 -0
- data/lib/tzinfo/definitions/Europe/Tirane.rb +167 -0
- data/lib/tzinfo/definitions/Europe/Tiraspol.rb +14 -0
- data/lib/tzinfo/definitions/Europe/Uzhgorod.rb +158 -0
- data/lib/tzinfo/definitions/Europe/Vaduz.rb +149 -0
- data/lib/tzinfo/definitions/Europe/Vatican.rb +14 -0
- data/lib/tzinfo/definitions/Europe/Vienna.rb +175 -0
- data/lib/tzinfo/definitions/Europe/Vilnius.rb +153 -0
- data/lib/tzinfo/definitions/Europe/Warsaw.rb +200 -0
- data/lib/tzinfo/definitions/Europe/Zagreb.rb +14 -0
- data/lib/tzinfo/definitions/Europe/Zaporozhye.rb +155 -0
- data/lib/tzinfo/definitions/Europe/Zurich.rb +156 -0
- data/lib/tzinfo/definitions/GB.rb +12 -0
- data/lib/tzinfo/definitions/GB__m__Eire.rb +12 -0
- data/lib/tzinfo/definitions/GMT.rb +12 -0
- data/lib/tzinfo/definitions/GMT0.rb +12 -0
- data/lib/tzinfo/definitions/GMT__m__0.rb +12 -0
- data/lib/tzinfo/definitions/GMT__p__0.rb +12 -0
- data/lib/tzinfo/definitions/Greenwich.rb +12 -0
- data/lib/tzinfo/definitions/HST.rb +12 -0
- data/lib/tzinfo/definitions/Hongkong.rb +12 -0
- data/lib/tzinfo/definitions/Iceland.rb +12 -0
- data/lib/tzinfo/definitions/Indian/Antananarivo.rb +21 -0
- data/lib/tzinfo/definitions/Indian/Chagos.rb +20 -0
- data/lib/tzinfo/definitions/Indian/Christmas.rb +19 -0
- data/lib/tzinfo/definitions/Indian/Cocos.rb +19 -0
- data/lib/tzinfo/definitions/Indian/Comoro.rb +19 -0
- data/lib/tzinfo/definitions/Indian/Kerguelen.rb +19 -0
- data/lib/tzinfo/definitions/Indian/Mahe.rb +19 -0
- data/lib/tzinfo/definitions/Indian/Maldives.rb +20 -0
- data/lib/tzinfo/definitions/Indian/Mauritius.rb +19 -0
- data/lib/tzinfo/definitions/Indian/Mayotte.rb +19 -0
- data/lib/tzinfo/definitions/Indian/Reunion.rb +19 -0
- data/lib/tzinfo/definitions/Iran.rb +12 -0
- data/lib/tzinfo/definitions/Israel.rb +12 -0
- data/lib/tzinfo/definitions/Jamaica.rb +12 -0
- data/lib/tzinfo/definitions/Japan.rb +12 -0
- data/lib/tzinfo/definitions/Kwajalein.rb +12 -0
- data/lib/tzinfo/definitions/Libya.rb +12 -0
- data/lib/tzinfo/definitions/MET.rb +165 -0
- data/lib/tzinfo/definitions/MST.rb +12 -0
- data/lib/tzinfo/definitions/MST7MDT.rb +12 -0
- data/lib/tzinfo/definitions/Mexico/BajaNorte.rb +14 -0
- data/lib/tzinfo/definitions/Mexico/BajaSur.rb +14 -0
- data/lib/tzinfo/definitions/Mexico/General.rb +14 -0
- data/lib/tzinfo/definitions/Mideast/Riyadh87.rb +14 -0
- data/lib/tzinfo/definitions/Mideast/Riyadh88.rb +14 -0
- data/lib/tzinfo/definitions/Mideast/Riyadh89.rb +14 -0
- data/lib/tzinfo/definitions/NZ.rb +12 -0
- data/lib/tzinfo/definitions/NZ__m__CHAT.rb +12 -0
- data/lib/tzinfo/definitions/Navajo.rb +12 -0
- data/lib/tzinfo/definitions/PRC.rb +12 -0
- data/lib/tzinfo/definitions/PST8PDT.rb +12 -0
- data/lib/tzinfo/definitions/Pacific/Apia.rb +21 -0
- data/lib/tzinfo/definitions/Pacific/Auckland.rb +189 -0
- data/lib/tzinfo/definitions/Pacific/Chatham.rb +161 -0
- data/lib/tzinfo/definitions/Pacific/Easter.rb +179 -0
- data/lib/tzinfo/definitions/Pacific/Efate.rb +39 -0
- data/lib/tzinfo/definitions/Pacific/Enderbury.rb +21 -0
- data/lib/tzinfo/definitions/Pacific/Fakaofo.rb +19 -0
- data/lib/tzinfo/definitions/Pacific/Fiji.rb +23 -0
- data/lib/tzinfo/definitions/Pacific/Funafuti.rb +19 -0
- data/lib/tzinfo/definitions/Pacific/Galapagos.rb +20 -0
- data/lib/tzinfo/definitions/Pacific/Gambier.rb +19 -0
- data/lib/tzinfo/definitions/Pacific/Guadalcanal.rb +19 -0
- data/lib/tzinfo/definitions/Pacific/Guam.rb +21 -0
- data/lib/tzinfo/definitions/Pacific/Honolulu.rb +23 -0
- data/lib/tzinfo/definitions/Pacific/Johnston.rb +18 -0
- data/lib/tzinfo/definitions/Pacific/Kiritimati.rb +21 -0
- data/lib/tzinfo/definitions/Pacific/Kosrae.rb +21 -0
- data/lib/tzinfo/definitions/Pacific/Kwajalein.rb +21 -0
- data/lib/tzinfo/definitions/Pacific/Majuro.rb +20 -0
- data/lib/tzinfo/definitions/Pacific/Marquesas.rb +19 -0
- data/lib/tzinfo/definitions/Pacific/Midway.rb +23 -0
- data/lib/tzinfo/definitions/Pacific/Nauru.rb +22 -0
- data/lib/tzinfo/definitions/Pacific/Niue.rb +21 -0
- data/lib/tzinfo/definitions/Pacific/Norfolk.rb +20 -0
- data/lib/tzinfo/definitions/Pacific/Noumea.rb +25 -0
- data/lib/tzinfo/definitions/Pacific/Pago_Pago.rb +23 -0
- data/lib/tzinfo/definitions/Pacific/Palau.rb +19 -0
- data/lib/tzinfo/definitions/Pacific/Pitcairn.rb +20 -0
- data/lib/tzinfo/definitions/Pacific/Ponape.rb +19 -0
- data/lib/tzinfo/definitions/Pacific/Port_Moresby.rb +20 -0
- data/lib/tzinfo/definitions/Pacific/Rarotonga.rb +45 -0
- data/lib/tzinfo/definitions/Pacific/Saipan.rb +22 -0
- data/lib/tzinfo/definitions/Pacific/Samoa.rb +14 -0
- data/lib/tzinfo/definitions/Pacific/Tahiti.rb +19 -0
- data/lib/tzinfo/definitions/Pacific/Tarawa.rb +19 -0
- data/lib/tzinfo/definitions/Pacific/Tongatapu.rb +27 -0
- data/lib/tzinfo/definitions/Pacific/Truk.rb +19 -0
- data/lib/tzinfo/definitions/Pacific/Wake.rb +19 -0
- data/lib/tzinfo/definitions/Pacific/Wallis.rb +19 -0
- data/lib/tzinfo/definitions/Pacific/Yap.rb +14 -0
- data/lib/tzinfo/definitions/Poland.rb +12 -0
- data/lib/tzinfo/definitions/Portugal.rb +12 -0
- data/lib/tzinfo/definitions/ROC.rb +12 -0
- data/lib/tzinfo/definitions/ROK.rb +12 -0
- data/lib/tzinfo/definitions/Singapore.rb +12 -0
- data/lib/tzinfo/definitions/SystemV/AST4.rb +14 -0
- data/lib/tzinfo/definitions/SystemV/AST4ADT.rb +14 -0
- data/lib/tzinfo/definitions/SystemV/CST6.rb +14 -0
- data/lib/tzinfo/definitions/SystemV/CST6CDT.rb +14 -0
- data/lib/tzinfo/definitions/SystemV/EST5.rb +14 -0
- data/lib/tzinfo/definitions/SystemV/EST5EDT.rb +14 -0
- data/lib/tzinfo/definitions/SystemV/HST10.rb +14 -0
- data/lib/tzinfo/definitions/SystemV/MST7.rb +14 -0
- data/lib/tzinfo/definitions/SystemV/MST7MDT.rb +14 -0
- data/lib/tzinfo/definitions/SystemV/PST8.rb +14 -0
- data/lib/tzinfo/definitions/SystemV/PST8PDT.rb +14 -0
- data/lib/tzinfo/definitions/SystemV/YST9.rb +14 -0
- data/lib/tzinfo/definitions/SystemV/YST9YDT.rb +14 -0
- data/lib/tzinfo/definitions/Turkey.rb +12 -0
- data/lib/tzinfo/definitions/UCT.rb +12 -0
- data/lib/tzinfo/definitions/US/Alaska.rb +14 -0
- data/lib/tzinfo/definitions/US/Aleutian.rb +14 -0
- data/lib/tzinfo/definitions/US/Arizona.rb +14 -0
- data/lib/tzinfo/definitions/US/Central.rb +14 -0
- data/lib/tzinfo/definitions/US/East__m__Indiana.rb +14 -0
- data/lib/tzinfo/definitions/US/Eastern.rb +14 -0
- data/lib/tzinfo/definitions/US/Hawaii.rb +14 -0
- data/lib/tzinfo/definitions/US/Indiana__m__Starke.rb +14 -0
- data/lib/tzinfo/definitions/US/Michigan.rb +14 -0
- data/lib/tzinfo/definitions/US/Mountain.rb +14 -0
- data/lib/tzinfo/definitions/US/Pacific.rb +14 -0
- data/lib/tzinfo/definitions/US/Pacific__m__New.rb +14 -0
- data/lib/tzinfo/definitions/US/Samoa.rb +14 -0
- data/lib/tzinfo/definitions/UTC.rb +12 -0
- data/lib/tzinfo/definitions/Universal.rb +12 -0
- data/lib/tzinfo/definitions/WET.rb +153 -0
- data/lib/tzinfo/definitions/W__m__SU.rb +12 -0
- data/lib/tzinfo/definitions/Zulu.rb +12 -0
- data/lib/tzinfo/timezone.rb +275 -0
- data/lib/tzinfo/tzdataparser.rb +991 -0
- metadata +861 -0
@@ -0,0 +1,275 @@
|
|
1
|
+
|
2
|
+
module TZInfo
|
3
|
+
class PeriodNotFound < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
# Timezone is the base class of all timezones. It provides a factory method
|
7
|
+
# get to access timezones by identifier. Once a specific Timezone has been
|
8
|
+
# retrieved, DateTimes and Times can be converted between the UTC and the
|
9
|
+
# local time for the zone. For example:
|
10
|
+
#
|
11
|
+
# tz = TZInfo::Timezone.get('America/New_York')
|
12
|
+
# puts tz.utc_to_local(DateTime.new(2005,8,29,15,35,0)).to_s
|
13
|
+
# puts tz.local_to_utc(Time.utc(2005,8,29,11,35,0)).to_s
|
14
|
+
#
|
15
|
+
# The timezone information all comes from the tz database
|
16
|
+
# (see http://www.twinsun.com/tz/tz-link.htm)
|
17
|
+
class Timezone
|
18
|
+
# Returns a timezone by its identifier (e.g. "Europe/London",
|
19
|
+
# "America/Chicago" and "UTC").
|
20
|
+
#
|
21
|
+
# Raises an exception of the timezone couldn't be found.
|
22
|
+
def self.get(identifier)
|
23
|
+
raise 'Invalid identifier' if identifier !~ /^[A-z0-9\+\-_]+(\/[A-z0-9\+\-_]+)*$/
|
24
|
+
identifier = identifier.gsub(/-/, '__m__').gsub(/\+/, '__p__')
|
25
|
+
require "tzinfo/definitions/#{identifier}"
|
26
|
+
|
27
|
+
m = Definitions
|
28
|
+
identifier.split(/\//).each {|part|
|
29
|
+
m = m.const_get(part)
|
30
|
+
}
|
31
|
+
m.instance
|
32
|
+
end
|
33
|
+
|
34
|
+
# Initializes the timezone.
|
35
|
+
def initialize
|
36
|
+
super
|
37
|
+
@periods = []
|
38
|
+
@identifier = nil
|
39
|
+
end
|
40
|
+
|
41
|
+
# The identifier of the timezone, e.g. "Europe/Paris".
|
42
|
+
def identifier
|
43
|
+
@identifier
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the TimezonePeriod for the given UTC time. utc can either be
|
47
|
+
# a DateTime or a Time. Any timezone information in utc is ignored (it is
|
48
|
+
# treated as a UTC time).
|
49
|
+
#
|
50
|
+
# If no TimezonePeriod could be found, PeriodNotFound is raised.
|
51
|
+
def period_for_utc(utc)
|
52
|
+
run_on_datetime(utc) {|utc|
|
53
|
+
# dumb search for now
|
54
|
+
@periods.each {|period|
|
55
|
+
if period.valid_for_utc?(utc)
|
56
|
+
return period
|
57
|
+
end
|
58
|
+
}
|
59
|
+
|
60
|
+
# if nothing found, assume the first and last periods are unbounded
|
61
|
+
if @periods.length > 0
|
62
|
+
|
63
|
+
last = @periods[@periods.length - 1]
|
64
|
+
if last.utc_after_start?(utc)
|
65
|
+
last
|
66
|
+
else
|
67
|
+
first = @periods[0]
|
68
|
+
if first.utc_before_end?(utc)
|
69
|
+
first
|
70
|
+
else
|
71
|
+
raise PeriodNotFound, "No time period found for #{utc}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
else
|
75
|
+
raise PeriodNotFound, "No time period found for #{utc}"
|
76
|
+
end
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
# Returns the TimezonePeriod for the given local time. local can either be
|
81
|
+
# a DateTime or a Time. Any timezone information in local is ignored (it is
|
82
|
+
# treated as a time in the current timezone).
|
83
|
+
#
|
84
|
+
# If no TimezonePeriod could be found, PeriodNotFound is raised. This will
|
85
|
+
# happen when a change to daylight savings occurs and an hour is skipped.
|
86
|
+
def period_for_local(local)
|
87
|
+
run_on_datetime(local) {|local|
|
88
|
+
# dumb search for now
|
89
|
+
@periods.each {|period|
|
90
|
+
if period.valid_for_local?(local)
|
91
|
+
return period
|
92
|
+
end
|
93
|
+
}
|
94
|
+
|
95
|
+
# if nothing found, assume the first and last periods are unbounded
|
96
|
+
if @periods.length > 0
|
97
|
+
|
98
|
+
last = @periods[@periods.length - 1]
|
99
|
+
if last.local_after_start?(local)
|
100
|
+
last
|
101
|
+
else
|
102
|
+
first = @periods[0]
|
103
|
+
if first.local_before_end?(local)
|
104
|
+
first
|
105
|
+
else
|
106
|
+
raise PeriodNotFound, "No time period found for #{utc}. This could be because a change to daylight savings time caused an hour to be skipped."
|
107
|
+
end
|
108
|
+
end
|
109
|
+
else
|
110
|
+
raise PeriodNotFound, "No time period found for #{utc}. This could be because a change to daylight savings time caused an hour to be skipped."
|
111
|
+
end
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
# Converts a time in UTC to the local timezone. utc can either be
|
116
|
+
# a DateTime or a Time. The returned time has the same type as utc.
|
117
|
+
# Any timezone information in utc is ignored (it is treated as a UTC time).
|
118
|
+
def utc_to_local(utc)
|
119
|
+
run_on_datetime(utc) {|utc|
|
120
|
+
period_for_utc(utc).to_local(utc)
|
121
|
+
}
|
122
|
+
end
|
123
|
+
|
124
|
+
# Converts a time in the local timezone to UTC. local can either be
|
125
|
+
# a DateTime or a Time. The returned time has the same type as local.
|
126
|
+
# Any timezone information in local is ignored (it is treated as a local time).
|
127
|
+
#
|
128
|
+
# During the period when daylight savings reverts to standard time and there
|
129
|
+
# are two possible UTC times for each local time, local_to_utc returns the
|
130
|
+
# earlier time.
|
131
|
+
#
|
132
|
+
# For times skipped during a change to daylight savings, PeriodNotFound is
|
133
|
+
# raised.
|
134
|
+
def local_to_utc(local)
|
135
|
+
run_on_datetime(local) {|local|
|
136
|
+
period_for_local(local).to_utc(local)
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
# Returns the current time in the timezone as a Time.
|
141
|
+
def now
|
142
|
+
utc_to_local(Time.now.utc)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns the TimezonePeriod for the current time.
|
146
|
+
def current_period
|
147
|
+
period_for_utc(Time.now.utc)
|
148
|
+
end
|
149
|
+
|
150
|
+
# Returns the current time and TimezonePeriod as an array.
|
151
|
+
def current_period_and_time
|
152
|
+
utc = Time.now.utc
|
153
|
+
[utc_to_local(utc), period_for_utc(utc)]
|
154
|
+
end
|
155
|
+
|
156
|
+
protected
|
157
|
+
def add_period(period)
|
158
|
+
@periods << period
|
159
|
+
end
|
160
|
+
|
161
|
+
def set_identifier(identifier)
|
162
|
+
@identifier = identifier
|
163
|
+
end
|
164
|
+
|
165
|
+
private
|
166
|
+
# Executes a block with a DateTime. If datetime is a Time it will be
|
167
|
+
# converted to a DateTime before yielding to the block and the result of
|
168
|
+
# the block will be converted back to a Time.
|
169
|
+
def run_on_datetime(datetime)
|
170
|
+
if datetime.instance_of?(Time)
|
171
|
+
datetime = DateTime.new(datetime.year, datetime.mon, datetime.mday, datetime.hour, datetime.min, datetime.sec)
|
172
|
+
result = yield datetime
|
173
|
+
|
174
|
+
# not necessarily utc, but pretend it is
|
175
|
+
Time.utc(result.year, result.mon, result.mday, result.hour, result.min, result.sec)
|
176
|
+
else
|
177
|
+
yield datetime
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# A period of time in a timezone where the same offset from UTC applies.
|
183
|
+
class TimezonePeriod
|
184
|
+
# Start time of the period (UTC). May be nil if unbounded.
|
185
|
+
attr_reader :utc_start
|
186
|
+
|
187
|
+
# End time of the period (UTC). May be nil if unbounded.
|
188
|
+
attr_reader :utc_end
|
189
|
+
|
190
|
+
# Base offset of the timezone from UTC (seconds).
|
191
|
+
attr_reader :utc_offset
|
192
|
+
|
193
|
+
# Offset from the local time where daylight savings is in effect (seconds).
|
194
|
+
# E.g.: utc_offset could be -5 hours. Normally, std_offset would be 0.
|
195
|
+
# During daylight savings, std_offset would become +1 hours.
|
196
|
+
attr_reader :std_offset
|
197
|
+
|
198
|
+
# The identifier of this period, e.g. "GMT" (Greenwich Mean Time) or "BST"
|
199
|
+
# (British Summer Time) for "Europe/London".
|
200
|
+
attr_reader :zone_identifier
|
201
|
+
|
202
|
+
# Start time of the period (local time). May be nil if unbounded.
|
203
|
+
attr_reader :local_start
|
204
|
+
|
205
|
+
# End time of the period (local time). May be nil if unbounded.
|
206
|
+
attr_reader :local_end
|
207
|
+
|
208
|
+
# Initializes a new TimezonePeriod.
|
209
|
+
def initialize(utc_start, utc_end, utc_offset, std_offset, zone_identifier)
|
210
|
+
@utc_start = utc_start
|
211
|
+
@utc_end = utc_end
|
212
|
+
@utc_offset = utc_offset
|
213
|
+
@std_offset = std_offset
|
214
|
+
@zone_identifier = zone_identifier
|
215
|
+
|
216
|
+
@local_start = utc_start.nil? ? nil : to_local(utc_start)
|
217
|
+
@local_end = utc_end.nil? ? nil : to_local(utc_end)
|
218
|
+
end
|
219
|
+
|
220
|
+
# Total offset from UTC (seconds). Equal to utc_offset + std_offset.
|
221
|
+
def utc_total_offset
|
222
|
+
utc_offset + std_offset
|
223
|
+
end
|
224
|
+
|
225
|
+
# Total offset from UTC (days). Result is a Rational.
|
226
|
+
def utc_total_offset_rational
|
227
|
+
Rational(utc_total_offset, 86400)
|
228
|
+
end
|
229
|
+
|
230
|
+
# true if daylight savings is in effect for this period; otherwise false.
|
231
|
+
def dst?
|
232
|
+
std_offset != 0
|
233
|
+
end
|
234
|
+
|
235
|
+
# true if this period is valid for the given utc DateTime; otherwise false.
|
236
|
+
def valid_for_utc?(utc)
|
237
|
+
utc_after_start?(utc) && utc_before_end?(utc)
|
238
|
+
end
|
239
|
+
|
240
|
+
# true if the given utc DateTime is after the start of the period; otherwise false.
|
241
|
+
def utc_after_start?(utc)
|
242
|
+
@utc_start.nil? || @utc_start <= utc
|
243
|
+
end
|
244
|
+
|
245
|
+
# true if the given utc DateTime is before the end of the period; otherwise false.
|
246
|
+
def utc_before_end?(utc)
|
247
|
+
@utc_end.nil? || @utc_end > utc
|
248
|
+
end
|
249
|
+
|
250
|
+
# true if this period is valid for the given local DateTime; otherwise false.
|
251
|
+
def valid_for_local?(local)
|
252
|
+
local_after_start?(local) && local_before_end?(local)
|
253
|
+
end
|
254
|
+
|
255
|
+
# true if the given local DateTime is after the start of the period; otherwise false.
|
256
|
+
def local_after_start?(local)
|
257
|
+
@local_start.nil? || @local_start <= local
|
258
|
+
end
|
259
|
+
|
260
|
+
# true if the given local DateTime is before the end of the period; otherwise false.
|
261
|
+
def local_before_end?(local)
|
262
|
+
@local_end.nil? || @local_end > local
|
263
|
+
end
|
264
|
+
|
265
|
+
# Converts a UTC DateTime to local time based on the offset of this period.
|
266
|
+
def to_local(utc)
|
267
|
+
utc + utc_total_offset_rational
|
268
|
+
end
|
269
|
+
|
270
|
+
# Converts a local DateTime to UTC based on the offset of this period.
|
271
|
+
def to_utc(local)
|
272
|
+
local - utc_total_offset_rational
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
@@ -0,0 +1,991 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module TZInfo
|
4
|
+
|
5
|
+
# Parses tzdata from ftp://elsie.nci.nih.gov/pub/ and transforms it into
|
6
|
+
# a set of Ruby classes that can be used through Timezone and Country.
|
7
|
+
#
|
8
|
+
# Normally, this class wouldn't be used. It is only run to create a new
|
9
|
+
# tzinfo version for a new version of the tzdata data.
|
10
|
+
#
|
11
|
+
# This process is extremely slow (optimization is required).
|
12
|
+
class TZDataParser
|
13
|
+
# Initializes a new TZDataParser. input_dir must contain the extracted
|
14
|
+
# tzdata tarball. output_dir is the location to output the classes
|
15
|
+
# (in countries and definitions directories).
|
16
|
+
def initialize(input_dir, output_dir)
|
17
|
+
super()
|
18
|
+
@input_dir = input_dir
|
19
|
+
@output_dir = output_dir
|
20
|
+
@rule_sets = {}
|
21
|
+
@zones = {}
|
22
|
+
@countries = {}
|
23
|
+
@no_rules = TZDataNoRules.new
|
24
|
+
end
|
25
|
+
|
26
|
+
# Reads the tzdata source and generates the classes. Takes a long time
|
27
|
+
# to run. Currently outputs debugging information to standard out.
|
28
|
+
def execute
|
29
|
+
Dir.foreach(@input_dir) {|file|
|
30
|
+
load_rules(file) if file =~ /^[^\.]+$/
|
31
|
+
}
|
32
|
+
|
33
|
+
Dir.foreach(@input_dir) {|file|
|
34
|
+
load_zones(file) if file =~ /^[^\.]+$/
|
35
|
+
}
|
36
|
+
|
37
|
+
Dir.foreach(@input_dir) {|file|
|
38
|
+
load_links(file) if file =~ /^[^\.]+$/
|
39
|
+
}
|
40
|
+
|
41
|
+
load_countries
|
42
|
+
|
43
|
+
@zones.each_value {|zone|
|
44
|
+
zone.write_class(@output_dir)
|
45
|
+
}
|
46
|
+
|
47
|
+
@countries.each_value {|country|
|
48
|
+
country.write_class(@output_dir)
|
49
|
+
}
|
50
|
+
|
51
|
+
write_countries_index
|
52
|
+
end
|
53
|
+
|
54
|
+
# Parses a month specified in the tz data and converts it to a number
|
55
|
+
# between 1 and 12 representing January to December.
|
56
|
+
def self.parse_month(month)
|
57
|
+
lower = month.downcase
|
58
|
+
if lower =~ /^jan/
|
59
|
+
@month = 1
|
60
|
+
elsif lower =~ /^feb/
|
61
|
+
@month = 2
|
62
|
+
elsif lower =~ /^mar/
|
63
|
+
@month = 3
|
64
|
+
elsif lower =~ /^apr/
|
65
|
+
@month = 4
|
66
|
+
elsif lower =~ /^may/
|
67
|
+
@month = 5
|
68
|
+
elsif lower =~ /^jun/
|
69
|
+
@month = 6
|
70
|
+
elsif lower =~ /^jul/
|
71
|
+
@month = 7
|
72
|
+
elsif lower =~ /^aug/
|
73
|
+
@month = 8
|
74
|
+
elsif lower =~ /^sep/
|
75
|
+
@month = 9
|
76
|
+
elsif lower =~ /^oct/
|
77
|
+
@month = 10
|
78
|
+
elsif lower =~ /^nov/
|
79
|
+
@month = 11
|
80
|
+
elsif lower =~ /^dec/
|
81
|
+
@month = 12
|
82
|
+
else
|
83
|
+
raise "Invalid month: #{month}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
# Loads all the Rule definitions from the tz data and stores them in
|
89
|
+
# @rule_sets.
|
90
|
+
def load_rules(file)
|
91
|
+
puts 'load_rules: ' + file
|
92
|
+
|
93
|
+
IO.foreach(@input_dir + File::SEPARATOR + file) {|line|
|
94
|
+
line = line.gsub(/#.*$/, '')
|
95
|
+
line = line.gsub(/\s+$/, '')
|
96
|
+
|
97
|
+
if line =~ /^Rule\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)/
|
98
|
+
|
99
|
+
name = $1
|
100
|
+
|
101
|
+
if @rule_sets[name].nil?
|
102
|
+
@rule_sets[name] = TZDataRuleSet.new(name)
|
103
|
+
end
|
104
|
+
|
105
|
+
@rule_sets[name].add_rule(TZDataRule.new($2, $3, $4, $5, $6, $7, $8, $9))
|
106
|
+
end
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
# Gets a rules object for the given reference. Might be a named rule set,
|
111
|
+
# a fixed offset or an empty ruleset.
|
112
|
+
def get_rules(ref)
|
113
|
+
if ref == '-'
|
114
|
+
@no_rules
|
115
|
+
elsif ref =~ /^[0-9]+:[0-9]+$/
|
116
|
+
TZDataFixedOffsetRules.new(TZDataOffset.new(ref))
|
117
|
+
else
|
118
|
+
rule_set = @rule_sets[ref]
|
119
|
+
raise "Ruleset not found: #{ref}" if rule_set.nil?
|
120
|
+
rule_set
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Loads in the Zone definitions from the tz data and stores them in @zones.
|
125
|
+
def load_zones(file)
|
126
|
+
puts 'load_zones: ' + file
|
127
|
+
|
128
|
+
in_zone = nil
|
129
|
+
|
130
|
+
IO.foreach(@input_dir + File::SEPARATOR + file) {|line|
|
131
|
+
line = line.gsub(/#.*$/, '')
|
132
|
+
line = line.gsub(/\s+$/, '')
|
133
|
+
|
134
|
+
if in_zone
|
135
|
+
if line =~ /^\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)(\s+([0-9]+(\s+.*)?))?$/
|
136
|
+
|
137
|
+
in_zone.add_period(TZDataPeriod.new($1, get_rules($2), $3, $5))
|
138
|
+
|
139
|
+
in_zone = nil if $4.nil?
|
140
|
+
end
|
141
|
+
else
|
142
|
+
if line =~ /^Zone\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)(\s+([0-9]+(\s+.*)?))?$/
|
143
|
+
name = $1
|
144
|
+
|
145
|
+
if @zones[name].nil?
|
146
|
+
@zones[name] = TZDataZone.new(name)
|
147
|
+
end
|
148
|
+
|
149
|
+
@zones[name].add_period(TZDataPeriod.new($2, get_rules($3), $4, $6))
|
150
|
+
|
151
|
+
in_zone = @zones[name] if !$5.nil?
|
152
|
+
end
|
153
|
+
end
|
154
|
+
}
|
155
|
+
end
|
156
|
+
|
157
|
+
# Loads in the links and stores them in @zones.
|
158
|
+
def load_links(file)
|
159
|
+
puts 'load_links: ' + file
|
160
|
+
|
161
|
+
IO.foreach(@input_dir + File::SEPARATOR + file) {|line|
|
162
|
+
line = line.gsub(/#.*$/, '')
|
163
|
+
line = line.gsub(/\s+$/, '')
|
164
|
+
|
165
|
+
if line =~ /^Link\s+([^\s]+)\s+([^\s]+)/
|
166
|
+
name = $2
|
167
|
+
link_to = @zones[$1]
|
168
|
+
raise "Link to zone not found (#{name}->#{link_to})" if link_to.nil?
|
169
|
+
raise "Zone already defined: #{name}" if !@zones[name].nil?
|
170
|
+
@zones[name] = TZDataLink.new(name, link_to)
|
171
|
+
end
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
# Loads countries from iso3166.tab and zone.tab and stores the result in
|
176
|
+
# @countries.
|
177
|
+
def load_countries
|
178
|
+
puts 'load_countries'
|
179
|
+
|
180
|
+
IO.foreach(@input_dir + File::SEPARATOR + 'iso3166.tab') {|line|
|
181
|
+
line = line.gsub(/#.*$/, '')
|
182
|
+
line = line.gsub(/\s+$/, '')
|
183
|
+
|
184
|
+
if line =~ /^([A-Z]{2})\s+(.*)$/
|
185
|
+
code = $1
|
186
|
+
name = $2
|
187
|
+
@countries[code] = TZDataCountry.new(code, name)
|
188
|
+
end
|
189
|
+
}
|
190
|
+
|
191
|
+
IO.foreach(@input_dir + File::SEPARATOR + 'zone.tab') {|line|
|
192
|
+
line = line.gsub(/#.*$/, '')
|
193
|
+
line = line.gsub(/\s+$/, '')
|
194
|
+
|
195
|
+
if line =~ /^([A-Z]{2})\s+([^\s]+)\s+([^\s]+)(\s+(.*))?$/
|
196
|
+
code = $1
|
197
|
+
zone_name = $3
|
198
|
+
|
199
|
+
country = @countries[code]
|
200
|
+
raise "Country not found: #{code}" if country.nil?
|
201
|
+
|
202
|
+
zone = @zones[zone_name]
|
203
|
+
raise "Zone not found: #{zone_name}" if zone.nil?
|
204
|
+
|
205
|
+
country.add_zone(zone)
|
206
|
+
end
|
207
|
+
}
|
208
|
+
end
|
209
|
+
|
210
|
+
# Writes a country index file.
|
211
|
+
def write_countries_index
|
212
|
+
dir = @output_dir + File::SEPARATOR + 'countries'
|
213
|
+
FileUtils.mkdir_p(dir)
|
214
|
+
|
215
|
+
File.open(dir + File::SEPARATOR + 'Index.rb', 'w') {|file|
|
216
|
+
file.puts('require \'tzinfo/country\'')
|
217
|
+
file.puts('module TZInfo')
|
218
|
+
file.puts('module Countries')
|
219
|
+
|
220
|
+
file.puts('class Index #:nodoc:')
|
221
|
+
|
222
|
+
file.puts('@@all_codes = [')
|
223
|
+
|
224
|
+
@countries.each_value {|country|
|
225
|
+
file.puts("'#{country.code.gsub(/'/, '\\\'')}',")
|
226
|
+
}
|
227
|
+
|
228
|
+
file.puts(']')
|
229
|
+
file.puts('@@all_codes.freeze')
|
230
|
+
|
231
|
+
file.puts('def self.all_codes')
|
232
|
+
file.puts(' @@all_codes')
|
233
|
+
file.puts('end')
|
234
|
+
|
235
|
+
file.puts('end') # end class
|
236
|
+
|
237
|
+
|
238
|
+
file.puts('end') # end module Countries
|
239
|
+
file.puts('end') # end module TZInfo
|
240
|
+
}
|
241
|
+
end
|
242
|
+
|
243
|
+
end
|
244
|
+
|
245
|
+
# Base class for all rule sets.
|
246
|
+
class TZDataRules
|
247
|
+
# Name of the rule set, e.g. EU.
|
248
|
+
attr_reader :name
|
249
|
+
|
250
|
+
def initialize(name)
|
251
|
+
@name = name
|
252
|
+
end
|
253
|
+
|
254
|
+
protected
|
255
|
+
# Writes a period of time with the same utc and std offsets to the file.
|
256
|
+
def write_period(file, utc_start, utc_end, period, std_offset, letter)
|
257
|
+
file.puts "add_period(TimezonePeriod.new(#{datetime_constructor(utc_start)},#{datetime_constructor(utc_end)},#{period.utc_offset.to_seconds},#{std_offset.to_seconds},#{quote_str(period.format.expand(std_offset, letter))}))"
|
258
|
+
puts "Period from #{utc_start} to #{utc_end}, utc_offset=#{period.utc_offset.to_seconds}, std_offset=#{std_offset.to_seconds}, name=#{period.format.expand(std_offset, letter)}"
|
259
|
+
end
|
260
|
+
|
261
|
+
private
|
262
|
+
def datetime_constructor(datetime)
|
263
|
+
if datetime.nil?
|
264
|
+
'nil'
|
265
|
+
else
|
266
|
+
"DateTime.new(#{datetime.year},#{datetime.mon},#{datetime.mday},#{datetime.hour},#{datetime.min},#{datetime.sec})"
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def quote_str(str)
|
271
|
+
"'#{str.gsub(/'/, '\\\'')}'"
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
# Empty rule set with a fixed daylight savings (std) offset.
|
276
|
+
class TZDataFixedOffsetRules < TZDataRules
|
277
|
+
attr_reader :offset
|
278
|
+
|
279
|
+
def initialize(offset)
|
280
|
+
super(offset.to_s)
|
281
|
+
@offset = offset
|
282
|
+
end
|
283
|
+
|
284
|
+
# Writes a single period to the file with the fixed offset. Returns the
|
285
|
+
# end of the period in UTC and the offset.
|
286
|
+
def write_class_periods(file, utc_start, period, last_utc_offset, std_offset)
|
287
|
+
result = period.valid_until.nil? ? nil :
|
288
|
+
period.valid_until.to_utc(period.utc_offset, @offset)
|
289
|
+
|
290
|
+
write_period(file, utc_start, result, period, @offset, nil)
|
291
|
+
|
292
|
+
[result, @offset]
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
# An empty set of rules.
|
297
|
+
class TZDataNoRules < TZDataRules
|
298
|
+
def initialize
|
299
|
+
super('-')
|
300
|
+
end
|
301
|
+
|
302
|
+
# Writes a single period to the file with a zero daylight savings offset.
|
303
|
+
def write_class_periods(file, utc_start, period, last_utc_offset, std_offset)
|
304
|
+
# no rules to apply, just take the end of the period and convert to
|
305
|
+
# utc according to the zone offset
|
306
|
+
|
307
|
+
result = period.valid_until.nil? ? nil :
|
308
|
+
period.valid_until.to_utc(period.utc_offset, TZDataOffset.zero)
|
309
|
+
|
310
|
+
write_period(file, utc_start, result, period, TZDataOffset.zero, nil)
|
311
|
+
|
312
|
+
[result, TZDataOffset.zero]
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
# A rule set (as defined by Rule name in the tz data).
|
317
|
+
class TZDataRuleSet < TZDataRules
|
318
|
+
attr_reader :rules
|
319
|
+
|
320
|
+
def initialize(name)
|
321
|
+
super
|
322
|
+
@rules = []
|
323
|
+
end
|
324
|
+
|
325
|
+
# Adds a new rule to the set.
|
326
|
+
def add_rule(rule)
|
327
|
+
@rules << rule
|
328
|
+
end
|
329
|
+
|
330
|
+
# Finds all the periods between utc_start and period.valid_until and writes
|
331
|
+
# them to file. Returns the end of the period and the final std_offset.
|
332
|
+
#
|
333
|
+
# This is where almost all the time is currently spent running the import.
|
334
|
+
def write_class_periods(file, utc_start, period, last_utc_offset, std_offset)
|
335
|
+
# search the rule space between utc_start and period.valid_until
|
336
|
+
# (both can be nil = unbounded)
|
337
|
+
# For simplicity treat unbounded ends as fixed dates. This is not too bad
|
338
|
+
# as there wasn't daylight savings before 1900 and the rules will change
|
339
|
+
# in the future.
|
340
|
+
|
341
|
+
# divide the time up into periods with the same std_offset
|
342
|
+
# need to keep finding the earliest rule after utc_start and before period.valid_until
|
343
|
+
#puts name
|
344
|
+
|
345
|
+
utc_current = utc_start.nil? ? DateTime.new(1850, 1, 1, 0, 0, 0) : utc_start
|
346
|
+
|
347
|
+
unbounded_end = period.valid_until.nil?
|
348
|
+
if unbounded_end
|
349
|
+
utc_end = DateTime.now + 14600
|
350
|
+
else
|
351
|
+
utc_end = period.valid_until.to_utc(period.utc_offset, std_offset)
|
352
|
+
end
|
353
|
+
|
354
|
+
#puts "utc_end: #{utc_end}"
|
355
|
+
|
356
|
+
first = true
|
357
|
+
letter = nil
|
358
|
+
|
359
|
+
if last_utc_offset != period.utc_offset
|
360
|
+
# change of offset
|
361
|
+
# need to check if there is a wallclock time transition right at the start
|
362
|
+
# of the period using the _last_ utc offset (see Asia/Qyzylorda Apr 1 1982)
|
363
|
+
|
364
|
+
#puts "checking last_utc_offset #{last_utc_offset.inspect}"
|
365
|
+
|
366
|
+
earliest = earliest_in_bounds(utc_current, utc_end, last_utc_offset, std_offset)
|
367
|
+
|
368
|
+
if !earliest.nil? && earliest[1] == utc_current
|
369
|
+
# found the transition
|
370
|
+
# no period to write here, just update the std_offset
|
371
|
+
rule = earliest[0]
|
372
|
+
std_offset = rule.save
|
373
|
+
letter = rule.letter
|
374
|
+
first = false
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
# Main loop. Repeatedly find earliest rule to apply.
|
379
|
+
while utc_current < utc_end
|
380
|
+
#puts "utc_current: #{utc_current}"
|
381
|
+
|
382
|
+
earliest = earliest_in_bounds(utc_current, utc_end, period.utc_offset, std_offset)
|
383
|
+
|
384
|
+
if earliest.nil?
|
385
|
+
#puts 'found no earliest rule'
|
386
|
+
write_period(file, utc_current, utc_end, period, std_offset, letter)
|
387
|
+
|
388
|
+
[utc_end, std_offset]
|
389
|
+
break
|
390
|
+
else
|
391
|
+
write_period(file, utc_current, earliest[1], period, std_offset, letter) if !first || earliest[1] > utc_current
|
392
|
+
|
393
|
+
raise 'Not moved forwards' if !first and earliest[1] <= utc_current
|
394
|
+
first = false if first
|
395
|
+
|
396
|
+
rule = earliest[0]
|
397
|
+
utc_current = earliest[1]
|
398
|
+
std_offset = rule.save
|
399
|
+
letter = rule.letter
|
400
|
+
|
401
|
+
if !unbounded_end
|
402
|
+
utc_end = period.valid_until.to_utc(period.utc_offset, std_offset)
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
[utc_end, std_offset]
|
408
|
+
end
|
409
|
+
|
410
|
+
# Finds the earliest rule that applies at of after utc_start and before
|
411
|
+
# utc_end that has a different std_offset to the current std_offset.
|
412
|
+
def earliest_in_bounds(utc_start, utc_end, utc_offset, std_offset)
|
413
|
+
earliest_utc = nil
|
414
|
+
earliest_rule = nil
|
415
|
+
@rules.each {|rule|
|
416
|
+
# only consider rules that change the offset
|
417
|
+
if rule.save.to_seconds != std_offset.to_seconds
|
418
|
+
test = rule.earliest_in_bounds(utc_start, utc_end, utc_offset, std_offset)
|
419
|
+
|
420
|
+
if !test.nil? && (earliest_utc.nil? || test < earliest_utc)
|
421
|
+
earliest_utc = test
|
422
|
+
earliest_rule = rule
|
423
|
+
end
|
424
|
+
end
|
425
|
+
}
|
426
|
+
|
427
|
+
if earliest_rule.nil?
|
428
|
+
nil
|
429
|
+
else
|
430
|
+
[earliest_rule, earliest_utc]
|
431
|
+
end
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
# A rule in a RuleSet (a single Rule line in the tz data).
|
436
|
+
class TZDataRule
|
437
|
+
attr_reader :from
|
438
|
+
attr_reader :to
|
439
|
+
attr_reader :type
|
440
|
+
attr_reader :in_month
|
441
|
+
attr_reader :on_day
|
442
|
+
attr_reader :at_time
|
443
|
+
attr_reader :save
|
444
|
+
attr_reader :letter
|
445
|
+
|
446
|
+
def initialize(from, to, type, in_month, on_day, at_time, save, letter)
|
447
|
+
@from = parse_from(from)
|
448
|
+
@to = parse_to(to)
|
449
|
+
|
450
|
+
# get rid of to only
|
451
|
+
raise 'to cannot be only if from is minimum' if @to == :only && @from == :min
|
452
|
+
@to = @from if @to == :only
|
453
|
+
|
454
|
+
@type = parse_type(type)
|
455
|
+
@in_month = TZDataParser.parse_month(in_month)
|
456
|
+
@on_day = TZDataDayOfMonth.new(on_day)
|
457
|
+
@at_time = TZDataTime.new(at_time)
|
458
|
+
@save = TZDataOffset.new(save)
|
459
|
+
@letter = parse_letter(letter)
|
460
|
+
end
|
461
|
+
|
462
|
+
# Gets the earliest UTC time this rule can be applied that is greater than
|
463
|
+
# or equal to utc_start and before utc_end.
|
464
|
+
def earliest_in_bounds(utc_start, utc_end, utc_offset, std_offset)
|
465
|
+
earliest = earliest_start_date(utc_start, utc_offset, std_offset)
|
466
|
+
if !earliest.nil? && earliest < utc_end
|
467
|
+
earliest
|
468
|
+
else
|
469
|
+
nil
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
# Gets the earliest UTC time this rule can be applied that is greater than
|
474
|
+
# or equal to utc_start.
|
475
|
+
def earliest_start_date(utc_now, utc_offset, std_offset)
|
476
|
+
#puts "testing rule #{@from}-#{@to}"
|
477
|
+
|
478
|
+
# convert the utc definition to whatever reference this rule is in terms of
|
479
|
+
|
480
|
+
if @at_time.ref == :standard
|
481
|
+
rule_now = utc_now + Rational(utc_offset.to_seconds, 86400)
|
482
|
+
#puts "converted utc to standard: #{rule_now}"
|
483
|
+
elsif @at_time.ref == :wall_clock
|
484
|
+
rule_now = utc_now + Rational(utc_offset.to_seconds + std_offset.to_seconds, 86400)
|
485
|
+
#puts "converted utc to wall clock: #{rule_now}"
|
486
|
+
else
|
487
|
+
rule_now = utc_now
|
488
|
+
end
|
489
|
+
|
490
|
+
if @to == :max || @to >= rule_now.year
|
491
|
+
|
492
|
+
next_year = false
|
493
|
+
|
494
|
+
if @in_month > rule_now.mon
|
495
|
+
#puts 'month greater'
|
496
|
+
elsif @in_month < rule_now.mon
|
497
|
+
#puts 'month less'
|
498
|
+
next_year = true
|
499
|
+
else
|
500
|
+
# work out the complete time as this may move the day back/forward
|
501
|
+
abs_day = @on_day.to_absolute(rule_now.year, @in_month)
|
502
|
+
#puts "months equal #{abs_day}"
|
503
|
+
|
504
|
+
if abs_day > rule_now.mday
|
505
|
+
elsif abs_day < rule_now.mday
|
506
|
+
next_year = true
|
507
|
+
else
|
508
|
+
if @at_time.hour > rule_now.hour
|
509
|
+
elsif @at_time.hour < rule_now.hour
|
510
|
+
else
|
511
|
+
if @at_time.minute > rule_now.min
|
512
|
+
elsif @at_time.minute < rule_now.min
|
513
|
+
next_year = true
|
514
|
+
else
|
515
|
+
if @at_time.second >= rule_now.sec
|
516
|
+
else
|
517
|
+
next_year = true
|
518
|
+
end
|
519
|
+
end
|
520
|
+
end
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
if @from == :min
|
525
|
+
year = rule_now.year
|
526
|
+
else
|
527
|
+
if @from > rule_now.year
|
528
|
+
year = @from
|
529
|
+
else
|
530
|
+
year = rule_now.year
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
if next_year && year == rule_now.year
|
535
|
+
year = year + 1
|
536
|
+
end
|
537
|
+
|
538
|
+
if @to == :max || @to >= year
|
539
|
+
@at_time.to_utc(utc_offset, std_offset, year, @in_month, @on_day.to_absolute(year, @in_month))
|
540
|
+
else
|
541
|
+
nil
|
542
|
+
end
|
543
|
+
else
|
544
|
+
nil
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
private
|
549
|
+
def parse_from(from)
|
550
|
+
lower = from.downcase
|
551
|
+
if lower =~ /^min/
|
552
|
+
:min
|
553
|
+
elsif lower =~ /^[0-9]+$/
|
554
|
+
lower.to_i
|
555
|
+
else
|
556
|
+
raise "Invalid from: #{from}"
|
557
|
+
end
|
558
|
+
end
|
559
|
+
|
560
|
+
def parse_to(to)
|
561
|
+
lower = to.downcase
|
562
|
+
if lower =~ /^max/
|
563
|
+
:max
|
564
|
+
elsif lower =~ /^o/
|
565
|
+
:only
|
566
|
+
elsif lower =~ /^[0-9]+$/
|
567
|
+
lower.to_i
|
568
|
+
else
|
569
|
+
raise "Invalid to: #{to}"
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
def parse_type(type)
|
574
|
+
raise "Unsupported rule type: #{type}" if type != '-'
|
575
|
+
nil
|
576
|
+
end
|
577
|
+
|
578
|
+
def parse_letter(letter)
|
579
|
+
if letter == '-'
|
580
|
+
nil
|
581
|
+
else
|
582
|
+
letter
|
583
|
+
end
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
# Base class for Zones and Links.
|
588
|
+
class TZDataDefinition
|
589
|
+
attr_reader :name
|
590
|
+
attr_reader :name_for_class
|
591
|
+
|
592
|
+
def initialize(name)
|
593
|
+
@name = name
|
594
|
+
|
595
|
+
# + and - aren't allowed in class names
|
596
|
+
@name_for_class = name.gsub(/-/, '__m__').gsub(/\+/, '__p__')
|
597
|
+
end
|
598
|
+
|
599
|
+
# Creates necessary directories, the file, writes the class header and footer
|
600
|
+
# and yields to a block to write the content.
|
601
|
+
def create_file(output_dir)
|
602
|
+
modules = @name_for_class.split(/\//)
|
603
|
+
class_name = modules.pop
|
604
|
+
dir = output_dir + File::SEPARATOR + 'definitions' + File::SEPARATOR + modules.join(File::SEPARATOR)
|
605
|
+
FileUtils.mkdir_p(dir)
|
606
|
+
|
607
|
+
File.open(output_dir + File::SEPARATOR + 'definitions' + File::SEPARATOR + @name_for_class.gsub(/\//, File::SEPARATOR) + '.rb', 'w') {|file|
|
608
|
+
write_requires(file)
|
609
|
+
file.puts('module TZInfo')
|
610
|
+
file.puts('module Definitions #:nodoc:')
|
611
|
+
modules.each do |part|
|
612
|
+
file.puts("module #{part} #:nodoc:")
|
613
|
+
end
|
614
|
+
|
615
|
+
file.puts("class #{class_name} < #{superclass} #:nodoc:")
|
616
|
+
|
617
|
+
yield file
|
618
|
+
|
619
|
+
file.puts('@@instance = new')
|
620
|
+
file.puts('def self.instance')
|
621
|
+
file.puts(' @@instance')
|
622
|
+
file.puts('end')
|
623
|
+
|
624
|
+
file.puts('end') # end class
|
625
|
+
|
626
|
+
modules.each do
|
627
|
+
file.puts('end')
|
628
|
+
end
|
629
|
+
file.puts('end') # end module Definitions
|
630
|
+
file.puts('end') # end module TZInfo
|
631
|
+
}
|
632
|
+
end
|
633
|
+
|
634
|
+
# Called to write any requires into the file. Called by create_file.
|
635
|
+
def write_requires(file)
|
636
|
+
file.puts('require \'tzinfo/timezone\'')
|
637
|
+
end
|
638
|
+
end
|
639
|
+
|
640
|
+
# A tz data Link.
|
641
|
+
class TZDataLink < TZDataDefinition
|
642
|
+
attr_reader :link_to
|
643
|
+
|
644
|
+
def initialize(name, link_to)
|
645
|
+
super(name)
|
646
|
+
@link_to = link_to
|
647
|
+
end
|
648
|
+
|
649
|
+
# Called to write any requires into the file. Called by create_file.
|
650
|
+
def write_requires(file)
|
651
|
+
super
|
652
|
+
file.puts("require 'tzinfo/definitions/#{link_to.name_for_class}'")
|
653
|
+
end
|
654
|
+
|
655
|
+
# Superclass of this class (the class we are linking to).
|
656
|
+
def superclass
|
657
|
+
'Definitions::' + link_to.name_for_class.gsub(/\//, '::')
|
658
|
+
end
|
659
|
+
|
660
|
+
# Writes a class for this link.
|
661
|
+
def write_class(output_dir)
|
662
|
+
puts "writing link #{name}"
|
663
|
+
|
664
|
+
create_file(output_dir) {|file|
|
665
|
+
}
|
666
|
+
end
|
667
|
+
end
|
668
|
+
|
669
|
+
# A tz data Zone. Each line from the tz data is loaded as a TZDataPeriod.
|
670
|
+
class TZDataZone < TZDataDefinition
|
671
|
+
attr_reader :periods
|
672
|
+
|
673
|
+
def initialize(name)
|
674
|
+
super
|
675
|
+
@periods = []
|
676
|
+
end
|
677
|
+
|
678
|
+
def add_period(period)
|
679
|
+
@periods << period
|
680
|
+
end
|
681
|
+
|
682
|
+
# Superclass is a Timezone. Called by create_file.
|
683
|
+
def superclass
|
684
|
+
'Timezone'
|
685
|
+
end
|
686
|
+
|
687
|
+
# Writes the class for the zone. Iterates all the periods and asks them
|
688
|
+
# to write all periods in the timezone.
|
689
|
+
def write_class(output_dir)
|
690
|
+
puts "writing zone #{name}"
|
691
|
+
|
692
|
+
create_file(output_dir) {|file|
|
693
|
+
|
694
|
+
file.puts('def initialize')
|
695
|
+
file.puts(' super')
|
696
|
+
file.puts("set_identifier('#{@name.gsub(/'/, '\\\'')}')")
|
697
|
+
|
698
|
+
utc_start = nil
|
699
|
+
std_offset = TZDataOffset.zero
|
700
|
+
last_utc_offset = nil
|
701
|
+
|
702
|
+
@periods.each {|period|
|
703
|
+
last_utc_offset = period.utc_offset if last_utc_offset.nil?
|
704
|
+
result = period.write_class_periods(file, utc_start, last_utc_offset, std_offset)
|
705
|
+
utc_start = result[0]
|
706
|
+
std_offset = result[1]
|
707
|
+
last_utc_offset = period.utc_offset
|
708
|
+
}
|
709
|
+
|
710
|
+
file.puts('end')
|
711
|
+
}
|
712
|
+
end
|
713
|
+
end
|
714
|
+
|
715
|
+
# A period within a zone.
|
716
|
+
class TZDataPeriod
|
717
|
+
attr_reader :utc_offset
|
718
|
+
attr_reader :rule_set
|
719
|
+
attr_reader :format
|
720
|
+
attr_reader :valid_until
|
721
|
+
|
722
|
+
def initialize(utc_offset, rule_set, format, valid_until)
|
723
|
+
@utc_offset = TZDataOffset.new(utc_offset)
|
724
|
+
@rule_set = rule_set
|
725
|
+
@format = TZDataFormat.new(format)
|
726
|
+
@valid_until = valid_until.nil? ? nil : TZDataUntil.new(valid_until)
|
727
|
+
end
|
728
|
+
|
729
|
+
# Writes the definition of this period to the file. Calls the rule_set to
|
730
|
+
# do this.
|
731
|
+
def write_class_periods(file, utc_start, last_utc_offset, std_offset)
|
732
|
+
@rule_set.write_class_periods(file, utc_start, self, last_utc_offset, std_offset)
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
# A tz data time definition - an hour, minute, second and reference. Reference
|
737
|
+
# is either :utc, :standard or :wall_clock.
|
738
|
+
class TZDataTime
|
739
|
+
attr_reader :hour
|
740
|
+
attr_reader :minute
|
741
|
+
attr_reader :second
|
742
|
+
attr_reader :ref
|
743
|
+
|
744
|
+
def initialize(spec)
|
745
|
+
raise "Invalid time: #{spec}" if spec !~ /^([0-9]+)(:([0-9]+)(:([0-9]+))?)?([wguzs])?$/
|
746
|
+
|
747
|
+
@hour = $1.to_i
|
748
|
+
@minute = $3.nil? ? 0 : $3.to_i
|
749
|
+
@second = $5.nil? ? 0 : $5.to_i
|
750
|
+
|
751
|
+
if $6 == 's'
|
752
|
+
@ref = :standard
|
753
|
+
elsif $6 == 'g' || $6 == 'u' || $6 == 'z'
|
754
|
+
@ref = :utc
|
755
|
+
else
|
756
|
+
@ref = :wall_clock
|
757
|
+
end
|
758
|
+
end
|
759
|
+
|
760
|
+
# Converts the time to UTC given a utc_offset and std_offset.
|
761
|
+
def to_utc(utc_offset, std_offset, year, month, day)
|
762
|
+
result = DateTime.new(year, month, day, @hour, @minute, @second)
|
763
|
+
offset = 0
|
764
|
+
offset = offset + utc_offset.to_seconds if @ref == :standard || @ref == :wall_clock
|
765
|
+
offset = offset + std_offset.to_seconds if @ref == :wall_clock
|
766
|
+
result - Rational(offset, 86400)
|
767
|
+
end
|
768
|
+
end
|
769
|
+
|
770
|
+
# A tz data offset.
|
771
|
+
class TZDataOffset
|
772
|
+
attr_reader :hour
|
773
|
+
attr_reader :minute
|
774
|
+
attr_reader :second
|
775
|
+
|
776
|
+
def initialize(spec)
|
777
|
+
raise "Invalid time: #{spec}" if spec !~ /^(-)?([0-9]+)(:([0-9]+)(:([0-9]+))?)?$/
|
778
|
+
|
779
|
+
@negative = !$1.nil?
|
780
|
+
@hour = $2.to_i
|
781
|
+
@minute = $4.nil? ? 0 : $4.to_i
|
782
|
+
@second = $6.nil? ? 0 : $6.to_i
|
783
|
+
end
|
784
|
+
|
785
|
+
@@zero = TZDataOffset.new('0')
|
786
|
+
|
787
|
+
# A TZDataOffset representing 0.
|
788
|
+
def self.zero
|
789
|
+
@@zero
|
790
|
+
end
|
791
|
+
|
792
|
+
def negative?
|
793
|
+
@negative
|
794
|
+
end
|
795
|
+
|
796
|
+
def to_s
|
797
|
+
"#{@negative ? '-' : ''}#{@hour}:#{@minute}:#{@second}"
|
798
|
+
end
|
799
|
+
|
800
|
+
# Converts the offset to seconds.
|
801
|
+
def to_seconds
|
802
|
+
result = @hour
|
803
|
+
result = result * 60
|
804
|
+
result = result + @minute
|
805
|
+
result = result * 60
|
806
|
+
result = result + @second
|
807
|
+
result = -result if @negative
|
808
|
+
result
|
809
|
+
end
|
810
|
+
end
|
811
|
+
|
812
|
+
# A tz data day of the month reference. Can either be an absolute day,
|
813
|
+
# a last week day or a week day >= or <= than a specific day of month.
|
814
|
+
class TZDataDayOfMonth
|
815
|
+
attr_reader :type
|
816
|
+
attr_reader :day_of_month
|
817
|
+
attr_reader :day_of_week
|
818
|
+
attr_reader :operator
|
819
|
+
|
820
|
+
def initialize(spec)
|
821
|
+
raise "Invalid on: #{spec}" if spec !~ /^([0-9]+)|(last([A-z]+))|(([A-z]+)([<>]=)([0-9]+))$/
|
822
|
+
|
823
|
+
if $1
|
824
|
+
@type = :absolute
|
825
|
+
@day_of_month = $1.to_i
|
826
|
+
elsif $3
|
827
|
+
@type = :last
|
828
|
+
@day_of_week = parse_day_of_week($3)
|
829
|
+
else
|
830
|
+
@type = :comparison
|
831
|
+
@day_of_week = parse_day_of_week($5)
|
832
|
+
@operator = parse_operator($6)
|
833
|
+
@day_of_month = $7.to_i
|
834
|
+
end
|
835
|
+
end
|
836
|
+
|
837
|
+
# Returns the absolute day of month for the given year and month.
|
838
|
+
def to_absolute(year, month)
|
839
|
+
case
|
840
|
+
when @type == :last:
|
841
|
+
last_day_in_month = (Date.new(year, month, 1) >> 1) - 1
|
842
|
+
offset = last_day_in_month.wday - @day_of_week
|
843
|
+
offset = offset + 7 if offset < 0
|
844
|
+
(last_day_in_month - offset).day
|
845
|
+
when @type == :comparison:
|
846
|
+
pivot = Date.new(year, month, @day_of_month)
|
847
|
+
offset = @day_of_week - pivot.wday
|
848
|
+
offset = -offset if @operator == :less_equal
|
849
|
+
offset = offset + 7 if offset < 0
|
850
|
+
offset = -offset if @operator == :less_equal
|
851
|
+
result = pivot + offset
|
852
|
+
raise 'No suitable date found' if result.month != pivot.month
|
853
|
+
result.day
|
854
|
+
else #absolute
|
855
|
+
@day_of_month
|
856
|
+
end
|
857
|
+
end
|
858
|
+
|
859
|
+
private
|
860
|
+
def parse_day_of_week(day_of_week)
|
861
|
+
lower = day_of_week.downcase
|
862
|
+
if lower =~ /^mon/
|
863
|
+
1
|
864
|
+
elsif lower =~ /^tue/
|
865
|
+
2
|
866
|
+
elsif lower =~ /^wed/
|
867
|
+
3
|
868
|
+
elsif lower =~ /^thu/
|
869
|
+
4
|
870
|
+
elsif lower =~ /^fri/
|
871
|
+
5
|
872
|
+
elsif lower =~ /^sat/
|
873
|
+
6
|
874
|
+
elsif lower =~ /^sun/
|
875
|
+
0
|
876
|
+
else
|
877
|
+
raise "Invalid day of week: #{day_of_week}"
|
878
|
+
end
|
879
|
+
end
|
880
|
+
|
881
|
+
def parse_operator(operator)
|
882
|
+
if operator == '>='
|
883
|
+
:greater_equal
|
884
|
+
elsif operator == '<='
|
885
|
+
:less_equal
|
886
|
+
else
|
887
|
+
raise "Invalid operator: #{operator}"
|
888
|
+
end
|
889
|
+
end
|
890
|
+
end
|
891
|
+
|
892
|
+
# A tz data Zone until reference.
|
893
|
+
class TZDataUntil
|
894
|
+
def initialize(spec)
|
895
|
+
parts = spec.split(/\s+/)
|
896
|
+
raise "Invalid until: #{spec}" if parts.length < 1
|
897
|
+
|
898
|
+
@year = parts[0].to_i
|
899
|
+
@month = parts.length > 1 ? TZDataParser.parse_month(parts[1]) : 1
|
900
|
+
@day = TZDataDayOfMonth.new(parts.length > 2 ? parts[2] : '1')
|
901
|
+
@time = TZDataTime.new(parts.length > 3 ? parts[3] : '00:00')
|
902
|
+
end
|
903
|
+
|
904
|
+
# Converts the reference to a UTC DateTime.
|
905
|
+
def to_utc(utc_offset, std_offset)
|
906
|
+
@time.to_utc(utc_offset, std_offset, @year, @month, @day.to_absolute(@year, @month))
|
907
|
+
end
|
908
|
+
end
|
909
|
+
|
910
|
+
# A tz data Zone format string. Either alternate standard/daylight-savings
|
911
|
+
# or substitution (%s) format.
|
912
|
+
class TZDataFormat
|
913
|
+
def initialize(spec)
|
914
|
+
if spec =~ /([A-z]+)\/([A-z]+)/
|
915
|
+
@type = :alternate
|
916
|
+
@standard_abbrev = $1
|
917
|
+
@daylight_abbrev = $2
|
918
|
+
else
|
919
|
+
@type = :subst
|
920
|
+
@abbrev = spec
|
921
|
+
end
|
922
|
+
end
|
923
|
+
|
924
|
+
# Expands given the current daylight savings offset and Rule string.
|
925
|
+
def expand(std_offset, rule_string)
|
926
|
+
if @type == :alternate
|
927
|
+
if std_offset.to_seconds == 0
|
928
|
+
@standard_abbrev
|
929
|
+
else
|
930
|
+
@daylight_abbrev
|
931
|
+
end
|
932
|
+
else
|
933
|
+
sprintf(@abbrev, rule_string)
|
934
|
+
end
|
935
|
+
end
|
936
|
+
end
|
937
|
+
|
938
|
+
# An ISO 3166 country.
|
939
|
+
class TZDataCountry
|
940
|
+
attr_reader :code
|
941
|
+
attr_reader :name
|
942
|
+
attr_reader :zones
|
943
|
+
|
944
|
+
def initialize(code, name)
|
945
|
+
@code = code
|
946
|
+
@name = name
|
947
|
+
@zones = {}
|
948
|
+
end
|
949
|
+
|
950
|
+
def add_zone(zone)
|
951
|
+
@zones[zone.name] = zone
|
952
|
+
end
|
953
|
+
|
954
|
+
def write_class(output_dir)
|
955
|
+
dir = output_dir + File::SEPARATOR + 'countries'
|
956
|
+
FileUtils.mkdir_p(dir)
|
957
|
+
|
958
|
+
File.open(dir + File::SEPARATOR + @code + '.rb', 'w') {|file|
|
959
|
+
file.puts('require \'tzinfo/country\'')
|
960
|
+
file.puts('module TZInfo #:nodoc:')
|
961
|
+
file.puts('module Countries #:nodoc:')
|
962
|
+
|
963
|
+
file.puts("class #{@code} < Country #:nodoc:")
|
964
|
+
|
965
|
+
file.puts('def initialize')
|
966
|
+
file.puts(' super')
|
967
|
+
file.puts(" set_code('#{code.gsub(/'/, '\\\'')}')")
|
968
|
+
file.puts(" set_name('#{name.gsub(/'/, '\\\'')}')")
|
969
|
+
|
970
|
+
@zones.each_value {|zone|
|
971
|
+
file.puts(" add_zone('#{zone.name.gsub(/'/, '\\\'')}')")
|
972
|
+
}
|
973
|
+
|
974
|
+
file.puts(' zones_added')
|
975
|
+
|
976
|
+
file.puts('end')
|
977
|
+
|
978
|
+
file.puts('@@instance = new')
|
979
|
+
file.puts('def self.instance')
|
980
|
+
file.puts(' @@instance')
|
981
|
+
file.puts('end')
|
982
|
+
|
983
|
+
file.puts('end') # end class
|
984
|
+
|
985
|
+
|
986
|
+
file.puts('end') # end module Countries
|
987
|
+
file.puts('end') # end module TZInfo
|
988
|
+
}
|
989
|
+
end
|
990
|
+
end
|
991
|
+
end
|