/// <inheritdoc /> [NotNull] public DateTimeZone ForId([NotNull] string id) { if (!CanonicalIdMap.TryGetValue(Preconditions.CheckNotNull(id, nameof(id)), out string canonicalId)) { throw new ArgumentException("Time zone with ID " + id + " not found in source " + version, nameof(id)); } return(source.CreateZone(id, canonicalId)); }
/// <summary> /// Validates that the data within this source is consistent with itself. /// </summary> /// <remarks> /// Source data is not validated automatically when it's loaded, but any source /// loaded from data produced by <c>NodaTime.TzdbCompiler</c> (including the data shipped with Noda Time) /// will already have been validated via this method when it was originally produced. This method should /// only normally be called explicitly if you have data from a source you're unsure of. /// </remarks> /// <exception cref="InvalidNodaDataException">The source data is invalid. The source may not function /// correctly.</exception> public void Validate() { // Check that each entry has a canonical value. (Every mapping x to y // should be such that y maps to itself.) foreach (var entry in this.CanonicalIdMap) { string canonical; if (!CanonicalIdMap.TryGetValue(entry.Value, out canonical)) { throw new InvalidNodaDataException( "Mapping for entry {entry.Key} ({entry.Value}) is missing"); } if (entry.Value != canonical) { throw new InvalidNodaDataException( "Mapping for entry {entry.Key} ({entry.Value}) is not canonical ({entry.Value} maps to {canonical}"); } } // Check that every Windows mapping has a primary territory foreach (var mapZone in source.WindowsMapping.MapZones) { // Simplest way of checking is to find the primary mapping... if (!source.WindowsMapping.PrimaryMapping.ContainsKey(mapZone.WindowsId)) { throw new InvalidNodaDataException( $"Windows mapping for standard ID {mapZone.WindowsId} has no primary territory"); } } // Check that each Windows mapping has a known canonical ID. foreach (var mapZone in source.WindowsMapping.MapZones) { foreach (var id in mapZone.TzdbIds) { if (!CanonicalIdMap.ContainsKey(id)) { throw new InvalidNodaDataException( $"Windows mapping uses canonical ID {id} which is missing"); } } } // Check that each additional Windows standard name mapping has a known canonical ID. var additionalMappings = source.WindowsAdditionalStandardNameToIdMapping; if (additionalMappings != null) { foreach (var id in additionalMappings.Values) { if (!CanonicalIdMap.ContainsKey(id)) { throw new InvalidNodaDataException( $"Windows additional standard name mapping uses canonical ID {id} which is missing"); } } } // Check that each zone location has a valid zone ID if (ZoneLocations != null) { foreach (var location in ZoneLocations) { if (!CanonicalIdMap.ContainsKey(location.ZoneId)) { throw new InvalidNodaDataException( $"Zone location {location.CountryName} uses zone ID {location.ZoneId} which is missing"); } } } if (Zone1970Locations != null) { foreach (var location in Zone1970Locations) { if (!CanonicalIdMap.ContainsKey(location.ZoneId)) { throw new InvalidNodaDataException( $"Zone 1970 location {location.Countries[0].Name} uses zone ID {location.ZoneId} which is missing"); } } } }