From 715ddcea09f7717360f1ae66aaa25f180d3ece9e Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 17 Jul 2018 12:47:43 -0600 Subject: [PATCH 1/7] avoid day long gaps in sample data --- .../routes/lib/adjust_timestamp.js | 37 +++++-- .../routes/lib/adjust_timestamp.test.js | 103 +++++++++++++----- 2 files changed, 107 insertions(+), 33 deletions(-) diff --git a/src/server/sample_data/routes/lib/adjust_timestamp.js b/src/server/sample_data/routes/lib/adjust_timestamp.js index 749b181cbe544..57258cb4e7eeb 100644 --- a/src/server/sample_data/routes/lib/adjust_timestamp.js +++ b/src/server/sample_data/routes/lib/adjust_timestamp.js @@ -20,6 +20,19 @@ const MILLISECONDS_IN_DAY = 86400000; + +function iso8601ToDateIgnoringTime(iso8601) { + const split = iso8601.split('-'); + const year = parseInt(split[0]); + const month = parseInt(split[1]) - 1; // javascript months are zero-based indexed + const date = parseInt(split[2]); + return new Date(year, month, date); +} + +function toDateOnly(date) { + return new Date(date.getFullYear(), date.getMonth(), date.getDate()); +} + /** * Convert timestamp to timestamp that is relative to now * @@ -30,19 +43,29 @@ const MILLISECONDS_IN_DAY = 86400000; * @return {String} ISO8601 formated data string YYYY-MM-dd'T'HH:mm:ss.SSS of timestamp adjusted to now */ export function adjustTimestamp(timestamp, currentTimeMarker, now, preserveDayOfWeekTimeOfDay) { - const timestampDate = new Date(Date.parse(timestamp)); - if (!preserveDayOfWeekTimeOfDay) { // Move timestamp relative to now, preserving distance between currentTimeMarker and timestamp + const timestampDate = new Date(Date.parse(timestamp)); const timeDelta = timestampDate.getTime() - currentTimeMarker.getTime(); return (new Date(now.getTime() + timeDelta)).toISOString(); } // Move timestamp to current week, preserving day of week and time of day - const weekDelta = Math.round((timestampDate.getTime() - currentTimeMarker.getTime()) / (MILLISECONDS_IN_DAY * 7)); - const dayOfWeekDelta = timestampDate.getDay() - now.getDay(); - const daysDelta = dayOfWeekDelta * MILLISECONDS_IN_DAY + (weekDelta * MILLISECONDS_IN_DAY * 7); - const yearMonthDay = (new Date(now.getTime() + daysDelta)).toISOString().substring(0, 10); - return `${yearMonthDay}T${timestamp.substring(11)}`; + const timestampDateOnly = iso8601ToDateIgnoringTime(timestamp); + const nowDateOnly = toDateOnly(now); + const currentTimeMarkerDateOnly = toDateOnly(currentTimeMarker); + let partialWeek = 0; + if (timestampDateOnly.getDay() > currentTimeMarkerDateOnly.getDay() + && timestampDateOnly.getTime() < currentTimeMarkerDateOnly.getTime()) { + partialWeek = 1; + } + const unroundedWeekDelta = (timestampDateOnly.getTime() - currentTimeMarkerDateOnly.getTime()) / (MILLISECONDS_IN_DAY * 7); + const weekDelta = partialWeek + Math.floor(Math.abs(unroundedWeekDelta)); + const weekDirection = timestampDateOnly.getTime() < currentTimeMarkerDateOnly.getTime() ? -1 : 1; + + const dayOfWeekDelta = timestampDateOnly.getDay() - nowDateOnly.getDay(); + const daysDeltaInMS = dayOfWeekDelta * MILLISECONDS_IN_DAY + (weekDirection * weekDelta * MILLISECONDS_IN_DAY * 7); + const yearMonthDay = (new Date(nowDateOnly.getTime() + daysDeltaInMS)).toISOString().substring(0, 10); + return `${yearMonthDay}T${timestamp.substring(11)}`; } diff --git a/src/server/sample_data/routes/lib/adjust_timestamp.test.js b/src/server/sample_data/routes/lib/adjust_timestamp.test.js index ee74537058ece..3120968a41419 100644 --- a/src/server/sample_data/routes/lib/adjust_timestamp.test.js +++ b/src/server/sample_data/routes/lib/adjust_timestamp.test.js @@ -20,10 +20,10 @@ import { adjustTimestamp } from './adjust_timestamp'; -const currentTimeMarker = new Date(Date.parse('2018-01-02T00:00:00Z')); -const now = new Date(Date.parse('2018-04-25T18:24:58.650Z')); // Wednesday - describe('relative to now', () => { + const currentTimeMarker = new Date(Date.parse('2018-01-02T00:00:00Z')); + const now = new Date(Date.parse('2018-04-25T18:24:58.650Z')); // Wednesday + test('adjusts time to 10 minutes in past from now', () => { const originalTimestamp = '2018-01-01T23:50:00Z'; // -10 minutes relative to currentTimeMarker const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, false); @@ -38,36 +38,87 @@ describe('relative to now', () => { }); describe('preserve day of week and time of day', () => { - test('adjusts time to monday of the same week as now', () => { - const originalTimestamp = '2018-01-01T23:50:00Z'; // Monday, same week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-23T23:50:00Z'); - }); + const currentTimeMarker = new Date(Date.parse('2018-01-02T00:00:00')); //Tuesday + const now = new Date(Date.parse('2018-04-25T18:24:58.650')); // Wednesday - test('adjusts time to friday of the same week as now', () => { - const originalTimestamp = '2017-12-29T23:50:00Z'; // Friday, same week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-27T23:50:00Z'); + describe('2 weeks before', () => { + test('should properly adjust timestamp when day is before now day of week', () => { + const originalTimestamp = '2017-12-18T23:50:00'; // Monday, -2 week relative to currentTimeMarker + const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); + expect(timestamp).toBe('2018-04-09T23:50:00'); // Monday 2 week before now week + }); + + test('should properly adjust timestamp when day is same as now day of week', () => { + const originalTimestamp = '2017-12-20T23:50:00'; // Wednesday, -2 week relative to currentTimeMarker + const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); + expect(timestamp).toBe('2018-04-11T23:50:00'); // Wednesday 2 week before now week + }); + + test('should properly adjust timestamp when day is after now day of week', () => { + const originalTimestamp = '2017-12-22T16:16:50'; // Friday, -2 week relative to currentTimeMarker + const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); + expect(timestamp).toBe('2018-04-13T16:16:50'); // Friday 2 week before now week + }); }); - test('adjusts time to monday of the previous week as now', () => { - const originalTimestamp = '2017-12-25T23:50:00Z'; // Monday, previous week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-16T23:50:00Z'); + describe('week before', () => { + test('should properly adjust timestamp when day is before now day of week', () => { + const originalTimestamp = '2017-12-25T23:50:00'; // Monday, -1 week relative to currentTimeMarker + const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); + expect(timestamp).toBe('2018-04-16T23:50:00'); // Monday 1 week before now week + }); + + test('should properly adjust timestamp when day is same as now day of week', () => { + const originalTimestamp = '2017-12-27T23:50:00'; // Wednesday, -1 week relative to currentTimeMarker + const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); + expect(timestamp).toBe('2018-04-18T23:50:00'); // Wednesday 1 week before now week + }); + + test('should properly adjust timestamp when day is after now day of week', () => { + const originalTimestamp = '2017-12-29T16:16:50'; // Friday, -1 week relative to currentTimeMarker + const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); + expect(timestamp).toBe('2018-04-20T16:16:50'); // Friday 1 week before now week + }); }); - test('adjusts time to friday of the week after now', () => { - const originalTimestamp = '2018-01-05T23:50:00Z'; // Friday, next week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-05-04T23:50:00Z'); + describe('same week', () => { + test('should properly adjust timestamp when day is before now day of week', () => { + const originalTimestamp = '2018-01-01T23:50:00'; // Monday, same week relative to currentTimeMarker + const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); + expect(timestamp).toBe('2018-04-23T23:50:00'); // Monday same week as now + }); + + test('should properly adjust timestamp when day is same as now day of week', () => { + const originalTimestamp = '2018-01-03T23:50:00'; // Wednesday, same week relative to currentTimeMarker + const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); + expect(timestamp).toBe('2018-04-25T23:50:00'); // Wednesday same week as now + }); + + test('should properly adjust timestamp when day is after now day of week', () => { + const originalTimestamp = '2018-01-05T16:16:50'; // Friday, same week relative to currentTimeMarker + const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); + expect(timestamp).toBe('2018-04-27T16:16:50'); // Friday same week as now + }); }); - test('adjusts timestamp to correct day of week even when UTC day is on different day.', () => { - const currentTimeMarker = new Date(Date.parse('2018-01-02T00:00:00')); // Tuesday - const now = new Date(Date.parse('2018-06-14T10:38')); // Thurs - const originalTimestamp = '2018-01-01T17:57:25'; // Monday - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-06-11T17:57:25'); // Monday + describe('week after', () => { + test('should properly adjust timestamp when day is before now day of week', () => { + const originalTimestamp = '2018-01-08T23:50:00'; // Monday, 1 week after relative to currentTimeMarker + const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); + expect(timestamp).toBe('2018-04-23T23:50:00'); // Monday 1 week after now week + }); + + test('should properly adjust timestamp when day is same as now day of week', () => { + const originalTimestamp = '2018-01-10T23:50:00'; // Wednesday, same week relative to currentTimeMarker + const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); + expect(timestamp).toBe('2018-05-02T23:50:00'); // Wednesday 1 week after now week + }); + + test('should properly adjust timestamp when day is after now day of week', () => { + const originalTimestamp = '2018-01-12T16:16:50'; // Friday, same week relative to currentTimeMarker + const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); + expect(timestamp).toBe('2018-05-04T16:16:50'); // Friday 1 week after now week + }); }); }); From 3fb7ab2ffa37e36a09e4b2108d006fcf054c7105 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 17 Jul 2018 13:07:36 -0600 Subject: [PATCH 2/7] avoid using toISOString to avoid an timezone problems --- src/server/sample_data/routes/lib/adjust_timestamp.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/server/sample_data/routes/lib/adjust_timestamp.js b/src/server/sample_data/routes/lib/adjust_timestamp.js index 57258cb4e7eeb..75027bdc0812f 100644 --- a/src/server/sample_data/routes/lib/adjust_timestamp.js +++ b/src/server/sample_data/routes/lib/adjust_timestamp.js @@ -66,6 +66,11 @@ export function adjustTimestamp(timestamp, currentTimeMarker, now, preserveDayOf const dayOfWeekDelta = timestampDateOnly.getDay() - nowDateOnly.getDay(); const daysDeltaInMS = dayOfWeekDelta * MILLISECONDS_IN_DAY + (weekDirection * weekDelta * MILLISECONDS_IN_DAY * 7); - const yearMonthDay = (new Date(nowDateOnly.getTime() + daysDeltaInMS)).toISOString().substring(0, 10); - return `${yearMonthDay}T${timestamp.substring(11)}`; + + const adjustedTimestamp = (new Date(nowDateOnly.getTime() + daysDeltaInMS)); + const year = adjustedTimestamp.getFullYear(); + const month = adjustedTimestamp.getMonth() + 1; + const monthString = month < 10 ? `0${month}` : `${month}`; + const dateString = adjustedTimestamp.getDate() < 10 ? `0${adjustedTimestamp.getDate()}` : `${adjustedTimestamp.getDate()}`; + return `${year}-${monthString}-${dateString}T${timestamp.substring(11)}`; } From 4a1de8d59fe6fb39f5fa15115e158b1e1cf27a43 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Tue, 17 Jul 2018 14:49:06 -0600 Subject: [PATCH 3/7] unskip sample test now that problem is fixed --- test/functional/apps/home/_sample_data.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/functional/apps/home/_sample_data.js b/test/functional/apps/home/_sample_data.js index c615ff5ea362a..48cc3cf509936 100644 --- a/test/functional/apps/home/_sample_data.js +++ b/test/functional/apps/home/_sample_data.js @@ -50,8 +50,7 @@ export default function ({ getService, getPageObjects }) { expect(isInstalled).to.be(true); }); - // Skipping issue # 20807 - describe.skip('dashboard', () => { + describe('dashboard', () => { after(async () => { await PageObjects.common.navigateToUrl('home', 'tutorial_directory/sampleData'); await PageObjects.header.waitUntilLoadingHasFinished(); From d8b531a34375471622b83db29cb91c98319e374c Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 19 Jul 2018 20:25:39 -0600 Subject: [PATCH 4/7] use much better cj algorithm for translating time --- src/server/sample_data/routes/install.js | 13 +- .../routes/lib/adjust_timestamp.js | 76 ----------- .../routes/lib/adjust_timestamp.test.js | 124 ------------------ .../routes/lib/translate_timestamp.js | 70 ++++++++++ .../routes/lib/translate_timestamp.test.js | 107 +++++++++++++++ 5 files changed, 186 insertions(+), 204 deletions(-) delete mode 100644 src/server/sample_data/routes/lib/adjust_timestamp.js delete mode 100644 src/server/sample_data/routes/lib/adjust_timestamp.test.js create mode 100644 src/server/sample_data/routes/lib/translate_timestamp.js create mode 100644 src/server/sample_data/routes/lib/translate_timestamp.test.js diff --git a/src/server/sample_data/routes/install.js b/src/server/sample_data/routes/install.js index 8e096992a1982..a318bf3d49c45 100644 --- a/src/server/sample_data/routes/install.js +++ b/src/server/sample_data/routes/install.js @@ -21,7 +21,11 @@ import Joi from 'joi'; import { loadData } from './lib/load_data'; import { createIndexName } from './lib/create_index_name'; -import { adjustTimestamp } from './lib/adjust_timestamp'; +import { + dateToISO8601IgnoringTime, + translateTimeRelativeToDifference, + translateTimeRelativeToWeek +} from './lib/translate_timestamp'; export const createInstallRoute = () => ({ path: '/api/sample_data/{id}', @@ -80,12 +84,13 @@ export const createInstallRoute = () => ({ return reply(errMsg).code(err.status); } - const now = new Date(); - const currentTimeMarker = new Date(Date.parse(sampleDataset.currentTimeMarker)); + const nowReference = dateToISO8601IgnoringTime(new Date()); function updateTimestamps(doc) { sampleDataset.timeFields.forEach(timeFieldName => { if (doc[timeFieldName]) { - doc[timeFieldName] = adjustTimestamp(doc[timeFieldName], currentTimeMarker, now, sampleDataset.preserveDayOfWeekTimeOfDay); + doc[timeFieldName] = sampleDataset.preserveDayOfWeekTimeOfDay + ? translateTimeRelativeToWeek(doc[timeFieldName], sampleDataset.currentTimeMarker, nowReference) + : translateTimeRelativeToDifference(doc[timeFieldName], sampleDataset.currentTimeMarker, nowReference); } }); return doc; diff --git a/src/server/sample_data/routes/lib/adjust_timestamp.js b/src/server/sample_data/routes/lib/adjust_timestamp.js deleted file mode 100644 index 75027bdc0812f..0000000000000 --- a/src/server/sample_data/routes/lib/adjust_timestamp.js +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - -const MILLISECONDS_IN_DAY = 86400000; - - -function iso8601ToDateIgnoringTime(iso8601) { - const split = iso8601.split('-'); - const year = parseInt(split[0]); - const month = parseInt(split[1]) - 1; // javascript months are zero-based indexed - const date = parseInt(split[2]); - return new Date(year, month, date); -} - -function toDateOnly(date) { - return new Date(date.getFullYear(), date.getMonth(), date.getDate()); -} - -/** - * Convert timestamp to timestamp that is relative to now - * - * @param {String} timestamp ISO8601 formated data string YYYY-MM-dd'T'HH:mm:ss.SSS - * @param {Date} currentTimeMarker "now" reference marker in sample dataset - * @param {Date} now - * @param {Boolean} preserveDayOfWeekTimeOfDay - * @return {String} ISO8601 formated data string YYYY-MM-dd'T'HH:mm:ss.SSS of timestamp adjusted to now - */ -export function adjustTimestamp(timestamp, currentTimeMarker, now, preserveDayOfWeekTimeOfDay) { - if (!preserveDayOfWeekTimeOfDay) { - // Move timestamp relative to now, preserving distance between currentTimeMarker and timestamp - const timestampDate = new Date(Date.parse(timestamp)); - const timeDelta = timestampDate.getTime() - currentTimeMarker.getTime(); - return (new Date(now.getTime() + timeDelta)).toISOString(); - } - - // Move timestamp to current week, preserving day of week and time of day - const timestampDateOnly = iso8601ToDateIgnoringTime(timestamp); - const nowDateOnly = toDateOnly(now); - const currentTimeMarkerDateOnly = toDateOnly(currentTimeMarker); - - let partialWeek = 0; - if (timestampDateOnly.getDay() > currentTimeMarkerDateOnly.getDay() - && timestampDateOnly.getTime() < currentTimeMarkerDateOnly.getTime()) { - partialWeek = 1; - } - const unroundedWeekDelta = (timestampDateOnly.getTime() - currentTimeMarkerDateOnly.getTime()) / (MILLISECONDS_IN_DAY * 7); - const weekDelta = partialWeek + Math.floor(Math.abs(unroundedWeekDelta)); - const weekDirection = timestampDateOnly.getTime() < currentTimeMarkerDateOnly.getTime() ? -1 : 1; - - const dayOfWeekDelta = timestampDateOnly.getDay() - nowDateOnly.getDay(); - const daysDeltaInMS = dayOfWeekDelta * MILLISECONDS_IN_DAY + (weekDirection * weekDelta * MILLISECONDS_IN_DAY * 7); - - const adjustedTimestamp = (new Date(nowDateOnly.getTime() + daysDeltaInMS)); - const year = adjustedTimestamp.getFullYear(); - const month = adjustedTimestamp.getMonth() + 1; - const monthString = month < 10 ? `0${month}` : `${month}`; - const dateString = adjustedTimestamp.getDate() < 10 ? `0${adjustedTimestamp.getDate()}` : `${adjustedTimestamp.getDate()}`; - return `${year}-${monthString}-${dateString}T${timestamp.substring(11)}`; -} diff --git a/src/server/sample_data/routes/lib/adjust_timestamp.test.js b/src/server/sample_data/routes/lib/adjust_timestamp.test.js deleted file mode 100644 index 3120968a41419..0000000000000 --- a/src/server/sample_data/routes/lib/adjust_timestamp.test.js +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - -import { adjustTimestamp } from './adjust_timestamp'; - -describe('relative to now', () => { - const currentTimeMarker = new Date(Date.parse('2018-01-02T00:00:00Z')); - const now = new Date(Date.parse('2018-04-25T18:24:58.650Z')); // Wednesday - - test('adjusts time to 10 minutes in past from now', () => { - const originalTimestamp = '2018-01-01T23:50:00Z'; // -10 minutes relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, false); - expect(timestamp).toBe('2018-04-25T18:14:58.650Z'); - }); - - test('adjusts time to 1 hour in future from now', () => { - const originalTimestamp = '2018-01-02T01:00:00Z'; // + 1 hour relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, false); - expect(timestamp).toBe('2018-04-25T19:24:58.650Z'); - }); -}); - -describe('preserve day of week and time of day', () => { - const currentTimeMarker = new Date(Date.parse('2018-01-02T00:00:00')); //Tuesday - const now = new Date(Date.parse('2018-04-25T18:24:58.650')); // Wednesday - - describe('2 weeks before', () => { - test('should properly adjust timestamp when day is before now day of week', () => { - const originalTimestamp = '2017-12-18T23:50:00'; // Monday, -2 week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-09T23:50:00'); // Monday 2 week before now week - }); - - test('should properly adjust timestamp when day is same as now day of week', () => { - const originalTimestamp = '2017-12-20T23:50:00'; // Wednesday, -2 week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-11T23:50:00'); // Wednesday 2 week before now week - }); - - test('should properly adjust timestamp when day is after now day of week', () => { - const originalTimestamp = '2017-12-22T16:16:50'; // Friday, -2 week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-13T16:16:50'); // Friday 2 week before now week - }); - }); - - describe('week before', () => { - test('should properly adjust timestamp when day is before now day of week', () => { - const originalTimestamp = '2017-12-25T23:50:00'; // Monday, -1 week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-16T23:50:00'); // Monday 1 week before now week - }); - - test('should properly adjust timestamp when day is same as now day of week', () => { - const originalTimestamp = '2017-12-27T23:50:00'; // Wednesday, -1 week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-18T23:50:00'); // Wednesday 1 week before now week - }); - - test('should properly adjust timestamp when day is after now day of week', () => { - const originalTimestamp = '2017-12-29T16:16:50'; // Friday, -1 week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-20T16:16:50'); // Friday 1 week before now week - }); - }); - - describe('same week', () => { - test('should properly adjust timestamp when day is before now day of week', () => { - const originalTimestamp = '2018-01-01T23:50:00'; // Monday, same week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-23T23:50:00'); // Monday same week as now - }); - - test('should properly adjust timestamp when day is same as now day of week', () => { - const originalTimestamp = '2018-01-03T23:50:00'; // Wednesday, same week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-25T23:50:00'); // Wednesday same week as now - }); - - test('should properly adjust timestamp when day is after now day of week', () => { - const originalTimestamp = '2018-01-05T16:16:50'; // Friday, same week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-27T16:16:50'); // Friday same week as now - }); - }); - - describe('week after', () => { - test('should properly adjust timestamp when day is before now day of week', () => { - const originalTimestamp = '2018-01-08T23:50:00'; // Monday, 1 week after relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-04-23T23:50:00'); // Monday 1 week after now week - }); - - test('should properly adjust timestamp when day is same as now day of week', () => { - const originalTimestamp = '2018-01-10T23:50:00'; // Wednesday, same week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-05-02T23:50:00'); // Wednesday 1 week after now week - }); - - test('should properly adjust timestamp when day is after now day of week', () => { - const originalTimestamp = '2018-01-12T16:16:50'; // Friday, same week relative to currentTimeMarker - const timestamp = adjustTimestamp(originalTimestamp, currentTimeMarker, now, true); - expect(timestamp).toBe('2018-05-04T16:16:50'); // Friday 1 week after now week - }); - }); -}); - diff --git a/src/server/sample_data/routes/lib/translate_timestamp.js b/src/server/sample_data/routes/lib/translate_timestamp.js new file mode 100644 index 0000000000000..b87390f57f4ec --- /dev/null +++ b/src/server/sample_data/routes/lib/translate_timestamp.js @@ -0,0 +1,70 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +const MILLISECONDS_IN_DAY = 86400000; + +function iso8601ToDateIgnoringTime(iso8601) { + const split = iso8601.split('-'); + if (split.length < 3) { + throw new Error('Unexpected timestamp format, expecting YYYY-MM-DDTHH:mm:ss'); + } + const year = parseInt(split[0]); + const month = parseInt(split[1]) - 1; // javascript months are zero-based indexed + const date = parseInt(split[2]); + return new Date(year, month, date); +} + +export function dateToISO8601IgnoringTime(date) { + // not using "Date.toISOString" because only using Date methods that deal with local time + const year = date.getFullYear(); + const month = date.getMonth() + 1; + const monthString = month < 10 ? `0${month}` : `${month}`; + const dateString = date.getDate() < 10 ? `0${date.getDate()}` : `${date.getDate()}`; + return `${year}-${monthString}-${dateString}`; +} + +// Translate source timestamp by targetReference timestamp, +// perserving the distance between source and sourceReference +export function translateTimeRelativeToDifference(source, sourceReference, targetReference) { + const sourceDate = iso8601ToDateIgnoringTime(source); + const sourceReferenceDate = iso8601ToDateIgnoringTime(sourceReference); + const targetReferenceDate = iso8601ToDateIgnoringTime(targetReference); + + const delta = sourceDate.getTime() - sourceReferenceDate.getTime(); + const translatedDate = (new Date(targetReferenceDate.getTime() + delta)); + + return `${dateToISO8601IgnoringTime(translatedDate)}T${source.substring(11)}`; +} + +// Translate source timestamp by targetReference timestamp, +// perserving the week distance between source and sourceReference and day of week of the source timestamp +export function translateTimeRelativeToWeek(source, sourceReference, targetReference) { + const sourceReferenceDate = iso8601ToDateIgnoringTime(sourceReference); + const targetReferenceDate = iso8601ToDateIgnoringTime(targetReference); + + // targetReference only provides the week of year information. + const referenceDayOfWeekDelta = sourceReferenceDate.getDay() - targetReferenceDate.getDay(); + const targetReferenceSameDayOfWeekAsSourceReference = + new Date(targetReferenceDate.getTime() + (referenceDayOfWeekDelta * MILLISECONDS_IN_DAY)); + + return translateTimeRelativeToDifference( + source, + sourceReference, + dateToISO8601IgnoringTime(targetReferenceSameDayOfWeekAsSourceReference)); +} diff --git a/src/server/sample_data/routes/lib/translate_timestamp.test.js b/src/server/sample_data/routes/lib/translate_timestamp.test.js new file mode 100644 index 0000000000000..348fd2b429167 --- /dev/null +++ b/src/server/sample_data/routes/lib/translate_timestamp.test.js @@ -0,0 +1,107 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + +import { translateTimeRelativeToWeek } from './translate_timestamp'; + +describe('translateTimeRelativeToWeek', () => { + const sourceReference = '2018-01-02T00:00:00'; //Tuesday + const targetReference = '2018-04-25T18:24:58.650'; // Wednesday + + describe('2 weeks before', () => { + test('should properly adjust timestamp when day is before targetReference day of week', () => { + const source = '2017-12-18T23:50:00'; // Monday, -2 week relative to sourceReference + const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference); + expect(timestamp).toBe('2018-04-09T23:50:00'); // Monday 2 week before targetReference week + }); + + test('should properly adjust timestamp when day is same as targetReference day of week', () => { + const source = '2017-12-20T23:50:00'; // Wednesday, -2 week relative to sourceReference + const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference); + expect(timestamp).toBe('2018-04-11T23:50:00'); // Wednesday 2 week before targetReference week + }); + + test('should properly adjust timestamp when day is after targetReference day of week', () => { + const source = '2017-12-22T16:16:50'; // Friday, -2 week relative to sourceReference + const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference); + expect(timestamp).toBe('2018-04-13T16:16:50'); // Friday 2 week before targetReference week + }); + }); + + describe('week before', () => { + test('should properly adjust timestamp when day is before targetReference day of week', () => { + const source = '2017-12-25T23:50:00'; // Monday, -1 week relative to sourceReference + const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference); + expect(timestamp).toBe('2018-04-16T23:50:00'); // Monday 1 week before targetReference week + }); + + test('should properly adjust timestamp when day is same as targetReference day of week', () => { + const source = '2017-12-27T23:50:00'; // Wednesday, -1 week relative to sourceReference + const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference); + expect(timestamp).toBe('2018-04-18T23:50:00'); // Wednesday 1 week before targetReference week + }); + + test('should properly adjust timestamp when day is after targetReference day of week', () => { + const source = '2017-12-29T16:16:50'; // Friday, -1 week relative to sourceReference + const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference); + expect(timestamp).toBe('2018-04-20T16:16:50'); // Friday 1 week before targetReference week + }); + }); + + describe('same week', () => { + test('should properly adjust timestamp when day is before targetReference day of week', () => { + const source = '2018-01-01T23:50:00'; // Monday, same week relative to sourceReference + const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference); + expect(timestamp).toBe('2018-04-23T23:50:00'); // Monday same week as targetReference + }); + + test('should properly adjust timestamp when day is same as targetReference day of week', () => { + const source = '2018-01-03T23:50:00'; // Wednesday, same week relative to sourceReference + const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference); + expect(timestamp).toBe('2018-04-25T23:50:00'); // Wednesday same week as targetReference + }); + + test('should properly adjust timestamp when day is after targetReference day of week', () => { + const source = '2018-01-05T16:16:50'; // Friday, same week relative to sourceReference + const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference); + expect(timestamp).toBe('2018-04-27T16:16:50'); // Friday same week as targetReference + }); + }); + + describe('week after', () => { + test('should properly adjust timestamp when day is before targetReference day of week', () => { + const source = '2018-01-08T23:50:00'; // Monday, 1 week after relative to sourceReference + const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference); + expect(timestamp).toBe('2018-04-30T23:50:00'); // Monday 1 week after targetReference week + }); + + test('should properly adjust timestamp when day is same as targetReference day of week', () => { + const source = '2018-01-10T23:50:00'; // Wednesday, same week relative to sourceReference + const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference); + expect(timestamp).toBe('2018-05-02T23:50:00'); // Wednesday 1 week after targetReference week + }); + + test('should properly adjust timestamp when day is after targetReference day of week', () => { + const source = '2018-01-12T16:16:50'; // Friday, same week relative to sourceReference + const timestamp = translateTimeRelativeToWeek(source, sourceReference, targetReference); + expect(timestamp).toBe('2018-05-04T16:16:50'); // Friday 1 week after targetReference week + }); + }); +}); + From bca4726df0633f4ecf251928ab2413aed083a253 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 20 Jul 2018 12:54:18 -0600 Subject: [PATCH 5/7] cjcenizal review updates --- .../routes/lib/translate_timestamp.js | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/server/sample_data/routes/lib/translate_timestamp.js b/src/server/sample_data/routes/lib/translate_timestamp.js index b87390f57f4ec..f8d0f86e49709 100644 --- a/src/server/sample_data/routes/lib/translate_timestamp.js +++ b/src/server/sample_data/routes/lib/translate_timestamp.js @@ -30,7 +30,7 @@ function iso8601ToDateIgnoringTime(iso8601) { return new Date(year, month, date); } -export function dateToISO8601IgnoringTime(date) { +export function dateToIso8601IgnoringTime(date) { // not using "Date.toISOString" because only using Date methods that deal with local time const year = date.getFullYear(); const month = date.getMonth() + 1; @@ -46,10 +46,10 @@ export function translateTimeRelativeToDifference(source, sourceReference, targe const sourceReferenceDate = iso8601ToDateIgnoringTime(sourceReference); const targetReferenceDate = iso8601ToDateIgnoringTime(targetReference); - const delta = sourceDate.getTime() - sourceReferenceDate.getTime(); - const translatedDate = (new Date(targetReferenceDate.getTime() + delta)); + const timeDelta = sourceDate.getTime() - sourceReferenceDate.getTime(); + const translatedDate = (new Date(targetReferenceDate.getTime() + timeDelta)); - return `${dateToISO8601IgnoringTime(translatedDate)}T${source.substring(11)}`; + return `${dateToIso8601IgnoringTime(translatedDate)}T${source.substring(11)}`; } // Translate source timestamp by targetReference timestamp, @@ -58,13 +58,18 @@ export function translateTimeRelativeToWeek(source, sourceReference, targetRefer const sourceReferenceDate = iso8601ToDateIgnoringTime(sourceReference); const targetReferenceDate = iso8601ToDateIgnoringTime(targetReference); - // targetReference only provides the week of year information. - const referenceDayOfWeekDelta = sourceReferenceDate.getDay() - targetReferenceDate.getDay(); - const targetReferenceSameDayOfWeekAsSourceReference = - new Date(targetReferenceDate.getTime() + (referenceDayOfWeekDelta * MILLISECONDS_IN_DAY)); + // If these dates were in the same week, how many days apart would they be? + const dayOfWeekDelta = sourceReferenceDate.getDay() - targetReferenceDate.getDay(); + + // If we pretend that the targetReference is actually the same day of the week as the + // sourceReference, then we can translate the source to the target while preserving their + // days of the week. + const normalizationDelta = dayOfWeekDelta * MILLISECONDS_IN_DAY; + const normalizedTargetReference = + dateToIso8601IgnoringTime(new Date(targetReferenceDate.getTime() + normalizationDelta)); return translateTimeRelativeToDifference( source, sourceReference, - dateToISO8601IgnoringTime(targetReferenceSameDayOfWeekAsSourceReference)); + normalizedTargetReference); } From 04d721f27b470ca973e65a91541ac4e504513fd2 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Fri, 20 Jul 2018 14:45:00 -0600 Subject: [PATCH 6/7] update funtion name in install.js --- src/server/sample_data/routes/install.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/sample_data/routes/install.js b/src/server/sample_data/routes/install.js index a318bf3d49c45..0c00bcc739063 100644 --- a/src/server/sample_data/routes/install.js +++ b/src/server/sample_data/routes/install.js @@ -22,7 +22,7 @@ import Joi from 'joi'; import { loadData } from './lib/load_data'; import { createIndexName } from './lib/create_index_name'; import { - dateToISO8601IgnoringTime, + dateToIso8601IgnoringTime, translateTimeRelativeToDifference, translateTimeRelativeToWeek } from './lib/translate_timestamp'; @@ -84,7 +84,7 @@ export const createInstallRoute = () => ({ return reply(errMsg).code(err.status); } - const nowReference = dateToISO8601IgnoringTime(new Date()); + const nowReference = dateToIso8601IgnoringTime(new Date()); function updateTimestamps(doc) { sampleDataset.timeFields.forEach(timeFieldName => { if (doc[timeFieldName]) { From ac02a3cc0fd3c0cd9bb9a47046889fde803734a4 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Sun, 22 Jul 2018 12:06:54 -0600 Subject: [PATCH 7/7] push source reference date back a week --- src/server/sample_data/data_sets/flights/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/sample_data/data_sets/flights/index.js b/src/server/sample_data/data_sets/flights/index.js index 2439e7b4a6507..dd2e477ccc98f 100644 --- a/src/server/sample_data/data_sets/flights/index.js +++ b/src/server/sample_data/data_sets/flights/index.js @@ -113,7 +113,7 @@ export function flightsSpecProvider() { } }, timeFields: ['timestamp'], - currentTimeMarker: '2018-01-02T00:00:00', + currentTimeMarker: '2018-01-09T00:00:00', preserveDayOfWeekTimeOfDay: true, savedObjects: savedObjects, };