Welcome! Log In Create A New Profile

Advanced

[njs] Fixed parsing ISO 8601 format in Date.parse().

Andrey Zelenkov
April 19, 2017 10:52AM
details: http://hg.nginx.org/njs/rev/96fda9957427
branches:
changeset: 340:96fda9957427
user: Andrey Zelenkov <zelenkov@nginx.com>
date: Wed Apr 19 17:48:56 2017 +0300
description:
Fixed parsing ISO 8601 format in Date.parse().

Fixed parsing in case milliseconds are not specified.
Added converting to local time in case "Z" suffix is not specified.
Also minor style fixes included.

diffstat:

njs/njs_date.c | 51 ++++++++++++++++++++++++++++++++++++-----------
njs/test/njs_unit_test.c | 36 ++++++++++++++++++++++++++++++++-
2 files changed, 73 insertions(+), 14 deletions(-)

diffs (145 lines):

diff -r 5a5b70cbbde9 -r 96fda9957427 njs/njs_date.c
--- a/njs/njs_date.c Tue Apr 04 13:24:09 2017 +0300
+++ b/njs/njs_date.c Wed Apr 19 17:48:56 2017 +0300
@@ -304,9 +304,10 @@ njs_date_parse(njs_vm_t *vm, njs_value_t
static nxt_noinline double
njs_date_string_parse(njs_value_t *date)
{
- int ext, ms;
+ int ext, ms, ms_length, skipped;
+ double time;
struct tm tm;
- nxt_bool_t sign, week;
+ nxt_bool_t sign, week, utc;
const u_char *p, *next, *end;
njs_string_prop_t string;

@@ -319,11 +320,7 @@ njs_date_string_parse(njs_value_t *date)
return NAN;
}

- if (*p == '+') {
- p++;
- sign = 1;
-
- } else if (*p == '-') {
+ if (*p == '+' || *p == '-') {
p++;
sign = 1;

@@ -403,6 +400,14 @@ njs_date_string_parse(njs_value_t *date)
return NAN;
}

+ utc = 1;
+ end--;
+
+ if (*end != 'Z') {
+ utc = 0;
+ end++;
+ }
+
p = njs_date_time_parse(&tm, p + 1, end);
if (nxt_slow_path(p == NULL)) {
return NAN;
@@ -412,20 +417,42 @@ njs_date_string_parse(njs_value_t *date)
goto done;
}

- if (nxt_slow_path(p >= end || *p != '.')) {
+ if (nxt_slow_path(p > end || *p != '.')) {
return NAN;
}

- p = njs_date_number_parse(&ms, p + 1, end, 3);
+ p++;
+
+ ms_length = (end - p < 3) ? end - p : 3;
+
+ p = njs_date_number_parse(&ms, p, end, ms_length);
if (nxt_slow_path(p == NULL)) {
return NAN;
}

- if (nxt_slow_path(p >= end || *p != 'Z')) {
- return NAN;
+ if (end > p) {
+ p = njs_date_number_parse(&skipped, p, end, end - p);
+ if (nxt_slow_path(p == NULL)) {
+ return NAN;
+ }
}

- return njs_timegm(&tm) * 1000 + ms;
+ if (ms_length == 1) {
+ ms *= 100;
+
+ } else if (ms_length == 2) {
+ ms *= 10;
+ }
+
+ if (utc) {
+ time = njs_timegm(&tm);
+
+ } else {
+ tm.tm_isdst = -1;
+ time = mktime(&tm);
+ }
+
+ return time * 1000 + ms;
}

if (sign) {
diff -r 5a5b70cbbde9 -r 96fda9957427 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Tue Apr 04 13:24:09 2017 +0300
+++ b/njs/test/njs_unit_test.c Wed Apr 19 17:48:56 2017 +0300
@@ -5713,15 +5713,47 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("Date.parse('2011-06-24T06')"),
nxt_string("NaN") },

- { nxt_string("Date.parse('2011-06-24T06:01')"),
+ { nxt_string("Date.parse('2011-06-24T06:')"),
+ nxt_string("NaN") },
+
+ { nxt_string("Date.parse('2011-06-24T06:01:')"),
+ nxt_string("NaN") },
+
+ { nxt_string("Date.parse('2011-06-24T06:01Z')"),
nxt_string("1308895260000") },

- { nxt_string("Date.parse('2011-06-24T06:01:02')"),
+ { nxt_string("Date.parse('2011-06-24T06:01:02:')"),
+ nxt_string("NaN") },
+
+ { nxt_string("Date.parse('2011-06-24T06:01:02Z')"),
nxt_string("1308895262000") },

+ { nxt_string("Date.parse('2011-06-24T06:01:02.Z')"),
+ nxt_string("NaN") },
+
+ { nxt_string("Date.parse('2011-06-24T06:01:02.6Z')"),
+ nxt_string("1308895262600") },
+
+ { nxt_string("Date.parse('2011-06-24T06:01:02.62Z')"),
+ nxt_string("1308895262620") },
+
+ { nxt_string("Date.parse('2011-06-24T06:01:02:625Z')"),
+ nxt_string("NaN") },
+
{ nxt_string("Date.parse('2011-06-24T06:01:02.625Z')"),
nxt_string("1308895262625") },

+ { nxt_string("Date.parse('2011-06-24T06:01:02.6255555Z')"),
+ nxt_string("1308895262625") },
+
+ { nxt_string("Date.parse('2011-06-24T06:01:02.625555Z5')"),
+ nxt_string("NaN") },
+
+ { nxt_string("var d = new Date(); var str = d.toISOString();"
+ "var diff = Date.parse(str) - Date.parse(str.substring(0, str.length - 1));"
+ "d.getTimezoneOffset() == -diff/1000/60"),
+ nxt_string("true") },
+
{ nxt_string("Date.parse('24 Jun 2011')"),
nxt_string("1308873600000") },

_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[njs] Fixed parsing ISO 8601 format in Date.parse().

Andrey Zelenkov 750 April 19, 2017 10:52AM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 308
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready