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包含在这里?
答案 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);
解决您的困惑:
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.Today
或DateTime.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);