From 964fa27bfb9a5b1ef72a612d9b90e0891b21b9b0 Mon Sep 17 00:00:00 2001 From: The Dod Date: Tue, 21 Dec 2021 01:01:10 +0200 Subject: [PATCH 1/5] Add Four Twenty Clock app --- apps.json | 18 ++ apps/ftclock/ChangeLog | 1 + apps/ftclock/app-icon.js | 1 + apps/ftclock/app.js | 52 ++++ apps/ftclock/app.png | Bin 0 -> 6742 bytes apps/ftclock/fourTwenty.js | 45 +++ apps/ftclock/fourTwentyTz.js | 536 +++++++++++++++++++++++++++++++++ apps/ftclock/mkFourTwentyTz.py | 46 +++ apps/ftclock/screenshot.png | Bin 0 -> 17635 bytes 9 files changed, 699 insertions(+) create mode 100644 apps/ftclock/ChangeLog create mode 100644 apps/ftclock/app-icon.js create mode 100644 apps/ftclock/app.js create mode 100644 apps/ftclock/app.png create mode 100644 apps/ftclock/fourTwenty.js create mode 100644 apps/ftclock/fourTwentyTz.js create mode 100644 apps/ftclock/mkFourTwentyTz.py create mode 100644 apps/ftclock/screenshot.png diff --git a/apps.json b/apps.json index e5e9f8f02..3dc4c3577 100644 --- a/apps.json +++ b/apps.json @@ -5062,5 +5062,23 @@ {"name":"ltherm.app.js","url":"app.js"}, {"name":"ltherm.img","url":"icon.js","evaluate":true} ] + }, + { + "id": "ftclock", + "name": "Four Twenty Clock", + "version": "0.01", + "description": "A clock that tells when and where it's going to be 4:20 next", + "icon": "app.png", + "screenshots": [{"url":"screenshot.png"}], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS","BANGLEJS2"], + "allow_emulator": true, + "storage": [ + {"name":"ftclock.app.js","url":"app.js"}, + {"name":"fourTwenty","url":"fourTwenty.js"}, + {"name":"fourTwentyTz","url":"fourTwentyTz.js"}, + {"name":"ftclock.img","url":"app-icon.js","evaluate":true} + ] } ] diff --git a/apps/ftclock/ChangeLog b/apps/ftclock/ChangeLog new file mode 100644 index 000000000..9db0e26c5 --- /dev/null +++ b/apps/ftclock/ChangeLog @@ -0,0 +1 @@ +0.01: first release diff --git a/apps/ftclock/app-icon.js b/apps/ftclock/app-icon.js new file mode 100644 index 000000000..297847e95 --- /dev/null +++ b/apps/ftclock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwghC/AH4A/AH4A/AAMHu4ACuwHBs4HDsEGBIQLCsADBgwPDCAQGEuwXFBwI0GEAMHuAGCCoMHC4pMHEAIXEAgIGEBwI9BC4wSCC8IVCMAwIBs4XKUQJfITQgXCDwp8EHAqaECoLFEu4cDBIggBs6uFZozuGBAVmC4g+FMgZQEZQ5vGC4iRIC5IrDN4h5EC5J3BCoIKGgyaEC44VBC46yEDgoeDgxqLC5SCMAgoTFY47GFC4xFBdwwPBD4oWFAH4A/AH4A/AH4AjA==")) diff --git a/apps/ftclock/app.js b/apps/ftclock/app.js new file mode 100644 index 000000000..1aed8da54 --- /dev/null +++ b/apps/ftclock/app.js @@ -0,0 +1,52 @@ +let getNextFourTwenty = require("fourTwenty").getNextFourTwenty; +require("FontTeletext10x18Ascii").add(Graphics); +let leaf_img = "\x17\x18\x81\x00\x00\x10\x00\x00 \x00\x00@\x00\x01\xc0\x00\x03\x80\x00\x0f\x80\x00\x1f\x00\x00>\x00\x00|\x00\xc0\xf8\x19\xe1\xf0\xf1\xe3\xe3\xc3\xf7\xdf\x83\xff\xfe\x03\xff\xf8\x03\xff\xe0\x03\xff\x80\x03\xfe\x00\x7f\xff\xc0\xff\xff\xc0\x06\xe0\x00\x18\xc0\x00 \x80\x00\x00\x00"; + +// timeout used to update every minute +let drawTimeout; + +// schedule a draw for the next minute +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + + +function draw() { + g.reset(); + g.setBgColor("#ffffff"); + let date = new Date(); + let timeStr = require("locale").time(date,1); + let next420 = getNextFourTwenty(); + g.clearRect(0,26,g.getWidth(),g.getHeight()); + g.setColor("#00ff00").setFontAlign(0,-1).setFont("Teletext10x18Ascii",2); + g.drawString(next420.minutes? timeStr: `\0${leaf_img}${timeStr}\0${leaf_img}`, g.getWidth()/2, 28); + g.setColor("#000000"); + g.setFontAlign(-1,-1).setFont("Teletext10x18Ascii"); + g.drawString(g.wrapString(next420.text, g.getWidth()-8).join("\n"),4,60); + + // queue draw in one minute + queueDraw(); +} + +// Clear the screen once, at startup +g.clear(); +// Load widgets +Bangle.loadWidgets(); +Bangle.drawWidgets(); +// draw immediately at first, queue update +draw(); +// Stop updates when LCD is off, restart when on +Bangle.on('lcdPower',on=>{ + if (on) { + draw(); // draw immediately, queue redraw + } else { // stop draw timer + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + } +}); +// Show launcher when middle button pressed +Bangle.setUI("clock"); diff --git a/apps/ftclock/app.png b/apps/ftclock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..0553837ca47ff2061105cd49c40a86d8f66d4b7b GIT binary patch literal 6742 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 && current_min<25) { + current_time -= current_min-20; // 5 minutes grace period + } + let offset = 16*60+20-current_time; + if (offset<0) { + offset += 24*60; + } + return offset; +} + +function makeFourTwentyText(minutes, places) { + //let plural = minutes==1? "": "s"; + //let msgprefix = minutes? `${minutes} minute${plural} to`: "It is now"; + let msgprefix = minutes? `${minutes}m to`: "It is now"; + let msgsuffix = places.length>1? ", and other fine places": ""; + let msgplace = places[Math.floor(Math.random()*places.length)]; + return `${msgprefix} 4:20 at ${msgplace}${msgsuffix}.`; +} + +function getNextFourTwenty() { + let offs = get420offset(); + for (let i=0; i2: # e.g. America/North_Dakota/New_Salem + country = parts[1] # e.g. North Dakota + else: # e.g. America/Denver + country = countries[r[1]] # e.g. United States + if country==city: # Avoid awkward searches like "Anguilla, Anguilla" + country = r[1] # Use code instead + zones[int(r[0])] = {"name":', '.join((city,country))} +now = int(time.time()) +for r in csv.reader(open("timezone.csv")): + code = int(r[0]) + if code not in zones: + continue + starttime = int(r[2] or "0") # Bugger. They're feeding us blanks for UTC now + offs = int(r[3]) + if offs < 0: + offs += 60*60*24 + d = zones[code] + if starttime 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 W_a_}>UQb*A0000 Date: Tue, 21 Dec 2021 01:34:30 +0200 Subject: [PATCH 2/5] ftclock README and better screenshots --- apps.json | 3 ++- apps/ftclock/README.md | 16 ++++++++++++++++ apps/ftclock/mkFourTwentyTz.py | 4 ++-- apps/ftclock/screenshot.png | Bin 17635 -> 15457 bytes apps/ftclock/screenshot1.png | Bin 0 -> 19973 bytes 5 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 apps/ftclock/README.md create mode 100644 apps/ftclock/screenshot1.png diff --git a/apps.json b/apps.json index 3dc4c3577..6a9fc7309 100644 --- a/apps.json +++ b/apps.json @@ -5069,11 +5069,12 @@ "version": "0.01", "description": "A clock that tells when and where it's going to be 4:20 next", "icon": "app.png", - "screenshots": [{"url":"screenshot.png"}], + "screenshots": [{"url":"screenshot.png"}, {"url":"screenshot1.png"}], "type": "clock", "tags": "clock", "supports": ["BANGLEJS","BANGLEJS2"], "allow_emulator": true, + "readme": "README.md", "storage": [ {"name":"ftclock.app.js","url":"app.js"}, {"name":"fourTwenty","url":"fourTwenty.js"}, diff --git a/apps/ftclock/README.md b/apps/ftclock/README.md new file mode 100644 index 000000000..ed3b7b3bd --- /dev/null +++ b/apps/ftclock/README.md @@ -0,0 +1,16 @@ +# Four Twenty Clock + +A clock that tells when and where it's going to be [4:20](https://en.wikipedia.org/wiki/420_(cannabis_culture%29) next + +![screensot](screenshot.png) ![screenshot at 4:20](screenshot1.png) + +## Note + +Once in a while, there'd be updates to the [timezone database](https://timezonedb.com/download) which +would require updating `fourTwentyTz.js`. I'll do my best to release a new version every time this happens, +but if you ever need to do this yourself, just run `python mkFourTwentyTz.py` (after downloading the timezone CSV files. +See comment at the top of the script). + +## Creator + +[Nimrod Kerrett](zzzen.com) diff --git a/apps/ftclock/mkFourTwentyTz.py b/apps/ftclock/mkFourTwentyTz.py index 4de17c3cf..713b68059 100644 --- a/apps/ftclock/mkFourTwentyTz.py +++ b/apps/ftclock/mkFourTwentyTz.py @@ -1,4 +1,4 @@ -# Generates tz.js[on] from time zone csv files +# Generates fourTwentyTz.js from time zone csv files # get latest files from https://timezonedb.com/download import csv,json,time,os,math countries = {} @@ -35,7 +35,7 @@ for k in zones: continue offsdict[d["offs"]] = offsdict.get(d["offs"],[])+[d["name"]] res = sorted([[k,sorted(offsdict[k])] for k in offsdict],key=lambda x:-x[0]) -js = open("tz.js","w") +js = open("fourTwentyTz.js","w") js.write("// Generated by mk420tz.py - see https://github.com/thedod/BangleApps/420clock\n") js.write("// (version: {0})\n".format(time.ctime(time.time()))) js.write("// Data source: https://timezonedb.com/files/timezonedb.csv.zip\n") diff --git a/apps/ftclock/screenshot.png b/apps/ftclock/screenshot.png index e04f766463b05d0ff9826cbc8b8f10c1034d8307..9247e0e04a55b533955a24369e4d29d293f3b38d 100644 GIT binary patch literal 15457 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 X3LR-t-PP6E00000NkvXXu0mjf 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 W_a_}>UQb*A0000 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 ULn*~EGXMYp07*qoM6N<$f|JYjo&W#< literal 0 HcmV?d00001 From d80ebe08ede97b367932925bce540d8ed5a14d33 Mon Sep 17 00:00:00 2001 From: The Dod Date: Tue, 21 Dec 2021 10:56:37 +0200 Subject: [PATCH 3/5] README edit (gh markdown chokes on "(" in url) --- apps/ftclock/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ftclock/README.md b/apps/ftclock/README.md index ed3b7b3bd..665a7693d 100644 --- a/apps/ftclock/README.md +++ b/apps/ftclock/README.md @@ -1,6 +1,6 @@ # Four Twenty Clock -A clock that tells when and where it's going to be [4:20](https://en.wikipedia.org/wiki/420_(cannabis_culture%29) next +A clock that tells when and where it's going to be [4:20](https://en.wikipedia.org/wiki/420_%28cannabis_culture%29) next ![screensot](screenshot.png) ![screenshot at 4:20](screenshot1.png) From fea7c2dcf817fbb9e6fe402fae1d79bf8089cab2 Mon Sep 17 00:00:00 2001 From: The Dod Date: Wed, 5 Jan 2022 13:49:02 +0200 Subject: [PATCH 4/5] typo fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 😖 --- apps.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps.json b/apps.json index 04cc12a37..b0ebce263 100644 --- a/apps.json +++ b/apps.json @@ -5139,6 +5139,7 @@ {"name":"fourTwenty","url":"fourTwenty.js"}, {"name":"fourTwentyTz","url":"fourTwentyTz.js"}, {"name":"ftclock.img","url":"app-icon.js","evaluate":true} + ] }, { "id": "slash", From 6896b282b2ac83fdf6c4149ff463493a5b8c07a6 Mon Sep 17 00:00:00 2001 From: The Dod Date: Sun, 9 Jan 2022 14:17:14 +0200 Subject: [PATCH 5/5] Rewrite mkFourTwentyTz in JS (instead of Python) --- apps/ftclock/.gitignore | 4 + apps/ftclock/README.md | 18 +- apps/ftclock/fourTwentyTz.js | 997 +++++++++++++++------------------ apps/ftclock/mkFourTwentyTz.js | 74 +++ apps/ftclock/mkFourTwentyTz.py | 46 -- apps/ftclock/package.json | 15 + 6 files changed, 568 insertions(+), 586 deletions(-) create mode 100644 apps/ftclock/.gitignore create mode 100644 apps/ftclock/mkFourTwentyTz.js delete mode 100644 apps/ftclock/mkFourTwentyTz.py create mode 100644 apps/ftclock/package.json diff --git a/apps/ftclock/.gitignore b/apps/ftclock/.gitignore new file mode 100644 index 000000000..b384cf1f2 --- /dev/null +++ b/apps/ftclock/.gitignore @@ -0,0 +1,4 @@ +timezonedb.csv.zip +country.csv +zone.csv +timezone.csv diff --git a/apps/ftclock/README.md b/apps/ftclock/README.md index 665a7693d..f30151552 100644 --- a/apps/ftclock/README.md +++ b/apps/ftclock/README.md @@ -4,12 +4,20 @@ A clock that tells when and where it's going to be [4:20](https://en.wikipedia.o ![screensot](screenshot.png) ![screenshot at 4:20](screenshot1.png) -## Note +## Generating `fourTwentyTz.js` -Once in a while, there'd be updates to the [timezone database](https://timezonedb.com/download) which -would require updating `fourTwentyTz.js`. I'll do my best to release a new version every time this happens, -but if you ever need to do this yourself, just run `python mkFourTwentyTz.py` (after downloading the timezone CSV files. -See comment at the top of the script). +Once in a while we need to regenerate it for 2 reasons: + +* One or more places got in or out of daylight saving time (DST) mode. +* The database saying _when_ places enter/exit DST mode got updated. + +I'll do my best to release a new version every time this happens, +but if you ever need to do this yourself, here's how: + +* `cd` to the `ftclock` folder +* If you haven't done so yet, run `npm install` there (this would create the `node_modules` folder). +* Get and unzip the latest `timezone.csv.zip` from https://timezonedb.com/download +* Run `npm run make` ## Creator diff --git a/apps/ftclock/fourTwentyTz.js b/apps/ftclock/fourTwentyTz.js index e41f3fdd0..cebab42cb 100644 --- a/apps/ftclock/fourTwentyTz.js +++ b/apps/ftclock/fourTwentyTz.js @@ -1,536 +1,463 @@ -// Generated by mk420tz.py - see https://github.com/thedod/BangleApps/420clock -// (version: Sat Dec 18 10:17:32 2021) +// Generated by mkFourTwentyTz.js // Data source: https://timezonedb.com/files/timezonedb.csv.zip -// (version: Sat Oct 16 01:48:14 2021) -exports.timezones = [ - [ - 1380, - [ - "Azores, Portugal", - "Cape Verde, Cabo Verde", - "Scoresbysund, Greenland" - ] - ], - [ - 1320, - [ - "Noronha, Brazil", - "South Georgia, South Georgia and the South Sandwich Islands" - ] - ], - [ - 1260, - [ - "Araguaina, Brazil", - "Asuncion, Paraguay", - "Bahia, Brazil", - "Belem, Brazil", - "Buenos Aires, Argentina", - "Catamarca, Argentina", - "Cayenne, French Guiana", - "Cordoba, Argentina", - "Fortaleza, Brazil", - "Jujuy, Argentina", - "La Rioja, Argentina", - "Maceio, Brazil", - "Mendoza, Argentina", - "Miquelon, Saint Pierre and Miquelon", - "Montevideo, Uruguay", - "Nuuk, Greenland", - "Palmer, Antarctica", - "Paramaribo, Suriname", - "Punta Arenas, Chile", - "Recife, Brazil", - "Rio Gallegos, Argentina", - "Rothera, Antarctica", - "Salta, Argentina", - "San Juan, Argentina", - "San Luis, Argentina", - "Santarem, Brazil", - "Santiago, Chile", - "Sao Paulo, Brazil", - "Stanley, Falkland Islands (Malvinas)", - "Tucuman, Argentina", - "Ushuaia, Argentina" - ] - ], - [ - 1200, - [ - "Anguilla, AI", - "Antigua, Antigua and Barbuda", - "Aruba, AW", - "Barbados, BB", - "Bermuda, BM", - "Blanc-Sablon, Canada", - "Boa Vista, Brazil", - "Campo Grande, Brazil", - "Caracas, Venezuela (Bolivarian Republic of)", - "Cuiaba, Brazil", - "Curacao, Cura\u00e7ao", - "Dominica, DM", - "Glace Bay, Canada", - "Goose Bay, Canada", - "Grenada, GD", - "Guadeloupe, GP", - "Guyana, GY", - "Halifax, Canada", - "Kralendijk, Bonaire, Sint Eustatius and Saba", - "La Paz, Bolivia (Plurinational State of)", - "Lower Princes, Sint Maarten (Dutch part)", - "Manaus, Brazil", - "Marigot, Saint Martin (French part)", - "Martinique, MQ", - "Moncton, Canada", - "Montserrat, MS", - "Port of Spain, Trinidad and Tobago", - "Porto Velho, Brazil", - "Puerto Rico, PR", - "Santo Domingo, Dominican Republic", - "St Barthelemy, Saint Barth\u00e9lemy", - "St Kitts, Saint Kitts and Nevis", - "St Lucia, Saint Lucia", - "St Thomas, Virgin Islands (U.S.)", - "St Vincent, Saint Vincent and the Grenadines", - "Thule, Greenland", - "Tortola, Virgin Islands (British)" - ] - ], - [ - 1140, - [ - "Atikokan, Canada", - "Bogota, Colombia", - "Cancun, Mexico", - "Cayman, Cayman Islands", - "Detroit, United States of America", - "Easter, Chile", - "Eirunepe, Brazil", - "Grand Turk, Turks and Caicos Islands", - "Guayaquil, Ecuador", - "Havana, Cuba", - "Indianapolis, Indiana", - "Iqaluit, Canada", - "Jamaica, JM", - "Lima, Peru", - "Louisville, Kentucky", - "Marengo, Indiana", - "Monticello, Kentucky", - "Nassau, Bahamas", - "New York, United States of America", - "Nipigon, Canada", - "Panama, PA", - "Pangnirtung, Canada", - "Petersburg, Indiana", - "Port-au-Prince, Haiti", - "Rio Branco, Brazil", - "Thunder Bay, Canada", - "Toronto, Canada", - "Vevay, Indiana", - "Vincennes, Indiana", - "Winamac, Indiana" - ] - ], - [ - 1080, - [ - "Bahia Banderas, Mexico", - "Belize, BZ", - "Beulah, North Dakota", - "Center, North Dakota", - "Chicago, United States of America", - "Costa Rica, CR", - "El Salvador, SV", - "Galapagos, Ecuador", - "Guatemala, GT", - "Knox, Indiana", - "Managua, Nicaragua", - "Matamoros, Mexico", - "Menominee, United States of America", - "Merida, Mexico", - "Mexico City, Mexico", - "Monterrey, Mexico", - "New Salem, North Dakota", - "Rainy River, Canada", - "Rankin Inlet, Canada", - "Regina, Canada", - "Resolute, Canada", - "Swift Current, Canada", - "Tegucigalpa, Honduras", - "Tell City, Indiana", - "Winnipeg, Canada" - ] - ], - [ - 1020, - [ - "Boise, United States of America", - "Cambridge Bay, Canada", - "Chihuahua, Mexico", - "Creston, Canada", - "Dawson Creek, Canada", - "Dawson, Canada", - "Denver, United States of America", - "Edmonton, Canada", - "Fort Nelson, Canada", - "Hermosillo, Mexico", - "Inuvik, Canada", - "Mazatlan, Mexico", - "Ojinaga, Mexico", - "Phoenix, United States of America", - "Whitehorse, Canada", - "Yellowknife, Canada" - ] - ], - [ - 960, - [ - "Los Angeles, United States of America", - "Pitcairn, PN", - "Tijuana, Mexico", - "Vancouver, Canada" - ] - ], - [ - 900, - [ - "Anchorage, United States of America", - "Gambier, French Polynesia", - "Juneau, United States of America", - "Metlakatla, United States of America", - "Nome, United States of America", - "Sitka, United States of America", - "Yakutat, United States of America" - ] - ], - [ - 840, - [ - "Adak, United States of America", - "Honolulu, United States of America", - "Kiritimati, Kiribati", - "Rarotonga, Cook Islands", - "Tahiti, French Polynesia" - ] - ], - [ - 780, - [ - "Apia, Samoa", - "Auckland, New Zealand", - "Fakaofo, Tokelau", - "Kanton, Kiribati", - "McMurdo, Antarctica", - "Midway, United States Minor Outlying Islands", - "Niue, NU", - "Pago Pago, American Samoa", - "Tongatapu, Tonga" - ] - ], - [ - 720, - [ - "Anadyr, Russian Federation", - "Fiji, FJ", - "Funafuti, Tuvalu", - "Kamchatka, Russian Federation", - "Kwajalein, Marshall Islands", - "Majuro, Marshall Islands", - "Nauru, NR", - "Norfolk, Norfolk Island", - "Tarawa, Kiribati", - "Wake, United States Minor Outlying Islands", - "Wallis, Wallis and Futuna" - ] - ], - [ - 660, - [ - "Bougainville, Papua New Guinea", - "Casey, Antarctica", - "Efate, Vanuatu", - "Guadalcanal, Solomon Islands", - "Hobart, Australia", - "Kosrae, Micronesia (Federated States of)", - "Lord Howe, Australia", - "Macquarie, Australia", - "Magadan, Russian Federation", - "Melbourne, Australia", - "Noumea, New Caledonia", - "Pohnpei, Micronesia (Federated States of)", - "Sakhalin, Russian Federation", - "Srednekolymsk, Russian Federation", - "Sydney, Australia" - ] - ], - [ - 600, - [ - "Brisbane, Australia", - "Chuuk, Micronesia (Federated States of)", - "DumontDUrville, Antarctica", - "Guam, GU", - "Lindeman, Australia", - "Port Moresby, Papua New Guinea", - "Saipan, Northern Mariana Islands", - "Ust-Nera, Russian Federation", - "Vladivostok, Russian Federation" - ] - ], - [ - 540, - [ - "Chita, Russian Federation", - "Dili, Timor-Leste", - "Jayapura, Indonesia", - "Khandyga, Russian Federation", - "Palau, PW", - "Pyongyang, Korea (Democratic People's Republic of)", - "Seoul, Korea, Republic of", - "Tokyo, Japan", - "Yakutsk, Russian Federation" - ] - ], - [ - 480, - [ - "Brunei, Brunei Darussalam", - "Choibalsan, Mongolia", - "Hong Kong, HK", - "Irkutsk, Russian Federation", - "Kuala Lumpur, Malaysia", - "Kuching, Malaysia", - "Macau, Macao", - "Makassar, Indonesia", - "Manila, Philippines", - "Perth, Australia", - "Shanghai, China", - "Singapore, SG", - "Taipei, Taiwan, Province of China", - "Ulaanbaatar, Mongolia" - ] - ], - [ - 420, - [ - "Bangkok, Thailand", - "Barnaul, Russian Federation", - "Christmas, Christmas Island", - "Davis, Antarctica", - "Ho Chi Minh, Viet Nam", - "Hovd, Mongolia", - "Jakarta, Indonesia", - "Krasnoyarsk, Russian Federation", - "Novokuznetsk, Russian Federation", - "Novosibirsk, Russian Federation", - "Phnom Penh, Cambodia", - "Pontianak, Indonesia", - "Tomsk, Russian Federation", - "Vientiane, Lao People's Democratic Republic" - ] - ], - [ - 360, - [ - "Almaty, Kazakhstan", - "Bishkek, Kyrgyzstan", - "Chagos, British Indian Ocean Territory", - "Dhaka, Bangladesh", - "Omsk, Russian Federation", - "Qostanay, Kazakhstan", - "Thimphu, Bhutan", - "Urumqi, China", - "Vostok, Antarctica" - ] - ], - [ - 300, - [ - "Aqtau, Kazakhstan", - "Aqtobe, Kazakhstan", - "Ashgabat, Turkmenistan", - "Atyrau, Kazakhstan", - "Dushanbe, Tajikistan", - "Karachi, Pakistan", - "Kerguelen, French Southern Territories", - "Maldives, MV", - "Mawson, Antarctica", - "Oral, Kazakhstan", - "Qyzylorda, Kazakhstan", - "Samarkand, Uzbekistan", - "Tashkent, Uzbekistan", - "Yekaterinburg, Russian Federation" - ] - ], - [ - 240, - [ - "Astrakhan, Russian Federation", - "Baku, Azerbaijan", - "Dubai, United Arab Emirates", - "Mahe, Seychelles", - "Mauritius, MU", - "Muscat, Oman", - "Reunion, R\u00e9union", - "Samara, Russian Federation", - "Saratov, Russian Federation", - "Tbilisi, Georgia", - "Ulyanovsk, Russian Federation", - "Yerevan, Armenia" - ] - ], - [ - 180, - [ - "Addis Ababa, Ethiopia", - "Aden, Yemen", - "Antananarivo, Madagascar", - "Asmara, Eritrea", - "Baghdad, Iraq", - "Bahrain, BH", - "Comoro, Comoros", - "Dar es Salaam, Tanzania, United Republic of", - "Djibouti, DJ", - "Istanbul, Turkey", - "Kampala, Uganda", - "Kirov, Russian Federation", - "Kuwait, KW", - "Mayotte, YT", - "Minsk, Belarus", - "Mogadishu, Somalia", - "Moscow, Russian Federation", - "Nairobi, Kenya", - "Qatar, QA", - "Riyadh, Saudi Arabia", - "Simferopol, Ukraine", - "Syowa, Antarctica", - "Volgograd, Russian Federation" - ] - ], - [ - 120, - [ - "Amman, Jordan", - "Athens, Greece", - "Beirut, Lebanon", - "Blantyre, Malawi", - "Bucharest, Romania", - "Bujumbura, Burundi", - "Cairo, Egypt", - "Chisinau, Moldova, Republic of", - "Damascus, Syrian Arab Republic", - "Famagusta, Cyprus", - "Gaborone, Botswana", - "Gaza, Palestine, State of", - "Harare, Zimbabwe", - "Hebron, Palestine, State of", - "Helsinki, Finland", - "Jerusalem, Israel", - "Johannesburg, South Africa", - "Juba, South Sudan", - "Kaliningrad, Russian Federation", - "Khartoum, Sudan", - "Kiev, Ukraine", - "Kigali, Rwanda", - "Lubumbashi, Congo, Democratic Republic of the", - "Lusaka, Zambia", - "Maputo, Mozambique", - "Mariehamn, \u00c5land Islands", - "Maseru, Lesotho", - "Mbabane, Eswatini", - "Nicosia, Cyprus", - "Riga, Latvia", - "Sofia, Bulgaria", - "Tallinn, Estonia", - "Tripoli, Libya", - "Uzhgorod, Ukraine", - "Vilnius, Lithuania", - "Windhoek, Namibia", - "Zaporozhye, Ukraine" - ] - ], - [ - 60, - [ - "Algiers, Algeria", - "Amsterdam, Netherlands", - "Andorra, AD", - "Bangui, Central African Republic", - "Belgrade, Serbia", - "Berlin, Germany", - "Bratislava, Slovakia", - "Brazzaville, Congo", - "Brussels, Belgium", - "Budapest, Hungary", - "Busingen, Germany", - "Casablanca, Morocco", - "Ceuta, Spain", - "Copenhagen, Denmark", - "Douala, Cameroon", - "El Aaiun, Western Sahara", - "Gibraltar, GI", - "Kinshasa, Congo, Democratic Republic of the", - "Lagos, Nigeria", - "Libreville, Gabon", - "Ljubljana, Slovenia", - "Longyearbyen, Svalbard and Jan Mayen", - "Luanda, Angola", - "Luxembourg, LU", - "Madrid, Spain", - "Malabo, Equatorial Guinea", - "Malta, MT", - "Monaco, MC", - "Ndjamena, Chad", - "Niamey, Niger", - "Oslo, Norway", - "Paris, France", - "Podgorica, Montenegro", - "Porto-Novo, Benin", - "Prague, Czechia", - "Rome, Italy", - "San Marino, SM", - "Sarajevo, Bosnia and Herzegovina", - "Skopje, North Macedonia", - "Stockholm, Sweden", - "Tirane, Albania", - "Tunis, Tunisia", - "Vaduz, Liechtenstein", - "Vatican, Holy See", - "Vienna, Austria", - "Warsaw, Poland", - "Zagreb, Croatia", - "Zurich, Switzerland" - ] - ], - [ - 0, - [ - "Abidjan, C\u00f4te d'Ivoire", - "Accra, Ghana", - "Bamako, Mali", - "Banjul, Gambia", - "Bissau, Guinea-Bissau", - "Canary, Spain", - "Conakry, Guinea", - "Dakar, Senegal", - "Danmarkshavn, Greenland", - "Dublin, Ireland", - "Faroe, Faroe Islands", - "Freetown, Sierra Leone", - "Guernsey, GG", - "Isle of Man, IM", - "Jersey, JE", - "Lisbon, Portugal", - "Lome, Togo", - "London, United Kingdom of Great Britain and Northern Ireland", - "Madeira, Portugal", - "Monrovia, Liberia", - "Nouakchott, Mauritania", - "Ouagadougou, Burkina Faso", - "Reykjavik, Iceland", - "Sao Tome, Sao Tome and Principe", - "St Helena, Saint Helena, Ascension and Tristan da Cunha", - "Troll, Antarctica" - ] - ] -]; +// Sun Jan 09 2022 13:21:47 GMT+0200 (Israel Standard Time) +exports.timezones = { + "0": [ + "Troll, Antarctica", + "Ouagadougou, Burkina Faso", + "Abidjan, Côte d'Ivoire", + "Canary, Spain", + "Faroe, Faroe Islands", + "London, United Kingdom of Great Britain and Northern Ireland", + "Guernsey, Guernsey", + "Accra, Ghana", + "Danmarkshavn, Greenland", + "Banjul, Gambia", + "Conakry, Guinea", + "Bissau, Guinea-Bissau", + "Dublin, Ireland", + "Isle of_Man, Isle of Man", + "Reykjavik, Iceland", + "Jersey, Jersey", + "Monrovia, Liberia", + "Bamako, Mali", + "Nouakchott, Mauritania", + "Lisbon, Portugal", + "Madeira, Portugal", + "St Helena, Saint Helena, Ascension and Tristan da Cunha", + "Freetown, Sierra Leone", + "Dakar, Senegal", + "Sao Tome, Sao Tome and Principe", + "Lome, Togo" + ], + "60": [ + "Andorra, Andorra", + "Tirane, Albania", + "Luanda, Angola", + "Vienna, Austria", + "Sarajevo, Bosnia and Herzegovina", + "Brussels, Belgium", + "Porto-Novo, Benin", + "Kinshasa, Congo, Democratic Republic of the", + "Bangui, Central African Republic", + "Brazzaville, Congo", + "Zurich, Switzerland", + "Douala, Cameroon", + "Prague, Czechia", + "Berlin, Germany", + "Busingen, Germany", + "Copenhagen, Denmark", + "Algiers, Algeria", + "El Aaiun, Western Sahara", + "Madrid, Spain", + "Ceuta, Spain", + "Paris, France", + "Libreville, Gabon", + "Gibraltar, Gibraltar", + "Malabo, Equatorial Guinea", + "Zagreb, Croatia", + "Budapest, Hungary", + "Rome, Italy", + "Vaduz, Liechtenstein", + "Luxembourg, Luxembourg", + "Casablanca, Morocco", + "Monaco, Monaco", + "Podgorica, Montenegro", + "Skopje, North Macedonia", + "Malta, Malta", + "Niamey, Niger", + "Lagos, Nigeria", + "Amsterdam, Netherlands", + "Oslo, Norway", + "Warsaw, Poland", + "Belgrade, Serbia", + "Stockholm, Sweden", + "Ljubljana, Slovenia", + "Longyearbyen, Svalbard and Jan Mayen", + "Bratislava, Slovakia", + "San Marino, San Marino", + "Ndjamena, Chad", + "Tunis, Tunisia", + "Vatican, Holy See" + ], + "120": [ + "Mariehamn, Åland Islands", + "Sofia, Bulgaria", + "Bujumbura, Burundi", + "Gaborone, Botswana", + "Lubumbashi, Congo, Democratic Republic of the", + "Nicosia, Cyprus", + "Famagusta, Cyprus", + "Tallinn, Estonia", + "Cairo, Egypt", + "Helsinki, Finland", + "Athens, Greece", + "Jerusalem, Israel", + "Amman, Jordan", + "Beirut, Lebanon", + "Maseru, Lesotho", + "Vilnius, Lithuania", + "Riga, Latvia", + "Tripoli, Libya", + "Chisinau, Moldova, Republic of", + "Blantyre, Malawi", + "Maputo, Mozambique", + "Windhoek, Namibia", + "Gaza, Palestine, State of", + "Hebron, Palestine, State of", + "Bucharest, Romania", + "Kaliningrad, Russian Federation", + "Kigali, Rwanda", + "Khartoum, Sudan", + "Juba, South Sudan", + "Damascus, Syrian Arab Republic", + "Mbabane, Eswatini", + "Kiev, Ukraine", + "Uzhgorod, Ukraine", + "Zaporozhye, Ukraine", + "Johannesburg, South Africa", + "Lusaka, Zambia", + "Harare, Zimbabwe" + ], + "180": [ + "Syowa, Antarctica", + "Bahrain, Bahrain", + "Minsk, Belarus", + "Djibouti, Djibouti", + "Asmara, Eritrea", + "Addis Ababa, Ethiopia", + "Baghdad, Iraq", + "Nairobi, Kenya", + "Comoro, Comoros", + "Kuwait, Kuwait", + "Antananarivo, Madagascar", + "Qatar, Qatar", + "Moscow, Russian Federation", + "Simferopol, Ukraine", + "Kirov, Russian Federation", + "Volgograd, Russian Federation", + "Riyadh, Saudi Arabia", + "Mogadishu, Somalia", + "Istanbul, Turkey", + "Dar es_Salaam, Tanzania, United Republic of", + "Kampala, Uganda", + "Aden, Yemen", + "Mayotte, Mayotte" + ], + "240": [ + "Dubai, United Arab Emirates", + "Yerevan, Armenia", + "Baku, Azerbaijan", + "Tbilisi, Georgia", + "Mauritius, Mauritius", + "Muscat, Oman", + "Reunion, Réunion", + "Astrakhan, Russian Federation", + "Saratov, Russian Federation", + "Ulyanovsk, Russian Federation", + "Samara, Russian Federation", + "Mahe, Seychelles" + ], + "300": [ + "Mawson, Antarctica", + "Qyzylorda, Kazakhstan", + "Aqtobe, Kazakhstan", + "Aqtau, Kazakhstan", + "Atyrau, Kazakhstan", + "Oral, Kazakhstan", + "Maldives, Maldives", + "Karachi, Pakistan", + "Yekaterinburg, Russian Federation", + "Kerguelen, French Southern Territories", + "Dushanbe, Tajikistan", + "Ashgabat, Turkmenistan", + "Samarkand, Uzbekistan", + "Tashkent, Uzbekistan" + ], + "360": [ + "Vostok, Antarctica", + "Dhaka, Bangladesh", + "Thimphu, Bhutan", + "Urumqi, China", + "Chagos, British Indian Ocean Territory", + "Bishkek, Kyrgyzstan", + "Almaty, Kazakhstan", + "Qostanay, Kazakhstan", + "Omsk, Russian Federation" + ], + "420": [ + "Davis, Antarctica", + "Christmas, Christmas Island", + "Jakarta, Indonesia", + "Pontianak, Indonesia", + "Phnom Penh, Cambodia", + "Vientiane, Lao People's Democratic Republic", + "Hovd, Mongolia", + "Novosibirsk, Russian Federation", + "Barnaul, Russian Federation", + "Tomsk, Russian Federation", + "Novokuznetsk, Russian Federation", + "Krasnoyarsk, Russian Federation", + "Bangkok, Thailand", + "Ho Chi_Minh, Viet Nam" + ], + "480": [ + "Perth, Australia", + "Brunei, Brunei Darussalam", + "Shanghai, China", + "Hong Kong, Hong Kong", + "Makassar, Indonesia", + "Ulaanbaatar, Mongolia", + "Choibalsan, Mongolia", + "Macau, Macao", + "Kuala Lumpur, Malaysia", + "Kuching, Malaysia", + "Manila, Philippines", + "Irkutsk, Russian Federation", + "Singapore, Singapore", + "Taipei, Taiwan, Province of China" + ], + "540": [ + "Jayapura, Indonesia", + "Tokyo, Japan", + "Pyongyang, Korea (Democratic People's Republic of)", + "Seoul, Korea, Republic of", + "Palau, Palau", + "Chita, Russian Federation", + "Yakutsk, Russian Federation", + "Khandyga, Russian Federation", + "Dili, Timor-Leste" + ], + "600": [ + "DumontDUrville, Antarctica", + "Brisbane, Australia", + "Lindeman, Australia", + "Chuuk, Micronesia (Federated States of)", + "Guam, Guam", + "Saipan, Northern Mariana Islands", + "Port Moresby, Papua New Guinea", + "Vladivostok, Russian Federation", + "Ust-Nera, Russian Federation" + ], + "660": [ + "Casey, Antarctica", + "Lord Howe, Australia", + "Macquarie, Australia", + "Hobart, Australia", + "Melbourne, Australia", + "Sydney, Australia", + "Pohnpei, Micronesia (Federated States of)", + "Kosrae, Micronesia (Federated States of)", + "Noumea, New Caledonia", + "Bougainville, Papua New Guinea", + "Magadan, Russian Federation", + "Sakhalin, Russian Federation", + "Srednekolymsk, Russian Federation", + "Guadalcanal, Solomon Islands", + "Efate, Vanuatu" + ], + "720": [ + "Tarawa, Kiribati", + "Majuro, Marshall Islands", + "Kwajalein, Marshall Islands", + "Norfolk, Norfolk Island", + "Nauru, Nauru", + "Kamchatka, Russian Federation", + "Anadyr, Russian Federation", + "Funafuti, Tuvalu", + "Wake, United States Minor Outlying Islands", + "Wallis, Wallis and Futuna" + ], + "780": [ + "McMurdo, Antarctica", + "Pago Pago, American Samoa", + "Fiji, Fiji", + "Kanton, Kiribati", + "Niue, Niue", + "Auckland, New Zealand", + "Fakaofo, Tokelau", + "Tongatapu, Tonga", + "Midway, United States Minor Outlying Islands", + "Apia, Samoa" + ], + "840": [ + "Rarotonga, Cook Islands", + "Kiritimati, Kiribati", + "Tahiti, French Polynesia", + "Adak, United States of America", + "Honolulu, United States of America" + ], + "900": [ + "Gambier, French Polynesia", + "Anchorage, United States of America", + "Juneau, United States of America", + "Sitka, United States of America", + "Metlakatla, United States of America", + "Yakutat, United States of America", + "Nome, United States of America" + ], + "960": [ + "Vancouver, Canada", + "Tijuana, Mexico", + "Pitcairn, Pitcairn", + "Los Angeles, United States of America" + ], + "1020": [ + "Edmonton, Canada", + "Cambridge Bay, Canada", + "Yellowknife, Canada", + "Inuvik, Canada", + "Creston, Canada", + "Dawson Creek, Canada", + "Fort Nelson, Canada", + "Whitehorse, Canada", + "Dawson, Canada", + "Mazatlan, Mexico", + "Chihuahua, Mexico", + "Ojinaga, Mexico", + "Hermosillo, Mexico", + "Denver, United States of America", + "Boise, United States of America", + "Phoenix, United States of America" + ], + "1080": [ + "Belize, Belize", + "Winnipeg, Canada", + "Rainy River, Canada", + "Resolute, Canada", + "Rankin Inlet, Canada", + "Regina, Canada", + "Swift Current, Canada", + "Costa Rica, Costa Rica", + "Galapagos, Ecuador", + "Guatemala, Guatemala", + "Tegucigalpa, Honduras", + "Mexico City, Mexico", + "Merida, Mexico", + "Monterrey, Mexico", + "Matamoros, Mexico", + "Bahia Banderas, Mexico", + "Managua, Nicaragua", + "El Salvador, El Salvador", + "Chicago, United States of America", + "Tell City, Indiana", + "Knox, Indiana", + "Menominee, United States of America", + "Center, North Dakota", + "New_Salem, North Dakota", + "Beulah, North Dakota" + ], + "1140": [ + "Eirunepe, Brazil", + "Rio Branco, Brazil", + "Nassau, Bahamas", + "Toronto, Canada", + "Nipigon, Canada", + "Thunder Bay, Canada", + "Iqaluit, Canada", + "Pangnirtung, Canada", + "Atikokan, Canada", + "Easter, Chile", + "Bogota, Colombia", + "Havana, Cuba", + "Guayaquil, Ecuador", + "Port-au-Prince, Haiti", + "Jamaica, Jamaica", + "Cayman, Cayman Islands", + "Cancun, Mexico", + "Panama, Panama", + "Lima, Peru", + "Grand Turk, Turks and Caicos Islands", + "New York, United States of America", + "Detroit, United States of America", + "Louisville, Kentucky", + "Monticello, Kentucky", + "Indianapolis, Indiana", + "Vincennes, Indiana", + "Winamac, Indiana", + "Marengo, Indiana", + "Petersburg, Indiana", + "Vevay, Indiana" + ], + "1200": [ + "Antigua, Antigua and Barbuda", + "Anguilla, Anguilla", + "Aruba, Aruba", + "Barbados, Barbados", + "St Barthelemy, Saint Barthélemy", + "Bermuda, Bermuda", + "La Paz, Bolivia (Plurinational State of)", + "Kralendijk, Bonaire, Sint Eustatius and Saba", + "Campo Grande, Brazil", + "Cuiaba, Brazil", + "Porto Velho, Brazil", + "Boa Vista, Brazil", + "Manaus, Brazil", + "Halifax, Canada", + "Glace Bay, Canada", + "Moncton, Canada", + "Goose Bay, Canada", + "Blanc-Sablon, Canada", + "Curacao, Curaçao", + "Dominica, Dominica", + "Santo Domingo, Dominican Republic", + "Grenada, Grenada", + "Thule, Greenland", + "Guadeloupe, Guadeloupe", + "Guyana, Guyana", + "St Kitts, Saint Kitts and Nevis", + "St Lucia, Saint Lucia", + "Marigot, Saint Martin (French part)", + "Martinique, Martinique", + "Montserrat, Montserrat", + "Puerto Rico, Puerto Rico", + "Lower Princes, Sint Maarten (Dutch part)", + "Port of_Spain, Trinidad and Tobago", + "St Vincent, Saint Vincent and the Grenadines", + "Caracas, Venezuela (Bolivarian Republic of)", + "Tortola, Virgin Islands (British)", + "St Thomas, Virgin Islands (U.S.)" + ], + "1260": [ + "Palmer, Antarctica", + "Rothera, Antarctica", + "Buenos Aires, Argentina", + "Cordoba, Argentina", + "Salta, Argentina", + "Jujuy, Argentina", + "Tucuman, Argentina", + "Catamarca, Argentina", + "La Rioja, Argentina", + "San Juan, Argentina", + "Mendoza, Argentina", + "San Luis, Argentina", + "Rio Gallegos, Argentina", + "Ushuaia, Argentina", + "Belem, Brazil", + "Fortaleza, Brazil", + "Recife, Brazil", + "Araguaina, Brazil", + "Maceio, Brazil", + "Bahia, Brazil", + "Sao Paulo, Brazil", + "Santarem, Brazil", + "Santiago, Chile", + "Punta Arenas, Chile", + "Stanley, Falkland Islands (Malvinas)", + "Cayenne, French Guiana", + "Nuuk, Greenland", + "Miquelon, Saint Pierre and Miquelon", + "Asuncion, Paraguay", + "Paramaribo, Suriname", + "Montevideo, Uruguay" + ], + "1320": [ + "Noronha, Brazil", + "South Georgia, South Georgia and the South Sandwich Islands" + ], + "1380": [ + "Cape Verde, Cabo Verde", + "Scoresbysund, Greenland", + "Azores, Portugal" + ] +} \ No newline at end of file diff --git a/apps/ftclock/mkFourTwentyTz.js b/apps/ftclock/mkFourTwentyTz.js new file mode 100644 index 000000000..dd199523a --- /dev/null +++ b/apps/ftclock/mkFourTwentyTz.js @@ -0,0 +1,74 @@ +let fs = require('fs'); +let csv = require('csv'); + +let countries = {}, + zones = {}, + offsdict = {}, + now = Date.now(); // we need this to find zone's current DST state + +function handleWrite(err,bytes) { + if (err) { + console.log(`Error writing to file ${err}`); + } +} + +console.log("Generating fourTwentyTz.js..."); +fs.createReadStream(__dirname+'/country.csv') + .pipe(csv.parse()) + .on('data', (r) => { + countries[r[0]] = r[1]; + }) + .on('end', () => { + fs.createReadStream(__dirname+'/zone.csv') + .pipe(csv.parse()) + .on('data', (r) => { + let parts = r[2].replace('_',' ').split('/'); + let city = parts[parts.length-1]; + let country =''; + if (parts.length>2) { // e.g. America/North_Dakota/New_Salem + country = parts[1]; // e.g. North Dakota + } else { + country = countries[r[1]]; // e.g. United States + } + zones[parseInt(r[0])] = {"name": `${city}, ${country}`}; + }) + .on('end', () => { + fs.createReadStream(__dirname+'/timezone.csv') + .pipe(csv.parse()) + .on('data', (r) => { + code = parseInt(r[0]); + if (!(code in zones)) return; + starttime = parseInt(r[2] || "0"); // Bugger. They're feeding us blanks for UTC now + offs = parseInt(r[3]); + if (offs<0) { + offs += 60*60*24; + } + zone = zones[code]; + if (starttime { + for (z in zones) { + zone = zones[z]; + if (zone.offs%60) continue; // One a dem funky timezones. Ignore. + zonelist = offsdict[zone.offs] || []; + zonelist.push(zone.name); + offsdict[zone.offs] = zonelist; + } + fs.open("fourTwentyTz.js","w", (err, fd) => { + if (err) { + console.log("Can't open output file"); + return; + } + fs.write(fd, "// Generated by mkFourTwentyTz.js\n", handleWrite); + fs.write(fd, `// ${Date()}\n`, handleWrite); + fs.write(fd, "// Data source: https://timezonedb.com/files/timezonedb.csv.zip\n", handleWrite); + fs.write(fd, "exports.timezones = ", handleWrite); + fs.write(fd, JSON.stringify(offsdict, null, 4), handleWrite); + console.log('Done.'); + }); + }) + }) + }); diff --git a/apps/ftclock/mkFourTwentyTz.py b/apps/ftclock/mkFourTwentyTz.py deleted file mode 100644 index 713b68059..000000000 --- a/apps/ftclock/mkFourTwentyTz.py +++ /dev/null @@ -1,46 +0,0 @@ -# Generates fourTwentyTz.js from time zone csv files -# get latest files from https://timezonedb.com/download -import csv,json,time,os,math -countries = {} -for r in csv.reader(open("country.csv")): - countries[r[0]] = r[1] -zones = {} -for r in csv.reader(open("zone.csv")): - parts = r[2].replace('_',' ').split('/') - city = parts[-1] - if len(parts)>2: # e.g. America/North_Dakota/New_Salem - country = parts[1] # e.g. North Dakota - else: # e.g. America/Denver - country = countries[r[1]] # e.g. United States - if country==city: # Avoid awkward searches like "Anguilla, Anguilla" - country = r[1] # Use code instead - zones[int(r[0])] = {"name":', '.join((city,country))} -now = int(time.time()) -for r in csv.reader(open("timezone.csv")): - code = int(r[0]) - if code not in zones: - continue - starttime = int(r[2] or "0") # Bugger. They're feeding us blanks for UTC now - offs = int(r[3]) - if offs < 0: - offs += 60*60*24 - d = zones[code] - if starttime