1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/i18n/timezone.h"
6
7#include <map>
8
9#include "base/memory/singleton.h"
10#include "base/strings/string16.h"
11#include "base/strings/utf_string_conversions.h"
12#include "third_party/icu/source/i18n/unicode/timezone.h"
13
14namespace base {
15
16namespace {
17
18class TimezoneMap {
19 public:
20  static TimezoneMap* GetInstance() {
21    return Singleton<TimezoneMap>::get();
22  }
23
24  std::string CountryCodeForTimezone(const std::string& olson_code) {
25    std::map<std::string, std::string>::iterator iter = map_.find(olson_code);
26    if (iter != map_.end())
27      return iter->second;
28
29    return std::string();
30  }
31
32 private:
33  TimezoneMap() {
34    // These mappings are adapted from zone.tab, which is available at
35    // <http://www.ietf.org/timezones/data/zone.tab> and is a part of public
36    // domain.
37    struct OlsonCodeData {
38      std::string country_code;
39      std::string olson_code;
40    } olson_code_data[] = {
41        { "AD", "Europe/Andorra" },
42        { "AE", "Asia/Dubai" },
43        { "AF", "Asia/Kabul" },
44        { "AG", "America/Antigua" },
45        { "AI", "America/Anguilla" },
46        { "AL", "Europe/Tirane" },
47        { "AM", "Asia/Yerevan" },
48        { "AO", "Africa/Luanda" },
49        { "AQ", "Antarctica/McMurdo" },
50        { "AQ", "Antarctica/Rothera" },
51        { "AQ", "Antarctica/Palmer" },
52        { "AQ", "Antarctica/Mawson" },
53        { "AQ", "Antarctica/Davis" },
54        { "AQ", "Antarctica/Casey" },
55        { "AQ", "Antarctica/Vostok" },
56        { "AQ", "Antarctica/DumontDUrville" },
57        { "AQ", "Antarctica/Syowa" },
58        { "AR", "America/Argentina/Buenos_Aires" },
59        { "AR", "America/Argentina/Cordoba" },
60        { "AR", "America/Argentina/Salta" },
61        { "AR", "America/Argentina/Jujuy" },
62        { "AR", "America/Argentina/Tucuman" },
63        { "AR", "America/Argentina/Catamarca" },
64        { "AR", "America/Argentina/La_Rioja" },
65        { "AR", "America/Argentina/San_Juan" },
66        { "AR", "America/Argentina/Mendoza" },
67        { "AR", "America/Argentina/San_Luis" },
68        { "AR", "America/Argentina/Rio_Gallegos" },
69        { "AR", "America/Argentina/Ushuaia" },
70        { "AS", "Pacific/Pago_Pago" },
71        { "AT", "Europe/Vienna" },
72        { "AU", "Australia/Lord_Howe" },
73        { "AU", "Antarctica/Macquarie" },
74        { "AU", "Australia/Hobart" },
75        { "AU", "Australia/Currie" },
76        { "AU", "Australia/Melbourne" },
77        { "AU", "Australia/Sydney" },
78        { "AU", "Australia/Broken_Hill" },
79        { "AU", "Australia/Brisbane" },
80        { "AU", "Australia/Lindeman" },
81        { "AU", "Australia/Adelaide" },
82        { "AU", "Australia/Darwin" },
83        { "AU", "Australia/Perth" },
84        { "AU", "Australia/Eucla" },
85        { "AW", "America/Aruba" },
86        { "AX", "Europe/Mariehamn" },
87        { "AZ", "Asia/Baku" },
88        { "BA", "Europe/Sarajevo" },
89        { "BB", "America/Barbados" },
90        { "BD", "Asia/Dhaka" },
91        { "BE", "Europe/Brussels" },
92        { "BF", "Africa/Ouagadougou" },
93        { "BG", "Europe/Sofia" },
94        { "BH", "Asia/Bahrain" },
95        { "BI", "Africa/Bujumbura" },
96        { "BJ", "Africa/Porto-Novo" },
97        { "BL", "America/St_Barthelemy" },
98        { "BM", "Atlantic/Bermuda" },
99        { "BN", "Asia/Brunei" },
100        { "BO", "America/La_Paz" },
101        { "BQ", "America/Kralendijk" },
102        { "BR", "America/Noronha" },
103        { "BR", "America/Belem" },
104        { "BR", "America/Fortaleza" },
105        { "BR", "America/Recife" },
106        { "BR", "America/Araguaina" },
107        { "BR", "America/Maceio" },
108        { "BR", "America/Bahia" },
109        { "BR", "America/Sao_Paulo" },
110        { "BR", "America/Campo_Grande" },
111        { "BR", "America/Cuiaba" },
112        { "BR", "America/Santarem" },
113        { "BR", "America/Porto_Velho" },
114        { "BR", "America/Boa_Vista" },
115        { "BR", "America/Manaus" },
116        { "BR", "America/Eirunepe" },
117        { "BR", "America/Rio_Branco" },
118        { "BS", "America/Nassau" },
119        { "BT", "Asia/Thimphu" },
120        { "BW", "Africa/Gaborone" },
121        { "BY", "Europe/Minsk" },
122        { "BZ", "America/Belize" },
123        { "CA", "America/St_Johns" },
124        { "CA", "America/Halifax" },
125        { "CA", "America/Glace_Bay" },
126        { "CA", "America/Moncton" },
127        { "CA", "America/Goose_Bay" },
128        { "CA", "America/Blanc-Sablon" },
129        { "CA", "America/Toronto" },
130        { "CA", "America/Nipigon" },
131        { "CA", "America/Thunder_Bay" },
132        { "CA", "America/Iqaluit" },
133        { "CA", "America/Pangnirtung" },
134        { "CA", "America/Resolute" },
135        { "CA", "America/Atikokan" },
136        { "CA", "America/Rankin_Inlet" },
137        { "CA", "America/Winnipeg" },
138        { "CA", "America/Rainy_River" },
139        { "CA", "America/Regina" },
140        { "CA", "America/Swift_Current" },
141        { "CA", "America/Edmonton" },
142        { "CA", "America/Cambridge_Bay" },
143        { "CA", "America/Yellowknife" },
144        { "CA", "America/Inuvik" },
145        { "CA", "America/Creston" },
146        { "CA", "America/Dawson_Creek" },
147        { "CA", "America/Vancouver" },
148        { "CA", "America/Whitehorse" },
149        { "CA", "America/Dawson" },
150        { "CC", "Indian/Cocos" },
151        { "CD", "Africa/Kinshasa" },
152        { "CD", "Africa/Lubumbashi" },
153        { "CF", "Africa/Bangui" },
154        { "CG", "Africa/Brazzaville" },
155        { "CH", "Europe/Zurich" },
156        { "CI", "Africa/Abidjan" },
157        { "CK", "Pacific/Rarotonga" },
158        { "CL", "America/Santiago" },
159        { "CL", "Pacific/Easter" },
160        { "CM", "Africa/Douala" },
161        { "CN", "Asia/Shanghai" },
162        { "CN", "Asia/Harbin" },
163        { "CN", "Asia/Chongqing" },
164        { "CN", "Asia/Urumqi" },
165        { "CN", "Asia/Kashgar" },
166        { "CO", "America/Bogota" },
167        { "CR", "America/Costa_Rica" },
168        { "CU", "America/Havana" },
169        { "CV", "Atlantic/Cape_Verde" },
170        { "CW", "America/Curacao" },
171        { "CX", "Indian/Christmas" },
172        { "CY", "Asia/Nicosia" },
173        { "CZ", "Europe/Prague" },
174        { "DE", "Europe/Berlin" },
175        { "DE", "Europe/Busingen" },
176        { "DJ", "Africa/Djibouti" },
177        { "DK", "Europe/Copenhagen" },
178        { "DM", "America/Dominica" },
179        { "DO", "America/Santo_Domingo" },
180        { "DZ", "Africa/Algiers" },
181        { "EC", "America/Guayaquil" },
182        { "EC", "Pacific/Galapagos" },
183        { "EE", "Europe/Tallinn" },
184        { "EG", "Africa/Cairo" },
185        { "EH", "Africa/El_Aaiun" },
186        { "ER", "Africa/Asmara" },
187        { "ES", "Europe/Madrid" },
188        { "ES", "Africa/Ceuta" },
189        { "ES", "Atlantic/Canary" },
190        { "ET", "Africa/Addis_Ababa" },
191        { "FI", "Europe/Helsinki" },
192        { "FJ", "Pacific/Fiji" },
193        { "FK", "Atlantic/Stanley" },
194        { "FM", "Pacific/Chuuk" },
195        { "FM", "Pacific/Pohnpei" },
196        { "FM", "Pacific/Kosrae" },
197        { "FO", "Atlantic/Faroe" },
198        { "FR", "Europe/Paris" },
199        { "GA", "Africa/Libreville" },
200        { "GB", "Europe/London" },
201        { "GD", "America/Grenada" },
202        { "GE", "Asia/Tbilisi" },
203        { "GF", "America/Cayenne" },
204        { "GG", "Europe/Guernsey" },
205        { "GH", "Africa/Accra" },
206        { "GI", "Europe/Gibraltar" },
207        { "GL", "America/Godthab" },
208        { "GL", "America/Danmarkshavn" },
209        { "GL", "America/Scoresbysund" },
210        { "GL", "America/Thule" },
211        { "GM", "Africa/Banjul" },
212        { "GN", "Africa/Conakry" },
213        { "GP", "America/Guadeloupe" },
214        { "GQ", "Africa/Malabo" },
215        { "GR", "Europe/Athens" },
216        { "GS", "Atlantic/South_Georgia" },
217        { "GT", "America/Guatemala" },
218        { "GU", "Pacific/Guam" },
219        { "GW", "Africa/Bissau" },
220        { "GY", "America/Guyana" },
221        { "HK", "Asia/Hong_Kong" },
222        { "HN", "America/Tegucigalpa" },
223        { "HR", "Europe/Zagreb" },
224        { "HT", "America/Port-au-Prince" },
225        { "HU", "Europe/Budapest" },
226        { "ID", "Asia/Jakarta" },
227        { "ID", "Asia/Pontianak" },
228        { "ID", "Asia/Makassar" },
229        { "ID", "Asia/Jayapura" },
230        { "IE", "Europe/Dublin" },
231        { "IL", "Asia/Jerusalem" },
232        { "IM", "Europe/Isle_of_Man" },
233        { "IN", "Asia/Kolkata" },
234        { "IO", "Indian/Chagos" },
235        { "IQ", "Asia/Baghdad" },
236        { "IR", "Asia/Tehran" },
237        { "IS", "Atlantic/Reykjavik" },
238        { "IT", "Europe/Rome" },
239        { "JE", "Europe/Jersey" },
240        { "JM", "America/Jamaica" },
241        { "JO", "Asia/Amman" },
242        { "JP", "Asia/Tokyo" },
243        { "KE", "Africa/Nairobi" },
244        { "KG", "Asia/Bishkek" },
245        { "KH", "Asia/Phnom_Penh" },
246        { "KI", "Pacific/Tarawa" },
247        { "KI", "Pacific/Enderbury" },
248        { "KI", "Pacific/Kiritimati" },
249        { "KM", "Indian/Comoro" },
250        { "KN", "America/St_Kitts" },
251        { "KP", "Asia/Pyongyang" },
252        { "KR", "Asia/Seoul" },
253        { "KW", "Asia/Kuwait" },
254        { "KY", "America/Cayman" },
255        { "KZ", "Asia/Almaty" },
256        { "KZ", "Asia/Qyzylorda" },
257        { "KZ", "Asia/Aqtobe" },
258        { "KZ", "Asia/Aqtau" },
259        { "KZ", "Asia/Oral" },
260        { "LA", "Asia/Vientiane" },
261        { "LB", "Asia/Beirut" },
262        { "LC", "America/St_Lucia" },
263        { "LI", "Europe/Vaduz" },
264        { "LK", "Asia/Colombo" },
265        { "LR", "Africa/Monrovia" },
266        { "LS", "Africa/Maseru" },
267        { "LT", "Europe/Vilnius" },
268        { "LU", "Europe/Luxembourg" },
269        { "LV", "Europe/Riga" },
270        { "LY", "Africa/Tripoli" },
271        { "MA", "Africa/Casablanca" },
272        { "MC", "Europe/Monaco" },
273        { "MD", "Europe/Chisinau" },
274        { "ME", "Europe/Podgorica" },
275        { "MF", "America/Marigot" },
276        { "MG", "Indian/Antananarivo" },
277        { "MH", "Pacific/Majuro" },
278        { "MH", "Pacific/Kwajalein" },
279        { "MK", "Europe/Skopje" },
280        { "ML", "Africa/Bamako" },
281        { "MM", "Asia/Rangoon" },
282        { "MN", "Asia/Ulaanbaatar" },
283        { "MN", "Asia/Hovd" },
284        { "MN", "Asia/Choibalsan" },
285        { "MO", "Asia/Macau" },
286        { "MP", "Pacific/Saipan" },
287        { "MQ", "America/Martinique" },
288        { "MR", "Africa/Nouakchott" },
289        { "MS", "America/Montserrat" },
290        { "MT", "Europe/Malta" },
291        { "MU", "Indian/Mauritius" },
292        { "MV", "Indian/Maldives" },
293        { "MW", "Africa/Blantyre" },
294        { "MX", "America/Mexico_City" },
295        { "MX", "America/Cancun" },
296        { "MX", "America/Merida" },
297        { "MX", "America/Monterrey" },
298        { "MX", "America/Matamoros" },
299        { "MX", "America/Mazatlan" },
300        { "MX", "America/Chihuahua" },
301        { "MX", "America/Ojinaga" },
302        { "MX", "America/Hermosillo" },
303        { "MX", "America/Tijuana" },
304        { "MX", "America/Santa_Isabel" },
305        { "MX", "America/Bahia_Banderas" },
306        { "MY", "Asia/Kuala_Lumpur" },
307        { "MY", "Asia/Kuching" },
308        { "MZ", "Africa/Maputo" },
309        { "NA", "Africa/Windhoek" },
310        { "NC", "Pacific/Noumea" },
311        { "NE", "Africa/Niamey" },
312        { "NF", "Pacific/Norfolk" },
313        { "NG", "Africa/Lagos" },
314        { "NI", "America/Managua" },
315        { "NL", "Europe/Amsterdam" },
316        { "NO", "Europe/Oslo" },
317        { "NP", "Asia/Kathmandu" },
318        { "NR", "Pacific/Nauru" },
319        { "NU", "Pacific/Niue" },
320        { "NZ", "Pacific/Auckland" },
321        { "NZ", "Pacific/Chatham" },
322        { "OM", "Asia/Muscat" },
323        { "PA", "America/Panama" },
324        { "PE", "America/Lima" },
325        { "PF", "Pacific/Tahiti" },
326        { "PF", "Pacific/Marquesas" },
327        { "PF", "Pacific/Gambier" },
328        { "PG", "Pacific/Port_Moresby" },
329        { "PH", "Asia/Manila" },
330        { "PK", "Asia/Karachi" },
331        { "PL", "Europe/Warsaw" },
332        { "PM", "America/Miquelon" },
333        { "PN", "Pacific/Pitcairn" },
334        { "PR", "America/Puerto_Rico" },
335        { "PS", "Asia/Gaza" },
336        { "PS", "Asia/Hebron" },
337        { "PT", "Europe/Lisbon" },
338        { "PT", "Atlantic/Madeira" },
339        { "PT", "Atlantic/Azores" },
340        { "PW", "Pacific/Palau" },
341        { "PY", "America/Asuncion" },
342        { "QA", "Asia/Qatar" },
343        { "RE", "Indian/Reunion" },
344        { "RO", "Europe/Bucharest" },
345        { "RS", "Europe/Belgrade" },
346        { "RU", "Europe/Kaliningrad" },
347        { "RU", "Europe/Moscow" },
348        { "RU", "Europe/Volgograd" },
349        { "RU", "Europe/Samara" },
350        { "RU", "Asia/Yekaterinburg" },
351        { "RU", "Asia/Omsk" },
352        { "RU", "Asia/Novosibirsk" },
353        { "RU", "Asia/Novokuznetsk" },
354        { "RU", "Asia/Krasnoyarsk" },
355        { "RU", "Asia/Irkutsk" },
356        { "RU", "Asia/Yakutsk" },
357        { "RU", "Asia/Khandyga" },
358        { "RU", "Asia/Vladivostok" },
359        { "RU", "Asia/Sakhalin" },
360        { "RU", "Asia/Ust-Nera" },
361        { "RU", "Asia/Magadan" },
362        { "RU", "Asia/Kamchatka" },
363        { "RU", "Asia/Anadyr" },
364        { "RW", "Africa/Kigali" },
365        { "SA", "Asia/Riyadh" },
366        { "SB", "Pacific/Guadalcanal" },
367        { "SC", "Indian/Mahe" },
368        { "SD", "Africa/Khartoum" },
369        { "SE", "Europe/Stockholm" },
370        { "SG", "Asia/Singapore" },
371        { "SH", "Atlantic/St_Helena" },
372        { "SI", "Europe/Ljubljana" },
373        { "SJ", "Arctic/Longyearbyen" },
374        { "SK", "Europe/Bratislava" },
375        { "SL", "Africa/Freetown" },
376        { "SM", "Europe/San_Marino" },
377        { "SN", "Africa/Dakar" },
378        { "SO", "Africa/Mogadishu" },
379        { "SR", "America/Paramaribo" },
380        { "SS", "Africa/Juba" },
381        { "ST", "Africa/Sao_Tome" },
382        { "SV", "America/El_Salvador" },
383        { "SX", "America/Lower_Princes" },
384        { "SY", "Asia/Damascus" },
385        { "SZ", "Africa/Mbabane" },
386        { "TC", "America/Grand_Turk" },
387        { "TD", "Africa/Ndjamena" },
388        { "TF", "Indian/Kerguelen" },
389        { "TG", "Africa/Lome" },
390        { "TH", "Asia/Bangkok" },
391        { "TJ", "Asia/Dushanbe" },
392        { "TK", "Pacific/Fakaofo" },
393        { "TL", "Asia/Dili" },
394        { "TM", "Asia/Ashgabat" },
395        { "TN", "Africa/Tunis" },
396        { "TO", "Pacific/Tongatapu" },
397        { "TR", "Europe/Istanbul" },
398        { "TT", "America/Port_of_Spain" },
399        { "TV", "Pacific/Funafuti" },
400        { "TW", "Asia/Taipei" },
401        { "TZ", "Africa/Dar_es_Salaam" },
402        { "UA", "Europe/Kiev" },
403        { "UA", "Europe/Uzhgorod" },
404        { "UA", "Europe/Zaporozhye" },
405        { "UA", "Europe/Simferopol" },
406        { "UG", "Africa/Kampala" },
407        { "UM", "Pacific/Johnston" },
408        { "UM", "Pacific/Midway" },
409        { "UM", "Pacific/Wake" },
410        { "US", "America/New_York" },
411        { "US", "America/Detroit" },
412        { "US", "America/Kentucky/Louisville" },
413        { "US", "America/Kentucky/Monticello" },
414        { "US", "America/Indiana/Indianapolis" },
415        { "US", "America/Indiana/Vincennes" },
416        { "US", "America/Indiana/Winamac" },
417        { "US", "America/Indiana/Marengo" },
418        { "US", "America/Indiana/Petersburg" },
419        { "US", "America/Indiana/Vevay" },
420        { "US", "America/Chicago" },
421        { "US", "America/Indiana/Tell_City" },
422        { "US", "America/Indiana/Knox" },
423        { "US", "America/Menominee" },
424        { "US", "America/North_Dakota/Center" },
425        { "US", "America/North_Dakota/New_Salem" },
426        { "US", "America/North_Dakota/Beulah" },
427        { "US", "America/Denver" },
428        { "US", "America/Boise" },
429        { "US", "America/Phoenix" },
430        { "US", "America/Los_Angeles" },
431        { "US", "America/Anchorage" },
432        { "US", "America/Juneau" },
433        { "US", "America/Sitka" },
434        { "US", "America/Yakutat" },
435        { "US", "America/Nome" },
436        { "US", "America/Adak" },
437        { "US", "America/Metlakatla" },
438        { "US", "Pacific/Honolulu" },
439        { "UY", "America/Montevideo" },
440        { "UZ", "Asia/Samarkand" },
441        { "UZ", "Asia/Tashkent" },
442        { "VA", "Europe/Vatican" },
443        { "VC", "America/St_Vincent" },
444        { "VE", "America/Caracas" },
445        { "VG", "America/Tortola" },
446        { "VI", "America/St_Thomas" },
447        { "VN", "Asia/Ho_Chi_Minh" },
448        { "VU", "Pacific/Efate" },
449        { "WF", "Pacific/Wallis" },
450        { "WS", "Pacific/Apia" },
451        { "YE", "Asia/Aden" },
452        { "YT", "Indian/Mayotte" },
453        { "ZA", "Africa/Johannesburg" },
454        { "ZM", "Africa/Lusaka" },
455        { "ZW", "Africa/Harare" },
456        // The mappings below are custom additions to zone.tab.
457        { "GB", "Etc/GMT" },
458        { "GB", "Etc/UTC" },
459        { "GB", "Etc/UCT" },
460    };
461
462    for (size_t i = 0; i < ARRAYSIZE_UNSAFE(olson_code_data); ++i) {
463      map_[olson_code_data[i].olson_code] = olson_code_data[i].country_code;
464    }
465
466    // These are mapping from old codenames to new codenames. They are also
467    // part of public domain, and available at
468    // <http://www.ietf.org/timezones/data/backward>.
469    struct LinkData {
470      std::string old_code;
471      std::string new_code;
472    } link_data[] = {
473        { "Africa/Asmera", "Africa/Asmara" },
474        { "Africa/Timbuktu", "Africa/Bamako" },
475        { "America/Argentina/ComodRivadavia", "America/Argentina/Catamarca" },
476        { "America/Atka", "America/Adak" },
477        { "America/Buenos_Aires", "America/Argentina/Buenos_Aires" },
478        { "America/Catamarca", "America/Argentina/Catamarca" },
479        { "America/Coral_Harbour", "America/Atikokan" },
480        { "America/Cordoba", "America/Argentina/Cordoba" },
481        { "America/Ensenada", "America/Tijuana" },
482        { "America/Fort_Wayne", "America/Indiana/Indianapolis" },
483        { "America/Indianapolis", "America/Indiana/Indianapolis" },
484        { "America/Jujuy", "America/Argentina/Jujuy" },
485        { "America/Knox_IN", "America/Indiana/Knox" },
486        { "America/Louisville", "America/Kentucky/Louisville" },
487        { "America/Mendoza", "America/Argentina/Mendoza" },
488        { "America/Porto_Acre", "America/Rio_Branco" },
489        { "America/Rosario", "America/Argentina/Cordoba" },
490        { "America/Virgin", "America/St_Thomas" },
491        { "Asia/Ashkhabad", "Asia/Ashgabat" },
492        { "Asia/Chungking", "Asia/Chongqing" },
493        { "Asia/Dacca", "Asia/Dhaka" },
494        { "Asia/Katmandu", "Asia/Kathmandu" },
495        { "Asia/Calcutta", "Asia/Kolkata" },
496        { "Asia/Macao", "Asia/Macau" },
497        { "Asia/Tel_Aviv", "Asia/Jerusalem" },
498        { "Asia/Saigon", "Asia/Ho_Chi_Minh" },
499        { "Asia/Thimbu", "Asia/Thimphu" },
500        { "Asia/Ujung_Pandang", "Asia/Makassar" },
501        { "Asia/Ulan_Bator", "Asia/Ulaanbaatar" },
502        { "Atlantic/Faeroe", "Atlantic/Faroe" },
503        { "Atlantic/Jan_Mayen", "Europe/Oslo" },
504        { "Australia/ACT", "Australia/Sydney" },
505        { "Australia/Canberra", "Australia/Sydney" },
506        { "Australia/LHI", "Australia/Lord_Howe" },
507        { "Australia/NSW", "Australia/Sydney" },
508        { "Australia/North", "Australia/Darwin" },
509        { "Australia/Queensland", "Australia/Brisbane" },
510        { "Australia/South", "Australia/Adelaide" },
511        { "Australia/Tasmania", "Australia/Hobart" },
512        { "Australia/Victoria", "Australia/Melbourne" },
513        { "Australia/West", "Australia/Perth" },
514        { "Australia/Yancowinna", "Australia/Broken_Hill" },
515        { "Brazil/Acre", "America/Rio_Branco" },
516        { "Brazil/DeNoronha", "America/Noronha" },
517        { "Brazil/East", "America/Sao_Paulo" },
518        { "Brazil/West", "America/Manaus" },
519        { "Canada/Atlantic", "America/Halifax" },
520        { "Canada/Central", "America/Winnipeg" },
521        { "Canada/East-Saskatchewan", "America/Regina" },
522        { "Canada/Eastern", "America/Toronto" },
523        { "Canada/Mountain", "America/Edmonton" },
524        { "Canada/Newfoundland", "America/St_Johns" },
525        { "Canada/Pacific", "America/Vancouver" },
526        { "Canada/Saskatchewan", "America/Regina" },
527        { "Canada/Yukon", "America/Whitehorse" },
528        { "Chile/Continental", "America/Santiago" },
529        { "Chile/EasterIsland", "Pacific/Easter" },
530        { "Cuba", "America/Havana" },
531        { "Egypt", "Africa/Cairo" },
532        { "Eire", "Europe/Dublin" },
533        { "Europe/Belfast", "Europe/London" },
534        { "Europe/Tiraspol", "Europe/Chisinau" },
535        { "GB", "Europe/London" },
536        { "GB-Eire", "Europe/London" },
537        { "GMT+0", "Etc/GMT" },
538        { "GMT-0", "Etc/GMT" },
539        { "GMT0", "Etc/GMT" },
540        { "Greenwich", "Etc/GMT" },
541        { "Hongkong", "Asia/Hong_Kong" },
542        { "Iceland", "Atlantic/Reykjavik" },
543        { "Iran", "Asia/Tehran" },
544        { "Israel", "Asia/Jerusalem" },
545        { "Jamaica", "America/Jamaica" },
546        { "Japan", "Asia/Tokyo" },
547        { "Kwajalein", "Pacific/Kwajalein" },
548        { "Libya", "Africa/Tripoli" },
549        { "Mexico/BajaNorte", "America/Tijuana" },
550        { "Mexico/BajaSur", "America/Mazatlan" },
551        { "Mexico/General", "America/Mexico_City" },
552        { "NZ", "Pacific/Auckland" },
553        { "NZ-CHAT", "Pacific/Chatham" },
554        { "Navajo", "America/Denver" },
555        { "PRC", "Asia/Shanghai" },
556        { "Pacific/Samoa", "Pacific/Pago_Pago" },
557        { "Pacific/Yap", "Pacific/Chuuk" },
558        { "Pacific/Truk", "Pacific/Chuuk" },
559        { "Pacific/Ponape", "Pacific/Pohnpei" },
560        { "Poland", "Europe/Warsaw" },
561        { "Portugal", "Europe/Lisbon" },
562        { "ROC", "Asia/Taipei" },
563        { "ROK", "Asia/Seoul" },
564        { "Singapore", "Asia/Singapore" },
565        { "Turkey", "Europe/Istanbul" },
566        { "UCT", "Etc/UCT" },
567        { "US/Alaska", "America/Anchorage" },
568        { "US/Aleutian", "America/Adak" },
569        { "US/Arizona", "America/Phoenix" },
570        { "US/Central", "America/Chicago" },
571        { "US/East-Indiana", "America/Indiana/Indianapolis" },
572        { "US/Eastern", "America/New_York" },
573        { "US/Hawaii", "Pacific/Honolulu" },
574        { "US/Indiana-Starke", "America/Indiana/Knox" },
575        { "US/Michigan", "America/Detroit" },
576        { "US/Mountain", "America/Denver" },
577        { "US/Pacific", "America/Los_Angeles" },
578        { "US/Samoa", "Pacific/Pago_Pago" },
579        { "UTC", "Etc/UTC" },
580        { "Universal", "Etc/UTC" },
581        { "W-SU", "Europe/Moscow" },
582        { "Zulu", "Etc/UTC" },
583    };
584
585    for (size_t i = 0; i < ARRAYSIZE_UNSAFE(link_data); ++i) {
586      map_[link_data[i].old_code] = map_[link_data[i].new_code];
587    }
588  }
589
590  friend struct DefaultSingletonTraits<TimezoneMap>;
591
592  std::map<std::string, std::string> map_;
593
594  DISALLOW_COPY_AND_ASSIGN(TimezoneMap);
595};
596
597}  // namespace
598
599std::string CountryCodeForCurrentTimezone() {
600  scoped_ptr<icu::TimeZone> zone(icu::TimeZone::createDefault());
601  icu::UnicodeString id;
602  zone->getID(id);
603  string16 olson_code(id.getBuffer(), id.length());
604  return TimezoneMap::GetInstance()->CountryCodeForTimezone(
605      UTF16ToUTF8(olson_code));
606}
607
608}  // namespace base
609