dateTime.add(new Duration(days:1)) on 27th October UTC+2:00 produces 2013-10-27 23:00:00.000

1,059 views
Skip to first unread message

tomaszkubacki

unread,
Oct 29, 2013, 12:59:01 PM10/29/13
to mi...@dartlang.org
hi,

Assuming we have:

DateTime dt = new DateTime(2013,10,27); //UTC+2:00 Warsaw timezone
print(dt.add(new Duration(days:1))); 

It prints:
2013-10-27 23:00:00.000

I'm aware it's summer->winter time change related, but is it expected behavior ?

cheers,
Tomek



tomaszkubacki

unread,
Oct 29, 2013, 1:50:43 PM10/29/13
to mi...@dartlang.org
To make it a bit more clear:

DateTime dt = new DateTime(2013,10,27,0,0,0);
  print(dt.timeZoneOffset);
  print(dt);
  
  DateTime dt1 = dt.add(new Duration(hours: 24));
  
  print(dt1.timeZoneOffset);
  print(dt1);

results in:

2:00:00.000000
2013-10-27 00:00:00.000
1:00:00.000000
2013-10-27 23:00:00.000


Florian Loitsch

unread,
Oct 29, 2013, 2:26:48 PM10/29/13
to General Dart Discussion
Unless I miss something this looks like expected behavior: two dates and 24 hours between them.



--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
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

Lasse R.H. Nielsen

unread,
Oct 30, 2013, 3:10:20 AM10/30/13
to mi...@dartlang.org
The problem is that one day isn't necessarily 24 hours, which is what made the result unexpected: Adding "one day" (new Duration(day: 1)) to a DataTime did not increase the day (DateTime.day) by one. 

But yes, it is expected behavior. You can think of DateTime as keeping a single time in UTC, and adding one day to that give the UTC time 24 hours later. The two date-times are then printed as "local" time in two different time zones (one normal, one in daylight savings time).

We should document that Duration just treats "day" as a shorthand for 24 hours.

/L 'Leap seconds, making no simple system ever correct since 1972-06-30T23:59:60'.
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

Vadim Tsushko

unread,
Sep 3, 2014, 10:41:15 AM9/3/14
to mi...@dartlang.org
I've stumbled upon that behaviour just now and wonder what is recommended way to deal with it.
For example - I need to read simple date from external source (date without time part), increment it in the loop up to some other date (simple date without time) and say print date if it is last day of the month or last date in the whole interval.
Task looks simple enough but naive `currentDate = currentDate.add(new Duration(days:1))` give very unexpected results. Even if behaviour is expected.
I've added ad-hoq function 

    DateTime incrementDate(DateTime val) {
      DateTime res = val.add(new Duration(days:1));
      if (res.hour == 1) {
        res = new DateTime(res.year,res.month,res.day);
      } else if (res.hour == 23) {
        res = new DateTime(res.year,res.month,res.day + 1);
      }
      return res;    
    }

It `kind of` works, but looks extremely ugly. Maybe there is better way?
Actually I believe it would be nice to have separate `Date` class in the core. So for simple date tasks we would be free from all that complicated stuff with timezones.   
   


Vadim Tsushko

unread,
Sep 3, 2014, 10:49:37 AM9/3/14
to mi...@dartlang.org
Well, and looking at that `incrementDate` function I see now that it will give wrong result if timezone would shift at wrong direction by last day of month. Silly me.
But really - that should be easier. Python have both date and datetime...



Alan Knight

unread,
Sep 3, 2014, 1:35:08 PM9/3/14
to General Dart Discussion
I agree that there are times when it's much nicer to have a separate Date or Time object.

For your case, I think it would work reasonably if you create your Dates in UTC, so daylight savings time should never be an issue. e.g.
   new DateTime.utc(2013, 10, 27);
It might be a good idea to create your own Date class that wrapped that, just to make sure that you didn't accidentally get a non-UTC date.



On Wed, Sep 3, 2014 at 7:49 AM, Vadim Tsushko <vadimt...@gmail.com> wrote:
Well, and looking at that `incrementDate` function I see now that it will give wrong result if timezone would shift at wrong direction by last day of month. Silly me.
But really - that should be easier. Python have both date and datetime...



Vadim Tsushko

unread,
Sep 3, 2014, 2:18:46 PM9/3/14
to mi...@dartlang.org
Hi, Alan.

I have briefly tried to use utc datetimes but apparently it did not help me in my scenario. As I wrote I get my lower and upper bounds from external source as strings representing dates. So I can not simply use named utc constructor. I create date by static method fromString. I do not see how to command Datetime to create utc date from string. But if I convert value after creation by toUtc method I apparently get same behaviour.

Alan Knight

unread,
Sep 3, 2014, 3:21:16 PM9/3/14
to General Dart Discussion
You could probably do something like this to parse it.

parseIntoUtc(String s) {
  var basic = DateTime.parse(s);
  var utcDate = new DateTime.utc(basic.year, basic.month, basic.day);
  return utcDate;
}

But I'm confused by you saying that you get the same behavior. It seemed like your problem was related to adding 1 day being treated as the same as adding 24 hours, but if you crossed a boundary between daylight savings or equivalent, that that wasn't true. But daylight savings doesn't occur in UTC. So it would have to be a different problem, or else your original problem must be something different.


So, using the US data, where the time zone changes Nov 3, if I write 

main() { var d = new DateTime(2013, 11, 3); var e = d.add(new Duration(days:1)); print(d); print(e); }

I get

2013-11-03 00:00:00.000
2013-11-03 23:00:00.000

but if I change it to be 
var d = new DateTime.utc(2013, 11, 3);
then I get

2013-11-03 00:00:00.000Z 
2013-11-04 00:00:00.000Z

Note the Z at the end of the DateTime, indicating it is in UTC.



On Wed, Sep 3, 2014 at 11:18 AM, Vadim Tsushko <vadimt...@gmail.com> wrote:
Hi, Alan.

I have briefly tried to use utc datetimes but apparently it did not help me in my scenario. As I wrote I get my lower and upper bounds from external source as strings representing dates. So I can not simply use named utc constructor. I create date by static method fromString. I do not see how to command Datetime to create utc date from string. But if I convert value after creation by toUtc method I apparently get same behaviour.

Vadim Tsushko

unread,
Sep 3, 2014, 3:42:55 PM9/3/14
to mi...@dartlang.org
I write from tablet now so I did not express myself clearly.
I was doing something like

Datetime mydate = DateTime.parse(dateStr).toUtc();

It was not working and apparently should not work. Thank you for help, I will use your advice.

Vadim Tsushko

unread,
Sep 4, 2014, 1:18:15 AM9/4/14
to mi...@dartlang.org
Alan, just for update: I've tried your function and it works fine for me.
Looks pretty obvious now.
So I got rid of my ugly and buggy hack.

Thank you again. 
Reply all
Reply to author
Forward
0 new messages