简体   繁体   English

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

[英]Default ASP.NET DateTime.Kind to UTC in Web Method

I'm passing the following ISO 8601 date string to an ASP.NET Web Method: 我将以下ISO 8601日期字符串传递给ASP.NET Web方法:

2013-04-01T00:00:00.000Z 2013-04-01T00:00:00.000Z

This is automatically creating a date object with the following properties: 这将自动创建具有以下属性的日期对象:

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

This is annoying because I now have to remember to convert all my date objects to UTC by doing the following: 这很烦人,因为我现在必须记住通过执行以下操作将所有日期对象转换为UTC:

date = date.ToUniversalTime();

How can I change asp.net to make dates passed into a Web Method be in UTC by default instead of the server's local time? 如何更改asp.net以使传递给Web方法的日期默认为UTC而不是服务器的本地时间? Is there some configuration or hook that I can use to achieve this? 是否有一些配置或挂钩可用于实现此目的? Or maybe this just isn't possible? 或者这可能是不可能的?

I don't want to have to bother dealing with server's local time at all because it's completely irrelevant. 我根本不想打扰处理服务器的本地时间,因为它完全无关紧要。


Edit 编辑

Just adding a bit more information because I seem to have not explained myself that clearly above. 只是添加更多信息,因为我似乎没有在上面明确解释自己。 Here is some example code. 这是一些示例代码。

JavaScript: JavaScript的:

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

C#: 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.
}

See DateTimeOffset The browser may be in a different Timezone. 请参阅DateTimeOffset浏览器可能位于不同的时区。 If you are sure this is correct then you should remember that the LocalTimeZone is used by default when sending dates to the server and thus conversion would change the time. 如果您确定这是正确的,那么您应该记住在向服务器发送日期时默认使用LocalTimeZone,因此转换会改变时间。 You may have to use the SpecifyKind method. 您可能必须使用SpecifyKind方法。

I do believe if you specify the Timezone in the string you can get ASP.Net to pick it up also... 我相信如果你在字符串中指定时区,你可以让ASP.Net拿起它...

If not use a new parser and register it as the default or create a new type with the offset. 如果不使用新的解析器并将其注册为默认值,或使用偏移量创建新类型。

I found a workaround, but I'll still accept an answer that shows how to change the default behaviour of asp.net to default to the UTC date instead of the server's local time in the Web Method. 我找到了一个解决方法,但我仍然会接受一个答案,该答案显示如何将asp.net的默认行为更改为默认为UTC日期而不是Web方法中服务器的本地时间。

It seems that the value in the Date object will default to local time when the time zone is specified. 当指定时区时,似乎Date对象中的值将默认为本地时间。

The trick is to not pass in the time zone. 诀窍是不通过时区。 So any of these strings will work: 所以这些字符串都可以工作:

2013-04-01T00:00:00.000 // leave off the Z at the end of the ISO 8601 string 2013-04-01T00:00:00.000 //在ISO 8601字符串末尾留下Z.

2013-04-01 00:00:00 2013-04-01 00:00:00

2013-04-01 2013年4月1日

This, however, makes a date object with the following properties in the Web Method: 但是,这会在Web方法中生成具有以下属性的日期对象:

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

Kind: Unspecified 种类:未指定

The kind is unspecified, but the date objects properties remain in UTC, which is what matters for my purposes. 类型未指定,但日期对象属性保留在UTC中,这对我的目的很重要。

Try something like this, using DateTime.ParseExact() : 尝试这样的事情,使用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"     ,
      } ;

If you expect to deal with UTC designators like +00 , +0000 , +00:00 , you'll need to expand the format list using (respectively) the z , zz and zzz custom format specifiers . 如果您希望在处理UTC代号喜欢+00+0000+00:00 ,你需要扩大使用(分别)的格式列表zzzzzz自定义格式说明

Given that, this code 鉴于此,这段代码

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;
}

Produces the following results: 产生以下结果:

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

Edited to note: here's an expanded format list allowing the use of time zone designators such at +00 , +0000 , +00:00 , -08 , +0545 (Nepal), -03:30 (Newfoundland), etc. At this point, though, you're probably better off constructing a regular expression and rolling your own parser. 编辑要注意:这里是一个扩展的格式列表中允许使用的时区指示器,例如在+00+0000+00:00-08+0545 (尼泊尔) -03:30 (纽芬兰),等等。在这个但是,你可能最好还是构建一个正则表达式并滚动你自己的解析器。

