Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用已知但未给定的时区分析DateTime_C#_Parsing_Datetime_Windows Phone 7_Timezone - Fatal编程技术网

C# 使用已知但未给定的时区分析DateTime

C# 使用已知但未给定的时区分析DateTime,c#,parsing,datetime,windows-phone-7,timezone,C#,Parsing,Datetime,Windows Phone 7,Timezone,我遇到了解析日期和时间的问题: 我正在尝试解析从德国网站提取的日期时间字符串。其格式为“日.月.年24小时:分钟”,如: 01.01.2011 17:00 而且总是在德国时区。但问题来了: 应将“01.01.2011 17:00”解析为一个日期时间结构,其UTC格式为“01.01.2011 16:00”(此处,时区为CET,,不含夏令时) 而'01.06.2011 17:00'应解析为UTC格式的'01.01.2011 15:00'的DateTime结构(此处,时区为CEST,带夏令时)

我遇到了解析日期和时间的问题:

我正在尝试解析从德国网站提取的日期时间字符串。其格式为“日.月.年24小时:分钟”,如:

01.01.2011 17:00
而且总是在德国时区。但问题来了:

  • 应将“01.01.2011 17:00”解析为一个日期时间结构,其UTC格式为“01.01.2011 16:00”(此处,时区为CET,,不含夏令时)
  • 而'01.06.2011 17:00'应解析为UTC格式的'01.01.2011 15:00'的DateTime结构(此处,时区为CEST,夏令时)
我不知道如何做到这一点。如果我将本地时钟设置为德国时区,并使用
DateTime.ParseExact
和标志
DateTimeStyles.AssumeLocal
DateTimeStyles.AdjustToUniversal
进行解析,则解析正确。但是,我希望任何客户端都能独立于本地时钟和时区来解析它。另外,我不想自己做时区偏移,因为它取决于日期(夏季:-2/冬季:-1)


一旦我有了UTC的datetime,就可以很容易地将其转换为任何本地时区。

听起来你知道应该用哪个时区来解析它。假设.NET 3.5(因此
TimeZoneInfo
),您在逻辑上应该:

  • 将其解析为“本地”时间(不特定于时区)
  • 将当地时间转换为UTC时间
不幸的是。编辑:我以为你想用
DateTimeStyles.AssumeUniversal
转换并解析它,但这最终会返回一个本地
DateTime
,令人烦恼。基本上,您希望在适当的时间结束一个
DateTime
,以便您可以使用:

parsed = DateTime.SpecifyKind(parsed, DateTimeKind.Unspecified);
然后,您可以通过以下方式获得UTC值:

DateTime utc = TimeZoneInfo.ConvertTimeToUtc(parsed, germanTimeZone);
请注意,您确实首先需要一个“未指定”的日期时间,以便可以在任意时区将其转换为UTC。您还应该记住,由于DST更改,本地时间可能不明确(发生两次)或不可能(根本不发生)


是的,当它完成后,这将更容易:)

在看到任务无法在WP7/Silverlight框架的帮助下归档后,我编写了一个小助手来完成这项工作:

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));
    }
}
公共静态类DateTimeHelper
{
/// 
///尝试分析未使用时区注释的给定日期时间字符串
///信息,但已知位于CET/CEST区域,并返回DateTime结构
///UTC(因此可以转换为设备本地时间)。如果无法
///解析后,结果包含当前UTC日期/时间。
/// 
公共静态bool tryparsecetest(字符串s、字符串格式、IFormatProvider提供程序、DateTimeStyles样式、out DateTime结果)
{
//解析datetime,知道它在CET/CEST时区。解析的通用性取决于我们之后对它的修复
if(!DateTime.TryParseExact(s、格式、提供程序、样式、输出结果))
{
结果=DateTime.UtcNow;
返回false;
}
结果=DateTime.SpecifyKind(结果,DateTimeKind.Utc);
//以CET和CEST为单位的夏时制时间段的边界(不是UTC!)
//两个DateTime结构都属于“Utc”类型,以便能够将它们与解析结果进行比较
DateTime DstStart=LastSundayOf(result.Year,3)。AddHours(2);
DateTime DstEnd=LastSundayOf(result.Year,10)。AddHours(3);
//我们是否在夏令时内?

如果(DstStart.CompareTo)(结果)@Michael Haren的可能重复项:不,不是重复项。在我问这个问题之前,我看了一下,它对我的具体问题没有帮助。可能不是重复项,但我认为它会有帮助+1太好了,
ConvertTimeToUtc
不知何故是缺少的部分。不过,我还有最后一个问题:我从哪里得到
细菌anTimeZone
from?@Philip:您计算出适当的时区ID,然后使用时区信息。FindSystemTimeZoneById
。我想您想要的是“W.Europe标准时间”(忽略它被称为标准时间的事实;这只是ID-它仍然可以处理夏令时)。我可能应该提到我正在构建一个windows phone 7应用程序,
TimeZoneInfo
只有
ConvertTime
方法和时区
Utc
Local
。@Philip:Ah.是的,你应该提到这一点。所以你不能得到除本地时区以外的任何时区?恩。Noda time不是真的y产品已经准备好了,但是如果你想试试看它是否对你有帮助,我很乐意提供帮助。我们还没有进行
LocalDateTime
解析,但是你可以在.NET中进行解析,然后进行转换……感谢你的帮助。如果没有我以前不知道的
SpecifyKind
,我会浪费更多的时间:).我写了一个小助手(贴在这里作为答案)这就是诀窍。野田佳彦时间看起来很棒,但我不想为这样一个简单的工作包含整个库。我很惊讶你没有使用AssumeUniversal-我本来希望它已经返回UTC日期时间;如果不是这样的话,我为在这方面误导你道歉。日期时间让我恼火:(@Jon:老实说,我的想法完全一样,我想知道为什么它会产生如此奇怪的结果。直到我意识到它做了正确的事情,但与您可能期望的不同:如果让它解析“17:00”,它假设UTC时间为下午5点,但在我的情况下返回一个DateTime结构,即下午7点(种类=本地)(本地时区=德语)。如果您在此调用
SpecifyKind(..,Utc)
,它将返回一个晚上7点的Utc结构…是的:DateTime确实很烦人:)奇怪。啊,谢谢您让我知道。将在这方面编辑我的答案。只需说明为什么能够解析为不同类型很重要:)