use moment to detect timezones

This commit is contained in:
Andris Reinman 2016-04-29 19:13:51 +03:00
parent ae8a79ea07
commit 6e514e1ccc
11 changed files with 74 additions and 142 deletions

View file

@ -234,6 +234,9 @@ module.exports.insert = (listId, meta, subscription, callback) => {
Object.keys(subscription).forEach(key => {
let value = subscription[key];
key = tools.toDbKey(key);
if (key === 'tz') {
value = (value || '').toString().toLowerCase().trim();
}
if (allowedKeys.indexOf(key) >= 0) {
keys.push(key);
values.push(value);
@ -443,6 +446,9 @@ module.exports.update = (listId, cid, updates, allowEmail, callback) => {
Object.keys(updates).forEach(key => {
let value = updates[key];
key = tools.toDbKey(key);
if (key === 'tz') {
value = (value || '').toString().toLowerCase().trim();
}
if (allowedKeys.indexOf(key) >= 0) {
keys.push(key);
values.push(value);

127
lib/tz.js
View file

@ -1,127 +0,0 @@
'use strict';
// Timezone list from https://github.com/tamaspap/timezones (MIT licensed)
module.exports.list = {
'Pacific/Midway': '(UTC-11:00) Midway Island',
'Pacific/Samoa': '(UTC-11:00) Samoa',
'Pacific/Honolulu': '(UTC-10:00) Hawaii',
'US/Alaska': '(UTC-09:00) Alaska',
'America/Los_Angeles': '(UTC-08:00) Pacific Time (US & Canada)',
'America/Tijuana': '(UTC-08:00) Tijuana',
'US/Arizona': '(UTC-07:00) Arizona',
'America/Chihuahua': '(UTC-07:00) La Paz',
'America/Mazatlan': '(UTC-07:00) Mazatlan',
'US/Mountain': '(UTC-07:00) Mountain Time (US & Canada)',
'America/Managua': '(UTC-06:00) Central America',
'US/Central': '(UTC-06:00) Central Time (US & Canada)',
'America/Mexico_City': '(UTC-06:00) Mexico City',
'America/Monterrey': '(UTC-06:00) Monterrey',
'Canada/Saskatchewan': '(UTC-06:00) Saskatchewan',
'America/Bogota': '(UTC-05:00) Quito',
'US/Eastern': '(UTC-05:00) Eastern Time (US & Canada)',
'US/East-Indiana': '(UTC-05:00) Indiana (East)',
'America/Lima': '(UTC-05:00) Lima',
'Canada/Atlantic': '(UTC-04:00) Atlantic Time (Canada)',
'America/Caracas': '(UTC-04:30) Caracas',
'America/La_Paz': '(UTC-04:00) La Paz',
'America/Santiago': '(UTC-04:00) Santiago',
'Canada/Newfoundland': '(UTC-03:30) Newfoundland',
'America/Sao_Paulo': '(UTC-03:00) Brasilia',
'America/Argentina/Buenos_Aires': '(UTC-03:00) Georgetown',
'America/Godthab': '(UTC-03:00) Greenland',
'America/Noronha': '(UTC-02:00) Mid-Atlantic',
'Atlantic/Azores': '(UTC-01:00) Azores',
'Atlantic/Cape_Verde': '(UTC-01:00) Cape Verde Is.',
'Africa/Casablanca': '(UTC+00:00) Casablanca',
'Europe/London': '(UTC+00:00) London',
'Etc/Greenwich': '(UTC+00:00) Greenwich Mean Time : Dublin',
'Europe/Lisbon': '(UTC+00:00) Lisbon',
'Africa/Monrovia': '(UTC+00:00) Monrovia',
UTC: '(UTC+00:00) UTC',
'Europe/Amsterdam': '(UTC+01:00) Amsterdam',
'Europe/Belgrade': '(UTC+01:00) Belgrade',
'Europe/Berlin': '(UTC+01:00) Bern',
'Europe/Bratislava': '(UTC+01:00) Bratislava',
'Europe/Brussels': '(UTC+01:00) Brussels',
'Europe/Budapest': '(UTC+01:00) Budapest',
'Europe/Copenhagen': '(UTC+01:00) Copenhagen',
'Europe/Ljubljana': '(UTC+01:00) Ljubljana',
'Europe/Madrid': '(UTC+01:00) Madrid',
'Europe/Paris': '(UTC+01:00) Paris',
'Europe/Prague': '(UTC+01:00) Prague',
'Europe/Rome': '(UTC+01:00) Rome',
'Europe/Sarajevo': '(UTC+01:00) Sarajevo',
'Europe/Skopje': '(UTC+01:00) Skopje',
'Europe/Stockholm': '(UTC+01:00) Stockholm',
'Europe/Vienna': '(UTC+01:00) Vienna',
'Europe/Warsaw': '(UTC+01:00) Warsaw',
'Africa/Lagos': '(UTC+01:00) West Central Africa',
'Europe/Zagreb': '(UTC+01:00) Zagreb',
'Europe/Athens': '(UTC+02:00) Athens',
'Europe/Bucharest': '(UTC+02:00) Bucharest',
'Africa/Cairo': '(UTC+02:00) Cairo',
'Africa/Harare': '(UTC+02:00) Harare',
'Europe/Helsinki': '(UTC+02:00) Kyiv',
'Europe/Istanbul': '(UTC+02:00) Istanbul',
'Asia/Jerusalem': '(UTC+02:00) Jerusalem',
'Africa/Johannesburg': '(UTC+02:00) Pretoria',
'Europe/Riga': '(UTC+02:00) Riga',
'Europe/Sofia': '(UTC+02:00) Sofia',
'Europe/Tallinn': '(UTC+02:00) Tallinn',
'Europe/Vilnius': '(UTC+02:00) Vilnius',
'Asia/Baghdad': '(UTC+03:00) Baghdad',
'Asia/Kuwait': '(UTC+03:00) Kuwait',
'Europe/Minsk': '(UTC+03:00) Minsk',
'Africa/Nairobi': '(UTC+03:00) Nairobi',
'Asia/Riyadh': '(UTC+03:00) Riyadh',
'Europe/Volgograd': '(UTC+03:00) Volgograd',
'Asia/Tehran': '(UTC+03:30) Tehran',
'Asia/Muscat': '(UTC+04:00) Muscat',
'Asia/Baku': '(UTC+04:00) Baku',
'Europe/Moscow': '(UTC+04:00) St. Petersburg',
'Asia/Tbilisi': '(UTC+04:00) Tbilisi',
'Asia/Yerevan': '(UTC+04:00) Yerevan',
'Asia/Kabul': '(UTC+04:30) Kabul',
'Asia/Karachi': '(UTC+05:00) Karachi',
'Asia/Tashkent': '(UTC+05:00) Tashkent',
'Asia/Calcutta': '(UTC+05:30) Sri Jayawardenepura',
'Asia/Kolkata': '(UTC+05:30) Kolkata',
'Asia/Katmandu': '(UTC+05:45) Kathmandu',
'Asia/Almaty': '(UTC+06:00) Almaty',
'Asia/Dhaka': '(UTC+06:00) Dhaka',
'Asia/Yekaterinburg': '(UTC+06:00) Ekaterinburg',
'Asia/Rangoon': '(UTC+06:30) Rangoon',
'Asia/Bangkok': '(UTC+07:00) Hanoi',
'Asia/Jakarta': '(UTC+07:00) Jakarta',
'Asia/Novosibirsk': '(UTC+07:00) Novosibirsk',
'Asia/Hong_Kong': '(UTC+08:00) Hong Kong',
'Asia/Chongqing': '(UTC+08:00) Chongqing',
'Asia/Krasnoyarsk': '(UTC+08:00) Krasnoyarsk',
'Asia/Kuala_Lumpur': '(UTC+08:00) Kuala Lumpur',
'Australia/Perth': '(UTC+08:00) Perth',
'Asia/Singapore': '(UTC+08:00) Singapore',
'Asia/Taipei': '(UTC+08:00) Taipei',
'Asia/Ulan_Bator': '(UTC+08:00) Ulaan Bataar',
'Asia/Urumqi': '(UTC+08:00) Urumqi',
'Asia/Irkutsk': '(UTC+09:00) Irkutsk',
'Asia/Tokyo': '(UTC+09:00) Tokyo',
'Asia/Seoul': '(UTC+09:00) Seoul',
'Australia/Adelaide': '(UTC+09:30) Adelaide',
'Australia/Darwin': '(UTC+09:30) Darwin',
'Australia/Brisbane': '(UTC+10:00) Brisbane',
'Australia/Canberra': '(UTC+10:00) Canberra',
'Pacific/Guam': '(UTC+10:00) Guam',
'Australia/Hobart': '(UTC+10:00) Hobart',
'Australia/Melbourne': '(UTC+10:00) Melbourne',
'Pacific/Port_Moresby': '(UTC+10:00) Port Moresby',
'Australia/Sydney': '(UTC+10:00) Sydney',
'Asia/Yakutsk': '(UTC+10:00) Yakutsk',
'Asia/Vladivostok': '(UTC+11:00) Vladivostok',
'Pacific/Auckland': '(UTC+12:00) Wellington',
'Pacific/Fiji': '(UTC+12:00) Marshall Is.',
'Pacific/Kwajalein': '(UTC+12:00) International Date Line West',
'Asia/Kamchatka': '(UTC+12:00) Kamchatka',
'Asia/Magadan': '(UTC+12:00) Solomon Is.',
'Pacific/Tongatapu': '(UTC+13:00) Nuku\'alofa'
};

View file

@ -1,3 +1,3 @@
{
"schemaVersion": 5
"schemaVersion": 6
}

View file

@ -47,6 +47,7 @@
"html-to-text": "^2.1.0",
"humanize": "0.0.9",
"isemail": "^2.1.0",
"moment-timezone": "^0.5.3",
"morgan": "^1.7.0",
"multer": "^1.1.0",
"mysql": "^2.10.2",

View file

@ -1,6 +1,6 @@
/* eslint-env browser */
/* eslint prefer-arrow-callback: 0, object-shorthand: 0, new-cap: 0, no-invalid-this: 0, no-var: 0*/
/* globals $: false, moment: false, jstz: false */
/* globals $: false, moment: false */
'use strict';
@ -126,12 +126,11 @@ $('.page-refresh').each(function () {
}, interval * 1000);
});
if (typeof jstz !== 'undefined') {
if (typeof moment.tz !== 'undefined') {
(function () {
var tz = jstz.determine();
var tzname = tz && tz.name() || false;
if (tzname) {
$('.tz-detect').val(tzname);
var tz = moment.tz.guess();
if (tz) {
$('.tz-detect').val(tz);
}
})();
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -18,7 +18,7 @@ let uploads = multer({
});
let csvparse = require('csv-parse');
let fs = require('fs');
let tzlist = require('../lib/tz').list;
let moment = require('moment-timezone');
router.all('/*', (req, res, next) => {
if (!req.user) {
@ -279,14 +279,14 @@ router.get('/subscription/:id/add', passport.csrfProtection, (req, res) => {
data.customFields = fields.getRow(fieldList, data, false, true);
data.useEditor = true;
data.timezones = Object.keys(tzlist).map(tz => {
data.timezones = moment.tz.names().map(tz => {
let selected = false;
if (tz.toLowerCase().trim() === (data.tz || 'UTC').toLowerCase().trim()) {
selected = true;
}
return {
key: tz,
value: tzlist[tz],
value: tz,
selected
};
});
@ -322,7 +322,7 @@ router.get('/subscription/:id/edit/:cid', passport.csrfProtection, (req, res) =>
subscription.isSubscribed = subscription.status === 1;
let tzfound = false;
subscription.timezones = Object.keys(tzlist).map(tz => {
subscription.timezones = moment.tz.names().map(tz => {
let selected = false;
if (tz.toLowerCase().trim() === (subscription.tz || '').toLowerCase().trim()) {
selected = true;
@ -330,7 +330,7 @@ router.get('/subscription/:id/edit/:cid', passport.csrfProtection, (req, res) =>
}
return {
key: tz,
value: tzlist[tz],
value: tz,
selected
};
});

32
services/tzupdate.js Normal file
View file

@ -0,0 +1,32 @@
'use strict';
// This script re-calculates timezone offsets once a day
let moment = require('moment-timezone');
let db = require('../lib/db');
function updateTimezoneOffsets(callback) {
db.getConnection((err, connection) => {
if (err) {
return callback(err);
}
let values = [];
moment.tz.names().forEach(tz => {
let time = moment();
values.push('(' + connection.escape(tz.toLowerCase().trim()) + ',' + connection.escape(time.tz(tz).utcOffset()) + ')');
});
let query = 'INSERT INTO tzoffset (`tz`, `offset`) VALUES ' + values.join(', ') + ' ON DUPLICATE KEY UPDATE `offset` = VALUES(`offset`)';
connection.query(query, values, (err, result) => {
connection.release();
if (err) {
return callback(err);
}
return callback(null, result);
});
});
}
updateTimezoneOffsets(console.log);

View file

@ -0,0 +1,16 @@
# Header section
# Define incrementing schema version number
SET @schema_version = '6';
# Creates table to store timezone offsets required to calculate correct start time for sending
# messages to specific subscribers
CREATE TABLE `tzoffset` (
`tz` varchar(100) CHARACTER SET ascii NOT NULL DEFAULT '',
`offset` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`tz`)
) ENGINE=InnoDB DEFAULT CHARSET=ascii;
# Footer section
LOCK TABLES `settings` WRITE;
INSERT INTO `settings` (`key`, `value`) VALUES('db_schema_version', @schema_version) ON DUPLICATE KEY UPDATE `value`=@schema_version;
UNLOCK TABLES;

View file

@ -48,7 +48,7 @@
<script src="/datepicker/js/bootstrap-datepicker.min.js"></script>
<script src="/datatables/datatables.min.js"></script>
<script src="/moment/moment.min.js"></script>
<script src="/jstimezonedetect/jstz.min.js"></script>
<script src="/moment/moment-timezone-with-data.min"></script>
<script src="/javascript/tables.js"></script>
{{#if useEditor}}