NodaTime Errors after time switch

Yesterday Uruguay changed their clocks, and now I keep seeing exceptions when converting specific times for their timezone:

ERROR   Exception: - DateTime ConvertTimeToUtc(DateTime, String)    (05/10/2014 02:31:00, America/Montevideo)
NodaTime.SkippedTimeException: Specified argument was out of the range of valid values.
Parameter name: Local time 05/10/2014 02:31:00 is invalid in time zone America/Montevideo

I understand how a local time can be invalid:

"For example, suppose the time zone goes forward at 2am, so the second after 01:59:59 becomes 03:00:00. In that case, local times such as 02:30:00 never occur."

However, what I don't understand (and I probably need more coffee), is why NodaTime is not accounting for this? Should it not be aware that 02:31 is now an invalid local time - or should I be doing additional handling to account for this?

Functions I'm calling:

var timeZone = DateTimeZoneProviders.Tzdb[timezoneName];
var localTime = LocalDateTime.FromDateTime(timeToConvert).InZoneStrictly(timeZone);;
return DateTime.SpecifyKind(localTime.ToDateTimeUtc(), DateTimeKind.Utc);  
Jon Skeet
people
quotationmark

Yes, it is aware that it's an invalid local time - which is why when you specifically ask it to convert that local time into UTC, it throws an exception. It's roughly equivalent to calling Math.sqrt(-1).

The InZoneStrictly call you're making specifically throws an exception on either ambiguous or skipped times. If you use InZoneLeniently you won't get an exception, but it may not give you the result you want. Or, you could use LocalDateTime.InZone(DateTimeZone, ZoneLocalMappingResolver) which will allow you to map invalid local date/time values however you want.

As side-notes:

  • Your localTime variable is a ZonedDateTime, so the name is a bit misleading
  • You don't need to call SpecifyKind - ToDateTimeUtc will always return a DateTime with a kind of Utc, hence the name.

people

See more on this question at Stackoverflow