Date refactoring

590 views
Skip to first unread message

Florian Loitsch

unread,
May 14, 2012, 9:59:12 AM5/14/12
to General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
I'm in the process of refactoring the corelib's Date class, and would like to get some feedback on this.

The idea is to make it easier to use for the general case, and *not* implement a feature complete Date library. We eventually need something like Java's Joda library, but such a library would be way too big for the corelib and would confuse most people (Dates, DateTimes, and TimeZones are unfortunately pretty complicated...).

As a first step I want to do the modifications I propose in CL https://chromiumcodereview.appspot.com/10384149
That is: remove the TimeZone class, make Date hashable, add optional arguments to the constructor and add a way to get to the TimeZone(offset).
The biggest change in the CL is that it would not be possible to get to the UTC fields anymore. There would be a toUTCString() but no utcMonth (or any other getter).
The reasoning is that timezone-independent operations almost always only want the epoch-time (which is accessible through the 'value' field), or print it (for logging). Both use-cases are still covered.

Related bugs:
Timezone offset: http://dartbug.com/2579

The following bugs would be obsolete if I go ahead with my changes:
TimeZone utc/local constructors should be constants: http://dartbug.com/2581
DateImplementation doesn't check for required timezone argument: http://dartbug.com/1260

I also propose closing http://dartbug.com/1424 (Split into Date and TimeStamp). This is outside the scope of the corelib.

And since I start the discussion on Dates we should maybe also look at adding support for some other epochs:
Personally I don't see any good candidate, but I remember vaguely that at least one of those is commonly used. But that could be bad memory...

We should also consider:
Rename the time getters (d.hours -> d.hour, d.minutes -> d.minute, ...): http://dartbug.com/1985

// florian
--
Give a man a fire and he's warm for the whole day,
but set fire to him and he's warm for the rest of his life. - Terry Pratchett

Paul Brauner

unread,
May 14, 2012, 10:31:05 AM5/14/12
to Florian Loitsch, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
Something I often need is the equivalent of Date.fromEpoch but with human-readable arguments. Otherwise I keep going to http://www.epochconverter.com/ and I put the human-readable UTC date in a comment next to the timestamp. It doesn't add any expressivity, just readability.

Paul

Ladislav Thon

unread,
May 14, 2012, 10:31:42 AM5/14/12
to Florian Loitsch, General Dart Discussion
Hi,

The idea is to make it easier to use for the general case, and *not* implement a feature complete Date library. We eventually need something like Java's Joda library, but such a library would be way too big for the corelib and would confuse most people (Dates, DateTimes, and TimeZones are unfortunately pretty complicated...).

As a first step I want to do the modifications I propose in CL https://chromiumcodereview.appspot.com/10384149

if I understand correctly, your argument and your code is based on the assumption that timezones are hard, make the code complicated and in a vast majority of situations, they aren't even necessary. I completely and wholeheartedly agree. Having the corelib's date/time support as much timezones-free as possible is a goal I can identify with.

From looking at the proposed Date interface, it looks like it can't be completely timezones-free (because even the unix timestamp value refers to UTC), so instead, the date is implicitly in local timezone. Correct? I guess I can live with that.
 
I also propose closing http://dartbug.com/1424 (Split into Date and TimeStamp). This is outside the scope of the corelib.

I still believe that having separate Date and DateTime in the corelib (both of them in local timezone) is extremely valuable, because using date+time value for modeling date value gets inconvenient pretty quickly. I'm obviously not the one to decide what is in corelib's scope and what isn't, but I'd plead for considering this once more.

LT

Florian Loitsch

unread,
May 14, 2012, 10:41:06 AM5/14/12
to Ladislav Thon, General Dart Discussion
On Mon, May 14, 2012 at 4:31 PM, Ladislav Thon <lad...@gmail.com> wrote:
Hi,

The idea is to make it easier to use for the general case, and *not* implement a feature complete Date library. We eventually need something like Java's Joda library, but such a library would be way too big for the corelib and would confuse most people (Dates, DateTimes, and TimeZones are unfortunately pretty complicated...).

As a first step I want to do the modifications I propose in CL https://chromiumcodereview.appspot.com/10384149

if I understand correctly, your argument and your code is based on the assumption that timezones are hard, make the code complicated and in a vast majority of situations, they aren't even necessary. I completely and wholeheartedly agree. Having the corelib's date/time support as much timezones-free as possible is a goal I can identify with.
Correct: no (explicit) timezones in the corelib. 

From looking at the proposed Date interface, it looks like it can't be completely timezones-free (because even the unix timestamp value refers to UTC), so instead, the date is implicitly in local timezone. Correct? I guess I can live with that.
Yes. Dates will always be (implicitly) in the local timezone.

 
I also propose closing http://dartbug.com/1424 (Split into Date and TimeStamp). This is outside the scope of the corelib.

I still believe that having separate Date and DateTime in the corelib (both of them in local timezone) is extremely valuable, because using date+time value for modeling date value gets inconvenient pretty quickly. I'm obviously not the one to decide what is in corelib's scope and what isn't, but I'd plead for considering this once more.
From my point of view the biggest problem is that there is a lot of pressure to make "Date" the DateTime class leaving no good name for the actual Date class. I will think about this, but I think I would rather make working with Dates easier by providing something like an "Interval" class (similar to the Duration class) that deals nicer with Dates. For example: date + new Interval(months: 3, days: 1)

LT

Florian Loitsch

unread,
May 14, 2012, 10:43:06 AM5/14/12
to Paul Brauner, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
On Mon, May 14, 2012 at 4:31 PM, Paul Brauner <po...@google.com> wrote:
Something I often need is the equivalent of Date.fromEpoch but with human-readable arguments. Otherwise I keep going to http://www.epochconverter.com/ and I put the human-readable UTC date in a comment next to the timestamp. It doesn't add any expressivity, just readability.
I would use Date.fromString("ISO8601") for this. It would of course be slower, but that would be the case for anything that doesn't provide the epoch value.

Christian Grobmeier

unread,
May 14, 2012, 10:46:27 AM5/14/12
to Florian Loitsch, Ladislav Thon, General Dart Discussion
On Mon, May 14, 2012 at 4:41 PM, Florian Loitsch <floi...@google.com> wrote:
> On Mon, May 14, 2012 at 4:31 PM, Ladislav Thon <lad...@gmail.com> wrote:
>>
>> Hi,
>>
>>> The idea is to make it easier to use for the general case, and *not*
>>> implement a feature complete Date library. We eventually need something like
>>> Java's Joda library, but such a library would be way too big for the corelib
>>> and would confuse most people (Dates, DateTimes, and TimeZones are
>>> unfortunately pretty complicated...).
>>>
>>> As a first step I want to do the modifications I propose in
>>> CL https://chromiumcodereview.appspot.com/10384149
>>
>>
>> if I understand correctly, your argument and your code is based on the
>> assumption that timezones are hard, make the code complicated and in a vast
>> majority of situations, they aren't even necessary. I completely and
>> wholeheartedly agree. Having the corelib's date/time support as much
>> timezones-free as possible is a goal I can identify with.
>
> Correct: no (explicit) timezones in the corelib.

How should that look like? In the past years I needed access to
perfect timezone support (I am a Joda fan) and really cannot imagine
how it would work without.

>>
>> From looking at the proposed Date interface, it looks like it can't be
>> completely timezones-free (because even the unix timestamp value refers to
>> UTC), so instead, the date is implicitly in local timezone. Correct? I guess
>> I can live with that.
>
> Yes. Dates will always be (implicitly) in the local timezone.

Horrible outlook if I can't change the timezone.
Maybe I miss something, but if not, please reconsider. I constantly
need timezone calculations and would like to avoid writing my own lib.

That being said time in millis is always useful.

