zod icon indicating copy to clipboard operation
zod copied to clipboard

datetime validation fails if seconds are missing

Open u2ix opened this issue 1 year ago • 9 comments

Have an issue with a valid datetime value, as produced by the browser in a datetime picker field, is not accepted by the datetime() validation. After some digging I figured that when the seconds :00 are added the validation passes.

But according to ISO 8601, just the hour is required for a valid time. Also as the timestamp is produced like this "2024-07-18T11:00", I feel it would be really great if this is accepted by the library as also the Date constructor doesn't have any issue with this.

For now I had to put in a quite ugly preprocess to make the validation pass on the value provided by the browser:

z.preprocess(input => `${input}:00`,
            z.string().datetime({ local: true }))

u2ix avatar Jul 11 '24 23:07 u2ix

I have the same issue.

sachix1001 avatar Aug 15 '24 04:08 sachix1001

Likewise. I'm using js-joda to handle dates, and its LocalDateTime.toString() implementation follows the spec.

itsthekeming avatar Aug 16 '24 14:08 itsthekeming

I've noticed the same issue with z.string().time() where it requires HH:MM:SS to actually validate. The <input type='time' /> input by default uses HH:MM as mentioned in the MDN docs

Hopefully this can be fixed sometime soon

anthonyhagi avatar Sep 06 '24 11:09 anthonyhagi

An option to toggle between HH:MM and HH:MM:SS would be nice

Dino-Kupinic avatar Dec 12 '24 09:12 Dino-Kupinic

At first I was open to write a PR to implement it but the documentation specifies that the .time() function validates against the ISO time format so having an option to omit the seconds is not ideal here. You can always use a regex to validate the string for a valid time expression with optional seconds. Here's mine: /^([01]\d|2[0-3]):[0-5]\d(:[0-5]\d)?$/.

fvilers avatar Feb 07 '25 07:02 fvilers

@fvilers But a ISO time format is also valid without the seconds, and it's the way that browsers return the date in a valid ISO format, but the validation in the library tells us it's wrong. Going for a regex here, instead of fixing a obvious bug in this library, that many people have (see all the up-votes), seems to be kinda hack or a workaround, but not solving the problem.

u2ix avatar Feb 07 '25 09:02 u2ix

@u2ix As I'm reading https://en.wikipedia.org/wiki/ISO_8601#Times you might be right. It looks like the seconds could be omitted. I might create a PR to add this feature (an approval from the maintainer(s) would be great). Using a regex is not hacky as it's what is used behind the scenes by the time() validator. And as I see things, there is no bug in the current implementation as the documentation clearly states that the seconds are mandatory (z.string().time(); // ISO time format (HH:mm:ss[.SSSSSS]))

fvilers avatar Feb 07 '25 10:02 fvilers

Pleeease fix this annoying issue (not bug).. I think a modern library should handle without seconds.

ronnyandre avatar Mar 21 '25 11:03 ronnyandre

Same here. input with datetime-local type fails zod validation.

For my use case, I had to break down my input in 2 parts: time and date.

Waiting for some update here. Thanks ahead

stevemk42 avatar Apr 12 '25 18:04 stevemk42

Hi all, I was also running into the same issue, so I've submitted a PR for this change (#4315).

timorthi avatar May 03 '25 20:05 timorthi

Landed in 3.24.4

colinhacks avatar May 04 '25 23:05 colinhacks