Skip to content

Commit d1a9e36

Browse files
committed
simplify strictTime option
1 parent bfa3304 commit d1a9e36

File tree

3 files changed

+24
-31
lines changed

3 files changed

+24
-31
lines changed

src/formats.ts

+19-26
Original file line numberDiff line numberDiff line change
@@ -149,57 +149,50 @@ function compareDate(d1: string, d2: string): number | undefined {
149149
return 0
150150
}
151151

152-
const TIME = /^(\d\d):(\d\d):(\d\d)(\.\d+)?(z|[+-]\d\d(?::?\d\d)?)?$/i
153-
const PLUS_MINUS = /^[+-]/
154-
const TIMEZONE = /^[Zz]$/
155-
const ISO_8601_TIME = /^[+-](?:[01][0-9]|2[0-4])(?::?[0-5][0-9])?$/
152+
const TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-]\d\d)(?::?(\d\d))?)?$/i
156153

157-
function time(str: string, withTimeZone?: boolean, strict?: boolean): boolean {
154+
function time(str: string, withTimeZone?: boolean, strictTime?: boolean): boolean {
158155
const matches: string[] | null = TIME.exec(str)
159156
if (!matches) return false
160-
161-
const hour: number = +matches[1]
162-
const minute: number = +matches[2]
163-
const second: number = +matches[3]
164-
const timeZone: string = matches[5]
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 tzH: number = +(matches[5] || 0)
162+
const tzM: number = +(matches[6] || 0)
165163
return (
166-
((hour <= 23 && minute <= 59 && second <= 59) ||
167-
(hour === 23 && minute === 59 && second === 60)) &&
168-
(!withTimeZone ||
169-
(strict
170-
? TIMEZONE.test(timeZone) ||
171-
(PLUS_MINUS.test(timeZone) && time(timeZone.slice(1) + ":00")) ||
172-
ISO_8601_TIME.test(timeZone)
173-
: timeZone !== ""))
164+
((hr <= 23 && min <= 59 && sec < 60 && tzH <= 24 && tzM < 60) ||
165+
// leap second
166+
(hr - tzH === 23 && min - tzM === 59 && sec < 61 && tzH <= 24 && tzM < 60)) &&
167+
(!withTimeZone || (tz !== "" && (!strictTime || !!tz)))
174168
)
175169
}
176170

177-
function strict_time(str: string, withTimeZone?: boolean): boolean {
178-
return time(str, withTimeZone, true)
171+
function strict_time(str: string): boolean {
172+
return time(str, true, true)
179173
}
180174

181175
function compareTime(t1: string, t2: string): number | undefined {
182176
if (!(t1 && t2)) return undefined
183177
const a1 = TIME.exec(t1)
184178
const a2 = TIME.exec(t2)
185179
if (!(a1 && a2)) return undefined
186-
t1 = a1[1] + a1[2] + a1[3] + (a1[4] || "")
187-
t2 = a2[1] + a2[2] + a2[3] + (a2[4] || "")
180+
t1 = a1[1] + a1[2] + a1[3]
181+
t2 = a2[1] + a2[2] + a2[3]
188182
if (t1 > t2) return 1
189183
if (t1 < t2) return -1
190184
return 0
191185
}
192186

193187
const DATE_TIME_SEPARATOR = /t|\s/i
194-
function date_time(str: string): boolean {
188+
function date_time(str: string, strictTime?: boolean): boolean {
195189
// http://tools.ietf.org/html/rfc3339#section-5.6
196190
const dateTime: string[] = str.split(DATE_TIME_SEPARATOR)
197-
return dateTime.length === 2 && date(dateTime[0]) && time(dateTime[1], true)
191+
return dateTime.length === 2 && date(dateTime[0]) && time(dateTime[1], true, strictTime)
198192
}
199193

200194
function strict_date_time(str: string): boolean {
201-
const dateTime: string[] = str.split(DATE_TIME_SEPARATOR)
202-
return dateTime.length === 2 && date(dateTime[0]) && strict_time(dateTime[1], true)
195+
return date_time(str, true)
203196
}
204197

205198
function compareDateTime(dt1: string, dt2: string): number | undefined {

src/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export interface FormatOptions {
1818
mode?: FormatMode
1919
formats?: FormatName[]
2020
keywords?: boolean
21-
strictDate?: boolean
21+
strictTime?: boolean
2222
}
2323

2424
export type FormatsPluginOptions = FormatName[] | FormatOptions
@@ -32,7 +32,7 @@ const fastName = new Name("fastFormats")
3232

3333
const formatsPlugin: FormatsPlugin = (
3434
ajv: Ajv,
35-
opts: FormatsPluginOptions = {keywords: true, strictDate: false}
35+
opts: FormatsPluginOptions = {keywords: true, strictTime: false}
3636
): Ajv => {
3737
if (Array.isArray(opts)) {
3838
addFormats(ajv, opts, fullFormats, fullName)
@@ -41,7 +41,7 @@ const formatsPlugin: FormatsPlugin = (
4141
const [formats, exportName] =
4242
opts.mode === "fast" ? [fastFormats, fastName] : [fullFormats, fullName]
4343
const list = opts.formats || formatNames
44-
addFormats(ajv, list, opts.strictDate ? {...formats, ...strictFormats} : formats, exportName)
44+
addFormats(ajv, list, opts.strictTime ? {...formats, ...strictFormats} : formats, exportName)
4545
if (opts.keywords) formatLimit(ajv)
4646
return ajv
4747
}

tests/strictDate.spec.ts renamed to tests/strictTime.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import Ajv from "ajv"
22
import addFormats from "../dist"
33

44
const ajv = new Ajv({$data: true, strictTypes: false, formats: {allowedUnknown: true}})
5-
addFormats(ajv, {strictDate: true})
5+
addFormats(ajv, {mode: "full", strictTime: true})
66

7-
describe("strictDate option", () => {
7+
describe("strictTime option", () => {
88
it("a valid date-time string with time offset", () => {
99
expect(
1010
ajv.validate(

0 commit comments

Comments
 (0)