0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-03 23:00:14 -05:00

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
This commit is contained in:
Aileen Nowak 2016-02-02 09:04:40 +02:00 committed by kirrg001
parent 3736d8689b
commit 38a261daac
7 changed files with 65 additions and 46 deletions

@ -1 +0,0 @@
Subproject commit 39622c4e284554d0ac1f6dbe3de90a6e6943a6ed

View file

@ -60,7 +60,8 @@ updateConfigCache = function () {
postsPerPage: (settingsCache.postsPerPage && settingsCache.postsPerPage.value) || 5, postsPerPage: (settingsCache.postsPerPage && settingsCache.postsPerPage.value) || 5,
permalinks: (settingsCache.permalinks && settingsCache.permalinks.value) || '/:slug/', permalinks: (settingsCache.permalinks && settingsCache.permalinks.value) || '/:slug/',
twitter: (settingsCache.twitter && settingsCache.twitter.value) || '', 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 labs: labsValue
}); });

View file

@ -40,6 +40,12 @@
"isLength": [1, 1000] "isLength": [1, 1000]
} }
}, },
"activeTimezone": {
"defaultValue": "Europe/Dublin",
"validations": {
"isNull": false
}
},
"forceI18n": { "forceI18n": {
"defaultValue": "true", "defaultValue": "true",
"validations": { "validations": {

View file

@ -1,7 +1,7 @@
{ {
"timezones": [ "timezones": [
{ {
"name": "Pacific/Samoa", "name": "Pacific/Pago_Pago",
"label": "(GMT -11:00) Midway Island, Samoa", "label": "(GMT -11:00) Midway Island, Samoa",
"offset": -660 "offset": -660
}, },
@ -11,27 +11,27 @@
"offset": -600 "offset": -600
}, },
{ {
"name": "US/Alaska", "name": "America/Anchorage",
"label": "(GMT -9:00) Alaska", "label": "(GMT -9:00) Alaska",
"offset": -540 "offset": -540
}, },
{ {
"name": "Mexico/BajaNorte", "name": "America/Tijuana",
"label": "(GMT -8:00) Chihuahua, La Paz, Mazatlan", "label": "(GMT -8:00) Chihuahua, La Paz, Mazatlan",
"offset": -480 "offset": -480
}, },
{ {
"name": "US/Pacific", "name": "America/Los_Angeles",
"label": "(GMT -8:00) Pacific Time (US & Canada); Tijuana", "label": "(GMT -8:00) Pacific Time (US & Canada); Tijuana",
"offset": -480 "offset": -480
}, },
{ {
"name": "US/Arizona", "name": "America/Phoenix",
"label": "(GMT -7:00) Arizona", "label": "(GMT -7:00) Arizona",
"offset": -420 "offset": -420
}, },
{ {
"name": "US/Mountain", "name": "America/Denver",
"label": "(GMT -7:00) Mountain Time (US & Canada)", "label": "(GMT -7:00) Mountain Time (US & Canada)",
"offset": -420 "offset": -420
}, },
@ -41,17 +41,17 @@
"offset": -360 "offset": -360
}, },
{ {
"name": "US/Central", "name": "America/Chicago",
"label": "(GMT -6:00) Central Time (US & Canada)", "label": "(GMT -6:00) Central Time (US & Canada)",
"offset": -360 "offset": -360
}, },
{ {
"name": "Mexico/General", "name": "America/Mexico_City",
"label": "(GMT -6:00) Guadalajara, Mexico City, Monterrey", "label": "(GMT -6:00) Guadalajara, Mexico City, Monterrey",
"offset": -360 "offset": -360
}, },
{ {
"name": "Canada/Saskatchewan", "name": "America/Regina",
"label": "(GMT -6:00) Saskatchewan", "label": "(GMT -6:00) Saskatchewan",
"offset": -360 "offset": -360
}, },
@ -61,12 +61,12 @@
"offset": -300 "offset": -300
}, },
{ {
"name": "US/Eastern", "name": "America/New_York",
"label": "(GMT -5:00) Eastern Time (US & Canada)", "label": "(GMT -5:00) Eastern Time (US & Canada)",
"offset": -300 "offset": -300
}, },
{ {
"name": "US/East-Indiana", "name": "America/Fort_Wayne",
"label": "(GMT -5:00) Indiana (East)", "label": "(GMT -5:00) Indiana (East)",
"offset": -300 "offset": -300
}, },
@ -76,17 +76,17 @@
"offset": -270 "offset": -270
}, },
{ {
"name": "Canada/Atlantic", "name": "America/Halifax",
"label": "(GMT -4:00) Atlantic Time (Canada); Brasilia, Greenland", "label": "(GMT -4:00) Atlantic Time (Canada); Brasilia, Greenland",
"offset": -240 "offset": -240
}, },
{ {
"name": "Canada/Newfoundland", "name": "America/St_Johns",
"label": "(GMT -3:30) Newfoundland", "label": "(GMT -3:30) Newfoundland",
"offset": -210 "offset": -210
}, },
{ {
"name": "America/Buenos_Aires", "name": "America/Argentina/Buenos_Aires",
"label": "(GMT -3:00) Buenos Aires, Georgetown", "label": "(GMT -3:00) Buenos Aires, Georgetown",
"offset": -180 "offset": -180
}, },
@ -141,7 +141,7 @@
"offset": 60 "offset": 60
}, },
{ {
"name": "Africa/Bangui", "name": "Africa/Lagos",
"label": "(GMT +1:00) West Central Africa", "label": "(GMT +1:00) West Central Africa",
"offset": 60 "offset": 60
}, },
@ -156,7 +156,7 @@
"offset": 120 "offset": 120
}, },
{ {
"name": "Africa/Harare", "name": "Africa/Maputo",
"label": "(GMT +2:00) Harare", "label": "(GMT +2:00) Harare",
"offset": 120 "offset": 120
}, },
@ -191,7 +191,7 @@
"offset": 210 "offset": 210
}, },
{ {
"name": "Asia/Muscat", "name": "Asia/Dubai",
"label": "(GMT +4:00) Abu Dhabi, Muscat", "label": "(GMT +4:00) Abu Dhabi, Muscat",
"offset": 240 "offset": 240
}, },
@ -216,12 +216,12 @@
"offset": 300 "offset": 300
}, },
{ {
"name": "Asia/Calcutta", "name": "Asia/Kolkata",
"label": "(GMT +5:30) Chennai, Calcutta, Mumbai, New Delhi", "label": "(GMT +5:30) Chennai, Calcutta, Mumbai, New Delhi",
"offset": 330 "offset": 330
}, },
{ {
"name": "Asia/Katmandu", "name": "Asia/Kathmandu",
"label": "(GMT +5:45) Katmandu", "label": "(GMT +5:45) Katmandu",
"offset": 345 "offset": 345
}, },
@ -301,7 +301,7 @@
"offset": 630 "offset": 630
}, },
{ {
"name": "Australia/Canberra", "name": "Australia/Sydney",
"label": "(GMT +11:00) Canberra, Hobart, Melbourne, Sydney, Vladivostok", "label": "(GMT +11:00) Canberra, Hobart, Melbourne, Sydney, Vladivostok",
"offset": 660 "offset": 660
}, },

