我应该如何填写野田时间的IANA / Olson时区列表?
我在应用程序中使用NodaTime,我需要用户从下拉列表中select他们的时区。 我有以下软要求:
1)名单只包含真实场所的现在和将来合理有效的select。 应该过滤掉历史的,模糊的和通用的时区。
2)该列表应先按UTC偏移量sorting,然后按时区名称sorting。 这有希望使他们对用户有意义的顺序。
我已经写了下面的代码,这确实有效,但并不完全是我所追求的。 filter可能需要调整,我宁愿让偏移量代表基础(非dst)的偏移量,而不是当前的偏移量。
build议? build议?
var now = Instant.FromDateTimeUtc(DateTime.UtcNow); var tzdb = DateTimeZoneProviders.Tzdb; var list = from id in tzdb.Ids where id.Contains("/") && !id.StartsWith("etc", StringComparison.OrdinalIgnoreCase) let tz = tzdb[id] let offset = tz.GetOffsetFromUtc(now) orderby offset, id select new { Id = id, DisplayValue = string.Format("({0}) {1}", offset.ToString("+HH:mm", null), id) }; // ultimately we build a dropdown list, but for demo purposes you can just dump the results foreach (var item in list) Console.WriteLine(item.DisplayValue);
野田时间1.1有zone.tab数据 ,所以你现在可以做到以下几点:
/// <summary> /// Returns a list of valid timezones as a dictionary, where the key is /// the timezone id, and the value can be used for display. /// </summary> /// <param name="countryCode"> /// The two-letter country code to get timezones for. /// Returns all timezones if null or empty. /// </param> public IDictionary<string, string> GetTimeZones(string countryCode) { var now = SystemClock.Instance.Now; var tzdb = DateTimeZoneProviders.Tzdb; var list = from location in TzdbDateTimeZoneSource.Default.ZoneLocations where string.IsNullOrEmpty(countryCode) || location.CountryCode.Equals(countryCode, StringComparison.OrdinalIgnoreCase) let zoneId = location.ZoneId let tz = tzdb[zoneId] let offset = tz.GetZoneInterval(now).StandardOffset orderby offset, zoneId select new { Id = zoneId, DisplayValue = string.Format("({0:+HH:mm}) {1}", offset, zoneId) }; return list.ToDictionary(x => x.Id, x => x.DisplayValue); }
替代方法
根本不提供下拉菜单,您可以使用基于地图的时区select器 。
获得标准偏移很容易 – tz.GetZoneInterval(now).StandardOffset
。 这会给你“当前”的标准偏移量(一个区域可能随着时间而改变)。
过滤可能适合你 – 我不想肯定地说。 这些ID并不是真正为显示而devise的,这当然是不理想的 。 理想情况下,您可以使用Unicode CLDR“示例”位置,但目前我们还没有任何CLDR集成。