Search code examples
c#nodatime

How to add a year to an Instant in NodaTime?


From NodaTime's documentation I understand why there is no AddYear on a ZonedDateTime or an Instant. I need some way to get to 'this time next year' however (all the times I need are stored/used in UTC). So far, what I've come up with is this:

var start = SystemClock.Instance.GetCurrentInstant().InUtc();
var nextyear = start.Date.PlusYears(1).At(start.TimeOfDay).InUtc().ToInstant();

Is that the right way to do this? Which of all the reasons for not having an AddYear on ZonedDateTime might I run into problems with here?


Solution

  • If you're only dealing with UTC, and you're only using the ISO (Gregorian) calendar, then what you've got should be okay, although it can be simplified to:

    var nextYear = SystemClock.Instance.GetCurrentInstant()
       .InUtc()
       .LocalDateTime
       .PlusYears(1)
       .InUtc()
       .ToInstant();
    

    The reason it's okay to do this for UTC is that UTC doesn't have any transitions - you don't need to worry about "one year from this local date/time" being either ambiguous or skipped.

    It's just worth being aware of exactly what you're doing - that you're adding a year to "the current Gregorian date/time in UTC", not adding a year to "the current instant in time", because an instant doesn't have a concept of "a year".