>>
>>>
>>> I also propose closing http://dartbug.com/1424 (Split into Date and
>>> TimeStamp). This is outside the scope of the corelib.
>>
>>
>> I still believe that having separate Date and DateTime in the corelib
>> (both of them in local timezone) is extremely valuable, because using
>> date+time value for modeling date value gets inconvenient pretty quickly.
>> I'm obviously not the one to decide what is in corelib's scope and what
>> isn't, but I'd plead for considering this once more.
>
> From my point of view the biggest problem is that there is a lot of pressure
> to make "Date" the DateTime class leaving no good name for the actual Date
> class. I will think about this, but I think I would rather make working with
> Dates easier by providing something like an "Interval" class (similar to the
> Duration class) that deals nicer with Dates. For example: date + new
> Interval(months: 3, days: 1)
>>
>>
>> LT
>
>
>
>
> --
> Give a man a fire and he's warm for the whole day,
> but set fire to him and he's warm for the rest of his life. - Terry
> Pratchett



--
http://www.grobmeier.de
https://www.timeandbill.de

Florian Loitsch

unread,
May 14, 2012, 10:52:43 AM5/14/12
to Christian Grobmeier, Ladislav Thon, General Dart Discussion
On Mon, May 14, 2012 at 4:46 PM, Christian Grobmeier <grob...@gmail.com> wrote:
On Mon, May 14, 2012 at 4:41 PM, Florian Loitsch <floi...@google.com> wrote:
> On Mon, May 14, 2012 at 4:31 PM, Ladislav Thon <lad...@gmail.com> wrote:
>>
>> Hi,
>>
>>> The idea is to make it easier to use for the general case, and *not*
>>> implement a feature complete Date library. We eventually need something like
>>> Java's Joda library, but such a library would be way too big for the corelib
>>> and would confuse most people (Dates, DateTimes, and TimeZones are
>>> unfortunately pretty complicated...).
>>>
>>> As a first step I want to do the modifications I propose in
>>> CL https://chromiumcodereview.appspot.com/10384149
>>
>>
>> if I understand correctly, your argument and your code is based on the
>> assumption that timezones are hard, make the code complicated and in a vast
>> majority of situations, they aren't even necessary. I completely and
>> wholeheartedly agree. Having the corelib's date/time support as much
>> timezones-free as possible is a goal I can identify with.
>
> Correct: no (explicit) timezones in the corelib.

How should that look like? In the past years I needed access to
perfect timezone support (I am a Joda fan) and really cannot imagine
how it would work without.
Similar to Java this functionality would be provided by a separate library. If you need the complexity then you have to ask for it.
One reason for this (as already mentioned) is not to confuse developers that just want to do simple Date operations. The other is, that a Joda like library requires a lot of space; both in terms of code-size as well as in data.


>>
>> From looking at the proposed Date interface, it looks like it can't be
>> completely timezones-free (because even the unix timestamp value refers to
>> UTC), so instead, the date is implicitly in local timezone. Correct? I guess
>> I can live with that.
>
> Yes. Dates will always be (implicitly) in the local timezone.

Horrible outlook if I can't change the timezone.
Maybe I miss something, but if not, please reconsider. I constantly
need timezone calculations and would like to avoid writing my own lib.
Somebody will have to write (or port) a lib, but with a little bit of luck it will not be you ;)

Ladislav Thon

unread,
May 14, 2012, 10:56:05 AM5/14/12
to Christian Grobmeier, Florian Loitsch, General Dart Discussion
> Correct: no (explicit) timezones in the corelib.

How should that look like? In the past years I needed access to
perfect timezone support (I am a Joda fan) and really cannot imagine
how it would work without.

Even JodaTime (and ThreeTen too, IIRC) has Local[Date|DateTime|Time], and from my experience, timezone-less date values are far more common than the other ones. So I guess that the plan is to have a separate library with all those bells, timezones and whistles, but keep some small and most useful fraction of it right in the corelib.

LT

William Hesse

unread,
May 14, 2012, 10:57:41 AM5/14/12
to Christian Grobmeier, Florian Loitsch, Ladislav Thon, General Dart Discussion
Just so everyone is on the same page here:

A Date represents an absolute time (what many people would call a UTC
time) - an actual epoch value, that refers to
an instant that is the same around the world. That will definitely not change.

Almost all of the functions for converting Dates to strings, and
getting hours, minutes, days, seconds from them, and for creating and
modifying dates will use the local time zone to convert to local time,
and will assume their inputs are in local time. This is also the same
as before

Date is not really a good way for representing calendar days. If you
make a Date from a calendar day, that Date is dependent on your local
timezone, and if its value as a Date object somehow gets to another
computer, it may not represent a time on that same day. It is also
hard to add and subtract days, with summer daylight time changes
happening. This makes the problem no better or worse. The real
solution is a different object for calendar days, or a UTC calendar
day that is easy to use.

What the previous API had was storing the time zone (from creation)
along with the Date, and using that, rather than the current active
time zone, for input/output/conversion (I think). Usually there would
be no difference between the two.

I would like to know if this makes it any harder to do input/output from UTC.


On Mon, May 14, 2012 at 4:46 PM, Christian Grobmeier
--
William Hesse
Software Engineer
whe...@google.com

Google Denmark ApS
Frederiksborggade 20B, 1 sal
1360 København K
Denmark
CVR nr. 28 86 69 84

If you received this communication by mistake, please don't forward it
to anyone else (it may contain confidential or privileged
information), please erase all copies of it, including all
attachments, and please let the sender know it went to the wrong
person. Thanks.

Christian Grobmeier

unread,
May 14, 2012, 10:58:29 AM5/14/12
to Florian Loitsch, Ladislav Thon, General Dart Discussion
>> > Correct: no (explicit) timezones in the corelib.
>>
>> How should that look like? In the past years I needed access to
>> perfect timezone support (I am a Joda fan) and really cannot imagine
>> how it would work without.
>
> Similar to Java this functionality would be provided by a separate library.
> If you need the complexity then you have to ask for it.
> One reason for this (as already mentioned) is not to confuse developers that
> just want to do simple Date operations. The other is, that a Joda like
> library requires a lot of space; both in terms of code-size as well as in
> data.

I would find it pretty confusing if I can't fix my code because I have
no timezone avail :-)
I have learned there is no "simple date operation", even when it looks simple.

>> >> From looking at the proposed Date interface, it looks like it can't be
>> >> completely timezones-free (because even the unix timestamp value refers
>> >> to
>> >> UTC), so instead, the date is implicitly in local timezone. Correct? I
>> >> guess
>> >> I can live with that.
>> >
>> > Yes. Dates will always be (implicitly) in the local timezone.
>>
>> Horrible outlook if I can't change the timezone.
>> Maybe I miss something, but if not, please reconsider. I constantly
>> need timezone calculations and would like to avoid writing my own lib.
>
> Somebody will have to write (or port) a lib, but with a little bit of luck
> it will not be you ;)

With my luck, I will write it :-)

In any case, if you can create a (readable) field naming the time zone
in which the date was created would probably help debugging.
And a chance to return the time in millis would be fine

Christian Grobmeier

unread,
May 14, 2012, 11:00:05 AM5/14/12
to Ladislav Thon, Florian Loitsch, General Dart Discussion
Like java.util.Date, the Calendar classes and Joda, which now becomes
part of the SDK?
Hope it will not cause more confusion than expected.

>
> LT

Ladislav Thon

unread,
May 14, 2012, 11:10:24 AM5/14/12
to Christian Grobmeier, Florian Loitsch, General Dart Discussion
Like java.util.Date, the Calendar classes and Joda, which now becomes
part of the SDK?
Hope it will not cause more confusion than expected.

I'm pretty sure that nowadays, noone would publish a date library similar to java.util.Date or Calendar :-) And ThreeTen is quite different from Joda. I'd love to have Stephen Colebourne (co)designing Dart's date library, but I'm also sure that there already are some skilled people in the Dart team.

A lot of applications (I'd argue that majority of applications) only makes sense in a single timezone and their developers (myself included) don't really understand this stuff. Let's not complicate their lifes.

LT

Christian Grobmeier

unread,
May 14, 2012, 11:23:32 AM5/14/12
to Ladislav Thon, Florian Loitsch, General Dart Discussion
On Mon, May 14, 2012 at 5:10 PM, Ladislav Thon <lad...@gmail.com> wrote:
>> Like java.util.Date, the Calendar classes and Joda, which now becomes
>> part of the SDK?
>> Hope it will not cause more confusion than expected.
>
>
> I'm pretty sure that nowadays, noone would publish a date library similar to
> java.util.Date or Calendar :-) And ThreeTen is quite different from Joda.

I am referring to the fact that java.util.Date has not timezone
support and gives you month/day/year etc. It is pretty simple and
sound pretty much like what is proposed: a simple Date class with a
single timezone.

> I'd love to have Stephen Colebourne (co)designing Dart's date library, but
> I'm also sure that there already are some skilled people in the Dart team.

It did not doubt that.

> A lot of applications (I'd argue that majority of applications) only makes
> sense in a single timezone and their developers (myself included) don't
> really understand this stuff. Let's not complicate their lifes.

I am not sure why these signatures are considered complicated or confusing:

new Date(); // fixed timezone or underlying os timezone
new Date.germany();
new Date.utc(5); // utc +5

I highly doubt that people who deal with Date don't need access to TimeZone.

Either I have had bad luck but the past years I constantly worked on
applications which needed timezones. I am also not talking about
creating a killer-lib like JodaTime but completely getting rid of
timezones sounds wrong to me.

But well, at least I hope the new Date-classes allow creating a proper
lib. Anyway without such a lib I cannot move to Dart, stable or not.

Cheers
Christian

Florian Loitsch

unread,
May 14, 2012, 11:37:07 AM5/14/12
to General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager

Sean Eagan

unread,
May 14, 2012, 11:43:22 AM5/14/12
to Florian Loitsch, Ladislav Thon, General Dart Discussion
On Mon, May 14, 2012 at 9:41 AM, Florian Loitsch <floi...@google.com> wrote:
> From my point of view the biggest problem is that there is a lot of pressure
> to make "Date" the DateTime class leaving no good name for the actual Date
> class.

I would rename Date to Time, that is what Ruby and Go have:

http://www.ruby-doc.org/core-1.9.3/Time.html
http://golang.org/pkg/time/#Time

For the other interface, I would consider using Day instead of Date to
avoid any confusion with Date in Java/JavaScript.

'time of day' abstractions are not that common, but if needed, it
could be named TimeOfDay.

> I will think about this, but I think I would rather make working with
> Dates easier by providing something like an "Interval" class (similar to the
> Duration class) that deals nicer with Dates. For example: date + new
> Interval(months: 3, days: 1)

I think the term 'Interval' implies a contiguous interval between two
absolute values which are Comparable such as Date/Time, e.g.:

interface Interval<T extends Comparable> {
Interval(T one, T other);

final T start, end;
bool contains(T test);
}

As far as modeling day, week, month, and year deltas independent of
daylight savings time, varying month lengths, and leap years, I think
this should be added directly to Duration, or at least a sub-interface
thereof. This is tracked in http://dartbug.com/1426.

This can be done by having exact, non-additive fields for
milliseconds, days, and months, and then estimated additive getters
for all units, i.e. inMilliseconds ... inYears.

I mocked this up at:

https://gist.github.com/1979756

The Duration returned from Date/Time#difference would have a slightly
different implementation since it can provide exact values for the all
units, yet it would still only need to store a subset of milliseconds,
days, and months values internally.

Cheers,
Sean Eagan

afsina

unread,
May 15, 2012, 8:00:10 AM5/15/12
to General Dart Discussion


On May 14, 6:10 pm, Ladislav Thon <ladi...@gmail.com> wrote:
> > Like java.util.Date, the Calendar classes and Joda, which now becomes
> > part of the SDK?
> > Hope it will not cause more confusion than expected.
>
> I'm pretty sure that nowadays, noone would publish a date library similar
> to java.util.Date or Calendar :-) And ThreeTen is quite different from
> Joda. I'd love to have Stephen Colebourne (co)designing Dart's date
> library, but I'm also sure that there already are some skilled people in
> the Dart team.
>
> A lot of applications (I'd argue that *majority* of applications) only
> makes sense in a single timezone and their developers (myself included)
> don't really understand this stuff. Let's not complicate their lifes.
>
> LT

There is an interesting poll about names in JSR 310 - ThreeTen
( http://sourceforge.net/apps/mediawiki/threeten/index.php?title=ThreeTen
)
May be relevant with the discussion

https://www.rationalsurvey.com/studyPeriods/collect/stdy_perd_id/3775/page/intro

Ahmet

Sean Eagan

unread,
May 15, 2012, 11:25:16 AM5/15/12
to Florian Loitsch, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
On Mon, May 14, 2012 at 8:59 AM, Florian Loitsch <floi...@google.com> wrote:
> The idea is to make it easier to use for the general case, and *not*
> implement a feature complete Date library. We eventually need something like
> Java's Joda library, but such a library would be way too big for the corelib
> and would confuse most people (Dates, DateTimes, and TimeZones are
> unfortunately pretty complicated...).

I agree with keeping the size of dart:core down. I don't agree that
providing micro date/time APIs in dart:core is the solution. I think
these APIs would be abandoned, forever cluttering the top level
namespace of libraries, after a more full featured library came along.

I think a better option would be to provide a placeholder for that
more full featured library now, probably called "dart:time", which
contains Date, Duration, and TimeZone. Having the local time zone as
the default already means you don't have to think about time zones if
you don't want to. And if a better name were used instead of Date
(outside of computer science this refers to an entire day, not an
instant), such as Time, Instant, or Moment, then a class to represent
an entire day, called Date or Day, could be added to this library
either now or in the future. Other things could be added in the
future as well as pain points are discovered.

Thoughts?

Cheers,
Sean

Sean Eagan

unread,
May 15, 2012, 12:21:18 PM5/15/12
to Florian Loitsch, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
This would also be a good time to discuss:

http://dartbug.com/2771

(Date constructor should allow arguments to overflow/underflow)

Cheers,
Sean

Florian Loitsch

unread,
May 16, 2012, 6:37:38 AM5/16/12
to afsina, General Dart Discussion
Afaics there are no results yet. They should be available soon, though. When they are, don't hesitate to send an update to the list.
thanks,
// florian 


Ahmet

Florian Loitsch

unread,
May 16, 2012, 6:41:15 AM5/16/12
to Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
We are discussing moving even the simplified version of Date into its own library (for instance "dart:date"). So far no conclusion has been reached.
Wrt the naming. Yes, keeping the names consistent would be a plus, but "Date" seems to be pretty entrenched. Also, because there is just no really good substitute. None of DateTime, Time, Instant or Moment is something that is easily found.
// florian 

Cheers,
Sean

Sam McCall

unread,
May 16, 2012, 7:00:21 AM5/16/12
to Florian Loitsch, Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
On Wed, May 16, 2012 at 11:41 AM, Florian Loitsch <floi...@google.com> wrote:
We are discussing moving even the simplified version of Date into its own library (for instance "dart:date").
+1
 
Wrt the naming. Yes, keeping the names consistent would be a plus, but "Date" seems to be pretty entrenched. Also, because there is just no really good substitute. None of DateTime, Time, Instant or Moment is something that is easily found.
 
I think 'Date' is entrenched, but everyone has different expectations of it:
  • New developers expect it to be a calendar date with no time attached (as in English)
  • People familiar with other languages expect it to have a timezone, defaulting to local
  • And Dart is (sensibly) considering making it a UTC timestamp
I think 'Instant' is a better name, because:
  • Its plain-English meaning is closer to a timestamp than 'Date'
  • It's not misleadingly similar different concepts from other languages
    • most won't know it at all
    • people familiar with Joda will get the correct idea
    • people won't complain about it being different, most Date APIs suck
  • There will be less pressure to include formatting methods (and thus timezone logic) in this class if it's called Instant vs Date.
Cheers,
Sam

Ladislav Thon

unread,
May 16, 2012, 8:44:15 AM5/16/12
to Sam McCall, Florian Loitsch, Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
+∞ to what Sam said. Extracting date stuff to separate library works fine for me -- and it's a great opportunity to route people in the right direction where the full-featured timezone-aware date library will be.

LT

Sean Eagan

unread,
May 16, 2012, 9:21:38 AM5/16/12
to Florian Loitsch, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
On Wed, May 16, 2012 at 5:41 AM, Florian Loitsch <floi...@google.com> wrote:
> We are discussing moving even the simplified version of Date into its own
> library (for instance "dart:date"). So far no conclusion has been reached.

Glad to hear that it is being considered. I assume Duration,
Stopwatch, Timer, Clock (and TimeZone if it were kept) would also be
moved there ?

In this case I think "dart:time" would be a much better name since
durations, stopwatches, and timers don't have much to do with dates,
but _are_ related to the concept of time. Here are some existing
libraries which use "time" as the library name:

http://docs.python.org/library/time.html
http://golang.org/pkg/time/
http://www.ruby-doc.org/stdlib-1.9.3/libdoc/time/rdoc/index.html
http://threeten.sourceforge.net/apidocs-2012-04-24/javax/time/package-summary.html

> Wrt the naming. Yes, keeping the names consistent would be a plus

It's not just about consistency within Dart, but consistency with
English as well :).

> "Date" seems to be pretty entrenched.

But the _trend_ is moving away from "Date". Joda and eventually
ThreeTen use "Instant" / "DateTime", moment.js (http://momentjs.com)
uses "Moment". Go and Ruby use "Time". Python uses "DateTime".

> Also, because there is just no really
> good substitute. None of DateTime, Time, Instant or Moment is something that
> is easily found.

These all seem like improvements over "Date". And if this is in a
small "dart:time" library, then it should be quite easily found, once
the library itself is found at http://api.dartlang.org.

Cheers,
Sean Eagan

Florian Loitsch

unread,
May 16, 2012, 11:58:28 AM5/16/12
to Sam McCall, Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
On Wed, May 16, 2012 at 1:00 PM, Sam McCall <samm...@google.com> wrote:
On Wed, May 16, 2012 at 11:41 AM, Florian Loitsch <floi...@google.com> wrote:
We are discussing moving even the simplified version of Date into its own library (for instance "dart:date").
+1
 
Wrt the naming. Yes, keeping the names consistent would be a plus, but "Date" seems to be pretty entrenched. Also, because there is just no really good substitute. None of DateTime, Time, Instant or Moment is something that is easily found.
 
I think 'Date' is entrenched, but everyone has different expectations of it:
  • New developers expect it to be a calendar date with no time attached (as in English)
  • People familiar with other languages expect it to have a timezone, defaulting to local
  • And Dart is (sensibly) considering making it a UTC timestamp
I think 'Instant' is a better name, because:
The problem with "Instant" is that it clashes with threeten. There "Instant" is just a wrapper around the epoch-value. The equivalent class would be "ZonedDateTime" and that's a no go for the simplified class name.
 
  • Its plain-English meaning is closer to a timestamp than 'Date'
  • It's not misleadingly similar different concepts from other languages
    • most won't know it at all
    • people familiar with Joda will get the correct idea
    • people won't complain about it being different, most Date APIs suck
  • There will be less pressure to include formatting methods (and thus timezone logic) in this class if it's called Instant vs Date.
Cheers,
Sam

Sam McCall

unread,
May 16, 2012, 12:40:59 PM5/16/12
to Florian Loitsch, Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
On Wed, May 16, 2012 at 5:58 PM, Florian Loitsch <floi...@google.com> wrote:
On Wed, May 16, 2012 at 1:00 PM, Sam McCall <samm...@google.com> wrote:
On Wed, May 16, 2012 at 11:41 AM, Florian Loitsch <floi...@google.com> wrote:
We are discussing moving even the simplified version of Date into its own library (for instance "dart:date").
+1
 
Wrt the naming. Yes, keeping the names consistent would be a plus, but "Date" seems to be pretty entrenched. Also, because there is just no really good substitute. None of DateTime, Time, Instant or Moment is something that is easily found.
 
I think 'Date' is entrenched, but everyone has different expectations of it:
  • New developers expect it to be a calendar date with no time attached (as in English)
  • People familiar with other languages expect it to have a timezone, defaulting to local
  • And Dart is (sensibly) considering making it a UTC timestamp
I think 'Instant' is a better name, because:
The problem with "Instant" is that it clashes with threeten. There "Instant" is just a wrapper around the epoch-value. The equivalent class would be "ZonedDateTime" and that's a no go for the simplified class name.
I'm confused, I thought we were talking about a 'wrapper around an epoch-value' - that's the baseline that I'd expect to be (almost) part of the language.

Once you start including timezones then the complexity comes in, and I agree there's not a great name for that - but it would be one name among several in such a library (c.f. joda/threeten) and so it would be easier to draw distinctions through a naming system.

Florian Loitsch

unread,
May 16, 2012, 2:21:30 PM5/16/12
to Sam McCall, Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
On Wed, May 16, 2012 at 6:40 PM, Sam McCall <samm...@google.com> wrote:
On Wed, May 16, 2012 at 5:58 PM, Florian Loitsch <floi...@google.com> wrote:
On Wed, May 16, 2012 at 1:00 PM, Sam McCall <samm...@google.com> wrote:
On Wed, May 16, 2012 at 11:41 AM, Florian Loitsch <floi...@google.com> wrote:
We are discussing moving even the simplified version of Date into its own library (for instance "dart:date").
+1
 
Wrt the naming. Yes, keeping the names consistent would be a plus, but "Date" seems to be pretty entrenched. Also, because there is just no really good substitute. None of DateTime, Time, Instant or Moment is something that is easily found.
 
I think 'Date' is entrenched, but everyone has different expectations of it:
  • New developers expect it to be a calendar date with no time attached (as in English)
  • People familiar with other languages expect it to have a timezone, defaulting to local
  • And Dart is (sensibly) considering making it a UTC timestamp
I think 'Instant' is a better name, because:
The problem with "Instant" is that it clashes with threeten. There "Instant" is just a wrapper around the epoch-value. The equivalent class would be "ZonedDateTime" and that's a no go for the simplified class name.
I'm confused, I thought we were talking about a 'wrapper around an epoch-value' - that's the baseline that I'd expect to be (almost) part of the language.
You want year, month, ... getters and a toString method. There will be no explicit timezone since it will always be the local one.

Once you start including timezones then the complexity comes in, and I agree there's not a great name for that - but it would be one name among several in such a library (c.f. joda/threeten) and so it would be easier to draw distinctions through a naming system.
There will be no Timezone class but the Date class will have properties that implicitly make it live in the users timezone. There will be no way to get dates from other timezones (except maybe UTC). As such it resembles the ZonedDateTime class from ThreeTen.

Currently my biggest question is: should we have a way to get to UTC data (like the JS getUTCMonth) or not.
If yes we could have:
a. an isUtc boolean. This would basically replace the TimeZone class but still keeping exactly the same functionality.
b. only a toUtcString (which seems to be the most common use-case for utc dates).
c. a UtcDate class.
d. utc-getters (like in JavaScript).

Personally I'm against d, but a, b and c are all possible, and people here at the office seem to have different opinions. 

// florian

Sam McCall

unread,
May 16, 2012, 2:37:03 PM5/16/12
to Florian Loitsch, Mads Ager, Kasper Lund, Dan Grove, Sorin Mocanu, General Dart Discussion, Joshua Bloch, Sean Eagan, Nicolas Geoffray


On May 16, 2012 8:21 PM, "Florian Loitsch" <floi...@google.com> wrote:
>
> On Wed, May 16, 2012 at 6:40 PM, Sam McCall <samm...@google.com> wrote:
>>
>> On Wed, May 16, 2012 at 5:58 PM, Florian Loitsch <floi...@google.com> wrote:
>>>
>>> On Wed, May 16, 2012 at 1:00 PM, Sam McCall <samm...@google.com> wrote:
>>>>
>>>> On Wed, May 16, 2012 at 11:41 AM, Florian Loitsch <floi...@google.com> wrote:
>>>>>
>>>>> We are discussing moving even the simplified version of Date into its own library (for instance "dart:date").
>>>>
>>>> +1
>>>>  
>>>>>
>>>>> Wrt the naming. Yes, keeping the names consistent would be a plus, but "Date" seems to be pretty entrenched. Also, because there is just no really good substitute. None of DateTime, Time, Instant or Moment is something that is easily found.
>>>>
>>>>  
>>>> I think 'Date' is entrenched, but everyone has different expectations of it:
>>>> New developers expect it to be a calendar date with no time attached (as in English)
>>>> People familiar with other languages expect it to have a timezone, defaulting to local
>>>> And Dart is (sensibly) considering making it a UTC timestamp
>>>> I think 'Instant' is a better name, because:
>>>
>>> The problem with "Instant" is that it clashes with threeten. There "Instant" is just a wrapper around the epoch-value. The equivalent class would be "ZonedDateTime" and that's a no go for the simplified class name.
>>
>> I'm confused, I thought we were talking about a 'wrapper around an epoch-value' - that's the baseline that I'd expect to be (almost) part of the language.
>
> You want year, month, ... getters and a toString method. There will be no explicit timezone since it will always be the local one.

This is a really bad idea, in my (limited) experience. Apps whose date needs are simple need a timestamp that they can trivially compare, increment in seconds, and pass through safely. UTC timestamps a.k.a Instant achieves this.

Apps that need Day, local time, etc need to be timezone aware.

Providing a ZonedDateTime as the 'simple' type will result in lots of broken-by-default behavior and attractive nuisances for apps whose needs are simple.

Java's history is a good demonstration of this...

Florian Loitsch

unread,
May 16, 2012, 4:11:11 PM5/16/12
to Sam McCall, Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
FYI: after some input from other Googlers, option b is off the table.
// florian 

// florian

--
Give a man a fire and he's warm for the whole day,
but set fire to him and he's warm for the rest of his life. - Terry Pratchett

Christopher Wright

unread,
May 16, 2012, 5:13:59 PM5/16/12
to Florian Loitsch, Sam McCall, Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
On 16 May 2012 20:11, Florian Loitsch <floi...@google.com> wrote:
On Wed, May 16, 2012 at 8:21 PM, Florian Loitsch <floi...@google.com> wrote:
On Wed, May 16, 2012 at 6:40 PM, Sam McCall <samm...@google.com> wrote:
On Wed, May 16, 2012 at 5:58 PM, Florian Loitsch <floi...@google.com> wrote:
On Wed, May 16, 2012 at 1:00 PM, Sam McCall <samm...@google.com> wrote:
On Wed, May 16, 2012 at 11:41 AM, Florian Loitsch <floi...@google.com> wrote:
We are discussing moving even the simplified version of Date into its own library (for instance "dart:date").
+1
 
Wrt the naming. Yes, keeping the names consistent would be a plus, but "Date" seems to be pretty entrenched. Also, because there is just no really good substitute. None of DateTime, Time, Instant or Moment is something that is easily found.
 
I think 'Date' is entrenched, but everyone has different expectations of it:
  • New developers expect it to be a calendar date with no time attached (as in English)
  • People familiar with other languages expect it to have a timezone, defaulting to local
  • And Dart is (sensibly) considering making it a UTC timestamp
I think 'Instant' is a better name, because:
The problem with "Instant" is that it clashes with threeten. There "Instant" is just a wrapper around the epoch-value. The equivalent class would be "ZonedDateTime" and that's a no go for the simplified class name.
I'm confused, I thought we were talking about a 'wrapper around an epoch-value' - that's the baseline that I'd expect to be (almost) part of the language.
You want year, month, ... getters and a toString method. There will be no explicit timezone since it will always be the local one.

Once you start including timezones then the complexity comes in, and I agree there's not a great name for that - but it would be one name among several in such a library (c.f. joda/threeten) and so it would be easier to draw distinctions through a naming system.
There will be no Timezone class but the Date class will have properties that implicitly make it live in the users timezone. There will be no way to get dates from other timezones (except maybe UTC). As such it resembles the ZonedDateTime class from ThreeTen.

I don't think you can get away with this. Or rather, you can, but you'd be relying on someone else to write a de facto standard date/time library, like Java did.

Consider: my server's on the America/New York time zone (despite being located in Texas). I store my dates in UTC. How do I format these dates for my users, half of whom are in Seattle and half of whom are in New Zealand?

Okay, I do all my date formatting with client-side scripts. And I hope the user visiting an internet cafe while on vacation in Thailand doesn't mind seeing their data in UTC+7 rather than UTC-8 while looking at their work schedule, or think they're reporting in for a shift starting at 4pm rather 1am when they get back in three days. (Not an unreasonable situation with hospital staff scheduling.)
 
Currently my biggest question is: should we have a way to get to UTC data (like the JS getUTCMonth) or not.
If yes we could have:
a. an isUtc boolean. This would basically replace the TimeZone class but still keeping exactly the same functionality.
b. only a toUtcString (which seems to be the most common use-case for utc dates).
c. a UtcDate class.
d. utc-getters (like in JavaScript).

Personally I'm against d, but a, b and c are all possible, and people here at the office seem to have different opinions. 
FYI: after some input from other Googlers, option b is off the table.

Some thoughts and perhaps silly ideas on the matter:

Anything that involves scheduled tasks needs to use UTC internally. (Someone switch my server's timezone? I ain't even mad.)
Anything that ever needs to distinguish or order events by date needs to use UTC internally. (Daylight savings time was a recurring issue at my previous job.)
Anything that involves users in different timezones needs to store dates internally using some single, agreed-on timezone. (For instance, parsing out EXIF metadata to get the date at which a photo was taken, after the user uploads it.) UTC is the default choice.

What needs to deal with timezones other than UTC? Displaying stuff in a user's local timezone. Taking user input.

The only other situation in which it's tempting to use anything but UTC is when your userbase is small enough to be constrained in one timezone, or if time isn't sufficiently important in your system for users to mind seeing everything in your server's timezone (and you don't mind the occasional DST issue).

