date
Accepts below values and returns Date
object.
- ISO8601 extended-format
- string type
- always
- in fact, not strict specification but SUBSET like following:
2000-01-02T03:04:05.678Z
2000-01-02T03:04:05Z
2000-01-02T03:04Z
- unixtime-format
- number or number-like string type
- optional
ambient declarations
export function date(rules?: RulesForDate): DateSchema;
type RulesForNumber = {
iso8601?: {
defaultTimezone?: string;
},
unixtime?: {
strictType?: boolean;
precision: UNIXTIME.PRECISION;
},
ifUndefined?: Date | null;
ifEmptyString?: Date | null;
ifNull?: Date | null;
minValue?: Date | {value: Date, adjusts: boolean};
maxValue?: Date | {value: Date, adjusts: boolean};
transform?: (value: Date, fail: () => never) => Date;
}
type ErrorHandler = (err: ValueSchemaError) => Date | null | never;
interface DateSchema {
applyTo(value: unknown, onError?: ErrorHandler): Date | null
}
applyTo(value[, onError])
Applies schema to value
.
If an error occurs, this method calls onError
(if specified) or throw ValueSchemaError
(otherwise).
// should be OK
assert.deepStrictEqual(
vs.date().applyTo("2000-01-02T03:04:05.678Z"), // accepts ISO8601-based string, and returns Date object
new Date("2000-01-02T03:04:05.678Z"));
assert.deepStrictEqual(
vs.date().applyTo("2000-01-02T03:04:05.678+09:00"), // timezone +09:00
new Date("2000-01-01T18:04:05.678Z"));
assert.deepStrictEqual(
vs.date().applyTo("2000-01-02T03:04:05Z"), // milliseconds can be omitted
new Date("2000-01-02T03:04:05.000Z"));
assert.deepStrictEqual(
vs.date().applyTo("2000-01-02T03:04Z"), // seconds can also be omitted
new Date("2000-01-02T03:04:00.000Z"));
// should cause error
assert.deepStrictEqual( // catch error by callback function (that returns a value from applyTo() method)
vs.date().applyTo(
"abc",
(err) => new Date("2000-01-02T03:04:05.678Z")),
new Date("2000-01-02T03:04:05.678Z"));
assert.throws( // ... or try-catch syntax
() => vs.date().applyTo("abc"),
{name: "ValueSchemaError", rule: vs.RULE.PATTERN});
assert.throws(
() => vs.date().applyTo("2000-01-02T03:04:05.678"), // timezone can NOT be omitted if default timezone is not specified
{name: "ValueSchemaError", rule: vs.RULE.PATTERN});
assert.throws(
() => vs.date().applyTo(946782245678), // unixtime-based number can NOT be used by default
{name: "ValueSchemaError", rule: vs.RULE.TYPE});
rules
iso8601
// should be adjusted
assert.deepStrictEqual(
vs.date({
iso8601: {
defaultTimezone: "Z", // optional; defaults ""
},
}).applyTo("2000-01-02T03:04:05.678"), // timezone can be omitted
new Date("2000-01-02T03:04:05.678Z"));
assert.deepStrictEqual(
vs.date({
iso8601: {
defaultTimezone: "Z",
},
}).applyTo("2000-01-02T03:04:05.678+09:00"), // timezone in input value will be prioritized over default timezone
new Date("2000-01-01T18:04:05.678Z"));
// should cause error
assert.throws(
() => vs.date({
iso8601: {
defaultTimezone: "",
}
}).applyTo("2000-01-02T03:04:05.678"), // timezone can NOT be omitted if default timezone is empty
{name: "ValueSchemaError", rule: vs.RULE.PATTERN});
unixtime
Accept unixtime-based number or number-like string. When this parameter is omitted, unixtime will not be accepted.
value | description |
---|---|
DATE.UNIXTIME.PRECISION.MILLISECONDS |
milliseconds precision |
DATE.UNIXTIME.PRECISION.SECONDS |
seconds precision |
DATE.UNIXTIME.PRECISION.MINUTES |
minutes precision |
// should be adjusted
assert.deepStrictEqual(
vs.date({
unixtime: {
strictType: false, // optional; defaults false
precision: vs.DATE.UNIXTIME.PRECISION.MILLISECONDS, // required
},
}).applyTo(946782245678),
new Date("2000-01-02T03:04:05.678Z"));
assert.deepStrictEqual(
vs.date({
unixtime: {
strictType: false,
precision: vs.DATE.UNIXTIME.PRECISION.MILLISECONDS,
},
}).applyTo("946782245678"), // also accepts number-like string
new Date("2000-01-02T03:04:05.678Z"));
assert.deepStrictEqual(
vs.date({
unixtime: {
precision: vs.DATE.UNIXTIME.PRECISION.SECONDS, // seconds precision
},
}).applyTo(946782245),
new Date("2000-01-02T03:04:05.000Z"));
assert.deepStrictEqual(
vs.date({
unixtime: {
precision: vs.DATE.UNIXTIME.PRECISION.MINUTES, // minutes precision
},
}).applyTo(15779704),
new Date("2000-01-02T03:04:00.000Z"));
// should cause error
assert.throws(
() => vs.date({
unixtime: {
strictType: true, // accepts only number type
precision: vs.DATE.UNIXTIME.PRECISION.MILLISECONDS,
}
}).applyTo("946782245678"),
{name: "ValueSchemaError", rule: vs.RULE.PATTERN});
ifUndefined
Specifies return value when input value is undefined
.
NOTE: {ifUndefined: undefined}
is NOT equivalent to {}
. The former accepts undefined
input value (and keeps it as-is), the latter doesn’t.
// should be adjusted
assert.deepStrictEqual(
vs.date({ifUndefined: new Date("2000-01-02T03:04:05.678Z")}).applyTo(undefined),
new Date("2000-01-02T03:04:05.678Z"));
// should cause error
assert.throws(
() => vs.date().applyTo(undefined),
{name: "ValueSchemaError", rule: vs.RULE.UNDEFINED});
// should accept `undefined` value
assert.deepStrictEqual(
vs.date({ifUndefined: undefined}).applyTo(undefined),
undefined);
ifNull
Specifies return value when input value is null
.
// should be adjusted
assert.deepStrictEqual(
vs.date({ifNull: new Date("2000-01-02T03:04:05.678Z")}).applyTo(null),
new Date("2000-01-02T03:04:05.678Z"));
// should cause error
assert.throws(
() => vs.date().applyTo(null),
{name: "ValueSchemaError", rule: vs.RULE.NULL});
ifEmptyString
Specifies return value when input value is ""
.
// should be adjusted
assert.deepStrictEqual(
vs.date({ifEmptyString: new Date("2000-01-02T03:04:05.678Z")}).applyTo(""),
new Date("2000-01-02T03:04:05.678Z"));
// should cause error
assert.throws(
() => vs.date().applyTo(""),
{name: "ValueSchemaError", rule: vs.RULE.EMPTY_STRING});
minValue
Limits minimum value.
// should be adjusted
assert.deepStrictEqual(
vs.date({minValue: {value: new Date("2000-01-02T03:04:05.678Z"), adjusts: true}}).applyTo("2000-01-01T00:00:00.000Z"),
new Date("2000-01-02T03:04:05.678Z"));
// should cause errors
assert.throws(
() => vs.date({minValue: {value: new Date("2000-01-02T03:04:05.678Z"), adjusts: false}}).applyTo("2000-01-01T00:00:00.000Z"),
{name: "ValueSchemaError", rule: vs.RULE.MIN_VALUE});
assert.throws(
() => vs.date({minValue: new Date("2000-01-02T03:04:05.678Z")}).applyTo("2000-01-01T00:00:00.000Z"), // shorthand of {value: new Date("2000-01-02T03:04:05.678Z"), adjusts: false}
{name: "ValueSchemaError", rule: vs.RULE.MIN_VALUE});
maxValue
Limits maximum value.
// should be adjusted
assert.deepStrictEqual(
vs.date({maxValue: {value: new Date("2000-01-02T03:04:05.678Z"), adjusts: true}}).applyTo("2000-12-31T23:59:59.999Z"),
new Date("2000-01-02T03:04:05.678Z"));
// should cause errors
assert.throws(
() => vs.date({maxValue: {value: new Date("2000-01-02T03:04:05.678Z"), adjusts: false}}).applyTo("2000-12-31T23:59:59.999Z"),
{name: "ValueSchemaError", rule: vs.RULE.MAX_VALUE});
assert.throws(
() => vs.date({maxValue: new Date("2000-01-02T03:04:05.678Z")}).applyTo("2000-12-31T23:59:59.999Z"), // shorthand of {value: new Date("2000-01-02T03:04:05.678Z"), adjusts: false}
{name: "ValueSchemaError", rule: vs.RULE.MAX_VALUE});
transform
Transforms input value to another.
fail()
causes ValueSchemaError
.
// should be adjusted
assert.deepStrictEqual(
vs.date({transform: value => new Date(value.getTime() + 1000)}).applyTo("2000-01-01T00:00:00.000Z"),
new Date("2000-01-01T00:00:01.000Z"));
// should cause errors
assert.throws(
() => vs.date({transform: (value, fail) => fail()}).applyTo("2000-01-01T00:00:00.000Z"),
{name: "ValueSchemaError", rule: vs.RULE.TRANSFORM});