1

Let's say I have the date 2014-11-2T00:00:00-0600 then I want to add 1 day, and have 2014-11-3T00:00:00-0700 .

Now if I do :

crtDay.Plus(Duration.FromStandardDays(1));

crtDay is a ZonedDateTime object

I end up with : 2014-11-2T23:00:00-0700 .

How do I move to the next day? (I could add hours until I moved to the next day, but it feels like there has to be a better way.)

Thanks.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
sirrocco
  • 7,975
  • 4
  • 59
  • 81

1 Answers1

2

(I'll assume from the values you gave that you are working in the US Mountain time zone.)

A "standard day" is 24 hours. However, on the day you mentioned, there are 25 hours in the calendar day, because the hour from 01:00 to 02:00 is repeated for the daylight saving time fall-back transition. Thus, you end up on the same day if you only add 24 hours.

In Noda Time, the ZonedDateTime structure is meant to represent a specific moment in time, with respect to a time zone. Thus, you can only move by linear instantaneous time, using Duration.

To move by calendar time, you'll have to take it's LocalDateTime and add a Period to it. If desired, you can then create a new ZonedDateTime from the result.

ZonedDateTime nextDay = zdt.LocalDateTime.PlusDays(1).InZoneLeniently(zdt.Zone);

Here I use InZoneLeniently for convenience. However, you should understand the behavior of that particular resolver. A different resolver (or a custom one) might be more appropriate, depending on your needs.

Say for example that you were starting at 1:30 on that day instead. The lenient resolver will assume you wanted to choose the latter of the two occurrences. Essentially you would be adding 25 hours even though 24 hours would still yield the same clock time. Perhaps your users might expect you to land on the first occurrence.

Also consider the spring-forward transition, where if you started at 2:30 then you'd land on date/time that doesn't exist. The lenient resolver will advance to the next valid clock time for the time zone - which might be acceptable, but it would have a different clock time of 2:00. Your users might expect you'd advance by a whole hour instead of just the next valid clock time.

The built-in resolvers are being reconsidered for Noda Time v2. See issue 295, and this alternate implementation.

Community
  • 1
  • 1
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • 1
    Note that since Node Time 2.0, InZoneLeniently() has changed (returns earlier time instead of latter, and shifts by 1 hour instead of shifting to the next valid time). Reference: https://github.com/nodatime/nodatime/pull/365 – Matt Dec 06 '18 at 21:17