View file

@ -1,34 +1,38 @@
// # Date Helper // # Date Helper
// Usage: `{{date format="DD MM, YYYY"}}`, `{{date updated_at format="DD MM, YYYY"}}` // 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'), var moment = require('moment-timezone'),
date; date,
timezone;
date = function (date, options) { date = function (date, options) {
if (!options && date.hasOwnProperty('hash')) { if (!options && date.hasOwnProperty('hash')) {
options = date; options = date;
date = undefined; date = undefined;
timezone = options.data.blog.timezone;
// set to published_at by default, if it's available // set to published_at by default, if it's available
// otherwise, this will print the current date // otherwise, this will print the current date
if (this.published_at) { 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 // ensure that context is undefined, not null, as that can cause errors
date = date === null ? undefined : date; date = date === null ? undefined : date;
var f = options.hash.format || 'MMM Do, YYYY', var f = options.hash.format || 'MMM DD, YYYY',
timeago = options.hash.timeago; timeago = options.hash.timeago,
timeNow = moment().tz(timezone);
if (timeago) { if (timeago) {
date = moment(date).fromNow(); date = timezone ? moment(date).tz(timezone).from(timeNow) : moment(date).fromNow();
} else { } else {
date = moment(date).format(f); date = timezone ? moment(date).tz(timezone).format(f) : moment(date).format(f);
} }
return date; return date;
}; };

View file

@ -6,7 +6,7 @@ var should = require('should'),
// Stuff we are testing // Stuff we are testing
handlebars = hbs.handlebars, handlebars = hbs.handlebars,
helpers = require('../../../server/helpers'), helpers = require('../../../server/helpers'),
moment = require('moment'); moment = require('moment-timezone');
describe('{{date}} helper', function () { describe('{{date}} helper', function () {
before(function () { before(function () {
@ -17,22 +17,23 @@ describe('{{date}} helper', function () {
should.exist(handlebars.helpers.date); 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 () { it('creates properly formatted date strings', function () {
var testDates = [ var testDates = [
'2013-12-31T11:28:58.593Z', '2013-12-31T11:28:58.593+02:00',
'2014-01-01T01:28:58.593Z', '2014-01-01T01:28:58.593+11:00',
'2014-02-20T01:28:58.593Z', '2014-02-20T01:28:58.593-04:00',
'2014-03-01T01:28:58.593Z' '2014-03-01T01:28:58.593+00:00'
], ],
timezones = 'Europe/Dublin',
format = 'MMM Do, YYYY', format = 'MMM Do, YYYY',
context = { context = {
hash: { hash: {
format: format format: format
},
data: {
blog: {
timezone: 'Europe/Dublin'
}
} }
}; };
@ -40,20 +41,27 @@ describe('{{date}} helper', function () {
var rendered = helpers.date.call({published_at: d}, context); var rendered = helpers.date.call({published_at: d}, context);
should.exist(rendered); 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 () { it('creates properly formatted time ago date strings', function () {
var testDates = [ var testDates = [
'2013-12-31T23:58:58.593Z', '2013-12-31T23:58:58.593+02:00',
'2014-01-01T00:28:58.593Z', '2014-01-01T00:28:58.593+11:00',
'2014-11-20T01:28:58.593Z', '2014-11-20T01:28:58.593-04:00',
'2014-03-01T01:28:58.593Z' '2014-03-01T01:28:58.593+00:00'
], ],
timezones = 'Europe/Dublin',
timeNow = moment().tz('Europe/Dublin'),
context = { context = {
hash: { hash: {
timeago: true timeago: true
},
data: {
blog: {
timezone: 'Europe/Dublin'
}
} }
}; };
@ -61,7 +69,7 @@ describe('{{date}} helper', function () {
var rendered = helpers.date.call({published_at: d}, context); var rendered = helpers.date.call({published_at: d}, context);
should.exist(rendered); should.exist(rendered);
rendered.should.equal(moment(d).fromNow()); rendered.should.equal(moment(d).tz(timezones).from(timeNow));
}); });
}); });
}); });

View file

@ -54,6 +54,7 @@
"morgan": "1.7.0", "morgan": "1.7.0",
"multer": "1.1.0", "multer": "1.1.0",
"netjet": "1.1.0", "netjet": "1.1.0",
"moment-timezone": "0.5.1",
"node-uuid": "1.4.7", "node-uuid": "1.4.7",
"nodemailer": "0.7.1", "nodemailer": "0.7.1",
"oauth2orize": "1.2.2", "oauth2orize": "1.2.2",