在看到该任务不能与WP7/Silverlight的框架的帮助下archieved后,这将是Noda Time容易多了,我写了一个小帮手这项工作:
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));
}
}
诀窍是要分析它没有的DateTimeStyles.AssumeUniversal标志(这使得TryParseExact
假定日期是UTC和返回日期转换的/调整到地方),respecifying它作为UTC和然后手动将其调整至执行器等同于UTC。
它遵循DST规则,可以找到here。我在夏令时开始/结束之前/之后对所有4种边界案例进行了测试。这再次表明了测试的重要性:我必须将DstStart.CompareTo(result) < 0
中的<
运营商更改为<=
,以使其产生正确的结果。
我有这样的感觉,我在这里重新发明轮子(我讨厌这么做),但不想为这个简单的工作使用专用的库。我看了Noda Time这个很棒的项目,但我认为它不是必需的。
我希望我能用这个小帮手救一个人一点时间。对于所有时区而言,它并不是通用的(如果您需要使用像Noda Time这样的库),但是对于这些只有一个固定时区的情况,就像我的情况一样。
[在c#fx 3.5的特定时区中创建日期时间]的可能重复(http://stackoverflow.com/questions/246498/creating-a-datetime-in-a-specific-time-zone-in -c-fx-3-5) –
@迈克尔哈伦:不,它不是重复的。在我问这个问题之前,我看了一下,并没有帮助解决我的具体问题。 –
可能不是重复的,但我认为它会有帮助 –