const Iso8601Date = S.String.pipe(
S.pattern(/^(\d{4})-(\d{2})-(\d{2})$/),
S.transformOrFail(
S.DateTimeUtcFromSelf,
{
decode: (input, _, ast) => {
const match = input.match(/^(\d{4})-(\d{2})-(\d{2})$/)!
const [, yearStr, monthStr, dayStr] = match
const dateOption = DateTime.make(
{ year: Number(yearStr), month: Number(monthStr), day: Number(dayStr) }
)
return Option.match(dateOption, {
onNone: () => ParseResult.fail(new ParseResult.Type(ast, input)),
onSome: (date) => ParseResult.succeed(date)
})
},
encode: (dateTime) => {
const { year, month, day } = DateTime.toParts(dateTime)
return ParseResult.succeed(
`${year.toString().padStart(4, '0')}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`
)
}
}
)
)
const Iso8601Date = S.String.pipe(
S.pattern(/^(\d{4})-(\d{2})-(\d{2})$/),
S.transformOrFail(
S.DateTimeUtcFromSelf,
{
decode: (input, _, ast) => {
const match = input.match(/^(\d{4})-(\d{2})-(\d{2})$/)!
const [, yearStr, monthStr, dayStr] = match
const dateOption = DateTime.make(
{ year: Number(yearStr), month: Number(monthStr), day: Number(dayStr) }
)
return Option.match(dateOption, {
onNone: () => ParseResult.fail(new ParseResult.Type(ast, input)),
onSome: (date) => ParseResult.succeed(date)
})
},
encode: (dateTime) => {
const { year, month, day } = DateTime.toParts(dateTime)
return ParseResult.succeed(
`${year.toString().padStart(4, '0')}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}`
)
}
}
)
)