Sau khi thấy rằng nhiệm vụ không thể archieved với sự giúp đỡ của các khuôn khổ/Silverlight WP7, tôi đã viết một helper nhỏ không công việc:
public static class DateTimeHelper
{
/// <summary>
/// Tries to parse the given datetime string that is not annotated with a timezone
/// information but known to be in the CET/CEST zone and returns a DateTime struct
/// in UTC (so it can be converted to the devices local time). If it could not be
/// parsed, result contains the current date/time in UTC.
/// </summary>
public static bool TryParseCetCest(string s, string format, IFormatProvider provider, DateTimeStyles style, out DateTime result)
{
// Parse datetime, knowing it is in CET/CEST timezone. Parse as universal as we fix it afterwards
if (!DateTime.TryParseExact(s, format, provider, style, out result))
{
result = DateTime.UtcNow;
return false;
}
result = DateTime.SpecifyKind(result, DateTimeKind.Utc);
// The boundaries of the daylight saving time period in CET and CEST (_not_ in UTC!)
// Both DateTime structs are of kind 'Utc', to be able to compare them with the parsing result
DateTime DstStart = LastSundayOf(result.Year, 3).AddHours(2);
DateTime DstEnd = LastSundayOf(result.Year, 10).AddHours(3);
// Are we inside the daylight saving time period?
if (DstStart.CompareTo(result) <= 0 && result.CompareTo(DstEnd) < 0)
result = result.AddHours(-2); // CEST = UTC+2h
else
result = result.AddHours(-1); // CET = UTC+1h
return true;
}
/// <summary>
/// Returns the last sunday of the given month and year in UTC
/// </summary>
private static DateTime LastSundayOf(int year, int month)
{
DateTime firstOfNextMonth = new DateTime(year, month + 1, 1, 0, 0, 0, DateTimeKind.Utc);
return firstOfNextMonth.AddDays(firstOfNextMonth.DayOfWeek == DayOfWeek.Sunday ? -7 :
(-1 * (int)firstOfNextMonth.DayOfWeek));
}
}
Bí quyết là để phân tích nó mà không cờ DateTimeStyles.AssumeUniversal (điều này làm cho TryParseExact
giả ngày là UTC và trở về ngày quy đổi/điều chỉnh cục bộ), respecifying nó như là UTC và sau đó điều chỉnh thủ công nó thành actu al UTC tương đương.
Nó tuân thủ các quy tắc DST có thể được tìm thấy here. Tôi đã thử nghiệm nó với tất cả 4 trường hợp ranh giới ngay trước/sau khi bắt đầu/kết thúc thời gian tiết kiệm ánh sáng ban ngày. Điều đó cho thấy một lần nữa tầm quan trọng của thử nghiệm: Tôi đã phải thay đổi các nhà điều hành <
trong DstStart.CompareTo(result) < 0
để <=
để làm cho nó tạo ra kết quả chính xác.
Tôi có cảm giác rằng tôi đang phát minh lại bánh xe ở đây (mà tôi ghét phải làm), nhưng không muốn sử dụng một thư viện dành riêng cho công việc đơn giản này. Tôi đã có một cái nhìn tại Noda Thời gian đó là một dự án tuyệt vời, nhưng tôi nghĩ rằng nó không cần thiết cho việc này.
Tôi hy vọng tôi có thể tiết kiệm một chút thời gian với người trợ giúp nhỏ này. Nó là cố ý không chung chung cho tất cả các múi giờ (nếu bạn cần sử dụng một lib như Noda Thời gian thay vào đó), nhưng đối với những trường hợp mà bạn chỉ có một múi giờ cố định duy nhất, như trong trường hợp của tôi.
bản sao có thể có của [Tạo một ngày giờ trong một Múi giờ cụ thể trong C# fx 3.5] (http://stackoverflow.com/questions/246498/creating-a-datetime-in-a-specific-time-zone-in -c-fx-3-5) –
@ Michael Haren: Không, nó không phải là bản sao. Tôi đã xem xét điều này trước khi tôi hỏi câu hỏi này và nó đã không giúp với vấn đề cụ thể của tôi. –
không phải là một bản sao có lẽ nhưng tôi figured nó muốn được hữu ích –