And now, for the crazy idea:
How about UTC being the only way to store dates, and giving formatting and parsing options that are timezone-aware? You still need a notion of a timezone, but it would solve a number of bugs before they're written.

Florian Loitsch

unread,
May 16, 2012, 5:47:26 PM5/16/12
to Christopher Wright, Sam McCall, Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
On Wed, May 16, 2012 at 11:13 PM, Christopher Wright <dhas...@google.com> wrote:
On 16 May 2012 20:11, Florian Loitsch <floi...@google.com> wrote:
On Wed, May 16, 2012 at 8:21 PM, Florian Loitsch <floi...@google.com> wrote:
On Wed, May 16, 2012 at 6:40 PM, Sam McCall <samm...@google.com> wrote:
On Wed, May 16, 2012 at 5:58 PM, Florian Loitsch <floi...@google.com> wrote:
On Wed, May 16, 2012 at 1:00 PM, Sam McCall <samm...@google.com> wrote:
On Wed, May 16, 2012 at 11:41 AM, Florian Loitsch <floi...@google.com> wrote:
We are discussing moving even the simplified version of Date into its own library (for instance "dart:date").
+1
 
Wrt the naming. Yes, keeping the names consistent would be a plus, but "Date" seems to be pretty entrenched. Also, because there is just no really good substitute. None of DateTime, Time, Instant or Moment is something that is easily found.
 
