From 38a261daaced194febe82ca358df4e1aea178c3f Mon Sep 17 00:00:00 2001 From: Aileen Nowak Date: Tue, 2 Feb 2016 09:04:40 +0200 Subject: [PATCH] timezones: Always use the timezone of blog setting closes #6406 - adding timeZone Service to get the offset (=timezone reg. moment-timezone) overall available - new publishedAtOffset date as CP using timeZone service and moment-timezone to calculate offset incl. DST - removing timezone-obj transform as it became obsolete with moment-timezone - reading timezones from configuration/timezones api endpoint - adding a moment-utc transform to only work with utc times in backend - when switching the timezone in the select box, the user will be shown the local time of the selected timezone - added clock service to show actual time ticking below select box - default timezone is '(GMT) Greenwich Mean Time : Dublin, Edinburgh, London' - if no timezone is saved in the settings yet, the default value will be used - showing local time in 'Publish Date' when it's a draft and no actual publishedAt value exists - Removed the format 'DD MMM YY @ HH:mm (UTC Z)' which resolves to '01 Jan 16 @ 14:00 (UTC +02:00)' - Changing the date.js helper in core/server for moment-timezone - Fix timezone select: updates `selectedTimezone` to return the matching object from `availableTimezones` - Including timezones in test for date-helper - update to moment-timezone 0.5.1 - moving form-group of 'selectTimezone' further up so - Tests: - Set except for clock service in test env - adding fixtures to mirage - adding 'service.ajax' to navigation-test.js - adding 'service:ghostPaths' to navigation-test.js - Code improvements - Changing clockservice to ES6 --- core/client | 1 - core/server/api/settings.js | 3 +- core/server/data/schema/default-settings.json | 6 +++ core/server/data/timezones.json | 40 +++++++++---------- core/server/helpers/date.js | 20 ++++++---- core/test/unit/server_helpers/date_spec.js | 40 +++++++++++-------- package.json | 1 + 7 files changed, 65 insertions(+), 46 deletions(-) delete mode 160000 core/client diff --git a/core/client b/core/client deleted file mode 160000 index 39622c4e28..0000000000 --- a/core/client +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 39622c4e284554d0ac1f6dbe3de90a6e6943a6ed diff --git a/core/server/api/settings.js b/core/server/api/settings.js index 8ce7740361..9cf411e5d7 100644 --- a/core/server/api/settings.js +++ b/core/server/api/settings.js @@ -60,7 +60,8 @@ updateConfigCache = function () { postsPerPage: (settingsCache.postsPerPage && settingsCache.postsPerPage.value) || 5, permalinks: (settingsCache.permalinks && settingsCache.permalinks.value) || '/:slug/', twitter: (settingsCache.twitter && settingsCache.twitter.value) || '', - facebook: (settingsCache.facebook && settingsCache.facebook.value) || '' + facebook: (settingsCache.facebook && settingsCache.facebook.value) || '', + timezone: (settingsCache.activeTimezone && settingsCache.activeTimezone.value) || 'Europe/Dublin' }, labs: labsValue }); diff --git a/core/server/data/schema/default-settings.json b/core/server/data/schema/default-settings.json index 7e7de56bae..832e11bd4d 100644 --- a/core/server/data/schema/default-settings.json +++ b/core/server/data/schema/default-settings.json @@ -40,6 +40,12 @@ "isLength": [1, 1000] } }, + "activeTimezone": { + "defaultValue": "Europe/Dublin", + "validations": { + "isNull": false + } + }, "forceI18n": { "defaultValue": "true", "validations": { diff --git a/core/server/data/timezones.json b/core/server/data/timezones.json index 76df1959ed..03c93a4129 100644 --- a/core/server/data/timezones.json +++ b/core/server/data/timezones.json @@ -1,7 +1,7 @@ { "timezones": [ { - "name": "Pacific/Samoa", + "name": "Pacific/Pago_Pago", "label": "(GMT -11:00) Midway Island, Samoa", "offset": -660 }, @@ -11,27 +11,27 @@ "offset": -600 }, { - "name": "US/Alaska", + "name": "America/Anchorage", "label": "(GMT -9:00) Alaska", "offset": -540 }, { - "name": "Mexico/BajaNorte", + "name": "America/Tijuana", "label": "(GMT -8:00) Chihuahua, La Paz, Mazatlan", "offset": -480 }, { - "name": "US/Pacific", + "name": "America/Los_Angeles", "label": "(GMT -8:00) Pacific Time (US & Canada); Tijuana", "offset": -480 }, { - "name": "US/Arizona", + "name": "America/Phoenix", "label": "(GMT -7:00) Arizona", "offset": -420 }, { - "name": "US/Mountain", + "name": "America/Denver", "label": "(GMT -7:00) Mountain Time (US & Canada)", "offset": -420 }, @@ -41,17 +41,17 @@ "offset": -360 }, { - "name": "US/Central", + "name": "America/Chicago", "label": "(GMT -6:00) Central Time (US & Canada)", "offset": -360 }, { - "name": "Mexico/General", + "name": "America/Mexico_City", "label": "(GMT -6:00) Guadalajara, Mexico City, Monterrey", "offset": -360 }, { - "name": "Canada/Saskatchewan", + "name": "America/Regina", "label": "(GMT -6:00) Saskatchewan", "offset": -360 }, @@ -61,12 +61,12 @@ "offset": -300 }, { - "name": "US/Eastern", + "name": "America/New_York", "label": "(GMT -5:00) Eastern Time (US & Canada)", "offset": -300 }, { - "name": "US/East-Indiana", + "name": "America/Fort_Wayne", "label": "(GMT -5:00) Indiana (East)", "offset": -300 }, @@ -76,17 +76,17 @@ "offset": -270 }, { - "name": "Canada/Atlantic", + "name": "America/Halifax", "label": "(GMT -4:00) Atlantic Time (Canada); Brasilia, Greenland", "offset": -240 }, { - "name": "Canada/Newfoundland", + "name": "America/St_Johns", "label": "(GMT -3:30) Newfoundland", "offset": -210 }, { - "name": "America/Buenos_Aires", + "name": "America/Argentina/Buenos_Aires", "label": "(GMT -3:00) Buenos Aires, Georgetown", "offset": -180 }, @@ -141,7 +141,7 @@ "offset": 60 }, { - "name": "Africa/Bangui", + "name": "Africa/Lagos", "label": "(GMT +1:00) West Central Africa", "offset": 60 }, @@ -156,7 +156,7 @@ "offset": 120 }, { - "name": "Africa/Harare", + "name": "Africa/Maputo", "label": "(GMT +2:00) Harare", "offset": 120 }, @@ -191,7 +191,7 @@ "offset": 210 }, { - "name": "Asia/Muscat", + "name": "Asia/Dubai", "label": "(GMT +4:00) Abu Dhabi, Muscat", "offset": 240 }, @@ -216,12 +216,12 @@ "offset": 300 }, { - "name": "Asia/Calcutta", + "name": "Asia/Kolkata", "label": "(GMT +5:30) Chennai, Calcutta, Mumbai, New Delhi", "offset": 330 }, { - "name": "Asia/Katmandu", + "name": "Asia/Kathmandu", "label": "(GMT +5:45) Katmandu", "offset": 345 }, @@ -301,7 +301,7 @@ "offset": 630 }, { - "name": "Australia/Canberra", + "name": "Australia/Sydney", "label": "(GMT +11:00) Canberra, Hobart, Melbourne, Sydney, Vladivostok", "offset": 660 }, diff --git a/core/server/helpers/date.js b/core/server/helpers/date.js index bf39f0874d..17327c41c2 100644 --- a/core/server/helpers/date.js +++ b/core/server/helpers/date.js @@ -1,34 +1,38 @@ // # Date Helper // Usage: `{{date format="DD MM, YYYY"}}`, `{{date updated_at format="DD MM, YYYY"}}` // -// Formats a date using moment.js. Formats published_at by default but will also take a date as a parameter +// Formats a date using moment-timezone.js. Formats published_at by default but will also take a date as a parameter -var moment = require('moment'), - date; +var moment = require('moment-timezone'), + date, + timezone; date = function (date, options) { if (!options && date.hasOwnProperty('hash')) { options = date; date = undefined; + timezone = options.data.blog.timezone; // set to published_at by default, if it's available // otherwise, this will print the current date if (this.published_at) { - date = this.published_at; + date = moment(this.published_at).tz(timezone).format(); } } // ensure that context is undefined, not null, as that can cause errors date = date === null ? undefined : date; - var f = options.hash.format || 'MMM Do, YYYY', - timeago = options.hash.timeago; + var f = options.hash.format || 'MMM DD, YYYY', + timeago = options.hash.timeago, + timeNow = moment().tz(timezone); if (timeago) { - date = moment(date).fromNow(); + date = timezone ? moment(date).tz(timezone).from(timeNow) : moment(date).fromNow(); } else { - date = moment(date).format(f); + date = timezone ? moment(date).tz(timezone).format(f) : moment(date).format(f); } + return date; }; diff --git a/core/test/unit/server_helpers/date_spec.js b/core/test/unit/server_helpers/date_spec.js index b62f31cd68..6671f8a33f 100644 --- a/core/test/unit/server_helpers/date_spec.js +++ b/core/test/unit/server_helpers/date_spec.js @@ -6,7 +6,7 @@ var should = require('should'), // Stuff we are testing handlebars = hbs.handlebars, helpers = require('../../../server/helpers'), - moment = require('moment'); + moment = require('moment-timezone'); describe('{{date}} helper', function () { before(function () { @@ -17,22 +17,23 @@ describe('{{date}} helper', function () { should.exist(handlebars.helpers.date); }); - // TODO: When timezone support is added these tests should be updated - // to test the output of the helper against static strings instead - // of calling moment(). Without timezone support the output of this - // helper may differ depending on what timezone the tests are run in. - it('creates properly formatted date strings', function () { var testDates = [ - '2013-12-31T11:28:58.593Z', - '2014-01-01T01:28:58.593Z', - '2014-02-20T01:28:58.593Z', - '2014-03-01T01:28:58.593Z' + '2013-12-31T11:28:58.593+02:00', + '2014-01-01T01:28:58.593+11:00', + '2014-02-20T01:28:58.593-04:00', + '2014-03-01T01:28:58.593+00:00' ], + timezones = 'Europe/Dublin', format = 'MMM Do, YYYY', context = { hash: { format: format + }, + data: { + blog: { + timezone: 'Europe/Dublin' + } } }; @@ -40,20 +41,27 @@ describe('{{date}} helper', function () { var rendered = helpers.date.call({published_at: d}, context); should.exist(rendered); - rendered.should.equal(moment(d).format(format)); + rendered.should.equal(moment(d).tz(timezones).format(format)); }); }); it('creates properly formatted time ago date strings', function () { var testDates = [ - '2013-12-31T23:58:58.593Z', - '2014-01-01T00:28:58.593Z', - '2014-11-20T01:28:58.593Z', - '2014-03-01T01:28:58.593Z' + '2013-12-31T23:58:58.593+02:00', + '2014-01-01T00:28:58.593+11:00', + '2014-11-20T01:28:58.593-04:00', + '2014-03-01T01:28:58.593+00:00' ], + timezones = 'Europe/Dublin', + timeNow = moment().tz('Europe/Dublin'), context = { hash: { timeago: true + }, + data: { + blog: { + timezone: 'Europe/Dublin' + } } }; @@ -61,7 +69,7 @@ describe('{{date}} helper', function () { var rendered = helpers.date.call({published_at: d}, context); should.exist(rendered); - rendered.should.equal(moment(d).fromNow()); + rendered.should.equal(moment(d).tz(timezones).from(timeNow)); }); }); }); diff --git a/package.json b/package.json index c8ab1656d3..f1ab1db289 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "morgan": "1.7.0", "multer": "1.1.0", "netjet": "1.1.0", + "moment-timezone": "0.5.1", "node-uuid": "1.4.7", "nodemailer": "0.7.1", "oauth2orize": "1.2.2",