Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

what's the point of YearTwoDigits #52

Open
safareli opened this issue Feb 11, 2019 · 3 comments
Open

what's the point of YearTwoDigits #52

safareli opened this issue Feb 11, 2019 · 3 comments

Comments

@safareli
Copy link
Contributor

If YearTwoDigits is used and we have 95 as input string, it would be parsed to date where year is 95, is it expected? I think most users will expect to get 1995.
i.e. it should work like JS, for example:
new Date(Date.UTC(95,1,1)).getUTCFullYear() // => 1995
but:
new Date(Date.UTC(-17,1,1)).getUTCFullYear() // => -17

Either parsing should have side effect of looking at current century to have similar behavior or otherwise having YearTwoDigits has almost no point.

@garyb
Copy link
Member

garyb commented Feb 11, 2019

I use this as more of a printing library than a parsing library so haven't run into this particular problem, but yeah, it is kinda weird. I also agree YearTwoDigits is questionable in general, I can't think of a situation in which I'd ever want to use it, because of its ambiguity.

I don't really know how to resolve it though - whatever choice we make is going to be arbitrary. 40 means what? Year 40, 1940, or 2040? If it means 2040, why is 95 not 2095? We can definitely make some rules up to get more "sensible" behaviour, but they won't suit everyone in all situations.

Call me pessimistic, but I suspect we won't be using this library in the year 2100, so I don't think we need to make it effectful either, we can just hard code the century 😄.

@garyb garyb added the question label Feb 11, 2019
@garyb
Copy link
Member

garyb commented Feb 11, 2019

Looks like JS special cases the years 0-99 as being in the 1900s.

@safareli
Copy link
Contributor Author

safareli commented Feb 11, 2019

If we change

-| YearTwoDigits
+| YearTwoDigits Century

and add with some kind of Century module:

fromCentury :: Year -> Century
setYear :: Year99 -> Century -> Year
getYear99 :: Year -> Year99
getCentury :: Year -> Century

Then we can have implementation which works like this:

parse  [YearTwoDigits (Century 19)] "96" `yearEquals` 1996
parse  [YearTwoDigits (Century 19)] "96" `yearEquals` 1996
parse  [YearTwoDigits (Century 20)] "41" `yearEquals` 2041
parse  [YearTwoDigits (Century 20)] "01" `yearEquals` 2001

print [YearTwoDigits (Century 19)] (dateFromYear 1996) `shouldEqual` "96"
print [YearTwoDigits (Century 19)] (dateFromYear 1996) `shouldEqual` "96"
print [YearTwoDigits (Century 20)] (dateFromYear 2041) `shouldEqual` "41"
print [YearTwoDigits (Century 20)] (dateFromYear 2001) `shouldEqual` "01"

print [YearTwoDigits (Century 20)] (dateFromYear 1996) `shouldEqual` "1996"
print [YearTwoDigits (Century 10)] (dateFromYear 2041) `shouldEqual` "2041"

last 2 cases are a bit wrong, but it's happening because same type is used for print format and for parse format.

another option would be to use higher kinded type thing for format:

data ForamtF f =
...
| YearTwoDigits (f Unit Century)

type PickPrintFormat a b = a
type PickParseFormat a b = a
type PrintFormat = ForamtF PickPrintFormat
type ParseFormat = ForamtF PickParseFormat

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants