initial commit

This commit is contained in:
Dmitry Melnikov 2010-08-23 16:17:16 +04:00
commit 92325b766a
5 changed files with 707 additions and 0 deletions

1
Emakefile Executable file
View file

@ -0,0 +1 @@
{'src/*', [{d, 'EUNIT'}, debug_info, {i, "./include"}, {outdir, 'ebin'}]}.

3
Makefile Executable file
View file

@ -0,0 +1,3 @@
all:
mkdir -p ebin
erl -make

402
include/tz_database.hrl Executable file
View file

@ -0,0 +1,402 @@
%% Copyright (C) 07/01/2010 Dmitry S. Melnikov (dmitryme@gmail.com)
%%
%% This program is free software; you can redistribute it and/or
%% modify it under the terms of the GNU General Public License
%% as published by the Free Software Foundation; either version 2
%% of the License, or (at your option) any later version.
%%
%% This program is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%% GNU General Public License for more details.
%%
%% You should have received a copy of the GNU General Public License
%% along with this program; if not, write to the Free Software
%% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-author("Dmitry Melnikov <dmitryme@gmail.com>").
-define(tz_database,
[
{"Africa/Abidjan",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Accra",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Addis_Ababa",{"EAT","EAT"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Algiers",{"CET","CET"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Asmera",{"EAT","EAT"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Bamako",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Bangui",{"WAT","WAT"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Banjul",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Bissau",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Blantyre",{"CAT","CAT"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Brazzaville",{"WAT","WAT"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Bujumbura",{"CAT","CAT"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Cairo",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,fri,apr},{0,0},{last,fri,sep},{0,0}},
{"Africa/Casablanca",{"WET","WET"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Ceuta",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Africa/Conakry",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Dakar",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Dar_es_Salaam",{"EAT","EAT"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Djibouti",{"EAT","EAT"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Douala",{"WAT","WAT"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/El_Aaiun",{"WET","WET"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Freetown",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Gaborone",{"CAT","CAT"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Harare",{"CAT","CAT"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Johannesburg",{"SAST","SAST"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Kampala",{"EAT","EAT"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Khartoum",{"EAT","EAT"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Kigali",{"CAT","CAT"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Kinshasa",{"WAT","WAT"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Lagos",{"WAT","WAT"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Libreville",{"WAT","WAT"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Lome",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Luanda",{"WAT","WAT"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Lubumbashi",{"CAT","CAT"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Lusaka",{"CAT","CAT"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Malabo",{"WAT","WAT"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Maputo",{"CAT","CAT"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Maseru",{"SAST","SAST"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Mbabane",{"SAST","SAST"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Mogadishu",{"EAT","EAT"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Monrovia",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Nairobi",{"EAT","EAT"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Ndjamena",{"WAT","WAT"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Niamey",{"WAT","WAT"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Nouakchott",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Ouagadougou",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Porto-Novo",{"WAT","WAT"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Sao_Tome",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Timbuktu",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Tripoli",{"EET","EET"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Tunis",{"CET","CET"},undef,{1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Africa/Windhoek",{"WAT","WAT"},{"WAST","WAST"},{1,0},{1,0},{1,sun,sep},{2,0},{1,sun,apr},{2,0}},
{"America/Adak",{"HAST","HAST"},{"HADT","HADT"},{-10,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Anchorage",{"AKST","AKST"},{"AKDT","AKDT"},{-9,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Anguilla",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Antigua",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Araguaina",{"BRT","BRT"},{"BRST","BRST"},{-3,0},{1,0},{2,sun,oct},{0,0},{3,sun,feb},{0,0}},
{"America/Aruba",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Asuncion",{"PYT","PYT"},{"PYST","PYST"},{-4,0},{1,0},{1,sun,oct},{0,0},{1,sun,mar},{0,0}},
{"America/Barbados",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Belem",{"BRT","BRT"},undef,{-3,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Belize",{"CST","CST"},undef,{-6,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Boa_Vista",{"AMT","AMT"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Bogota",{"COT","COT"},undef,{-5,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Boise",{"MST","MST"},{"MDT","MDT"},{-7,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Buenos_Aires",{"ART","ART"},undef,{-3,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Cambridge_Bay",{"MST","MST"},{"MDT","MDT"},{-7,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Cancun",{"CST","CST"},{"CDT","CDT"},{-6,0},{1,0},{1,sun,apr},{2,0},{last,sun,oct},{2,0}},
{"America/Caracas",{"VET","VET"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Catamarca",{"ART","ART"},undef,{-3,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Cayenne",{"GFT","GFT"},undef,{-3,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Cayman",{"EST","EST"},undef,{-5,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Chicago",{"CST","Central Standard Time"},{"CDT","Central Daylight Time"},{-6,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Chihuahua",{"MST","MST"},{"MDT","MDT"},{-7,0},{1,0},{1,sun,apr},{2,0},{last,sun,oct},{2,0}},
{"America/Cordoba",{"ART","ART"},undef,{-3,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Costa_Rica",{"CST","CST"},undef,{-6,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Cuiaba",{"AMT","AMT"},{"AMST","AMST"},{-4,0},{1,0},{2,sun,oct},{0,0},{3,sun,feb},{0,0}},
{"America/Curacao",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Danmarkshavn",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Dawson",{"PST","PST"},{"PDT","PDT"},{-8,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Dawson_Creek",{"MST","MST"},undef,{-7,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Denver",{"MST","Mountain Standard Time"},{"MDT","Mountain Daylight Time"},{-7,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Detroit",{"EST","EST"},{"EDT","EDT"},{-5,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Dominica",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Edmonton",{"MST","MST"},{"MDT","MDT"},{-7,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Eirunepe",{"ACT","ACT"},undef,{-5,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/El_Salvador",{"CST","CST"},undef,{-6,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Fortaleza",{"BRT","BRT"},{"BRST","BRST"},{-3,0},{1,0},{2,sun,oct},{0,0},{3,sun,feb},{0,0}},
{"America/Glace_Bay",{"AST","AST"},{"ADT","ADT"},{-4,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Godthab",{"WGT","WGT"},{"WGST","WGST"},{-3,0},{1,0},{last,sat,mar},{22,0},{last,sat,oct},{23,0}},
{"America/Goose_Bay",{"AST","AST"},{"ADT","ADT"},{-4,0},{1,0},{1,sun,apr},{0,1},{last,sun,oct},{0,1}},
{"America/Grand_Turk",{"EST","EST"},{"EDT","EDT"},{-5,0},{1,0},{1,sun,apr},{0,0},{last,sun,oct},{0,0}},
{"America/Grenada",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Guadeloupe",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Guatemala",{"CST","CST"},undef,{-6,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Guayaquil",{"ECT","ECT"},undef,{-5,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Guyana",{"GYT","GYT"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Halifax",{"AST","AST"},{"ADT","ADT"},{-4,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Havana",{"CST","CST"},{"CDT","CDT"},{-5,0},{1,0},{1,sun,apr},{0,0},{last,sun,oct},{1,0}},
{"America/Hermosillo",{"MST","MST"},undef,{-7,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Indiana/Indianapolis",{"EST","EST"},undef,{-5,0},{0,0},{2,sun,mar},{0,0},{1,sun,nov},{0,0}},
{"America/Indiana/Knox",{"EST","EST"},undef,{-5,0},{0,0},{2,sun,mar},{0,0},{1,sun,nov},{0,0}},
{"America/Indiana/Marengo",{"EST","EST"},undef,{-5,0},{0,0},{2,sun,mar},{0,0},{1,sun,nov},{0,0}},
{"America/Indiana/Vevay",{"EST","EST"},undef,{-5,0},{0,0},{2,sun,mar},{0,0},{1,sun,nov},{0,0}},
{"America/Indianapolis",{"EST","EST"},undef,{-5,0},{0,0},{2,sun,mar},{0,0},{1,sun,nov},{0,0}},
{"America/Inuvik",{"MST","MST"},{"MDT","MDT"},{-7,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Iqaluit",{"EST","EST"},{"EDT","EDT"},{-5,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Jamaica",{"EST","EST"},undef,{-5,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Jujuy",{"ART","ART"},undef,{-3,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Juneau",{"AKST","AKST"},{"AKDT","AKDT"},{-9,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Kentucky/Louisville",{"EST","EST"},{"EDT","EDT"},{-5,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Kentucky/Monticello",{"EST","EST"},{"EDT","EDT"},{-5,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/La_Paz",{"BOT","BOT"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Lima",{"PET","PET"},undef,{-5,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Los_Angeles",{"PST","Pacific Standard Time"},{"PDT","Pacific Daylight Time"},{-8,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Louisville",{"EST","EST"},{"EDT","EDT"},{-5,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Maceio",{"BRT","BRT"},{"BRST","BRST"},{-3,0},{1,0},{2,sun,oct},{0,0},{3,sun,feb},{0,0}},
{"America/Managua",{"CST","CST"},undef,{-6,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Manaus",{"AMT","AMT"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Martinique",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Mazatlan",{"MST","MST"},{"MDT","MDT"},{-7,0},{1,0},{1,sun,apr},{2,0},{last,sun,oct},{2,0}},
{"America/Mendoza",{"ART","ART"},undef,{-3,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Menominee",{"CST","CST"},{"CDT","CDT"},{-6,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Merida",{"CST","CST"},{"CDT","CDT"},{-6,0},{1,0},{1,sun,apr},{2,0},{last,sun,oct},{2,0}},
{"America/Mexico_City",{"CST","CST"},{"CDT","CDT"},{-6,0},{1,0},{1,sun,apr},{2,0},{last,sun,oct},{2,0}},
{"America/Miquelon",{"PMST","PMST"},{"PMDT","PMDT"},{-3,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Monterrey",{"CST","CST"},{"CDT","CDT"},{-6,0},{1,0},{1,sun,apr},{2,0},{last,sun,oct},{2,0}},
{"America/Montevideo",{"UYT","UYT"},undef,{-3,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Montreal",{"EST","EST"},{"EDT","EDT"},{-5,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Montserrat",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Nassau",{"EST","EST"},{"EDT","EDT"},{-5,0},{1,0},{1,sun,apr},{2,0},{last,sun,oct},{2,0}},
{"America/New_York",{"EST","Eastern Standard Time"},{"EDT","Eastern Daylight Time"},{-5,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Nipigon",{"EST","EST"},{"EDT","EDT"},{-5,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Nome",{"AKST","AKST"},{"AKDT","AKDT"},{-9,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Noronha",{"FNT","FNT"},undef,{-2,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/North_Dakota/Center",{"CST","CST"},{"CDT","CDT"},{-6,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Panama",{"EST","EST"},undef,{-5,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Pangnirtung",{"EST","EST"},{"EDT","EDT"},{-5,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Paramaribo",{"SRT","SRT"},undef,{-3,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Phoenix",{"MST","Mountain Standard Time"},undef,{-7,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Port-au-Prince",{"EST","EST"},undef,{-5,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Port_of_Spain",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Porto_Velho",{"AMT","AMT"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Puerto_Rico",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Rainy_River",{"CST","CST"},{"CDT","CDT"},{-6,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Rankin_Inlet",{"CST","CST"},{"CDT","CDT"},{-6,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Recife",{"BRT","BRT"},{"BRST","BRST"},{-3,0},{1,0},{2,sun,oct},{0,0},{3,sun,feb},{0,0}},
{"America/Regina",{"CST","CST"},undef,{-6,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Rio_Branco",{"ACT","ACT"},undef,{-5,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Rosario",{"ART","ART"},undef,{-3,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Santiago",{"CLT","CLT"},{"CLST","CLST"},{-4,0},{1,0},{2,sun,oct},{0,0},{2,sun,mar},{0,0}},
{"America/Santo_Domingo",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Sao_Paulo",{"BRT","BRT"},{"BRST","BRST"},{-3,0},{1,0},{2,sun,oct},{0,0},{3,sun,feb},{0,0}},
{"America/Scoresbysund",{"EGT","EGT"},{"EGST","EGST"},{-1,0},{1,0},{last,sun,mar},{0,0},{last,sun,oct},{1,0}},
{"America/Shiprock",{"MST","MST"},{"MDT","MDT"},{-7,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/St_Johns",{"NST","NST"},{"NDT","NDT"},{-3,30},{1,0},{1,sun,apr},{0,1},{last,sun,oct},{0,1}},
{"America/St_Kitts",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/St_Lucia",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/St_Thomas",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/St_Vincent",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Swift_Current",{"CST","CST"},undef,{-6,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Tegucigalpa",{"CST","CST"},undef,{-6,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Thule",{"AST","AST"},undef,{-4,0},{0,0},{2,sun,mar},{0,0},{1,sun,nov},{0,0}},
{"America/Thunder_Bay",{"EST","EST"},{"EDT","EDT"},{-5,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Tijuana",{"PST","PST"},{"PDT","PDT"},{-8,0},{1,0},{1,sun,apr},{2,0},{last,sun,oct},{2,0}},
{"America/Tortola",{"AST","AST"},undef,{-4,0},{0,0},undef,{0,0},undef,{0,0}},
{"America/Vancouver",{"PST","PST"},{"PDT","PDT"},{-8,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Whitehorse",{"PST","PST"},{"PDT","PDT"},{-8,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Winnipeg",{"CST","CST"},{"CDT","CDT"},{-6,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{3,0}},
{"America/Yakutat",{"AKST","AKST"},{"AKDT","AKDT"},{-9,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"America/Yellowknife",{"MST","MST"},{"MDT","MDT"},{-7,0},{1,0},{2,sun,mar},{2,0},{1,sun,nov},{2,0}},
{"Antarctica/Casey",{"WST","WST"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Antarctica/Davis",{"DAVT","DAVT"},undef,{7,0},{0,0},undef,{0,0},undef,{0,0}},
{"Antarctica/DumontDUrville",{"DDUT","DDUT"},undef,{10,0},{0,0},undef,{0,0},undef,{0,0}},
{"Antarctica/Mawson",{"MAWT","MAWT"},undef,{6,0},{0,0},undef,{0,0},undef,{0,0}},
{"Antarctica/McMurdo",{"NZST","NZST"},{"NZDT","NZDT"},{12,0},{1,0},{1,sun,oct},{2,0},{3,sun,mar},{3,0}},
{"Antarctica/Palmer",{"CLT","CLT"},{"CLST","CLST"},{-4,0},{1,0},{2,sun,oct},{0,0},{2,sun,mar},{0,0}},
{"Antarctica/South_Pole",{"NZST","NZST"},{"NZDT","NZDT"},{12,0},{1,0},{1,sun,oct},{2,0},{3,sun,mar},{3,0}},
{"Antarctica/Syowa",{"SYOT","SYOT"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Antarctica/Vostok",{"VOST","VOST"},undef,{6,0},{0,0},undef,{0,0},undef,{0,0}},
{"Arctic/Longyearbyen",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Asia/Aden",{"AST","AST"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Almaty",{"ALMT","ALMT"},{"ALMST","ALMST"},{6,0},{1,0},{last,sun,mar},{0,0},{last,sun,oct},{0,0}},
{"Asia/Amman",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,thu,mar},{0,0},{last,thu,sep},{1,0}},
{"Asia/Anadyr",{"ANAT","ANAT"},{"ANAST","ANAST"},{12,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Asia/Aqtau",{"AQTT","AQTT"},{"AQTST","AQTST"},{4,0},{1,0},{last,sun,mar},{0,0},{last,sun,oct},{0,0}},
{"Asia/Aqtobe",{"AQTT","AQTT"},{"AQTST","AQTST"},{5,0},{1,0},{last,sun,mar},{0,0},{last,sun,oct},{0,0}},
{"Asia/Ashgabat",{"TMT","TMT"},undef,{5,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Baghdad",{"AST","AST"},{"ADT","ADT"},{3,0},{1,0},{1,sun,apr},{3,0},{1,sun,oct},{4,0}},
{"Asia/Bahrain",{"AST","AST"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Baku",{"AZT","AZT"},{"AZST","AZST"},{4,0},{1,0},{last,sun,mar},{1,0},{last,sun,oct},{1,0}},
{"Asia/Bangkok",{"ICT","ICT"},undef,{7,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Beirut",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{0,0},{last,sun,oct},{0,0}},
{"Asia/Bishkek",{"KGT","KGT"},{"KGST","KGST"},{5,0},{1,0},{last,sun,mar},{2,30},{last,sun,oct},{2,30}},
{"Asia/Brunei",{"BNT","BNT"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Calcutta",{"IST","IST"},undef,{5,30},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Choibalsan",{"CHOT","CHOT"},undef,{9,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Chongqing",{"CST","CST"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Colombo",{"LKT","LKT"},undef,{6,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Damascus",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{1,sun,apr},{0,0},{1,sun,oct},{0,0}},
{"Asia/Dhaka",{"BDT","BDT"},undef,{6,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Dili",{"TPT","TPT"},undef,{9,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Dubai",{"GST","GST"},undef,{4,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Dushanbe",{"TJT","TJT"},undef,{5,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Gaza",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{3,fri,apr},{0,0},{3,fri,oct},{0,0}},
{"Asia/Harbin",{"CST","CST"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Hong_Kong",{"HKT","HKT"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Hovd",{"HOVT","HOVT"},undef,{7,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Irkutsk",{"IRKT","IRKT"},{"IRKST","IRKST"},{8,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Asia/Istanbul",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Asia/Jakarta",{"WIT","WIT"},undef,{7,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Jayapura",{"EIT","EIT"},undef,{9,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Jerusalem",{"IST","IST"},{"IDT","IDT"},{2,0},{1,0},{1,sun,apr},{1,0},{1,sun,oct},{1,0}},
{"Asia/Kabul",{"AFT","AFT"},undef,{4,30},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Kamchatka",{"PETT","PETT"},{"PETST","PETST"},{12,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Asia/Karachi",{"PKT","PKT"},undef,{5,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Kashgar",{"CST","CST"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Katmandu",{"NPT","NPT"},undef,{5,45},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Krasnoyarsk",{"KRAT","KRAT"},{"KRAST","KRAST"},{7,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Asia/Kuala_Lumpur",{"MYT","MYT"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Kuching",{"MYT","MYT"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Kuwait",{"AST","AST"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Macao",{"CST","CST"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Macau",{"CST","CST"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Magadan",{"MAGT","MAGT"},{"MAGST","MAGST"},{11,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Asia/Makassar",{"CIT","CIT"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Manila",{"PHT","PHT"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Muscat",{"GST","GST"},undef,{4,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Nicosia",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Asia/Novosibirsk",{"NOVT","NOVT"},{"NOVST","NOVST"},{6,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Asia/Omsk",{"OMST","OMST"},{"OMSST","OMSST"},{6,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Asia/Oral",{"WST","WST"},undef,{5,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Phnom_Penh",{"ICT","ICT"},undef,{7,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Pontianak",{"WIT","WIT"},undef,{7,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Pyongyang",{"KST","KST"},undef,{9,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Qyzylorda",{"KST","KST"},undef,{6,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Qatar",{"AST","AST"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Rangoon",{"MMT","MMT"},undef,{6,30},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Riyadh",{"AST","AST"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Saigon",{"ICT","ICT"},undef,{7,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Sakhalin",{"SAKT","SAKT"},{"SAKST","SAKST"},{10,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Asia/Samarkand",{"UZT","UZT"},undef,{5,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Seoul",{"KST","KST"},undef,{9,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Shanghai",{"CST","CST"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Singapore",{"SGT","SGT"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Taipei",{"CST","CST"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Tashkent",{"UZT","UZT"},undef,{5,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Tbilisi",{"GET","GET"},{"GEST","GEST"},{4,0},{1,0},{last,sun,mar},{0,0},{last,sun,oct},{0,0}},
{"Asia/Tehran",{"IRT","IRT"},undef,{3,30},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Thimphu",{"BTT","BTT"},undef,{6,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Tokyo",{"JST","JST"},undef,{9,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Ujung_Pandang",{"CIT","CIT"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Ulaanbaatar",{"ULAT","ULAT"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Urumqi",{"CST","CST"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Vientiane",{"ICT","ICT"},undef,{7,0},{0,0},undef,{0,0},undef,{0,0}},
{"Asia/Vladivostok",{"VLAT","VLAT"},{"VLAST","VLAST"},{10,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Asia/Yakutsk",{"YAKT","YAKT"},{"YAKST","YAKST"},{9,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Asia/Yekaterinburg",{"YEKT","YEKT"},{"YEKST","YEKST"},{5,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Asia/Yerevan",{"AMT","AMT"},{"AMST","AMST"},{4,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Atlantic/Azores",{"AZOT","AZOT"},{"AZOST","AZOST"},{-1,0},{1,0},{last,sun,mar},{0,0},{last,sun,oct},{1,0}},
{"Atlantic/Bermuda",{"AST","AST"},{"ADT","ADT"},{-4,0},{1,0},{1,sun,apr},{2,0},{last,sun,oct},{2,0}},
{"Atlantic/Canary",{"WET","WET"},{"WEST","WEST"},{0,0},{1,0},{last,sun,mar},{1,0},{last,sun,oct},{2,0}},
{"Atlantic/Cape_Verde",{"CVT","CVT"},undef,{-1,0},{0,0},undef,{0,0},undef,{0,0}},
{"Atlantic/Faeroe",{"WET","WET"},{"WEST","WEST"},{0,0},{1,0},{last,sun,mar},{1,0},{last,sun,oct},{2,0}},
{"Atlantic/Jan_Mayen",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Atlantic/Madeira",{"WET","WET"},{"WEST","WEST"},{0,0},{1,0},{last,sun,mar},{1,0},{last,sun,oct},{2,0}},
{"Atlantic/Reykjavik",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Atlantic/South_Georgia",{"GST","GST"},undef,{-2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Atlantic/St_Helena",{"GMT","GMT"},undef,{0,0},{0,0},undef,{0,0},undef,{0,0}},
{"Atlantic/Stanley",{"FKT","FKT"},{"FKST","FKST"},{-4,0},{1,0},{1,sun,sep},{2,0},{3,sun,apr},{2,0}},
{"Australia/Adelaide",{"CST","CST"},{"CST","CST"},{9,30},{1,0},{last,sun,oct},{2,0},{last,sun,mar},{3,0}},
{"Australia/Brisbane",{"EST","EST"},undef,{10,0},{0,0},undef,{0,0},undef,{0,0}},
{"Australia/Broken_Hill",{"CST","CST"},{"CST","CST"},{9,30},{1,0},{last,sun,oct},{2,0},{last,sun,mar},{3,0}},
{"Australia/Darwin",{"CST","CST"},undef,{9,30},{0,0},undef,{0,0},undef,{0,0}},
{"Australia/Hobart",{"EST","EST"},{"EST","EST"},{10,0},{1,0},{1,sun,oct},{2,0},{last,sun,mar},{3,0}},
{"Australia/Lindeman",{"EST","EST"},undef,{10,0},{0,0},undef,{0,0},undef,{0,0}},
{"Australia/Lord_Howe",{"LHST","LHST"},{"LHST","LHST"},{10,30},{0,30},{last,sun,oct},{2,0},{last,sun,mar},{2,0}},
{"Australia/Melbourne",{"EST","EST"},{"EST","EST"},{10,0},{1,0},{last,sun,oct},{2,0},{last,sun,mar},{3,0}},
{"Australia/Perth",{"WST","WST"},undef,{8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Australia/Sydney",{"EST","EST"},{"EST","EST"},{10,0},{1,0},{last,sun,oct},{2,0},{last,sun,mar},{3,0}},
{"Europe/Amsterdam",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Andorra",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Athens",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Europe/Belfast",{"GMT","GMT"},{"BST","BST"},{0,0},{1,0},{last,sun,mar},{1,0},{last,sun,oct},{2,0}},
{"Europe/Belgrade",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Berlin",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Bratislava",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Brussels",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Bucharest",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Europe/Budapest",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Chisinau",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Europe/Copenhagen",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Dublin",{"GMT","GMT"},{"IST","IST"},{0,0},{1,0},{last,sun,mar},{1,0},{last,sun,oct},{2,0}},
{"Europe/Gibraltar",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Helsinki",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Europe/Istanbul",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Europe/Kaliningrad",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Kiev",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Europe/Lisbon",{"WET","WET"},{"WEST","WEST"},{0,0},{1,0},{last,sun,mar},{1,0},{last,sun,oct},{2,0}},
{"Europe/Ljubljana",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/London",{"GMT","GMT"},{"BST","BST"},{0,0},{1,0},{last,sun,mar},{1,0},{last,sun,oct},{2,0}},
{"Europe/Luxembourg",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Madrid",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Malta",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Minsk",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Monaco",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Moscow",{"MSK","MSK"},{"MSD","MSD"},{3,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Nicosia",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Europe/Oslo",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Paris",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Prague",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Riga",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Europe/Rome",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Samara",{"SAMT","SAMT"},{"SAMST","SAMST"},{4,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/San_Marino",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Sarajevo",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Simferopol",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Europe/Skopje",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Sofia",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Europe/Stockholm",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Tallinn",{"EET","EET"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Europe/Tirane",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Uzhgorod",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Europe/Vaduz",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Vatican",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Vienna",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Vilnius",{"EET","EET"},undef,{2,0},{0,0},undef,{0,0},undef,{0,0}},
{"Europe/Warsaw",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Zagreb",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Europe/Zaporozhye",{"EET","EET"},{"EEST","EEST"},{2,0},{1,0},{last,sun,mar},{3,0},{last,sun,oct},{4,0}},
{"Europe/Zurich",{"CET","CET"},{"CEST","CEST"},{1,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
{"Indian/Antananarivo",{"EAT","EAT"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Indian/Chagos",{"IOT","IOT"},undef,{6,0},{0,0},undef,{0,0},undef,{0,0}},
{"Indian/Christmas",{"CXT","CXT"},undef,{7,0},{0,0},undef,{0,0},undef,{0,0}},
{"Indian/Cocos",{"CCT","CCT"},undef,{6,30},{0,0},undef,{0,0},undef,{0,0}},
{"Indian/Comoro",{"EAT","EAT"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Indian/Kerguelen",{"TFT","TFT"},undef,{5,0},{0,0},undef,{0,0},undef,{0,0}},
{"Indian/Mahe",{"SCT","SCT"},undef,{4,0},{0,0},undef,{0,0},undef,{0,0}},
{"Indian/Maldives",{"MVT","MVT"},undef,{5,0},{0,0},undef,{0,0},undef,{0,0}},
{"Indian/Mauritius",{"MUT","MUT"},undef,{4,0},{0,0},undef,{0,0},undef,{0,0}},
{"Indian/Mayotte",{"EAT","EAT"},undef,{3,0},{0,0},undef,{0,0},undef,{0,0}},
{"Indian/Reunion",{"RET","RET"},undef,{4,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Apia",{"WST","WST"},undef,{-11,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Auckland",{"NZST","NZST"},{"NZDT","NZDT"},{12,0},{1,0},{1,sun,oct},{2,0},{3,sun,mar},{3,0}},
{"Pacific/Chatham",{"CHAST","CHAST"},{"CHADT","CHADT"},{12,45},{1,0},{1,sun,oct},{2,45},{3,sun,mar},{3,45}},
{"Pacific/Easter",{"EAST","EAST"},{"EASST","EASST"},{-6,0},{1,0},{2,sat,oct},{22,0},{2,sat,mar},{22,0}},
{"Pacific/Efate",{"VUT","VUT"},undef,{11,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Enderbury",{"PHOT","PHOT"},undef,{13,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Fakaofo",{"TKT","TKT"},undef,{-10,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Fiji",{"FJT","FJT"},undef,{12,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Funafuti",{"TVT","TVT"},undef,{12,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Galapagos",{"GALT","GALT"},undef,{-6,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Gambier",{"GAMT","GAMT"},undef,{-9,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Guadalcanal",{"SBT","SBT"},undef,{11,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Guam",{"ChST","ChST"},undef,{10,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Honolulu",{"HST","HST"},undef,{-10,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Johnston",{"HST","HST"},undef,{-10,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Kiritimati",{"LINT","LINT"},undef,{14,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Kosrae",{"KOST","KOST"},undef,{11,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Kwajalein",{"MHT","MHT"},undef,{12,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Majuro",{"MHT","MHT"},undef,{12,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Marquesas",{"MART","MART"},undef,{-9,30},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Midway",{"SST","SST"},undef,{-11,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Nauru",{"NRT","NRT"},undef,{12,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Niue",{"NUT","NUT"},undef,{-11,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Norfolk",{"NFT","NFT"},undef,{11,30},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Noumea",{"NCT","NCT"},undef,{11,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Pago_Pago",{"SST","SST"},undef,{-11,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Palau",{"PWT","PWT"},undef,{9,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Pitcairn",{"PST","PST"},undef,{-8,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Ponape",{"PONT","PONT"},undef,{11,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Port_Moresby",{"PGT","PGT"},undef,{10,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Rarotonga",{"CKT","CKT"},undef,{-10,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Saipan",{"ChST","ChST"},undef,{10,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Tahiti",{"TAHT","TAHT"},undef,{-10,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Tarawa",{"GILT","GILT"},undef,{12,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Tongatapu",{"TOT","TOT"},undef,{13,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Truk",{"TRUT","TRUT"},undef,{10,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Wake",{"WAKT","WAKT"},undef,{12,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Wallis",{"WFT","WFT"},undef,{12,0},{0,0},undef,{0,0},undef,{0,0}},
{"Pacific/Yap",{"YAPT","YAPT"},undef,{10,0},{0,0},undef,{0,0},undef,{0,0}}
]).

139
src/localtime.erl Executable file
View file

@ -0,0 +1,139 @@
%% Copyright (C) 07/01/2010 Dmitry S. Melnikov (dmitryme@gmail.com)
%%
%% This program is free software; you can redistribute it and/or
%% modify it under the terms of the GNU General Public License
%% as published by the Free Software Foundation; either version 2
%% of the License, or (at your option) any later version.
%%
%% This program is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%% GNU General Public License for more details.
%%
%% You should have received a copy of the GNU General Public License
%% along with this program; if not, write to the Free Software
%% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-module(localtime).
-author("Dmitry Melnikov <dmitryme@gmail.com>").
-include("include/tz_database.hrl").
-export(
[
utc_to_local/2
,local_to_utc/2
,local_to_local/3
,tz_name/2
]).
% utc_to_local(UtcDateTime, Timezone) -> LocalDateTime | {error, ErrDescr}
% UtcDateTime = DateTime()
% Timezone = String()
% LocalDateTime = DateTime()
% ErrDescr = unknown_tz
utc_to_local(UtcDateTime, Timezone) ->
case lists:keyfind(Timezone, 1, ?tz_database) of
false ->
{error, unknown_tz};
{_Tz, _, _, Shift, _DstShift, undef, _DstStartTime, undef, _DstEndTime} ->
adjust_datetime(UtcDateTime, Shift);
TzRule = {_, _, _, Shift, DstShift, _, _, _, _} ->
LocalDateTime = adjust_datetime(UtcDateTime, Shift),
case localtime_dst:check(LocalDateTime, TzRule) of
Res when (Res == is_in_dst) or (Res == time_not_exists) ->
adjust_datetime(LocalDateTime, DstShift);
is_not_in_dst ->
LocalDateTime;
ambiguous_time ->
RecheckIt = adjust_datetime(LocalDateTime, DstShift),
case localtime_dst:check(RecheckIt, TzRule) of
ambiguous_time ->
RecheckIt;
_ ->
LocalDateTime
end
end
end.
% local_to_utc(LocalDateTime, Timezone) -> UtcDateTime | tim_not_exists | {error, ErrDescr}
% LocalDateTime = DateTime()
% Timezone = String()
% UtcDateTime = DateTime()
% ErrDescr = unknown_tz
local_to_utc(LocalDateTime, Timezone) ->
case lists:keyfind(Timezone, 1, ?tz_database) of
false ->
{error, unknown_tz};
{_Tz, _, _, Shift, _DstShift, undef, _DstStartTime, undef, _DstEndTime} ->
adjust_datetime(LocalDateTime, invert_shift(Shift));
TzRule = {_, _, _, Shift, DstShift, _, _, _, _} ->
UtcDateTime = adjust_datetime(LocalDateTime, invert_shift(Shift)),
case localtime_dst:check(LocalDateTime, TzRule) of
is_in_dst ->
adjust_datetime(UtcDateTime, invert_shift(DstShift));
Res when (Res == is_not_in_dst) or (Res == ambiguous_time) ->
UtcDateTime;
time_not_exists ->
time_not_exists
end
end.
% local_to_local(LocalDateTime, TimezoneFrom, TimezoneTo) -> LocalDateTime | tim_not_exists | {error, ErrDescr}
% LocalDateTime = DateTime()
% TimezoneFrom = String()
% TimezoneTo = String()
% ErrDescr = unknown_tz
local_to_local(LocalDateTime, TimezoneFrom, TimezoneTo) ->
case local_to_utc(LocalDateTime, TimezoneFrom) of
Date = {{_,_,_},{_,_,_}} ->
utc_to_local(Date, TimezoneTo);
Res ->
Res
end.
% tz_name(DateTime(), Timezone) -> {Abbr, Name} | {{StdAbbr, StdName}, {DstAbbr, DstName}} | unable_to_detect
% Timezone = String()
% Abbr = String()
% Name = String()
% StdAbbr = String()
% StdName = String()
% DstAbbr = String()
% DstName = String()
tz_name(_UtcDateTime, "UTC") ->
{"UTC", "UTC"};
tz_name(LocalDateTime, Timezone) ->
case lists:keyfind(Timezone, 1, ?tz_database) of
false ->
{error, unknown_tz};
{_Tz, StdName, undef, _Shift, _DstShift, undef, _DstStartTime, undef, _DstEndTime} ->
StdName;
TzRule = {_, StdName, DstName, _Shift, _DstShift, _, _, _, _} ->
case localtime_dst:check(LocalDateTime, TzRule) of
is_in_dst ->
DstName;
is_not_in_dst ->
StdName;
ambiguous_time ->
{StdName, DstName};
time_not_exists ->
unable_to_detect
end
end.
adjust_datetime(DateTime, {Hours, Minutes}) ->
Seconds = calendar:datetime_to_gregorian_seconds(DateTime) + Hours * 3600,
case Hours < 0 of
true ->
calendar:gregorian_seconds_to_datetime(Seconds - Minutes * 60);
false ->
calendar:gregorian_seconds_to_datetime(Seconds + Minutes * 60)
end.
invert_shift({Hours, Minutes}) ->
{-Hours, Minutes}.
-ifdef(EUNIT).
-include_lib("eunit/include/eunit.hrl").
-endif.

162
src/localtime_dst.erl Executable file
View file

@ -0,0 +1,162 @@
%% Copyright (C) 07/01/2010 Dmitry S. Melnikov (dmitryme@gmail.com)
%%
%% This program is free software; you can redistribute it and/or
%% modify it under the terms of the GNU General Public License
%% as published by the Free Software Foundation; either version 2
%% of the License, or (at your option) any later version.
%%
%% This program is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
%% GNU General Public License for more details.
%%
%% You should have received a copy of the GNU General Public License
%% along with this program; if not, write to the Free Software
%% Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-module(localtime_dst).
-author("Dmitry Melnikov <dmitryme@gmail.com>").
-export(
[
check/2
]).
-compile([export_all]).
% check(DateTime, TimeZone) -> is_in_dst | is_not_in_dst | ambiguous_time | time_not_exists
% DateTime = DateTime()
% TimeZone = tuple()
check({Date = {Year, _, _},Time}, {_, _, _, _Shift, DstShift, DstStartRule, DstStartTime, DstEndRule, DstEndTime}) ->
DstStartDay = get_dst_day_of_year(DstStartRule, Year),
DstEndDay = get_dst_day_of_year(DstEndRule, Year),
CurrDay = get_day_of_year(Date),
case is_dst_date(DstStartDay, DstEndDay, CurrDay) of
equal_to_start ->
is_dst_start_time(time_to_minutes(Time), time_to_minutes(DstStartTime), time_to_minutes(DstShift));
equal_to_end ->
is_dst_end_time(time_to_minutes(Time), time_to_minutes(DstEndTime), time_to_minutes(DstShift));
Res ->
Res
end.
is_dst_start_time(CurrTime, DstStartTime, _DstShift) when CurrTime < DstStartTime ->
is_not_in_dst;
is_dst_start_time(CurrTime, DstStartTime, DstShift) when CurrTime >= (DstStartTime + DstShift) ->
is_in_dst;
is_dst_start_time(_CurrTime, _DstStartTime, _DstShift) ->
time_not_exists.
is_dst_end_time(CurrTime, DstEndTime, DstShift) when CurrTime < (DstEndTime - DstShift) ->
is_in_dst;
is_dst_end_time(CurrTime, DstEndTime, _DstShift) when CurrTime >= DstEndTime ->
is_not_in_dst;
is_dst_end_time(_CurrTime, _DstStartTime, _DstShift) ->
ambiguous_time.
is_dst_date(DstStartDay, _DstEndDay, CurrDay) when (CurrDay == DstStartDay) -> equal_to_start;
is_dst_date(_DstStartDay, DstEndDay, CurrDay) when (CurrDay == DstEndDay) -> equal_to_end;
is_dst_date(DstStartDay, DstEndDay, CurrDay)
when (DstStartDay < DstEndDay) andalso ((CurrDay > DstStartDay) and (CurrDay < DstEndDay)) ->
is_in_dst;
is_dst_date(DstStartDay, DstEndDay, CurrDay)
when (DstStartDay < DstEndDay) andalso ((CurrDay < DstStartDay) or (CurrDay > DstEndDay)) ->
is_not_in_dst;
is_dst_date(DstStartDay, DstEndDay, CurrDay)
when (DstStartDay > DstEndDay) andalso ((CurrDay < DstStartDay) and (CurrDay > DstEndDay)) ->
is_not_in_dst;
is_dst_date(DstStartDay, DstEndDay, CurrDay)
when (DstStartDay > DstEndDay) andalso ((CurrDay > DstStartDay) or (CurrDay < DstEndDay)) ->
is_in_dst.
get_dst_day_of_year({WeekDay,DayOfWeek,Month}, Year) when (WeekDay == last) or (WeekDay == 5) ->
IntMonth = month_to_int(Month),
IntDayOfWeek = day_to_int(DayOfWeek),
get_last_dst(IntDayOfWeek, IntMonth, Year);
get_dst_day_of_year({WeekDay,DayOfWeek,Month}, Year) when (WeekDay > 0) and (WeekDay =< 4) ->
IntMonth = month_to_int(Month),
IntDayOfWeek = day_to_int(DayOfWeek),
DstDays = get_day_of_year({Year, IntMonth, 1}),
DstDayOfWeek = calendar:day_of_the_week({Year, IntMonth, 1}),
case (DstDayOfWeek =:= IntDayOfWeek) and (WeekDay =:= 1) of
true ->
DstDays;
false ->
AdjustedDstDays =
case IntDayOfWeek >= DstDayOfWeek of
true ->
DstDays + (IntDayOfWeek - DstDayOfWeek);
false ->
DstDays + (7 - DstDayOfWeek) + IntDayOfWeek
end,
AdjustedDstDays + (WeekDay - 1) * 7
end;
get_dst_day_of_year(_, _) ->
throw({error, wrong_week_day}).
get_last_dst(IntDayOfWeek, IntMonth, Year) ->
MonthLastDays = calendar:date_to_gregorian_days(Year, IntMonth, 1) + calendar:last_day_of_the_month(Year, IntMonth),
MonthLastDate = calendar:gregorian_days_to_date(MonthLastDays),
MonthLastDayOfWeek = calendar:day_of_the_week(MonthLastDate),
case MonthLastDayOfWeek > IntDayOfWeek of
true ->
MonthLastDays - (MonthLastDayOfWeek - IntDayOfWeek) - calendar:date_to_gregorian_days({Year - 1, 12, 31});
false ->
MonthLastDays - MonthLastDayOfWeek - (7 - IntDayOfWeek) - calendar:date_to_gregorian_days({Year - 1, 12, 31})
end.
get_day_of_year(Date = {Year, _Month, _Day}) ->
calendar:date_to_gregorian_days(Date) - calendar:date_to_gregorian_days({Year - 1, 12, 31}).
month_to_int(jan) -> 1;
month_to_int(feb) -> 2;
month_to_int(mar) -> 3;
month_to_int(apr) -> 4;
month_to_int(may) -> 5;
month_to_int(jun) -> 6;
month_to_int(jul) -> 7;
month_to_int(aug) -> 8;
month_to_int(sep) -> 9;
month_to_int(oct) -> 10;
month_to_int(nov) -> 11;
month_to_int(dec) -> 12.
day_to_int(mon) -> 1;
day_to_int(tue) -> 2;
day_to_int(wed) -> 3;
day_to_int(thu) -> 4;
day_to_int(fri) -> 5;
day_to_int(sat) -> 6;
day_to_int(sun) -> 7.
time_to_minutes({Hours, Minutes}) ->
Hours * 60 + Minutes;
time_to_minutes({Hours, Minutes, _Seconds}) ->
Hours * 60 + Minutes.
-ifdef(EUNIT).
-include_lib("eunit/include/eunit.hrl").
get_day_of_year_test() ->
?assertEqual(62, get_dst_day_of_year({1,wed,mar}, 2010)).
check_test() ->
Tz = {"Europe/Moscow",{3,0},{1,0},{last,sun,mar},{2,0},{last,sun,oct},{3,0}},
?assertEqual(is_not_in_dst, local_time_dst:check({{2010, 1, 1}, {10, 10, 0}}, Tz)),
?assertEqual(is_in_dst, check({{2010, 7, 8}, {10, 10, 0}}, Tz)),
?assertEqual(is_not_in_dst, check({{2010, 3, 28}, {1, 59, 0}}, Tz)),
?assertEqual(invalid_label, check({{2010, 3, 28}, {2, 00, 0}}, Tz)),
?assertEqual(invalid_label, check({{2010, 3, 28}, {2, 15, 0}}, Tz)),
?assertEqual(invalid_label, check({{2010, 3, 28}, {2, 30, 0}}, Tz)),
?assertEqual(invalid_label, check({{2010, 3, 28}, {2, 59, 0}}, Tz)),
?assertEqual(is_in_dst, check({{2010, 3, 28}, {3, 00, 0}}, Tz)),
?assertEqual(is_in_dst, check({{2010, 10, 31}, {1, 59, 0}}, Tz)),
?assertEqual(ambiguos, check({{2010, 10, 31}, {2, 00, 0}}, Tz)),
?assertEqual(ambiguos, check({{2010, 10, 31}, {2, 10, 0}}, Tz)),
?assertEqual(ambiguos, check({{2010, 10, 31}, {2, 30, 0}}, Tz)),
?assertEqual(ambiguos, check({{2010, 10, 31}, {2, 59, 0}}, Tz)),
?assertEqual(is_not_in_dst, check({{2010, 10, 31}, {3, 00, 0}}, Tz)).
-endif.