4 ms·
The article is making two somewhat unrelated complaints: 1. Date.iso8601 does not correctly parse some ISO 8601 formats like ordinal dates or month-only dates.
by haberman 14y ago
The article is making two somewhat unrelated complaints:
1. Date.iso8601 does not correctly parse some ISO 8601 formats like ordinal dates or month-only dates.
2. The Date class does not support year-only or year/month granularity.
In response to the first, the documentation for Date.iso8601 (http://ruby-doc.org/stdlib-1.9.3/libdoc/date/rdoc/Date.html#method-c-iso8601 http://ruby-doc.org/stdlib-1.9.3/libdoc/date/rdoc/Date.html#...) says:
"Creates a new Date object by parsing from a string according to some typical ISO 8601 formats."
Not "all ISO 8601 formats," "some typical ISO 8601 formats." While supporting more formats is obviously desirable, the method never claimed to be a complete ISO 8601 implementation. It would be nicer if it were, but would also take more work and it appears that 100% spec support was neither prioritized nor promised.
I believe the second complaint is less justified. Asking a single class (Date) to support multiple granularities opens up a lot of semantic conundrums that have no obvious resolution. What should this return?
Date.iso8601("2012-01") < Date.iso8601("2012-01-05")
If one is truly month granularity and one is day granularity, then the two aren't directly comparable. It would make more sense to me to have the month granularity representation be a separate class altogether (YearMonth?) with easy and well-defined conversions between the two.
- tommorris 14y agoSure, it's a tough problem. The resolution to my complaint is a proper ISO 8601 implementation for Ruby. Which I'll probably have to write. ;)
- sorbits 14y agoISO 8601 is large standard and predates the internet (as we know it) and seems like an attempt of formalizing all the many different ways people expressed dates (on physical papers in addition to computer systems), and also some ways no-one would ever use. I think you’ll find a lot of APIs (or formats) claiming to support an “ISO 8601 date” when in fact they mean a date of the form “YYYY-MM-DD” — it’s a common misunderstanding, but I think better that, than actually allowing the full range of dates allowed by the actual ISO 8601 standard :)
- tommorris 14y agoOh sure, I know the full extent of the madness. At a previous job I was working with XML Schema durations to represent energy emissions data. It gives me bad memories.
- rafaelferreira 14y agoPerhaps a useful compromise would be to implement W3C's ISO-8601 profile http://www.w3.org/TR/NOTE-datetime http://www.w3.org/TR/NOTE-datetime
- pjscott 14y agoMy God. The W3C actually made something simpler. Drastically simpler; simple enough to write down on one page. Mind you, it's just a note that someone else submitted, and the W3C hasn't formally discussed it, let alone blessed it -- but even so, it's heartening.
- ibotty 14y agoof course you can compare them (4 states: before, after, same, overlapping). you cannot put them into an order. that's something different.
- jeffdavis 14y agoThere are different ways to overlap, too, so I don't think it's correct to say that there are only 4 states.
- nona 14y agoMaybe a Date should be a Range of Time? Even a specific date is a 24h interval.
- jeffdavis 14y agoThe problem with making all dates into ranges is that there would be no total order. To effectively have a total order, you would need to say "give me the range of time at the smallest possible granularity", which is really just asking for a point in time. If the granularity becomes smaller later, it might break the application if you aren't careful. So, I don't think it's a good idea to give up on points in time. However, I strongly agree that ranges of time are a very useful concept, and I spent a lot of time implementing Range Types[1] in postgresql for that reason. I think Ruby should have both ranges of time and points of time (and ideally work with the SQL counterparts seamlessly). [1] http://www.postgresql.org/docs/9.2/static/rangetypes.html http://www.postgresql.org/docs/9.2/static/rangetypes.html
- DougWebb 14y agoDoes a point in time ever really exist? I think it's all ranges, just with smaller granularities, until you get into quantum mechanics. So, your point-in-time type is actually a range-with-granularity-X type, which should be able to inter-operate with range types of different granularities in a well-defined way. I've recently done a lot of work using time ranges (a scheduling app) in C#, using the TimePeriod library available via NuGet. Very helpful library, but it would have been even better if DB2 (which I have to use quite often) supported a range type like you've implemented for PostgreSQL.
- jeffdavis 14y ago"Does a point in time ever really exist?" I agree, but that gets a little too philosophical. Does an integer exist? What about characters: is my "a" really the same as your "a"? The way I see it, there are a lot of practical reasons to look at time as a total order for some things, even if ranges are available. Programming languages and databases should model reality, but only in the sense that it's relevant to what you are trying to do. If you are writing a scheduling app, then ranges of time are very important, and should be their own data type. If you just want to tell your customers when they bought some widget, a point in time makes more sense.
- jeffdavis 14y agoIf you support only a subset of the standard, or if you extend the standard, that may still be OK (not without problems, but still OK in some situations). This case seems like an outright violation, however. If the standard says that ####-## is a year-month date with month granularity, and you interpret it as an ordinal date, then that's a clear violation. It means that others communicating with you won't just get an error, they will get the wrong answer, which is much worse.
- badgar 14y agoSo it's not even a subset of ISO 8601, it's just the umpteenth ad-hoc date parsing method with semantics defined as "portion of a 3k line C file with no comments": https://github.com/ruby/ruby/blob/7ea675732ac1dac72f07756498706678d8725719/ext/date/date_parse.c#L2600 https://github.com/ruby/ruby/blob/7ea675732ac1dac72f07756498... PS I did my undergrad thesis on Ruby; I love the language. But now that I have a job where people read my code more often than it's written, I understand why things like clear semantics matter. And why method names should be precise since they lead developers to assume behavior. Didn't your english teacher tell you a poem's title means something? So do method names. "iso8601" implies some meaningful relationship to ISO 8601, but the only relationship here is that the coders of this method were thinking hard about ISO 8601 when they wrote it.