2017-03-09 54 views
0

TL:DR:我有以下的輸入字符串:解析日期和轉換西歐標準時間爲UTC

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作爲輸入實際上是格林威治標準時間+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

爲什麼你把它標記爲JavaScript? – mason

+1

首先選擇一種語言C#或JavaScript。其次我認爲'd'應該是'dd',但我可能是錯的。第三,你的子串長度爲24個字符,有效地返回'Thu Mar 09 2017 18:00:00',所以'DateTime'對象無法知道它應該加1. – TheLethalCoder

+0

結果是'18:00:00'你的意思是'selectedTime'擁有那個值? – TheLethalCoder

回答

0

將您的代碼更改爲此(在添加日期之前添加ToUniversalTime())爲我解決了這個問題。

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

那麼當然你最後可以只用return nextTargetDay;

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); 
+0

謝謝。只是更新了我的代碼,但現在我正在拼命解析 –

+0

@ el_buck0查看更新回答 – TheLethalCoder

+0

謝謝!但我認爲它應該是子字符串(splittedValues [1] .IndexOf(「(」)+ 1).TrimEnd(')')); –

2

使用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以UnspecifiedDateTimeKind存儲它。
  • TimeZoneInfo.ConvertTimeToUtc這裏所用的datetime是Unspecified datetime,就像它在明確指定的時區一樣讀取,並將其轉換爲UTC。
+0

我已經提出了你的答案,因爲我相信它已經到了問題的核心,並提示瞭解決問題的方法。不過,我在答案中已經實現了這個問題所需的代碼。隨意添加到您的答案,如果你想! – TheLethalCoder