当种类为Utc时,从datetime UTC转换为datetimeoffset时出错

use*_*595 1 c# timezone datetime datetimeoffset

当类型为Utc时,将UTC中的DateTime转换为DateTimeOffset时出错。origDateTime来自Web服务,因此我无法控制内容或格式。在大多数情况下,它带有Kind = Unspecified(即使在Utc中,即使时间很艰难)也可以正常工作,但是在极少数情况下,Kind = Utc然后转换为DateTimeOffset会引发异常:“ Utc DateTime实例的UTC偏移量必须为0。\ r \ n参数名称:offset“我应如何解决?

        try {

            //cause error !!!!
            DateTime databaseUtcTime = DateTime.Parse("4/2/2016 6:25:20 PM");
            var localTimeTemp = databaseUtcTime.ToLocalTime();
            DateTime origDateTime = localTimeTemp.ToUniversalTime();

            //this is working
            //DateTime origDateTime = DateTime.Parse("4/2/2016 6:25:20 PM");

            string timeZoneName = "Pacific Standard Time";
            TimeZoneInfo localTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
            DateTimeOffset localTime = new DateTimeOffset(origDateTime, localTimeZone.GetUtcOffset(origDateTime));
            return localTime;
        }
        catch (Exception ex) {
            string msg = ex.Message;
            return null;
        }
Run Code Online (Sandbox Code Playgroud)

Mat*_*int 6

一些东西:

  • 如果您确实需要在不调整其值KindDateTime情况下切换的,请使用DateTime.SpecifyKind。它比处理壁虱更干净。但是,我认为您确实不需要这样做。

  • 不要使用ToLocalTimeToUniversalTime。两者都将在转换过程中使用服务器的时区设置。

  • 我不确定您的实际代码是否实际上在解析字符串,因为您表示它来自数据库。如果它来自数据库,则不涉及任何字符串解析。只需执行以下操作:

    DateTime databaseUtcTime = (DateTime) yourDataReader["YourDataField"];
    
    Run Code Online (Sandbox Code Playgroud)
  • 输入后,便可以使用TimeZoneInfo.ConvertTime函数进行转换。您现有的代码无法正确转换时间,只是分配了一个偏移量而没有正确调整时间值。

    既然你想你的输出是一个datetimeoffset,那么最简单的方法是首先你的输入转换datetimedatetimeoffset与零偏移(因为它来自UTC)。

    DateTimeOffset dtoUtc = new DateTimeOffset(databaseUtcTime, TimeSpan.Zero);
    
    Run Code Online (Sandbox Code Playgroud)

    然后,转换非常简单:

    string timeZoneName = "Pacific Standard Time";
    TimeZoneInfo localTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
    DateTimeOffset dtoLocal = TimeZoneInfo.ConvertTime(dtoUtc, localTimeZone);
    
    Run Code Online (Sandbox Code Playgroud)