Yet another Gregorian.d contribution
Yao G.
nospamyao at gmail.com
Sun Aug 22 16:43:45 PDT 2010
Well, as the title says. I needed a date library for a small D project I'm
working. I tried to use the Gregorian.d module that Andrei started, but as
it was just a simple draft, it lacked a lot of content.
And as Boost's date_time was the basis for Andrei's work, and I had prior
experience working with this library, I tried to implement almost all of
what was needed to have a working Date struct, as documented here:
http://www.boost.org/doc/libs/1_42_0/doc/html/date_time/gregorian.html
The only concrete date types that I didn't implemented were some ranges
(converted from C++ iterators) to iterate Dates on monthly and yearly
basis. Everything else is there in one way or another. Now, the original
Boost library is quite complex and comprehensive (I'm talking about the
Date facilities, I didn't even tried to implement time, LocalDate,
TimeZones and string conversion), so I had to do some compromises in order
to at least finish the module. So here are some of the things I didn't
implemented:
- There's no notion of +infinites and -infinites. The only special value
supported is Not A Date. This because if I wanted to support infinities, I
had to implement a big and complex struct that
emulates a integer with support to IEEE754 NAN and infinites. This can be
done, but it would make the gregorian.d module even bigger.
- The integer type used internally for doing the calculations is int, and
cannot be changed at compile time. I didn't know how to propagate the same
integer type across all the different date structures and functions,
without doing the template instantiation each time the user need a Date
instance.
- There's no way to change the granularity of the Date structure. The
minimal unit used is days. But as this is how was originally implemented,
I don't think it's a bad decision (sorry Michel Fortin).
- The calendar used is Gregorian, and there's no way to change it to
another (like Julian, ISO8601, Coptic, etc.). Almost all the calculations
are done internally by the Date class. This is because, first, I followed
the model Andrei used, and second, almost everyone and his mother use
Gregorian. Is de facto standard. :p
- There are not ranges to iterate using months or years as units. Again,
for implementing this, I would have to implement yet another internal
structure that emulates a wrapping integer with arbitrary upper and lower
bounds. This structure is quite big too, so I would bloat even more the
module.
- The work I did is kinda shoddy and amateurish. :D I used a lot of
properties (@safe), pure and nothrow, I overdid with the comments and the
unittest, I don't get ranges quite well yet, etc. I don't expect the
module to be used as is, but more like something that a more experienced
programmer can copy and improve to make a better gregorian module.
And just to be clear: This module contains only the implementation of the
Date struct and friends (ranges, DateRange, DayCount, etc), so no time,
UTC support, only basic ISO8601 support, no local time, or time zones, no
complex conversion to strings and parsing etc. See
http://www.boost.org/doc/libs/1_42_0/doc/html/date_time/gregorian.html if
you want to have a small idea of what's implemented.
Oh, I almost forgot, the code is here: http://ideone.com/SCR34
Apologies for this tl;dr; wall of text. And I'm eagerly awaiting some
comments, critics and ideas to improve this work.
Thanks.
--
Yao G.
More information about the Digitalmars-d
mailing list