Skip to content

Commit 71d07e6

Browse files
committed
fix: dateRange gets translated to incorrect value
Fixes #348
1 parent d087837 commit 71d07e6

File tree

2 files changed

+53
-5
lines changed

2 files changed

+53
-5
lines changed

packages/cubejs-api-gateway/dateParser.js

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@ const chrono = require('chrono-node');
22
const moment = require('moment-timezone');
33
const UserError = require('./UserError');
44

5+
const momentFromResult = (result, timezone) => {
6+
const dateMoment = moment().tz(timezone);
7+
8+
dateMoment.set('year', result.get('year'));
9+
dateMoment.set('month', result.get('month') - 1);
10+
dateMoment.set('date', result.get('day'));
11+
dateMoment.set('hour', result.get('hour'));
12+
dateMoment.set('minute', result.get('minute'));
13+
dateMoment.set('second', result.get('second'));
14+
dateMoment.set('millisecond', result.get('millisecond'));
15+
16+
return dateMoment;
17+
};
18+
519
module.exports = (dateString, timezone) => {
620
let momentRange;
721
dateString = dateString.toLowerCase();
@@ -29,18 +43,37 @@ module.exports = (dateString, timezone) => {
2943
moment.tz(timezone).startOf('day').add(-1, 'day'),
3044
moment.tz(timezone).endOf('day').add(-1, 'day')
3145
];
46+
} else if (dateString.match(/^from (.*) to (.*)$/)) {
47+
// eslint-disable-next-line no-unused-vars
48+
const [all, from, to] = dateString.match(/^from (.*) to (.*)$/);
49+
const fromResults = chrono.parse(from, moment().tz(timezone));
50+
const toResults = chrono.parse(to, moment().tz(timezone));
51+
if (!fromResults) {
52+
throw new UserError(`Can't parse date: '${from}'`);
53+
}
54+
if (!toResults) {
55+
throw new UserError(`Can't parse date: '${to}'`);
56+
}
57+
const exactGranularity = ['second', 'minute', 'hour'].find(g => dateString.indexOf(g) !== -1) || 'day';
58+
momentRange = [
59+
momentFromResult(fromResults[0].start, timezone),
60+
momentFromResult(toResults[0].start, timezone)
61+
];
62+
momentRange = [momentRange[0].startOf(exactGranularity), momentRange[1].endOf(exactGranularity)];
3263
} else {
33-
const results = chrono.parse(dateString);
64+
const results = chrono.parse(dateString, moment().tz(timezone));
3465
if (!results) {
3566
throw new UserError(`Can't parse date: '${dateString}'`);
3667
}
68+
const exactGranularity = ['second', 'minute', 'hour'].find(g => dateString.indexOf(g) !== -1) || 'day';
3769
momentRange = results[0].end ? [
38-
moment(results[0].start.moment()).tz(timezone).startOf('day'),
39-
moment(results[0].end.moment()).tz(timezone).endOf('day')
70+
momentFromResult(results[0].start, timezone),
71+
momentFromResult(results[0].end, timezone)
4072
] : [
41-
moment(results[0].start.moment()).tz(timezone).startOf('day'),
42-
moment(results[0].start.moment()).tz(timezone).endOf('day')
73+
momentFromResult(results[0].start, timezone),
74+
momentFromResult(results[0].start, timezone)
4375
];
76+
momentRange = [momentRange[0].startOf(exactGranularity), momentRange[1].endOf(exactGranularity)];
4477
}
4578
return momentRange.map(d => d.format(moment.HTML5_FMT.DATETIME_LOCAL_MS));
4679
};

packages/cubejs-api-gateway/dateParser.test.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,19 @@ describe(`dateParser`, () => {
3333
]
3434
);
3535
});
36+
37+
test(`from 23 hours ago to now`, () => {
38+
expect(dateParser('from 23 hours ago to now', 'UTC')).toStrictEqual(
39+
[
40+
new Date((Math.floor(new Date().getTime() / (1000 * 60 * 60)) - 23) * (1000 * 60 * 60)).toISOString().replace('Z', ''),
41+
new Date((Math.ceil(new Date().getTime() / (1000 * 60 * 60))) * (1000 * 60 * 60) - 1).toISOString().replace('Z', '')
42+
]
43+
);
44+
});
45+
46+
test(`from 7 days ago to now`, () => {
47+
expect(dateParser('from 7 days ago to now', 'UTC')).toStrictEqual(
48+
[dateParser('last 7 days', 'UTC')[0], dateParser('today', 'UTC')[1]]
49+
);
50+
});
3651
});

0 commit comments

Comments
 (0)