@@ -7,6 +7,8 @@ export type FormatName =
77 | "date"
88 | "time"
99 | "date-time"
10+ | "iso-time"
11+ | "iso-date-time"
1012 | "duration"
1113 | "uri"
1214 | "uri-reference"
@@ -44,8 +46,10 @@ export const fullFormats: DefinedFormats = {
4446 // date: http://tools.ietf.org/html/rfc3339#section-5.6
4547 date : fmtDef ( date , compareDate ) ,
4648 // date-time: http://tools.ietf.org/html/rfc3339#section-5.6
47- time : fmtDef ( time , compareTime ) ,
48- "date-time" : fmtDef ( date_time , compareDateTime ) ,
49+ time : fmtDef ( getTime ( true ) , compareTime ) ,
50+ "date-time" : fmtDef ( getDateTime ( true ) , compareDateTime ) ,
51+ "iso-time" : fmtDef ( getTime ( ) , compareTime ) ,
52+ "iso-date-time" : fmtDef ( getDateTime ( ) , compareDateTime ) ,
4953 // duration: https://tools.ietf.org/html/rfc3339#appendix-A
5054 duration : / ^ P (? ! $ ) ( ( \d + Y ) ? ( \d + M ) ? ( \d + D ) ? ( T (? = \d ) ( \d + H ) ? ( \d + M ) ? ( \d + S ) ? ) ? | ( \d + W ) ? ) $ / ,
5155 uri,
@@ -94,11 +98,19 @@ export const fastFormats: DefinedFormats = {
9498 ...fullFormats ,
9599 date : fmtDef ( / ^ \d \d \d \d - [ 0 - 1 ] \d - [ 0 - 3 ] \d $ / , compareDate ) ,
96100 time : fmtDef (
97- / ^ (?: [ 0 - 2 ] \d : [ 0 - 5 ] \d : [ 0 - 5 ] \d | 2 3 : 5 9 : 6 0 ) (?: \. \d + ) ? (?: z | [ + - ] \d \d (?: : ? \d \d ) ? ) ? $ / i,
101+ / ^ (?: [ 0 - 2 ] \d : [ 0 - 5 ] \d : [ 0 - 5 ] \d | 2 3 : 5 9 : 6 0 ) (?: \. \d + ) ? (?: z | [ + - ] \d \d (?: : ? \d \d ) ? ) $ / i,
98102 compareTime
99103 ) ,
100104 "date-time" : fmtDef (
101- / ^ \d \d \d \d - [ 0 - 1 ] \d - [ 0 - 3 ] \d [ t \s ] (?: [ 0 - 2 ] \d : [ 0 - 5 ] \d : [ 0 - 5 ] \d | 2 3 : 5 9 : 6 0 ) (?: \. \d + ) ? (?: z | [ + - ] \d \d (?: : ? \d \d ) ? ) $ / i,
105+ / ^ \d \d \d \d - [ 0 - 1 ] \d - [ 0 - 3 ] \d t (?: [ 0 - 2 ] \d : [ 0 - 5 ] \d : [ 0 - 5 ] \d | 2 3 : 5 9 : 6 0 ) (?: \. \d + ) ? (?: z | [ + - ] \d \d (?: : ? \d \d ) ? ) $ / i,
106+ compareDateTime
107+ ) ,
108+ "iso-time" : fmtDef (
109+ / ^ (?: [ 0 - 2 ] \d : [ 0 - 5 ] \d : [ 0 - 5 ] \d | 2 3 : 5 9 : 6 0 ) (?: \. \d + ) ? (?: z | [ + - ] \d \d (?: : ? \d \d ) ? ) ? $ / i,
110+ compareTime
111+ ) ,
112+ "iso-date-time" : fmtDef (
113+ / ^ \d \d \d \d - [ 0 - 1 ] \d - [ 0 - 3 ] \d [ t \s ] (?: [ 0 - 2 ] \d : [ 0 - 5 ] \d : [ 0 - 5 ] \d | 2 3 : 5 9 : 6 0 ) (?: \. \d + ) ? (?: z | [ + - ] \d \d (?: : ? \d \d ) ? ) ? $ / i,
102114 compareDateTime
103115 ) ,
104116 // uri: https://github.com/mafintosh/is-my-json-valid/blob/master/formats.js
@@ -111,12 +123,6 @@ export const fastFormats: DefinedFormats = {
111123 / ^ [ a - z 0 - 9 . ! # $ % & ' * + / = ? ^ _ ` { | } ~ - ] + @ [ a - z 0 - 9 ] (?: [ a - z 0 - 9 - ] { 0 , 61 } [ a - z 0 - 9 ] ) ? (?: \. [ a - z 0 - 9 ] (?: [ a - z 0 - 9 - ] { 0 , 61 } [ a - z 0 - 9 ] ) ? ) * $ / i,
112124}
113125
114- export const strictFormats : Partial < DefinedFormats > = {
115- // date-time: http://tools.ietf.org/html/rfc3339#section-5.6
116- time : fmtDef ( strict_time , compareTime ) ,
117- "date-time" : fmtDef ( strict_date_time , compareDateTime ) ,
118- }
119-
120126export const formatNames = Object . keys ( fullFormats ) as FormatName [ ]
121127
122128function isLeapYear ( year : number ) : boolean {
@@ -151,26 +157,24 @@ function compareDate(d1: string, d2: string): number | undefined {
151157
152158const TIME = / ^ ( \d \d ) : ( \d \d ) : ( \d \d (?: \. \d + ) ? ) ( z | ( [ + - ] ) ( \d \d ) (?: : ? ( \d \d ) ) ? ) ? $ / i
153159
154- function time ( str : string , withTimeZone ?: boolean , strictTime ?: boolean ) : boolean {
155- const matches : string [ ] | null = TIME . exec ( str )
156- if ( ! matches ) return false
157- const hr : number = + matches [ 1 ]
158- const min : number = + matches [ 2 ]
159- const sec : number = + matches [ 3 ]
160- const tz : string | undefined = matches [ 4 ]
161- const tzSign : number = matches [ 5 ] === "-" ? - 1 : 1
162- const tzH : number = + ( matches [ 6 ] || 0 )
163- const tzM : number = + ( matches [ 7 ] || 0 )
164- if ( tzH > 23 || tzM > 59 || ( withTimeZone && ( tz === "" || ( strictTime && ! tz ) ) ) ) return false
165- if ( hr <= 23 && min <= 59 && sec < 60 ) return true
166- // leap second
167- const utcMin = min - tzM * tzSign
168- const utcHr = hr - tzH * tzSign - ( utcMin < 0 ? 1 : 0 )
169- return ( utcHr === 23 || utcHr === - 1 ) && ( utcMin === 59 || utcMin === - 1 ) && sec < 61
170- }
171-
172- function strict_time ( str : string ) : boolean {
173- return time ( str , true , true )
160+ function getTime ( strictTimeZone ?: boolean ) : ( str : string ) => boolean {
161+ return function time ( str : string ) : boolean {
162+ const matches : string [ ] | null = TIME . exec ( str )
163+ if ( ! matches ) return false
164+ const hr : number = + matches [ 1 ]
165+ const min : number = + matches [ 2 ]
166+ const sec : number = + matches [ 3 ]
167+ const tz : string | undefined = matches [ 4 ]
168+ const tzSign : number = matches [ 5 ] === "-" ? - 1 : 1
169+ const tzH : number = + ( matches [ 6 ] || 0 )
170+ const tzM : number = + ( matches [ 7 ] || 0 )
171+ if ( tzH > 23 || tzM > 59 || ( strictTimeZone && ! tz ) ) return false
172+ if ( hr <= 23 && min <= 59 && sec < 60 ) return true
173+ // leap second
174+ const utcMin = min - tzM * tzSign
175+ const utcHr = hr - tzH * tzSign - ( utcMin < 0 ? 1 : 0 )
176+ return ( utcHr === 23 || utcHr === - 1 ) && ( utcMin === 59 || utcMin === - 1 ) && sec < 61
177+ }
174178}
175179
176180function compareTime ( t1 : string , t2 : string ) : number | undefined {
@@ -186,14 +190,14 @@ function compareTime(t1: string, t2: string): number | undefined {
186190}
187191
188192const DATE_TIME_SEPARATOR = / t | \s / i
189- function date_time ( str : string , strictTime ?: boolean ) : boolean {
190- // http://tools.ietf.org/html/rfc3339#section-5.6
191- const dateTime : string [ ] = str . split ( DATE_TIME_SEPARATOR )
192- return dateTime . length === 2 && date ( dateTime [ 0 ] ) && time ( dateTime [ 1 ] , true , strictTime )
193- }
193+ function getDateTime ( strictTimeZone ?: boolean ) : ( str : string ) => boolean {
194+ const time = getTime ( strictTimeZone )
194195
195- function strict_date_time ( str : string ) : boolean {
196- return date_time ( str , true )
196+ return function date_time ( str : string ) : boolean {
197+ // http://tools.ietf.org/html/rfc3339#section-5.6
198+ const dateTime : string [ ] = str . split ( DATE_TIME_SEPARATOR )
199+ return dateTime . length === 2 && date ( dateTime [ 0 ] ) && time ( dateTime [ 1 ] )
200+ }
197201}
198202
199203function compareDateTime ( dt1 : string , dt2 : string ) : number | undefined {
0 commit comments