Web方法中的默认ASP.NET DateTime.Kind到UTC

时间:2014-05-21 16:37:30

标签: c# asp.net

我将以下ISO 8601日期字符串传递给ASP.NET Web方法:

  

2013-04-01T00:00:00.000Z

这会自动创建一个具有以下属性的日期对象:

Value: 3/31/2013 8:00:00 PM
Kind:  Local (EDT)

这很烦人,因为我现在必须记住通过执行以下操作将所有日期对象转换为UTC:

date = date.ToUniversalTime();

如何更改asp.net以使传递给Web方法的日期默认为UTC而不是服务器的本地时间?是否有一些配置或挂钩可用于实现此目的?或者这可能是不可能的?

我根本不想打扰处理服务器的本地时间,因为它完全无关紧要。


修改

添加更多信息,因为我似乎没有在上面明确解释过自己。这是一些示例代码。

JavaScript的:

PageMethods.SendData("2013-04-01T00:00:00.000Z");

C#:

[WebMethod]
static public void SendData(DateTime date)
{
    // The value of date in here is 3/31/2013 8:00:00 PM Local
    // How can I make it so the default is 04/01/2014 0:00:00 AM Utc
    // without typing any extra code in here? 
    // How can I change ASP.NET's default behaviour?
    // I don't want to rely on the developer remembering.
}

3 个答案:

答案 0 :(得分:1)

请参阅DateTimeOffset浏览器可能位于不同的时区。如果您确定这是正确的,那么您应该记住在向服务器发送日期时默认使用LocalTimeZone,因此转换会改变时间。您可能必须使用SpecifyKind方法。

我相信如果你在字符串中指定时区,你可以让ASP.Net拿起它...

如果不使用新的解析器并将其注册为默认值,或者使用偏移量创建新类型。

答案 1 :(得分:0)

使用DateTime.ParseExact()

尝试这样的事情
    public static DateTime ParseAsZuluTime( string iso8601ZuluTime )
    {
      const DateTimeStyles style = DateTimeStyles.AssumeUniversal
                                 | DateTimeStyles.AdjustToUniversal
                                 ;
      DateTime value = DateTime.ParseExact( iso8601ZuluTime , formats , CultureInfo.InvariantCulture , style ) ;
      return value ;
    }
    static readonly string[] formats = {
      "yyyy-MM-ddTHH:mm:ss.fffK" , // K accepts
      "yyyy-MM-ddTHH:mm:ss.ffK"  , // the 'Z' suffix
      "yyyy-MM-ddTHH:mm:ss.fK"   , // or no suffix
      "yyyy-MM-ddTHH:mm:ssK"     ,
      "yyyy-MM-ddTHH:mm:ssK"     ,
      } ;

如果您希望处理+00+0000+00:00等UTC指示符,则需要使用({分别)z, zz and zzz custom format specifiers扩展格式列表。

鉴于此,此代码

static void Main( string[] args )
{
  string[] texts         = { "2014-05-23T17:45:32.123" ,
                             "2014-05-23T17:45:32.12"  ,
                             "2014-05-23T17:45:32.1"   ,
                             "2014-05-23T17:45:32"     ,
                             "2014-05-23T17:45"        ,
                           } ;
  string[] utcDesignators = { ""  ,
                              "Z"
                            } ;

  foreach ( string timeString in texts )
  {

    foreach ( string utc in utcDesignators )
    {
      string   timestamp = timeString+utc ;
      DateTime parsed    = ParseAsZuluTime(timestamp) ;

      Console.WriteLine() ;
      Console.WriteLine( "Text:     {0}" , timestamp  ) ;
      Console.WriteLine( "DateTime: {0:yyyy-MM-ddThh:mm:ss.fff}, Kind: {1}" , parsed , parsed.Kind ) ;

    }
  }
  Console.WriteLine() ;

  return;
}

产生以下结果:

Text:     2014-05-23T17:45:32.123
DateTime: 2014-05-23T05:45:32.123, Kind: Utc

Text:     2014-05-23T17:45:32.123Z
DateTime: 2014-05-23T05:45:32.123, Kind: Utc

Text:     2014-05-23T17:45:32.12
DateTime: 2014-05-23T05:45:32.120, Kind: Utc

Text:     2014-05-23T17:45:32.12Z
DateTime: 2014-05-23T05:45:32.120, Kind: Utc

Text:     2014-05-23T17:45:32.1
DateTime: 2014-05-23T05:45:32.100, Kind: Utc

Text:     2014-05-23T17:45:32.1Z
DateTime: 2014-05-23T05:45:32.100, Kind: Utc

Text:     2014-05-23T17:45:32
DateTime: 2014-05-23T05:45:32.000, Kind: Utc

Text:     2014-05-23T17:45:32Z
DateTime: 2014-05-23T05:45:32.000, Kind: Utc

Text:     2014-05-23T17:45
DateTime: 2014-05-23T05:45:00.000, Kind: Utc

Text:     2014-05-23T17:45Z
DateTime: 2014-05-23T05:45:00.000, Kind: Utc

编辑注意:这是一个扩展格式列表,允许在+00+0000+00:00,{{1}使用时区指示符},-08(尼泊尔),+0545(纽芬兰)等等。不过,在这一点上,你最好还是构建一个正则表达式并滚动你自己的解析器。

-03:30

答案 2 :(得分:0)

我找到了解决方法,但我仍然会接受一个答案,该答案显示如何将asp.net的默认行为更改为默认为UTC日期而不是Web方法中服务器的本地时间

在指定时区时,似乎Date对象中的值将默认为本地时间。

诀窍是不通过时区。所以这些字符串中的任何一个都可以工作:

  

2013-04-01T00:00:00.000 //在ISO 8601字符串末尾留下Z

     

2013-04-01 00:00:00

     

2013年4月1日

但是,这会在Web方法中生成具有以下属性的日期对象:

  

价值:4/01/2013 0:00:00 AM

     

种类:未指定

类型未指定,但日期对象属性保留在UTC中,这对我来说非常重要。