static readonly string[] formats = {
  //-----------------------------------------------------------------------------------
  // ISO 8601 Long Form
  //-----------------------------------------------------------------------------------
  // The 'K'   specifier accepts the Z designator for UTC or no designator
  // The 'z'   specifier accepts a time zone designator as '[+/-]HH'
  // The 'zz'  specifier accepts a time zone designator as '[+/-]HHMM'
  // The 'zzz' specifier accepts a time zone designator as '[+/-]HH:MM'
  //-----------------------------------------------------------------------------------
  "yyyy-MM-ddTHH:mm:ss.fffK"   , "yyyy-MM-ddTHH:mm:ss.ffK"   , "yyyy-MM-ddTHH:mm:ss.fK"   , "yyyy-MM-ddTHH:mm:ssK"   , "yyyy-MM-ddTHH:mm:ssK"   , "yyyy-MM-ddTHH:mmK"   ,
  "yyyy-MM-ddTHH:mm:ss.fffz"   , "yyyy-MM-ddTHH:mm:ss.ffz"   , "yyyy-MM-ddTHH:mm:ss.fz"   , "yyyy-MM-ddTHH:mm:ssz"   , "yyyy-MM-ddTHH:mm:ssz"   , "yyyy-MM-ddTHH:mmz"   ,
  "yyyy-MM-ddTHH:mm:ss.fffzz"  , "yyyy-MM-ddTHH:mm:ss.ffzz"  , "yyyy-MM-ddTHH:mm:ss.fzz"  , "yyyy-MM-ddTHH:mm:sszz"  , "yyyy-MM-ddTHH:mm:sszz"  , "yyyy-MM-ddTHH:mmzz"  ,
  "yyyy-MM-ddTHH:mm:ss.fffzzz" , "yyyy-MM-ddTHH:mm:ss.ffzzz" , "yyyy-MM-ddTHH:mm:ss.fzzz" , "yyyy-MM-ddTHH:mm:sszzz" , "yyyy-MM-ddTHH:mm:sszzz" , "yyyy-MM-ddTHH:mmzzz" ,
  //-----------------------------------------------------------------------------------
  // ISO 8601 Compact Form
  //-----------------------------------------------------------------------------------
  // The 'K'   specifier accepts the Z designator for UTC or no designator
  // The 'z'   specifier accepts a time zone designator as '[+/-]HH'
  // The 'zz'  specifier accepts a time zone designator as '[+/-]HHMM'
  // The 'zzz' specifier accepts a time zone designator as '[+/-]HH:MM'
  //-----------------------------------------------------------------------------------
  "yyyyMMddTHHmmss.fffK"   , "yyyyMMddTHHmmss.ffK"   , "yyyyMMddTHHmmss.fK"   , "yyyyMMddTHHmmssK"   , "yyyyMMddTHHmmssK"   , "yyyyMMddTHHmmK"   ,
  "yyyyMMddTHHmmss.fffz"   , "yyyyMMddTHHmmss.ffz"   , "yyyyMMddTHHmmss.fz"   , "yyyyMMddTHHmmssz"   , "yyyyMMddTHHmmssz"   , "yyyyMMddTHHmmz"   ,
  "yyyyMMddTHHmmss.fffzz"  , "yyyyMMddTHHmmss.ffzz"  , "yyyyMMddTHHmmss.fzz"  , "yyyyMMddTHHmmsszz"  , "yyyyMMddTHHmmsszz"  , "yyyyMMddTHHmmzz"  ,
  "yyyyMMddTHHmmss.fffzzz" , "yyyyMMddTHHmmss.ffzzz" , "yyyyMMddTHHmmss.fzzz" , "yyyyMMddTHHmmsszzz" , "yyyyMMddTHHmmsszzz" , "yyyyMMddTHHmmzzz" ,
  //-----------------------------------------------------------------------------------
  // ISO 8601 More Compact Form (omitting the 'T' time separator)
  //-----------------------------------------------------------------------------------
  // The 'K'   specifier accepts the Z designator for UTC or no designator
  // The 'z'   specifier accepts a time zone designator as '[+/-]HH'
  // The 'zz'  specifier accepts a time zone designator as '[+/-]HHMM'
  // The 'zzz' specifier accepts a time zone designator as '[+/-]HH:MM'
  //-----------------------------------------------------------------------------------
  "yyyyMMddHHmmss.fffK"   , "yyyyMMddHHmmss.ffK"   , "yyyyMMddHHmmss.fK"   , "yyyyMMddHHmmssK"   , "yyyyMMddHHmmssK"   , "yyyyMMddHHmmK"   ,
  "yyyyMMddHHmmss.fffz"   , "yyyyMMddHHmmss.ffz"   , "yyyyMMddHHmmss.fz"   , "yyyyMMddHHmmssz"   , "yyyyMMddHHmmssz"   , "yyyyMMddHHmmz"   ,
  "yyyyMMddHHmmss.fffzz"  , "yyyyMMddHHmmss.ffzz"  , "yyyyMMddHHmmss.fzz"  , "yyyyMMddHHmmsszz"  , "yyyyMMddHHmmsszz"  , "yyyyMMddHHmmzz"  ,
  "yyyyMMddHHmmss.fffzzz" , "yyyyMMddHHmmss.ffzzz" , "yyyyMMddHHmmss.fzzz" , "yyyyMMddHHmmsszzz" , "yyyyMMddHHmmsszzz" , "yyyyMMddHHmmzzz" ,
  //-----------------------------------------------------------------------------------
} ;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM