DateTime必须包含TimeZone信息并考虑夏令时

时间:2011-05-25 11:30:10

标签: c# datetime timezone dst

我处于这样一种情况,即我的程序有2个集成到第三方系统。这些集成包括:1)TCP / IP上的XML协议和2)WCF中的Web服务。

在任何一种情况下,集成合作伙伴都需要传递给我们的TimeStamps / DateTimes以包含有关TimeZone和Daylight Savings的信息,因此无论客户的TimeZone / Position如何,他们都可以显示正确的时间。

我宁愿不改变当前的协议,在任何一种情况下他们都期望DateTime,所以我的问题是:是否可以将TimeZone和Daylight Savings信息作为DateTime的一部分传递?

现在我的时间戳看起来像这样:

2011-04-27T15:14:13.963

我希望看起来像这样(我位于丹麦,所以我们使用CEST)并能够使用DateTime对象传输信息

 2011-04-27T15:14:13.963 +01:00

但是,我不知道如何实现这一目标,也不考虑夏令时因素

3 个答案:

答案 0 :(得分:5)

如果你需要知道日期/时间时区,你必须提出自己的封装:

  • DateTime仅包含日期/时间以及有关它是“本地”(在系统时区中)还是UTC
  • 的信息
  • DateTimeOffset包含有关日期/时间及其与UTC的偏移量的信息,但这与其时区不同

您可以在结构中合并TimeZoneInfoDateTimeOffset

或者,如果您很乐意使用beta-quality,API-could-still-change软件,您可以使用Noda Time,我开始基本上将Joda Time API移植到的项目。 NET。

就流程内表示而言......就传递信息而言,您需要找出您的集成合作伙伴使用的内容。例如,他们可能想要UTC时间和Olsen时区名称......或者他们可能只想要偏移量。

包括UTC 的“当前”偏移量可能足够,而不是包括全时区信息,如果您只需要知道时间戳时用户的当地时间是多少创建。这只是意味着你不知道2秒后的当地时间是什么......

答案 1 :(得分:3)

而不是DateTime使用DateTimeOffset,其中包含时区偏移信息。

至于夏令时 - 您需要使用Olsen database

请参阅this相关问题。

答案 2 :(得分:2)

使用UTC时间,您可以坚持使用DateTime。 UTC将就地转换为本地(或任何其他时间)。这也解决了夏令时的问题。使用UTC是最好的解决方案,我对它有一些了解。

小型演示:

namespace TimeZoneTest
{
  using System;
  using System.Globalization;

  class Program
  {
      static void Main(string[] args)
      {
          // get local time
          DateTime localTime = DateTime.Now;
          Console.WriteLine(string.Format(
              CultureInfo.CurrentCulture, 
              "localTime = {0}, localTime.Kind = {1}", 
              localTime, 
              localTime.Kind));

          // get local time zone, or use TimeZoneInfo to get any time zone you want
          TimeZone ltz = TimeZone.CurrentTimeZone;
          Console.WriteLine(string.Format("local time zone = {0}", ltz.StandardName));

          // convert local time to UTC
          DateTime utcTime = ltz.ToUniversalTime(localTime);
          Console.WriteLine(string.Format(CultureInfo.CurrentCulture,
              "utcTime = {0}, utcTime.Kind = {1}",
              utcTime,
              utcTime.Kind));

          // transfer date via service, as ISO time string
          string isoUtc = utcTime.ToString("o");
          Console.WriteLine("...");
          Console.WriteLine(string.Format("transfer: isoUtc = {0}", isoUtc));
          Console.WriteLine("...");

          // now on the other side
          DateTime utcTimeRecieved = DateTime.ParseExact(
              isoUtc, 
              "o", 
              CultureInfo.InvariantCulture, 
              DateTimeStyles.RoundtripKind);
          Console.WriteLine(string.Format(CultureInfo.CurrentCulture, 
              "utcTimeRecieved = {0}, utcTimeRecieved.Kind = {1}", 
              utcTimeRecieved, 
              utcTimeRecieved.Kind));

          // client time zone, or use TimeZoneInfo to get any time zone you want
          TimeZone ctz = TimeZone.CurrentTimeZone;
          Console.WriteLine(string.Format("client time zone = {0}", ctz.StandardName));

          // get local time from utc
          DateTime clientLocal = ctz.ToLocalTime(utcTimeRecieved);
          Console.WriteLine(string.Format(
              CultureInfo.CurrentCulture,
              "clientLocal = {0}, clientLocal.Kind = {1}",
              clientLocal,
              clientLocal.Kind));

          Console.WriteLine("\nPress any key to exit..");
          Console.ReadKey();
      }
  }

}