1
1
// Times are parsed as UTC if no offset is specified
2
-
3
- class IsoDateParts {
2
+ export class IsoDateParts {
4
3
static DEFAULT_TIMEZONE_OFFSET = {
5
4
hours : 0 ,
6
5
minutes : 0 ,
7
6
} ;
8
7
9
- static VAGUE_DATE_REGEX = / ^ \d { 5 , 7 } $ / ;
10
- static PARTIAL_DATE_REGEX = / ^ ( \d { 4 } ) (?: - ( [ 0 1 ] \d ) (?: - ( [ 0 - 3 ] \d ) ) ? ) ? $ / ;
11
- static FULL_DATE_REGEX = / ^ ( \d { 4 } ) - ? ( [ 0 1 ] \d ) - ? ( [ 0 - 3 ] \d ) $ / ; // dashes optional when 8 digits
12
-
13
- static VAGUE_DATETIME_REGEX = / ^ ( \d { 4 } ) - ? ( [ 0 1 ] \d ) - ? ( [ 0 - 3 ] \d ) T ( \d { 1 } | \d { 3 } | \d { 5 } ) (?: [ \. \, ] ( \d + ) ) ? ( [ + - ] \d { 2 } : ? \d { 2 } | Z ) ? $ / ;
14
- static DATETIME_REGEX = / ^ ( \d { 4 } ) - ? ( [ 0 1 ] \d ) - ? ( [ 0 - 3 ] \d ) T ( [ 0 - 2 ] \d ) (?: : ? ( [ 0 - 5 ] \d ) ) ? (?: : ? ( [ 0 - 5 ] \d ) ) ? (?: [ \. \, ] ( \d + ) ) ? ( Z | [ + - ] [ 0 - 2 ] \d (?: : ? [ 0 - 5 ] \d ) ? ) ? $ / ;
8
+ static FULL_DATE_REGEX = / ^ ( \d { 4 } ) - ? ( [ 0 1 ] \d ) - ? ( [ 0 - 3 ] \d ) $ / ;
9
+ static DATETIME_REGEX = / ^ ( \d { 4 } ) - ? ( [ 0 1 ] \d ) - ? ( [ 0 - 3 ] \d ) T ( [ 0 - 2 ] \d (?: [ \. \, ] \d + ) ? ) (?: : ? ( [ 0 - 5 ] \d (?: [ \. \, ] \d + ) ? ) (?: : ? ( [ 0 - 5 ] \d ) ) ? (?: [ \. \, ] ( \d + ) ) ? ) ? ( Z | [ + - ] [ 0 - 2 ] \d (?: : ? [ 0 - 5 ] \d ) ? ) ? $ / ;
10
+ static TIMEZONE_REGEX = / ^ ( [ + - ] \d { 2 } ) (?: : ? ( \d { 2 } ) ) ? $ / ;
11
+ static IS_FRACTIONAL_REGEX = / ^ \d + [ \. \, ] \d + $ / ;
15
12
16
- // this format is cursed, burn it with fire https://en.wikipedia.org/wiki/ISO_week_date
17
- static DATE_WEEK_REGEX = / ^ ( \d { 4 } ) - W \d { 2 } - ? \d { 0 , 1 } / ; // unsupported
18
- static YEARDAY_REGEX = / ^ ( \d { 4 } ) - ? \d { 3 } $ / ; // unsupported
19
- static TIMEZONE_REGEX = / ^ ( [ + - ] \d { 2 } ) (?: : ? ( \d { 2 } ) ) ? $ / ; // unsupported
13
+ // Unsupported formats https://en.wikipedia.org/wiki/ISO_week_date
14
+ static DATE_WEEK_REGEX = / ^ ( \d { 4 } ) - W \d { 2 } - ? \d { 0 , 1 } / ;
15
+ static YEARDAY_REGEX = / ^ ( \d { 4 } ) - ? \d { 3 } $ / ;
20
16
21
17
static getTimezoneOffset ( offset = "" ) {
22
18
if ( offset === "Z" ) {
@@ -51,35 +47,28 @@ class IsoDateParts {
51
47
52
48
static getParts ( str ) {
53
49
if ( str . match ( this . DATE_WEEK_REGEX ) || str . match ( this . YEARDAY_REGEX ) ) {
54
- throw new Error ( `Unsupported date format (dropped syntax): ${ str } ` ) ;
55
- }
56
-
57
- if ( str . match ( this . VAGUE_DATE_REGEX ) ) {
58
- throw new Error ( `Unsupported date format (vague date): ${ str } ` ) ;
50
+ throw new Error ( `Unsupported date format (unsupported syntax): ${ str } ` ) ;
59
51
}
60
52
61
- let dateMatch = str . match ( this . PARTIAL_DATE_REGEX ) || str . match ( this . FULL_DATE_REGEX ) ;
53
+ let dateMatch = str . match ( this . FULL_DATE_REGEX ) ;
62
54
if ( dateMatch ) {
63
55
return this . getByDateTime ( dateMatch ) ;
64
56
}
65
57
66
- let vagueDatetime = str . match ( this . VAGUE_DATETIME_REGEX ) ;
67
- if ( vagueDatetime ) {
68
- throw new Error ( `Unsupported date format (vague datetime): ${ str } ` ) ;
69
- }
70
-
71
58
let dateTimeMatch = str . match ( this . DATETIME_REGEX ) ;
72
59
if ( dateTimeMatch ) {
60
+ if ( dateTimeMatch [ 4 ] ?. match ( this . IS_FRACTIONAL_REGEX ) || dateTimeMatch [ 5 ] ?. match ( this . IS_FRACTIONAL_REGEX ) ) {
61
+ throw new Error ( `Unsupported date format (fractional hours or minutes): ${ str } ` ) ;
62
+ }
63
+
73
64
return this . getByDateTime ( dateTimeMatch ) ;
74
65
}
75
66
76
- throw new Error ( `Unsupported date format (unknown) : ${ str } ` ) ;
67
+ throw new Error ( `Unsupported date format: ${ str } ` ) ;
77
68
}
78
69
}
79
70
80
- class IsoDate {
81
- #source;
82
-
71
+ export class IsoDate {
83
72
static parse ( str ) {
84
73
let parts = IsoDateParts . getParts ( str ) ;
85
74
if ( parts ) {
@@ -102,14 +91,6 @@ class IsoDate {
102
91
return [ this . year , this . month , this . day , this . hours , this . minutes , this . seconds , this . milliseconds ] ;
103
92
}
104
93
105
- set source ( val ) {
106
- this . #source = val ;
107
- }
108
-
109
- get source ( ) {
110
- return this . #source;
111
- }
112
-
113
94
checkParts ( ) {
114
95
// months: 0-indexed, 0–11 are valid
115
96
if ( this . month < 0 || this . month > 11 ) {
@@ -123,4 +104,6 @@ class IsoDate {
123
104
}
124
105
}
125
106
126
- export { IsoDate } ;
107
+ export function parse ( str ) {
108
+ return IsoDate . parse ( str ) ;
109
+ }
0 commit comments