Fix minor issues with timezones

This commit is contained in:
Daniel García Aubert 2017-08-07 16:53:08 +02:00
parent 7eae2a0618
commit 660078f284
3 changed files with 192 additions and 3 deletions

View File

@ -3,6 +3,12 @@
## 3.10.2 ## 3.10.2
Released 2017-mm-dd Released 2017-mm-dd
Announcements:
- Allow to override with any aggregation for histograms instantiated w/o aggregation.
Bug fixes:
- Apply timezone after truncating the minimun date for each bin to calculate timestamps in time-series.
## 3.10.1 ## 3.10.1
Released 2017-08-04 Released 2017-08-04

View File

@ -246,7 +246,7 @@ var dateHistogramQueryTpl = dot.template([
' date_part(', ' date_part(',
' \'epoch\', ', ' \'epoch\', ',
' date_trunc(', ' date_trunc(',
' \'{{=it._aggregation}}\', {{=it._column}}::timestamptz', ' \'{{=it._aggregation}}\', {{=it._column}}::timestamp AT TIME ZONE \'{{=it._offset}}\'',
' ) AT TIME ZONE \'{{=it._offset}}\'', ' ) AT TIME ZONE \'{{=it._offset}}\'',
' )', ' )',
' )::numeric AS timestamp,', ' )::numeric AS timestamp,',
@ -333,7 +333,7 @@ Histogram.prototype._buildQuery = function (psql, override, callback) {
var _column = this.column; var _column = this.column;
var _query = this.query; var _query = this.query;
if (this._columnType === 'date' && this.aggregation !== undefined) { if (this._columnType === 'date' && (this.aggregation !== undefined || override.aggregation !== undefined)) {
return this._buildDateHistogramQuery(psql, override, callback); return this._buildDateHistogramQuery(psql, override, callback);
} }

View File

@ -888,7 +888,6 @@ describe('histogram-dates: aggregation input value', function() {
}); });
}); });
describe('histogram-dates: timestamp starts at epoch', function() { describe('histogram-dates: timestamp starts at epoch', function() {
afterEach(function(done) { afterEach(function(done) {
@ -958,3 +957,187 @@ describe('histogram-dates: timestamp starts at epoch', function() {
}); });
}); });
}); });
describe('histogram-dates: trunc timestamp for each bin respecting user\'s timezone', function() {
afterEach(function(done) {
if (this.testClient) {
this.testClient.drain(done);
} else {
done();
}
});
var mapConfig = createMapConfig(
[
{
type: "cartodb",
options: {
source: {
id: "a0"
},
cartocss: "#points { marker-width: 10; marker-fill: red; }",
cartocss_version: "2.3.0"
}
}
],
{
timezone_epoch_histogram: {
source: {
id: 'a0'
},
type: 'histogram',
options: {
column: 'd',
aggregation: 'auto'
}
}
},
[
{
id: 'a0',
type: 'source',
params: {
query: [
'select null::geometry the_geom_webmercator, date AS d',
'from generate_series(',
'\'1970-01-01 00:00:00\'::timestamp,',
'\'1970-01-01 01:59:00\'::timestamp,',
' \'1 minute\'::interval',
') date'
].join(' ')
}
}
]
);
it('should return histogram with two buckets', function(done) {
this.testClient = new TestClient(mapConfig, 1234);
const override = {
aggregation: 'day',
offset: '-3600'
};
this.testClient.getDataview('timezone_epoch_histogram', override, function(err, dataview) {
assert.ifError(err);
var OFFSET_IN_MINUTES = -1 * 60; // GMT-01
var initialTimestamp = '1969-12-31T00:00:00-01:00';
var binsStartInMilliseconds = dataview.bins_start * 1000;
var binsStartFormatted = moment.utc(binsStartInMilliseconds)
.utcOffset(OFFSET_IN_MINUTES)
.format();
assert.equal(binsStartFormatted, initialTimestamp);
dataview.bins.forEach(function (bin, index) {
var binTimestampExpected = moment.utc(initialTimestamp)
.utcOffset(OFFSET_IN_MINUTES)
.add(index, override.aggregation)
.format();
var binsTimestampInMilliseconds = bin.timestamp * 1000;
var binTimestampFormatted = moment.utc(binsTimestampInMilliseconds)
.utcOffset(OFFSET_IN_MINUTES)
.format();
assert.equal(binTimestampFormatted, binTimestampExpected);
assert.ok(bin.timestamp <= bin.min, 'bin timestamp < bin min: ' + JSON.stringify(bin));
assert.ok(bin.min <= bin.max, 'bin min < bin max: ' + JSON.stringify(bin));
});
done();
});
});
});
describe('histogram: be able to override with aggregation for histograms instantiated w/o aggregation', function() {
afterEach(function(done) {
if (this.testClient) {
this.testClient.drain(done);
} else {
done();
}
});
var mapConfig = createMapConfig(
[
{
type: "cartodb",
options: {
source: {
id: "a0"
},
cartocss: "#points { marker-width: 10; marker-fill: red; }",
cartocss_version: "2.3.0"
}
}
],
{
timezone_epoch_histogram: {
source: {
id: 'a0'
},
type: 'histogram',
options: {
column: 'd',
}
}
},
[
{
id: 'a0',
type: 'source',
params: {
query: [
'select null::geometry the_geom_webmercator, date AS d',
'from generate_series(',
'\'1970-01-01 00:00:00\'::timestamp,',
'\'1970-01-01 01:59:00\'::timestamp,',
' \'1 minute\'::interval',
') date'
].join(' ')
}
}
]
);
it('should apply aggregation to the histogram', function(done) {
this.testClient = new TestClient(mapConfig, 1234);
const override = {
aggregation: 'day',
offset: '-3600'
};
this.testClient.getDataview('timezone_epoch_histogram', override, function(err, dataview) {
assert.ifError(err);
var OFFSET_IN_MINUTES = -1 * 60; // GMT-01
var initialTimestamp = '1969-12-31T00:00:00-01:00';
var binsStartInMilliseconds = dataview.bins_start * 1000;
var binsStartFormatted = moment.utc(binsStartInMilliseconds)
.utcOffset(OFFSET_IN_MINUTES)
.format();
assert.equal(binsStartFormatted, initialTimestamp);
dataview.bins.forEach(function (bin, index) {
var binTimestampExpected = moment.utc(initialTimestamp)
.utcOffset(OFFSET_IN_MINUTES)
.add(index, override.aggregation)
.format();
var binsTimestampInMilliseconds = bin.timestamp * 1000;
var binTimestampFormatted = moment.utc(binsTimestampInMilliseconds)
.utcOffset(OFFSET_IN_MINUTES)
.format();
assert.equal(binTimestampFormatted, binTimestampExpected);
assert.ok(bin.timestamp <= bin.min, 'bin timestamp < bin min: ' + JSON.stringify(bin));
assert.ok(bin.min <= bin.max, 'bin min < bin max: ' + JSON.stringify(bin));
});
done();
});
});
});