I think 'Date' is entrenched, but everyone has different expectations of it:
  • New developers expect it to be a calendar date with no time attached (as in English)
  • People familiar with other languages expect it to have a timezone, defaulting to local
  • And Dart is (sensibly) considering making it a UTC timestamp
I think 'Instant' is a better name, because:
The problem with "Instant" is that it clashes with threeten. There "Instant" is just a wrapper around the epoch-value. The equivalent class would be "ZonedDateTime" and that's a no go for the simplified class name.
I'm confused, I thought we were talking about a 'wrapper around an epoch-value' - that's the baseline that I'd expect to be (almost) part of the language.
You want year, month, ... getters and a toString method. There will be no explicit timezone since it will always be the local one.

Once you start including timezones then the complexity comes in, and I agree there's not a great name for that - but it would be one name among several in such a library (c.f. joda/threeten) and so it would be easier to draw distinctions through a naming system.
There will be no Timezone class but the Date class will have properties that implicitly make it live in the users timezone. There will be no way to get dates from other timezones (except maybe UTC). As such it resembles the ZonedDateTime class from ThreeTen.

I don't think you can get away with this. Or rather, you can, but you'd be relying on someone else to write a de facto standard date/time library, like Java did.
This has been stated since the beginning: the corelib's date class will only implement a subset of what is necessary to do full Date/Time manipulation. The question is what is simple enough while still useful.
We will *not* have complete support for Timezones in the corelib. This would be to complex and way too big. ThreeTen, for example, has more than 5MB source (and there are probably some data files that need to be shipped too).
 

Consider: my server's on the America/New York time zone (despite being located in Texas). I store my dates in UTC. How do I format these dates for my users, half of whom are in Seattle and half of whom are in New Zealand?
send the epoch value to both. That's actually the perfect use-case. 

Okay, I do all my date formatting with client-side scripts. And I hope the user visiting an internet cafe while on vacation in Thailand doesn't mind seeing their data in UTC+7 rather than UTC-8 while looking at their work schedule, or think they're reporting in for a shift starting at 4pm rather 1am when they get back in three days. (Not an unreasonable situation with hospital staff scheduling.)
If they switch the timezone of their computer then they will see the Dates in the new timezone. Yes.
 
 
Currently my biggest question is: should we have a way to get to UTC data (like the JS getUTCMonth) or not.
If yes we could have:
a. an isUtc boolean. This would basically replace the TimeZone class but still keeping exactly the same functionality.
b. only a toUtcString (which seems to be the most common use-case for utc dates).
c. a UtcDate class.
d. utc-getters (like in JavaScript).

Personally I'm against d, but a, b and c are all possible, and people here at the office seem to have different opinions. 
FYI: after some input from other Googlers, option b is off the table.

Some thoughts and perhaps silly ideas on the matter:

Anything that involves scheduled tasks needs to use UTC internally. (Someone switch my server's timezone? I ain't even mad.)
Absolutely not. The only thing you need is the epoch value. Nobody should ever look at some UTC getters to do scheduling.
 
Anything that ever needs to distinguish or order events by date needs to use UTC internally. (Daylight savings time was a recurring issue at my previous job.)
Again, no. You only need the '.value' of dates.
 
Anything that involves users in different timezones needs to store dates internally using some single, agreed-on timezone. (For instance, parsing out EXIF metadata to get the date at which a photo was taken, after the user uploads it.) UTC is the default choice.
Again. No. Exchanging dateTimes should be done using the epoch value. Nothing else makes sense. Otherwise you would need to parse some string, or similar. 

What needs to deal with timezones other than UTC? Displaying stuff in a user's local timezone. Taking user input.
Then it will have the user's timezone. Should work in almost all cases. 

The only other situation in which it's tempting to use anything but UTC is when your userbase is small enough to be constrained in one timezone, or if time isn't sufficiently important in your system for users to mind seeing everything in your server's timezone (and you don't mind the occasional DST issue).
The server's timezone should never come into play. 

And now, for the crazy idea:
How about UTC being the only way to store dates, and giving formatting and parsing options that are timezone-aware? You still need a notion of a timezone, but it would solve a number of bugs before they're written.
Something like ThreeTen's Instant class?
Given that we won't support other timezones than Local and UTC I don't see the value in forcing users into dealing with TimeZones, Calendars, etc.
Give them what covers almost all use-cases. If they need more, let them import some more specialized class.
Fwiw I want to provide a Date API that is (mostly) a subset of something more sophisticated (like ThreeTen). Currently I'm willing to give up on two things:
- keeping the same names: "Date" in corelib might not be the same as the "Date" from the more sophisticated library.
- dates outside a reasonable range might be wrong. Imho it is not worth the trouble to keep daylight-savings, etc if it was before a certain date. Most of these simplifications are exactly the same as in JS.

Other than that I don't see why a simplified Date class wouldn't be helpful. It would be basically identical to a ZonedDateTime from ThreeTen that is instantiated with the current timezone. The main difference would be that you just cannot instantiate ZonedDateTime with anything else (except maybe UTC which is still under discussion).

Lasse R.H. Nielsen

unread,
May 16, 2012, 9:00:04 PM5/16/12
to Florian Loitsch, Christopher Wright, Sam McCall, Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
On Wed, May 16, 2012 at 11:47 PM, Florian Loitsch <floi...@google.com> wrote:

> Other than that I don't see why a simplified Date class wouldn't be helpful.
> It would be basically identical to a ZonedDateTime from ThreeTen that is
> instantiated with the current timezone. The main difference would be that
> you just cannot instantiate ZonedDateTime with anything else (except maybe
> UTC which is still under discussion).

I can live with not having a wrapper for a ms-since-epoch value. It
really is just a number.

The "Date" wrapper will then provide "calendar" access to such a
moment using a single default calendar (proleptic gregorian) in a
single time zone (default is current local time).

I would still want to be able to:
- Create date objects in any time zone (as minutes delta from UTC,
anything else is too complex)
- read the time zone of a Date object.
This would allow a server to operate on dates in the client's time
zone, if it can get the time zone from the client.

The system must be able to find the current time zone anyway, and the
Date object must be able to handle any current time zone, so this will
not cause any extra complexity by itself (except perhaps in dart2js).

Or, do you plan to let the the Date object handle daylight saving too?
I.e., not just one timezone, but two, and rules for selecting one or
the other?

/L
--
Lasse R.H. Nielsen
l...@google.com
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K -
Denmark - CVR nr. 28 86 69 84

Florian Loitsch

unread,
May 22, 2012, 11:02:05 AM5/22/12
to Lasse R.H. Nielsen, Christopher Wright, Sam McCall, Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
Update:
I recently uploaded a CL that prepares the removal of the TimeZone class. I tried to minimize breakage but it is a breaking change. A follow-up change will then remove the methods and classes I marked as deprecated:


On Thu, May 17, 2012 at 3:00 AM, Lasse R.H. Nielsen <l...@chromium.org> wrote:
On Wed, May 16, 2012 at 11:47 PM, Florian Loitsch <floi...@google.com> wrote:

> Other than that I don't see why a simplified Date class wouldn't be helpful.
> It would be basically identical to a ZonedDateTime from ThreeTen that is
> instantiated with the current timezone. The main difference would be that
> you just cannot instantiate ZonedDateTime with anything else (except maybe
> UTC which is still under discussion).

I can live with not having a wrapper for a ms-since-epoch value.  It
really is just a number.

The "Date" wrapper will then provide "calendar" access to such a
moment using a single default calendar (proleptic gregorian) in a
single time zone (default is current local time).

