How should I populate a list of IANA / Olson time zones from Noda Time?
我在应用程序中使用NodaTime,我需要用户从下拉列表中选择他们的时区。 我有以下软要求:
1)该列表仅包含对于真实场所现在和将来合理有效的选择。 应过滤掉历史,模糊和通用时区。
2)列表应首先按UTC偏移量排序,然后按时区名称排序。 这有希望将它们置于对用户有意义的顺序中。
我写了下面的代码,它确实有效,但并不完全是我所追求的。 可能需要调整滤波器,我宁愿让偏移代表基本(非dst)偏移,而不是当前偏移。
建议?建议?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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); |
Noda Time 1.1具有zone.tab数据,因此您现在可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /// <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); } |
替代方法
您可以使用基于地图的时区选择器,而不是提供下拉菜单。
获得标准偏移很容易 -
过滤可能适合您 - 我不想肯定地说。 由于ID并非真正用于显示,因此它当然不是理想的。 理想情况下,您将使用Unicode CLDR"示例"位置,但目前我们在此方面没有任何CLDR集成。