Skip to content
This repository was archived by the owner on Nov 29, 2023. It is now read-only.

Commit a49bc5d

Browse files
Merge pull request #148 from enketo/fix/dates-138-II
Fix/dates 138 ii
2 parents 78d4955 + 57bdb8a commit a49bc5d

File tree

5 files changed

+46
-29
lines changed

5 files changed

+46
-29
lines changed

src/openrosa-extensions.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -528,25 +528,29 @@ function asInteger(r) {
528528

529529
function asDate(r) {
530530
let temp;
531+
let timeComponent;
531532
switch(r.t) {
532533
case 'bool': return new Date(NaN);
533534
case 'date': return r.v;
534-
case 'num': temp = new Date(1970, 0, 1); temp.setDate(temp.getDate() + r.v); return temp;
535+
case 'num': temp = new Date(0); temp.setTime(temp.getTime() + r.v * 24 * 60 * 60 * 1000); return temp;
535536
case 'arr':
536537
case 'str':
537538
r = asString(r);
538539
if(RAW_NUMBER.test(r)) {
539-
// Create a date at 00:00:00 1st Jan 1970 _in the current timezone_
540-
temp = new Date(1970, 0, 1);
541-
temp.setDate(1 + parseInt(r, 10));
540+
temp = new Date(0);
541+
temp.setTime(temp.getTime() + parseInt(r, 10) * 24 * 60 * 60 * 1000);
542542
return temp;
543543
} else if(DATE_STRING.test(r)) {
544544
temp = r.indexOf('T');
545-
if(temp !== -1) r = r.substring(0, temp);
545+
if(temp !== -1) {
546+
timeComponent = r.substring(temp);
547+
r = r.substring(0, temp);
548+
}
546549
temp = r.split('-');
547550
if(isValidDate(temp[0], temp[1], temp[2])) {
551+
timeComponent = timeComponent ? timeComponent : 'T00:00:00.000' + getTimezoneOffsetAsTime(new Date(r));
548552
const time = `${_zeroPad(temp[0])}-${_zeroPad(temp[1])}-${_zeroPad(temp[2])}`+
549-
'T00:00:00.000' + getTimezoneOffsetAsTime(new Date(r));
553+
timeComponent;
550554
return new Date(time);
551555
}
552556
}

test/integration/complex.spec.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const _ = require('lodash');
33
const {initDoc, assert} = require('./helpers');
44

55
const SIMPLE_DATE_MATCH = /^\d{4}-[0-1]\d-[0-3]\d$/;
6+
const SIMPLE_DATE_OR_DATE_TIME_MATCH = /^\d{4}-[0-1]\d-[0-3]\d(T[0-2]\d:[0-5]\d:[0-5]\d\.\d\d\d(Z|[+-][0-1]\d(:[0-5]\d)?))?$/;
67

78
describe('some complex examples', () => {
89
const doc = initDoc('');
@@ -19,7 +20,7 @@ describe('some complex examples', () => {
1920
"if(selected('approx' ,'date'), 'first' ,'second')": /^second$/,
2021
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method, 'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date, 'testing')": /testing/,
2122
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method, 'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date, concat('testing', '1', '2', '3', '...'))": /testing/,
22-
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method, 'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date, date-time(0))": SIMPLE_DATE_MATCH,
23+
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method, 'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date, date-time(0))": SIMPLE_DATE_OR_DATE_TIME_MATCH,
2324
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method, 'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date, date-time(decimal-date-time(today() - 60)))": SIMPLE_DATE_MATCH,
2425
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method ,'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date ,date-time(decimal-date-time(today()- 60 )))": SIMPLE_DATE_MATCH,
2526
'if(true(), today(), today())': SIMPLE_DATE_MATCH,

test/integration/openrosa-xpath/date-time.spec.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ describe('#date-time()', () => {
88
});
99

1010
describe('valid date-time string', () => {
11-
it('should be converted to date string', () => {
12-
assertStringValue("date-time('1970-01-01T21:50:49Z')", '1970-01-01');
11+
it('should be converted to date-time string in the local time zone', () => {
12+
assertStringValue("date-time('1970-01-01T21:50:49Z')", '1970-01-01T14:50:49.000-07:00');
1313
});
1414
});
1515

1616
describe('positive number', () => {
1717
it('should be converted', () => {
18-
assertStringValue('date-time(0)', '1970-01-01');
19-
assertStringValue('date-time(1)', '1970-01-02');
18+
assertStringValue('date-time(0)', '1969-12-31T17:00:00.000-07:00');
19+
assertStringValue('date-time(1)', '1970-01-01T17:00:00.000-07:00');
2020
});
2121
});
2222

test/integration/openrosa-xpath/date.spec.js

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ describe('#date()', () => {
3838
assertNumberRounded('"2018-01-01" + 1', 17533.29167, 100000);
3939
});
4040

41+
it('example 2', () => {
42+
assertNumberRounded('date("1970-01-01T00:00:00.000+00:00")', 0, 100000);
43+
});
44+
45+
it('example 3', () => {
46+
assertNumberRounded('date(0)', 0, 100000);
47+
});
48+
4149
describe('with explicit number() call', () => {
4250
it('example 1', () => {
4351
assertNumberRounded('number("2018-01-01" + 1)', 17533.29167, 100000);
@@ -61,6 +69,10 @@ describe('#date()', () => {
6169
it('example 5', () => {
6270
assertStringValue('"2021-11-30" - "2021-11-29"', '1');
6371
});
72+
it('example 6', () => {
73+
assertStringValue('date(decimal-date-time("2003-10-20T08:00:00.000-07:00"))', '2003-10-20T08:00:00.000-07:00');
74+
});
75+
6476

6577
[
6678
'today()',
@@ -104,10 +116,10 @@ describe('#date()', () => {
104116

105117
describe('number', () => {
106118
[
107-
['date(0)', '1970-01-01'],
108-
['date(1)', '1970-01-02'],
109-
['date(1.5)', '1970-01-02'],
110-
['date(-1)', '1969-12-31'],
119+
['date(0)', '1969-12-31T17:00:00.000-07:00'],
120+
['date(1)', '1970-01-01T17:00:00.000-07:00'],
121+
['date(1.5)', '1970-01-02T05:00:00.000-07:00'],
122+
['date(-1)', '1969-12-30T17:00:00.000-07:00'],
111123
].forEach(([expr, expected]) => {
112124
it(expr + ' should be converted to ' + expected, () => {
113125
assertString(expr, expected);
@@ -131,16 +143,16 @@ describe('#date()', () => {
131143
['date("2004-05-01") != date("2004-05-01")', false],
132144
['"string" != date("1999-09-09")', true],
133145
['"string" = date("1999-09-09")', false],
134-
['date(0) = date("1970-01-01")', true],
135-
['date(0) != date("1970-01-01")', false],
136-
['date(1) = date("1970-01-02")', true],
137-
['date(1) != date("1970-01-02")', false],
138-
['date(-1) = date("1969-12-31")', true],
139-
['date(-1) != date("1969-12-31")', false],
140-
['date(14127) = date("2008-09-05")', true],
141-
['date(14127) != date("2008-09-05")', false],
142-
['date(-10252) = date("1941-12-07")', true],
143-
['date(-10252) != date("1941-12-07")', false],
146+
['date(0) = date("1970-01-01T00:00:00.000Z")', true],
147+
['date(0) != date("1970-01-01T00:00:00.000Z")', false],
148+
['date(1) = date("1970-01-02T00:00:00.000Z")', true],
149+
['date(1) != date("1970-01-02T00:00:00.000Z")', false],
150+
['date(-1) = date("1969-12-31T00:00:00.000Z")', true],
151+
['date(-1) != date("1969-12-31T00:00:00.000Z")', false],
152+
['date(14127) = date("2008-09-05T00:00:00.000Z")', true],
153+
['date(14127) != date("2008-09-05T00:00:00.000Z")', false],
154+
['date(-10252) = date("1941-12-07T00:00:00.000Z")', true],
155+
['date(-10252) != date("1941-12-07T00:00:00.000Z")', false],
144156
['date("2012-01-01") < today()', true],
145157
['date("2012-01-01") > today()', false],
146158
['date("2100-01-02") > today()', true],

test/unit/openrosa-extensions.spec.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,12 @@ describe('openrosa-extensions', () => {
7979
});
8080
});
8181

82-
it('should convert zero to 1 Jan 1970 in local timezone', () => {
82+
it('should convert zero to 1 Jan 1970 UTC', () => {
8383
// when
8484
const res = date(wrapVal(0));
8585

8686
// then
87-
assert.equal(res.v.toISOString(), '1970-01-01T07:00:00.000Z');
87+
assert.equal(res.v.toISOString(), '1970-01-01T00:00:00.000Z');
8888
});
8989
});
9090

@@ -111,12 +111,12 @@ describe('openrosa-extensions', () => {
111111
});
112112
});
113113

114-
it('should convert zero to 1 Jan 1970 in local timezone', () => {
114+
it('should convert zero to 1 Jan 1970 UTC', () => {
115115
// when
116116
const res = dateTime(wrapVal(0));
117117

118118
// then
119-
assert.equal(res.v.toISOString(), '1970-01-01T07:00:00.000Z');
119+
assert.equal(res.v.toISOString(), '1970-01-01T00:00:00.000Z');
120120
});
121121
});
122122

0 commit comments

Comments
 (0)