获取给定本地时间作为字符串的日期时间对象,将日期作为 UTC 日期时间和时区区域设置字符串?



我正在使用来自多个来源的数据,我需要整理一个准确的日期时间。

我有:

A) 代表一天中某个时间的string,例如:"下午 4:00">
B) 一个旨在表示纯日期的DateTime对象,通过创建为特定日期的午夜祖鲁时间(偏移量为 00:00)。
C) 代表时区区域设置的string,例如:"美国/Los_Angeles">

如何获得具有正确刻度数的精确DateTime对象,表示该日期 (B) 在该区域设置 (C) 中经历的时间 (A)?

这里有一个使用 NodaTime 的示例,在处理日历、时区、日期和时间时,它比任何框架类都更可靠:

var timeString = "4:00 pm";
var pureDate = new DateTime(2017, 5, 22, 0, 0, 0, DateTimeKind.Utc);
var timezoneString = "America/Los_Angeles";
var localTime = ParseTimeString(timeString);
var localDate = LocalDate.FromDateTime(pureDate);
var localDateTime = localDate.At(localTime);
var zone = DateTimeZoneProviders.Tzdb[timezoneString];
var zonedDateTime = localDateTime.InZoneStrictly(zone);

zonedDateTime里面,你会发现你的完整日期:

"2017-05-22T16:00:00 America/Los_Angeles (-07)"

您可以使用zonedDateTime.ToDateTimeUtc()来获取 UTC 格式的System.DateTime实例。

ParseTimeString使用格式说明符解析时间字符串:

public static LocalTime ParseTimeString(string timeString)
{
var pattern = LocalTimePattern.CreateWithInvariantCulture("h:mm tt");
return pattern.Parse(timeString).Value;
}

使用DateTimeDateTimeOffsetTimeZoneInfo时的注意事项

如果您不想使用 NodaTime,请注意内置类可能存在的陷阱:

  1. Windows 中的TimeZoneInfo使用与 IANA/TZDB 不兼容的不同说明符。如果您在使用前未转换America/Los_Angeles时区字符串,则它将无法正常工作(请参阅 https://stackoverflow.com/tags/timezone/info)
  2. DateTimeOffset(比DateTime更可靠)在创建时仍然会丢失信息。时区数据无法持久保存,您将只有一个与 UTC 有偏移量的日期。
  3. 您需要手动解析自定义时间字符串(可能使用正则表达式)。

以下是我最终在没有NodaTime的情况下解决它的方式:

public static DateTime Combine(DateTime date, string time, string timeZone)
{
TimeZoneInfo tzInfo = TimeZoneInfo.FindSystemTimeZoneById(TimezoneDictionary[timeZone]);
var timeOfDay = DateTime.ParseExact(time, "h:mm tt", null).TimeOfDay;
var combined = date.Add(timeOfDay).Subtract(tzInfo.BaseUtcOffset);
if (tzInfo.IsDaylightSavingTime(combined))
combined = combined.Subtract(TimeSpan.FromHours(1));
return combined;
}

我还需要这本字典将 IANA 时区转换为Microsoft:

private static Dictionary<string, string> TimezoneDictionary = new Dictionary<string, string>
{
{ "America/Los_Angeles", "Pacific Standard Time" },
{ "America/Denver", "Mountain Standard Time" },
{ "America/Chicago", "Central Standard Time" },
{ "America/New_York", "Eastern Standard Time" },
//many more of course, just clipping this list for brevity.
};

相关内容

  • 没有找到相关文章

最新更新