std.datetime

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Feb 10 08:31:55 PST 2017


On Friday, February 10, 2017 19:06:53 drug via Digitalmars-d-learn wrote:
> 10.02.2017 18:02, Jonathan M Davis via Digitalmars-d-learn пишет:
> > On Friday, February 10, 2017 14:35:28 drug via Digitalmars-d-learn 
wrote:
> >> I found error - years should start from 1, not 0.
> >> But if months or days start from 0 std.datetime throws exception and
> >> don't for years - it isn't clear that zero year is negative one (in
> >> that
> >> mean that stdTime for '0000' years will be negative.
> >
> > As the documentation states in multiple places, std.datetime follows ISO
> > 8601, which uses the Proleptic Gregorian Calendar, and that specifies
> > that the year 0 is equivalent to what you would normall consider to be
> > 1 B.C. And that's part of the spec for the ISO extended format that
> > fromISOExtString uses.
> >
> > Now, while it is mentioned in multiple places that std.datetime follows
> > ISO 8601 and that it follows the Proleptic Gregorian Calender (even
> > providing a link to wikipedia), it does look like it fails to
> > specifically mention that on the primary ddoc comment of SysTime. So,
> > that should be improved. However, the documentation for SysTime.year
> > does state that positive years are A.D., whereas non-positive are B.C.
> > So, the information is there, even without having to look up the
> > Proleptic Gregorian Calender or ISO 8601.
> >
> > What would have made it clearer for you?
> >
> > - Jonathan M Davis
>
> Is zero positive or negative? May be add statement that zero year is 1
> B.C.? Thank you for your good job!

Neither. It's zero. That's why the documentation says that B.C. is
non-positive - non-positive encompasses all of the negative numbers plus
zero. And on yearBC, it does say that 0 is treated as 1 B.C. year doesn't
mention that, but it's right above yearBC in the docs. It should probably
link to yearBC though to make that clearer.

B.C. does get kind of wonky though, since mathematically, it pretty much
_has_ to be the case that 1 B.C. is 0 unless you just skip 0 (since
otherwise all of the A.D. years get shifted by one, and then the years that
most everyone uses would be shifted by one - e.g. 2017 would become 2016,
which obviously doesn't work). And skipping 0 - as is done when normally
talking about A.D. and B.C. - is just plain messy mathematically, just like
trying to deal with the switch between the Julian and Gregorian calendars is
a mess (even without getting into the issues related to different regions
switching calendars at different times) - which is why ISO 8601 uses the
Proleptic Gregorian Calendar, making it Gregorian the whole way. It's very
mathematically neat, but it then runs afoul of how folks normally think of
dates in the B.C. range. So, ultimately, it seems to be the best of a
variety of bad answers to the problem.

I suppose that we could have gone C#'s route, since they use the Proleptic
Gregorian Calender but didn't implement B.C. But then that gets pretty weird
when you have 0 hnsecs be the default value, since once you have time zones
west of UTC, you suddenly end up with them being in B.C., and if you don't
have B.C... I ported std.datetime to C++ once where I was working, and I
tried to strip out stuff like B.C. thinking that it would make the code
simpler, and it actually made it worse. So, yeah, it's just messy all
around. Fortunately, most code doesn't actually care about dates that far
back, and for the code that does, there's yearBC for anyone who wants a date
that looks more familiar.

- Jonathan M Davis




More information about the Digitalmars-d-learn mailing list