我正在处理来自多个来源的数据,我需要整理一个准确的DateTime。
我有:
A)表示一天中某个时间的string
,例如:“下午4:00”
B)用于表示纯日期的DateTime
对象,通过创建特定日期的午夜,祖鲁时间(偏移00:00)。
C)表示时区语言环境的string
,例如:“America / Los_Angeles”
如何获得一个精确的DateTime
对象,其中包含正确的刻度数,表示该区域(C)在该日期(B)所经历的时间(A)?
答案 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;
}
DateTime
,DateTimeOffset
和TimeZoneInfo
如果您不想使用NodaTime,请注意内置类可能存在的缺陷:
TimeZoneInfo
使用与IANA / TZDB不兼容的其他说明符。如果您在使用前未进行转换,则America/Los_Angeles
时区字符串将无效(请参阅https://stackoverflow.com/tags/timezone/info)DateTimeOffset
(比DateTime
更可靠)在创建时仍会丢失信息。时区数据无法保留,您只有一个与UTC偏移的日期。答案 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.
};