I would still want to be able to:
- Create date objects in any time zone (as minutes delta from UTC,
anything else is too complex)
I thought about this for a long time, but eventually decided to just give access to a UTC class (the 'isUtc" boolean).
Implementing the ofsetted date is then a simple matter of wrapping a UTC-based date.

- read the time zone of a Date object.
This would allow a server to operate on dates in the client's time
zone, if it can get the time zone from the client.
Date objects will have a way to get to their abbreviation. That isn't as helpful as it sounds (since abbreviations are not unique), but that's a start.

I also want to add a static method to get the Olson time-zone id (like "Europe/London"), but I haven't started working on this yet. I have some ideas of how to implementing in a platform independent way, though.

The system must be able to find the current time zone anyway, and the
Date object must be able to handle any current time zone, so this will
not cause any extra complexity by itself (except perhaps in dart2js).
If it was that simple...
What every system gives you is the abbreviation (and that one is now exposed). Only Windows (and maybe Mac?) has a system API to get the Olson id. But as stated above: I intend to add a *static* method to get this id. Contrary to the abbreviation this id represents a geographic location and not an offset, and is therefore time independent.
 

Or, do you plan to let the the Date object handle daylight saving too?
I.e., not just one timezone, but two, and rules for selecting one or
the other?
I'm thinking of adding a isDaylightSaving (or similar) predicate on Date instances, but nothing has started yet. Should be pretty straight-forward, though.

Note: additional features are lower on my list than refactoring the API. It is always easy to add new functionality, but changing names or arguments potentially breaks users, and has therefore higher priority.

/L
--
Lasse R.H. Nielsen
l...@google.com
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K -
Denmark - CVR nr. 28 86 69 84

William Hesse

unread,
May 22, 2012, 11:57:07 AM5/22/12
to Florian Loitsch, Lasse R.H. Nielsen, Christopher Wright, Sam McCall, Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
I support using something other than Date, such as Time, since I am
convinced by the examples of other languages
that are not using Date for this basic class.

I still find this discussion hard to follow, because I am never sure
that people are talking about the same things.
Especially this part was hard to understand:

>> The "Date" wrapper will then provide "calendar" access to such a
>> moment using a single default calendar (proleptic gregorian) in a
>> single time zone (default is current local time).
>>
>> I would still want to be able to:
>> - Create date objects in any time zone (as minutes delta from UTC,
>> anything else is too complex)

I don't understand what this means at all. I assume that all the
references to Date here
are to times, and we are not talking about the "calendar date without
a time of day" issue at all.

I assume that everyone is agreed that a time is internally an epoch
value, and that converting a time to
a displayed string in the local time zone will therefore be a
calculation including the time zone offset.

The options for toString and fromString seem to be:
1) Use the local time zone.
2) Use UTC
3) Include the desired time zone as a parameter
4) Include the desired time zone as an additional field on a time
instance, and pass it (or assume local) in the constructor.

I think what Florian is doing is moving from option 4 to option 1.

