Skip to content

Incorrect handling of dates that are formatted correctly but do not exist #82

@Wizzerinus

Description

@Wizzerinus

Hey! thanks in advance for reading this.

While working on a project, I've noticed that dates like 2025-25-25 with the formatting type %Y-%m-%d (just as an example) are silently clipped to valid bounds when parsed rather than returning an error. For example,

ghci> parseTime defaultTimeLocale "%Y-%m-%d" "2025-25-25" :: Maybe UTCTime
Just 2025-12-25 00:00:00 UTC
ghci> parseTime defaultTimeLocale "%Y-%j" "2025-999" :: Maybe Day
Just 2025-12-31
ghci> parseTime defaultTimeLocale "%Y-%m-%d" "2025-01-50" :: Maybe Day
Just 2025-01-31

The error seems to come from inside Data.Thyme.Calendar.Internal. There is an Iso between the number of days in the year, and pairs of month and day: https://github.com/haskell-github-trust/thyme/blob/master/src/Data/Thyme/Calendar/Internal.hs#L429, and another Iso between the number of days since the beginning of time, and pairs of year and day: https://github.com/haskell-github-trust/thyme/blob/master/src/Data/Thyme/Calendar/Internal.hs#L256

However, to the best of my knowledge, it is not valid to write Iso like this, since pairs of year and day may represent an invalid state, such as "Year X, day 999" or "Year 2001, day 366". Since Iso instead of Prism is used, the code may not return Nothing in such cases, and has to silently clip the date instead. At best this is counterintuitive, and at worst might introduce security vulnerabilities.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions