ZonedDateTime.atStartOfDay constructor

ZonedDateTime.atStartOfDay(
  1. LocalDate date,
  2. DateTimeZone zone
)

Returns the earliest valid ZonedDateTime with the given local date.

If midnight exists unambiguously on the given date, it is returned. If the given date has an ambiguous start time (e.g. the clocks go back from 1am to midnight) then the earlier ZonedDateTime is returned. If the given date has no midnight (e.g. the clocks go forward from midnight to 1am) then the earliest valid value is returned; this will be the instant of the transition.

  • date: The local date to map in this time zone.
  • zone: The date time zone to map this local date into.

Returns: The ZonedDateTime representing the earliest time in the given date, in this time zone.

  • SkippedTimeError: The entire day was skipped due to a very large time zone transition. (This is extremely rare.)

Implementation

factory ZonedDateTime.atStartOfDay(LocalDate date, DateTimeZone zone) {
  LocalDateTime midnight = date.atMidnight();
  var mapping = zone.mapLocal(midnight);
  switch (mapping.count) {
    // Midnight doesn't exist. Maybe we just skip to 1am (or whatever), or maybe the whole day is missed.
    case 0:
      var interval = mapping.lateInterval;
      // Safe to use Start, as it can't extend to the start of time.
      var offsetDateTime = IOffsetDateTime.fromInstant(interval.start, interval.wallOffset, date.calendar);
      // It's possible that the entire day is skipped. For example, Samoa skipped December 30th 2011.
      // We know the two values are in the same calendar here, so we just need to check the YearMonthDay.
      if (ILocalDate.yearMonthDay(offsetDateTime.calendarDate) != ILocalDate.yearMonthDay(date)) {
        throw SkippedTimeError(midnight, zone);
      }
      return IZonedDateTime.trusted(offsetDateTime, zone);
    // Unambiguous or occurs twice, we can just use the offset from the earlier interval.
    case 1:
    case 2:
      return IZonedDateTime.trusted(midnight.withOffset(mapping.earlyInterval.wallOffset), zone);
    default:
      throw StateError("This won't happen.");
  }
}