Thread overview
std.datetime
Feb 10, 2017
drug
Feb 10, 2017
drug
Feb 10, 2017
Jonathan M Davis
Feb 10, 2017
drug
Feb 10, 2017
Jonathan M Davis
Feb 10, 2017
drug
February 10, 2017
unittest
{
	import std.datetime : SysTime, UTC;

	{
		auto st = SysTime();
		st.timezone(UTC());

		long date  = st.fromISOExtString("2017-02-10T00:00:00Z").stdTime,
			time_of_day = st.fromISOExtString("0000-01-01T23:59:50Z").stdTime,
			timestamp   = st.fromISOExtString("0000-01-01T23:59:55Z").stdTime;

		import std.stdio;
		st.stdTime(date);
		writeln(st);
		st.stdTime(timestamp);
		writeln(st);
		st.stdTime(date+timestamp);
		writeln(st);
	}
}

prints
```
2017-Feb-10 00:00:00Z
0000-Jan-01 23:59:55Z
2016-Feb-10 23:59:55Z
```
I expect
```
2017-Feb-10 00:00:00Z
0000-Jan-01 23:59:55Z
2017-Feb-10 23:59:55Z
```

Why does it decrement years? What do I do wrong?
February 10, 2017
10.02.2017 14:15, drug пишет:
> unittest
> {
>     import std.datetime : SysTime, UTC;
>
>     {
>         auto st = SysTime();
>         st.timezone(UTC());
>
>         long date  = st.fromISOExtString("2017-02-10T00:00:00Z").stdTime,
>             time_of_day =
> st.fromISOExtString("0000-01-01T23:59:50Z").stdTime,
>             timestamp   =
> st.fromISOExtString("0000-01-01T23:59:55Z").stdTime;
>
>         import std.stdio;
>         st.stdTime(date);
>         writeln(st);
>         st.stdTime(timestamp);
>         writeln(st);
>         st.stdTime(date+timestamp);
>         writeln(st);
>     }
> }
>
> prints
> ```
> 2017-Feb-10 00:00:00Z
> 0000-Jan-01 23:59:55Z
> 2016-Feb-10 23:59:55Z
> ```
> I expect
> ```
> 2017-Feb-10 00:00:00Z
> 0000-Jan-01 23:59:55Z
> 2017-Feb-10 23:59:55Z
> ```
>
> Why does it decrement years? What do I do wrong?
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.
February 10, 2017
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

February 10, 2017
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!
February 10, 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


February 10, 2017
10.02.2017 19:31, Jonathan M Davis via Digitalmars-d-learn пишет:
> 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
yes, it's my fault

> 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
>
>
Thank you for your answer!