Skip to content

Commit

Permalink
Add support for global timezones. Closes elastic#1600
Browse files Browse the repository at this point in the history
  • Loading branch information
jbudz committed Oct 16, 2015
1 parent 6a3ee68 commit 9571469
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 13 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
"minimatch": "2.0.10",
"mkdirp": "0.5.1",
"moment": "2.10.6",
"moment-timezone": "^0.4.1",
"raw-loader": "0.5.1",
"request": "2.61.0",
"requirefrom": "0.2.0",
Expand Down Expand Up @@ -147,6 +148,7 @@
"html-entities": "1.1.3",
"husky": "0.8.1",
"istanbul-instrumenter-loader": "0.1.3",
"json-loader": "^0.5.3",
"karma": "0.13.9",
"karma-chrome-launcher": "0.2.0",
"karma-coverage": "0.5.1",
Expand Down
1 change: 1 addition & 0 deletions src/optimize/BaseOptimizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class BaseOptimizer {
},
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style', `css${mapQ}`) },
{ test: /\.jade$/, loader: 'jade' },
{ test: /\.json$/, loader: 'json' },
{ test: /\.(html|tmpl)$/, loader: 'raw' },
{ test: /\.png$/, loader: 'url?limit=10000&name=[path][name].[ext]' },
{ test: /\.(woff|woff2|ttf|eot|svg|ico)(\?|$)/, loader: 'file?name=[path][name].[ext]' },
Expand Down
9 changes: 9 additions & 0 deletions src/plugins/kibana/public/kibana.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ require('plugins/kibana/dashboard/index');
require('plugins/kibana/settings/index');
require('plugins/kibana/doc/index');

var moment = require('moment-timezone');

var chrome = require('ui/chrome');
var routes = require('ui/routes');
var modules = require('ui/modules');
Expand Down Expand Up @@ -48,8 +50,15 @@ chrome
}
])
.setRootController('kibana', function ($scope, $rootScope, courier, config) {
function setDefaultTimezone() {
moment.tz.setDefault(config.get('dateFormat:tz'));
}

// wait for the application to finish loading
$scope.$on('application.load', function () {
courier.start();
});

$scope.$on('init:config', setDefaultTimezone);
$scope.$on('change:config.dateFormat:tz', setDefaultTimezone);
});
10 changes: 8 additions & 2 deletions src/ui/public/agg_types/buckets/date_histogram.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ define(function (require) {
var TimeBuckets = Private(require('ui/time_buckets'));
var createFilter = Private(require('ui/agg_types/buckets/create_filter/date_histogram'));
var intervalOptions = Private(require('ui/agg_types/buckets/_interval_options'));
var timeZone = tzDetect.determine().name();
var configDefaults = Private(require('ui/config/defaults'));

var detectedTimezone = tzDetect.determine().name();
var tzOffset = moment().format('Z');

function getInterval(agg) {
Expand Down Expand Up @@ -94,7 +96,11 @@ define(function (require) {
var interval = agg.buckets.getInterval();
output.bucketInterval = interval;
output.params.interval = interval.expression;
output.params.time_zone = timeZone || tzOffset;

var isDefaultTimezone = config.get('dateFormat:tz') === configDefaults['dateFormat:tz'].value;
output.params.time_zone = isDefaultTimezone ?
(detectedTimezone || tzOffset) :
config.get('dateFormat:tz');

var scaleMetrics = interval.scaled && interval.scale < 1;
if (scaleMetrics) {
Expand Down
11 changes: 10 additions & 1 deletion src/ui/public/config/defaults.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
define(function () {
define(function (require) {
var moment = require('moment-timezone');
var _ = require('lodash');

return function configDefaultsProvider() {
// wraped in provider so that a new instance is given to each app/test

Expand All @@ -20,6 +23,12 @@ define(function () {
value: 'MMMM Do YYYY, HH:mm:ss.SSS',
description: 'When displaying a pretty formatted date, use this format',
},
'dateFormat:tz': {
value: 'Default',
description: 'Which timezone should be used. "Default" will use your detected timezone.',
type: 'select',
options: _.union(['Default'], moment.tz.names())
},
'dateFormat:scaled': {
type: 'json',
value:
Expand Down
43 changes: 35 additions & 8 deletions src/ui/public/stringify/__tests__/_date.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,47 @@
describe('Date Format', function () {
var fieldFormats;
var expect = require('expect.js');
var ngMock = require('ngMock');
var moment = require('moment-timezone');
var fieldFormats;
var settings;
var convert;
var $scope;
var off;

beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
beforeEach(ngMock.inject(function (Private, config, $rootScope) {
$scope = $rootScope;
settings = config;

fieldFormats = Private(require('ui/registry/field_formats'));
var DateFormat = fieldFormats.getType('date');
var date = new DateFormat();

convert = date.convert.bind(date);
}));

it('decoding an undefined or null date should return an empty string', function () {
var DateFormat = fieldFormats.getType('date');
var date = new DateFormat({
pattern: 'dd-MM-yyyy'
});
expect(date.convert(null)).to.be('-');
expect(date.convert(undefined)).to.be('-');
expect(convert(null)).to.be('-');
expect(convert(undefined)).to.be('-');
});

it('should clear the memoization cache after changing the date', function () {
function setDefaultTimezone() {
moment.tz.setDefault(settings.get('dateFormat:tz'));
}
var time = 1445027693942;

off = $scope.$on('change:config.dateFormat:tz', setDefaultTimezone);

settings.set('dateFormat:tz', 'America/Chicago');
$scope.$digest();
var chicagoTime = convert(time);

settings.set('dateFormat:tz', 'America/Phoenix');
$scope.$digest();
var phoenixTime = convert(time);

expect(chicagoTime).not.to.equal(phoenixTime);
off();
});
});
11 changes: 9 additions & 2 deletions src/ui/public/stringify/types/Date.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ define(function (require) {
DateTime.fieldType = 'date';

DateTime.paramDefaults = new BoundToConfigObj({
pattern: '=dateFormat'
pattern: '=dateFormat',
timezone: '=dateFormat:tz'
});

DateTime.editor = {
Expand All @@ -41,16 +42,22 @@ define(function (require) {
// don't give away our ref to converter so
// we can hot-swap when config changes
var pattern = this.param('pattern');
var timezone = this.param('timezone');

if (this._memoizedPattern !== pattern) {
var timezoneChanged = this._timeZone !== timezone;
var datePatternChanged = this._memoizedPattern !== pattern;
if (timezoneChanged || datePatternChanged) {
this._timeZone = timezone;
this._memoizedPattern = pattern;

this._memoizedConverter = _.memoize(function converter(val) {
if (val === null || val === undefined) {
return '-';
}
return moment(val).format(pattern);
});
}

return this._memoizedConverter(val);
};

Expand Down
2 changes: 2 additions & 0 deletions webpackShims/moment-timezone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
var moment = module.exports = require('../node_modules/moment-timezone/moment-timezone');
moment.tz.load(require('../node_modules/moment-timezone/data/packed/latest.json'));

0 comments on commit 9571469

Please sign in to comment.