解析日期并将W.欧洲标准时间转换为UTC

时间:2017-03-09 15:02:13

标签: c# datetime

TL:DR :我有以下输入字符串:

Thu Mar 09 2017 18:00:00 GMT+0100

我正在尝试使用以下格式将其转换为DateTime对象:

"ddd MMM dd yyyy HH:mm:ss"

这显然不起作用,因为我忽略了GMT+0100部分。我怎么能包括这个?

我没有设法解析并将以下输入转换为正确的UTC DateTime对象:

输入字符串 selectedDate

1,Thu Mar 09 2017 18:00:00 GMT+0100 (W. Europe Standard Time)

功能:

var splittedValues = selectedDate.Split(',');

var selectDayOfWeek = (DayOfWeek)int.Parse(splittedValues[0]);

var selectedTime = DateTime.ParseExact(splittedValues[1].Substring(0, 24),
    "ddd MMM d yyyy HH:mm:ss",
    CultureInfo.InvariantCulture);

DateTime today = new DateTime(DateTime.Today.Ticks, DateTimeKind.Unspecified);

// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
int daysUntilNextTargetDay = ((int)selectDayOfWeek - (int)today.DayOfWeek + 7) % 7;

DateTime nextTargetDay = today.AddDays(daysUntilNextTargetDay).AddHours(selectedTime.Hour).AddMinutes(selectedTime.Minute);

return nextTargetDay.ToUniversalTime();

结果时间部分始终为18:00:00 应为17:00,因为输入实际上是GMT +01

这里的问题是什么?

更新: 正如其他人指出存在错误所以我将代码更新为:

var splittedValues = selectedDate.Split(',');

var selectDayOfWeek = (DayOfWeek)int.Parse(splittedValues[0]);

var selectedTime = DateTime.ParseExact(splittedValues[1].Substring(0, 33),
                "ddd MMM dd yyyy HH:mm:ss",
                CultureInfo.InvariantCulture).ToUniversalTime();

// The (... + 7) % 7 ensures we end up with a value in the range [0, 6]
int daysUntilNextTargetDay = ((int)selectDayOfWeek - (int)DateTime.Today.DayOfWeek + 7) % 7;

DateTime nextTargetDay = DateTime.Today.AddDays(daysUntilNextTargetDay).AddHours(selectedTime.Hour).AddMinutes(selectedTime.Minute);

return nextTargetDay;

但现在解析失败,因为子字符串与"ddd MMM dd yyyy HH:mm:ss"不匹配 如何将GMT + 0100包含在这里?

3 个答案:

答案 0 :(得分:1)

在特定时区之间转换时使用TimeZoneInfo

TimeZoneInfo westInfo =
    TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");

DateTime westTime = DateTime.Parse("2012.12.04T08:35:00");
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(westTime, westInfo);

解决您的困惑:

  • 此处使用的DateTime.Parse不对给定值的时区进行假设。 IT使用DateTimeKind Unspecified
  • 存储它 此处使用的
  • TimeZoneInfo.ConvertTimeToUtc需要Unspecified日期时间,将其读取为显式指定的时区,并将其转换为UTC。

答案 1 :(得分:0)

将代码更改为此(在添加日期之前添加ToUniversalTime())为我修复了它。

 DateTime nextTargetDay = today.ToUniversalTime().AddDays(daysUntilNextTargetDay).AddHours(selectedTime.Hour).AddMinutes(selectedTime.Minute);

当然,你最后可以return nextTargetDay;

答案 2 :(得分:0)

调查MSDN我可以发现代码的初始问题。这是因为您使用d dd,因为09不是9

  
      
  • d:该月的某一天,从1到31。
  •   
  • dd:该月的某一天,从01到31。
  •   

其次,+1被“忽略”的原因是你在子串中排除它,即

splittedValues[1].Substring(0, 24) == "Thu Mar 09 2017 18:00:00";

所以基本上你需要用正确的格式说明符包含字符串的那一部分(我不确定哪一个)。或者自己询问并根据需要减去一小时的结果。

旁注:以下代码很奇怪(在我看来,可能有原因):

DateTime today = new DateTime(DateTime.Today.Ticks, DateTimeKind.Unspecified);

您可以使用DateTime.TodayDateTime.Now.Date

正如answer by @calypso中所提到的,您可以使用TimeZoneInfo class.他们的回答是关于如何使用它的一般方法。但是对于您可以做的特定示例(代码未经测试但看起来应该有效):

var selectedTime = DateTime.ParseExact(splittedValues[1].Substring(0, 24), "ddd MMM dd yyyy HH:mm:ss", CultureInfo.InvariantCulture);
TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(splittedValues[1].Substring(splittedValues[1].IndexOf("(") + 1).TrimEnd(")"));
DateTime utcTime = TimeZoneInfo.ConvertTimeToUtc(selectedTime, timeZoneInfo);