>
> I thought about this for a long time, but eventually decided to just give
> access to a UTC class (the 'isUtc" boolean).
> Implementing the ofsetted date is then a simple matter of wrapping a
> UTC-based date.
>

What is this isUtc boolean? Is is a property of a time instance, or
is it an argument to the conversion functions?
What is an ofsetted date? Would these ever be stored?

>> - read the time zone of a Date object.
>> This would allow a server to operate on dates in the client's time
>> zone, if it can get the time zone from the client.
>

Is this assuming that time objects carry around their originating time
zone with them? The numeric value
will be an epoch value, and will stay correct (refer to the same
instant in time) when the data moves across geographic locations.

To me, thinking of times as absolute things that are simultaneous
around the world, and a time zone as something separate, that is
linked to location, is the only way to avoid confusion. The idea that
3pm in one time zone is at all similar to 3pm in another time zone can
only lead to confusion. Time zones are almost more like localization
and internationalization, than they are something to do with time.

> Date objects will have a way to get to their abbreviation. That isn't as
> helpful as it sounds (since abbreviations are not unique), but that's a
> start.
This seems to assume also that times carry around a time zone, and
that is what the abbreviation refers to.

>
> I also want to add a static method to get the Olson time-zone id (like
> "Europe/London"), but I haven't started working on this yet. I have some
> ideas of how to implementing in a platform independent way, though.
>>
>>
>> The system must be able to find the current time zone anyway, and the
>> Date object must be able to handle any current time zone, so this will
>> not cause any extra complexity by itself (except perhaps in dart2js).

>> Or, do you plan to let the the Date object handle daylight saving too?
>> I.e., not just one timezone, but two, and rules for selecting one or
>> the other?
>
> I'm thinking of adding a isDaylightSaving (or similar) predicate on Date
> instances, but nothing has started yet. Should be pretty straight-forward,
> though.

I don't understand how a isDaylightSaving has any meaning on a time,
except by reference to
a local time zone.

The various operating systems make it difficult to get information
about other time zones than the local
zone, so I cannot imagine putting any conversions to strings or hours
except local zone and UTC in the base library.

So the base library would only support:
Showing times in a clients local time zone, if conversion is done on the client.

Showing times in the server's time zone, if the base library's
conversion is used on the server. This would usually be wrong.

Showing times in arbitrary time zones, if an extension library is
used, with all the bells and whistles, on the server, or perhaps on
the client.

Working with calendar dates using the default conversion functions, if
everybody is lucky and no time objects are sent to different time
zones.

Working with calendar dates using UTC conversion functions, which is a
pain, but will always work.

If a time is associated with a certain time zone, it seems to me it
would also be associated with a location. These are both things that
should not be carried around by every single time object.

If someone is proposing something for the base library that is really
different than this, then please be clear about it.
I think the only radically different proposal is that all times carry
a time zone with them - I would call this a time plus a time zone. In
this case, a question is whether the zone is a geographic location,
which remains the same all year, but has different offsets during
different months, or whether the zone is a fixed offset. So people
should specify this.

Sean Eagan

unread,
May 22, 2012, 12:31:38 PM5/22/12
to Florian Loitsch, Lasse R.H. Nielsen, Christopher Wright, Sam McCall, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
On Tue, May 22, 2012 at 10:02 AM, Florian Loitsch <floi...@google.com> wrote:
> I thought about this for a long time, but eventually decided to just give
> access to a UTC class (the 'isUtc" boolean).

I noticed you also added 'toUtc' and 'toLocal' methods. Will the
constructors be updated to allow creation of utc Dates, or will it be
required to first create a local Date and then call 'toUtc' on it ?

Also, these methods might be good candidates for being getters, e.g.
'inLocal' and 'inUtc' (similar to the Duration in... getters) or
'asLocal' and 'asUtc'.

> Note: additional features are lower on my list than refactoring the API. It
> is always easy to add new functionality, but changing names or arguments
> potentially breaks users, and has therefore higher priority.

I compiled a list of Date refactoring issues that have yet to be
discussed on the list (that I know of):

Date constructor should allow arguments to overflow/underflow
http://dartbug.com/2771

Inconsistent Date field names
http://dartbug.com/1985

Rename Date.fromString to Date.parse
http://dartbug.com/3068

Date.fromEpoch and Date#value inconsistently named
http://dartbug.com/3172

Any input ?

Cheers,
Sean Eagan

Florian Loitsch

unread,
May 22, 2012, 1:15:42 PM5/22/12
to Sean Eagan, Lasse R.H. Nielsen, Christopher Wright, Sam McCall, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
On Tue, May 22, 2012 at 6:31 PM, Sean Eagan <seane...@gmail.com> wrote:
On Tue, May 22, 2012 at 10:02 AM, Florian Loitsch <floi...@google.com> wrote:
> I thought about this for a long time, but eventually decided to just give
> access to a UTC class (the 'isUtc" boolean).

I noticed you also added 'toUtc' and 'toLocal' methods.  Will the
constructors be updated to allow creation of utc Dates, or will it be
required to first create a local Date and then call 'toUtc' on it ?
All the constructors have an optional "isUtc" flag. (Except for "fromString" which extracts the boolean from the given string).
 

Also, these methods might be good candidates for being getters, e.g.
'inLocal' and 'inUtc' (similar to the Duration in... getters) or
'asLocal' and 'asUtc'.
I will think about it and discuss it with other team-members. Personally I don't have a really strong opinion, but I prefer the "toLocal" since it somehow reminds me of the toString, toDouble, toInt. But again: I will discuss this. 

> Note: additional features are lower on my list than refactoring the API. It
> is always easy to add new functionality, but changing names or arguments
> potentially breaks users, and has therefore higher priority.

I compiled a list of Date refactoring issues that have yet to be
discussed on the list (that I know of):

Date constructor should allow arguments to overflow/underflow
http://dartbug.com/2771
No real objection yet. I will have to check if the underlying systems support it.
No promises, but I will eventually look into this one. There are just tasks with higher priorities. 


Inconsistent Date field names
http://dartbug.com/1985
Personally in favor of it. I want to check with some other Googlers first, but unless they object I'm going to do the renaming soon.

Rename Date.fromString to Date.parse
http://dartbug.com/3068
I'm currently working very Date locally. However for this issue I would like to look at all corelib classes at the same time, so that we have consistent interfaces. So, absolutely no decision here yet, and delayed for now.


Date.fromEpoch and Date#value inconsistently named
http://dartbug.com/3172
To be honest, I don't think that the naming here has a huge impact, but I will think about it. For people familiar with Dates, the terms "epoch" as well as "value" are probably ok. Others (non-familiar with Dates) probably have to look at the dartDoc anyways, unless we call it secondsSinceFirstOfJanuary1970 (which will not happen).
Right now I would prefer keeping it as it is, but I'm considering changing to fromEpochValue.
If I don't forget I will look at Joda and ThreeTen later, but maybe somebody knows by heart how they would have named the constructor and field?

// florian


Any input ?

Cheers,
Sean Eagan

Florian Loitsch

unread,
May 22, 2012, 4:09:22 PM5/22/12
to William Hesse, Lasse R.H. Nielsen, Christopher Wright, Sam McCall, Sean Eagan, General Dart Discussion, Dan Grove, Sorin Mocanu, Joshua Bloch, Kasper Lund, Nicolas Geoffray, Mads Ager
To eliminate all kinds of confusions here is a summary of what we are going to get if I go through with my changes. (This is not necessarily a reply to Bill's mail, even though it should answer all of his questions).

To start out with: unless I (or we) find a better name, a "Date" instance will represent a "ZonedDateTime" object (this is, I think, what ThreeTen would call it). Semantically this just means that it will combine a specific moment in time (represented as time elapsed since epoch, 1970-01-01) with a time zone corresponding to a geographic location (which we usually represent by the Olson id: eg. "Europe/London").
Almost all systems only provide support for 2 time zones: the local one, and UTC. The local time zone corresponds to a geographic location, and UTC is location independent with an offset of 0. Note that this functionality is provided by the system and therefore cheap (and small) to implement. (There is no guarantee that the system's local time zone corresponds to a "correct" time zone, but we can assume, without bad consequences, that it actually does.)

Dart Dates are simply the combination of the epoch-time plus a (geographic) time zone: UTC or local. Since there are only two possible values for the time zone, we encode the field as a boolean.

So why do I emphasize this "geographic" location part so much: it is important to see that the local timezone is not a fixed offset, but changes for countries with daylight-saving. Unfortunately people confuse those two concepts (geographic timezone and offset timezone), and to be honest we are not helping either: since yesterday we have "timeZoneName" and "timeZoneOffset" members in Date instance. These give the (abbreviated) name and offset of the geographic timezone *at that specific instant in time*. For example timeZoneOffset will return "CET" (Central European Time) for dates that lie in the winter and "CEST" (Central European Summer Time) for the ones in summer. The actual geographic time zone, however, does not change and is in my case "Europe/Copenhagen".

The geographic time zone name, or "id" is currently not available, although I would like to add a static getter for it eventually. Note that the timeZoneId can be static since, contrary to the abbreviated timeZoneName, it is date independent and only depends on the user's location (or more correctly on her computer's settings). TimeZoneId would, for example, return "Europe/London".

How does this compare to JavaScript's Date class?:
in JavaScript a Date class only holds its epoch-value. From this point of view it is time-zone independent.
However, all of its common accessors (getHours, getYear, ...) assume to work in the local time-zone. In addition to these standard accessors JavaScript comes with UTC accessors (getUTCHours, getUTCYear, toUTCString...).

Dart and JavaScript provide exactly the same functionality. They just view Date instances differently: whereas Dart encodes the time-zone during creation, JavaScript lets the user specify it at every access (by choosing between the local and the UTC getters, like getHours and getUTCHours).
The Date class in Dart has the advantage that it scales more easily to more time zones. It is true, that, by default, there are only 2 time zones, but it is, for example, pretty easy to encode any offset by wrapping a UTC-based Dart class:

class OffsetDate implements Date {
  Duration offset;
  Date date;
  OffsetDate.fromEpoch(int epochValue, Duration offset)
     : offset = offset,
       this.date = new Date.fromEpoch(epochValue + offset.inSeconds, isUtc: true);
  int get value() => date.value - offset;

  int get year() => date.year;
  int get month() => date.month;
  ...
}

Note that this class nicely illustrates the difference between a class that encodes the time-zone location (Date) and the time-zone offset (OffsetDate). Say we add a duration to a date instance. The instance of the Date class will return another Date with the same time-zone location but potentially with a different offset (in case we switched daylight saving). The OffsetDate, on the other hand, will return an instance with the same offset. More sophisticated implementations could of course have more information (and not just the current offset) to make the correct adjustment.

For some time I played with the idea of merging the implementation of the OffsetDate class into the corelib's Date class, but decided eventually against it. As you can see, it is however trivial to add by yourself.

Serialization and communication:
some date libraries wrap the seconds since epoch integer (for example in ThreeTen it is called "Instance"). This way the instant-value has a separate type from integers. It also allows to start counting from a different point in time (and not the epoch 1970-01-01). In Dart's corelib there is no need to complicate things, and we keep the instant value as an integer. This is the value that is universally accepted and agreed upon. Every system understands epoch-seconds (or milliseconds) and this is hence the value that should be used to communicate with other systems.
It is up to the serializer if she also wants to send the timezone offset (which could be used in something like the OffsetDate above) or the timeZoneId (once it is available). The critical information is however the epoch value.

Calendar dates:
we all agree that "Date" is not the correct name for an instant + time-zone. However the correct name (ThreeTen calls it "ZonedDateTime") would be confusing for most people. The principal reason I would search for a better name would be to free the "Date" identifier for calendar dates (i.e. year/month/day). For now I will however try to provide enough functionality so that "Date" can be (ab)used as calendar date too.
For example I'm toying with the idea of adding a DateAdjuster interface (inspired by ThreeTen):

interface DateAdjuster {
  int durationInDaysAt(Date d);
}

This would allow classes like:
class DatePeriod implements DateAdjuster {
  int years, months, days;
  var resolutionStrategy;
  DatePeriod([this.years = 0, this.moths = 0, this.days = 0,
                    resolutionStrategy = DatePeriod.PREVIOUS_VALID]);
  int durationInDaysAt(Date d) { ... }
  ...
}

or
class NextEndOfMonthAdjuster implements DateAdjuster { ... }

You could then write:
date.adjust(new DatePeriod(months: 1));
If date was the 31st of January adding 1 month is ambiguous (28th of February, 1st of March, or exception). The resolutionStrategy would make it clear that the 28th of February is the intended new Date.
NextEndOfMonthAdjuster, on the other hand, could simply move to the next end of the month.

Date.adjust would be implement as:
Date adjust(DateAdjuster adjuster) {
  int inDays = adjuster.durationInDaysAt(this);
  return new Date(this.year, this.month, this.day + inDays, this.hour, this....);
}

I hope this summary clarifies Dart's Date strategy and thanks for reading so far,
// florian
Reply all
Reply to author
Forward
0 new messages