获取DateTime对象给定本地时间为字符串,日期为UTC DateTime和时区区域字符串?

时间:2017-05-22 20:00:54

标签: c# datetime timezone

我正在处理来自多个来源的数据,我需要整理一个准确的DateTime。

我有:

A)表示一天中某个时间的string,例如:“下午4:00” B)用于表示纯日期的DateTime对象,通过创建特定日期的午夜,祖鲁时间(偏移00:00)。 C)表示时区语言环境的string,例如:“America / Los_Angeles”

如何获得一个精确的DateTime对象,其中包含正确的刻度数,表示该区域(C)在该日期(B)所经历的时间(A)?

2 个答案:

答案 0 :(得分:1)

这里有一个使用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,请注意内置类可能存在的缺陷:

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

答案 1 :(得分:0)

以下是我如何用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.
    };