开发者

DateTime must contain TimeZone information and take Daylight Savings into account

开发者 https://www.devze.com 2023-03-08 17:49 出处:网络
I\'m placed in a situation where my program has 2 integratio开发者_开发问答ns towards 3rd party systems. The integrations consists of 1) XML protocol over TCP/IP and 2) Webservices made in WCF.

I'm placed in a situation where my program has 2 integratio开发者_开发问答ns towards 3rd party systems. The integrations consists of 1) XML protocol over TCP/IP and 2) Webservices made in WCF.

In either case the integration partner needs the TimeStamps / DateTimes I pass to them to contain information about the TimeZone and Daylight Savings, so they can display the correct time regardless of their customers TimeZone / Position.

I'd rather not change the current protocol, in either cases they expect DateTime, so my question is: Is it possible to pass the TimeZone and Daylight Savings information as a part of the DateTime?

Right now my timestamps looks like this:

2011-04-27T15:14:13.963

I would love to have it look something like this (I'm located in Denmark so we use CEST) and be able to transfer the information with a DateTime object

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

However I do not know how I should accomplish this nor take into account the Daylight Savings Factor


If you need to know both the date/time and the time zone, you'll have to come up with your own encapsulation:

  • DateTime only contains the date/time and information as to whether it's "local" (in the system time zone) or UTC
  • DateTimeOffset contains information about the date/time and its offset to UTC, but that's not the same as its time zone

You could combine TimeZoneInfo and DateTimeOffset in a struct though.

Alternatively, if you're happy to use beta-quality, API-could-still-change software, you could use Noda Time, a project I started to basically port the Joda Time API to .NET.

That's in terms of in-process representation... as for passing the information around, you need to find out what your integration partners use. For example, they might want the UTC time and an Olsen time zone name... or they may just want the offset.

Including the "current" offset from UTC may be enough, rather than including full time zone information, if you only need to know what the local time was for the user at the time the timestamp was created. It just means you don't know what the local time was 2 seconds later...


Instead of DateTime use DateTimeOffset, which contains timezone offset information.

As for daylight savings time - you will need to use the Olsen database.

See this related question.


Use UTC time and you can stick with DateTime. UTC is converted to local (or any other time) in-place. Also this solves problem with Daylight Saving Time. Using UTC is the best solution, I have had some expirience with it.

Small demo:

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

}

0

精彩评论

暂无评论...
验证码 换一张
取 消