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