DateTime должен содержать информацию о часовом поясе и учитывать летнее время - PullRequest
2 голосов
/ 25 мая 2011

Я попал в ситуацию, когда моя программа имеет 2 интеграции со сторонними системами. Интеграция состоит из 1) протокола XML по TCP / IP и 2) веб-сервисов, созданных в WCF.

В любом случае партнеру по интеграции требуются временные метки / даты, которые я передаю им, чтобы они содержали информацию о часовом поясе и летнем времени, чтобы они могли отображать правильное время независимо от своих клиентов.

Я бы предпочел не изменять текущий протокол, в любом случае они ожидают DateTime, поэтому мой вопрос: возможно ли передать информацию о TimeZone и Daylight Savings как часть DateTime?

Прямо сейчас мои временные метки выглядят так:

2011-04-27T15:14:13.963

Мне бы хотелось, чтобы это выглядело примерно так (я нахожусь в Дании, поэтому мы используем CEST) и смогу передавать информацию с помощью объекта DateTime

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

Однако я не знаю, как мне это сделать, и не учитывать фактор летнего времени

Ответы [ 3 ]

5 голосов
/ 25 мая 2011

Если вам нужно знать как дату / время , так и часовой пояс, вам придется придумать собственную инкапсуляцию:

  • DateTime содержит толькодата / время и информация о том, является ли это «местным» (в системном часовом поясе) или UTC
  • DateTimeOffset, содержит информацию о дате / времени и смещении к UTC, но это не то же самое, чтоего часовой пояс

Вы можете объединить TimeZoneInfo и DateTimeOffset в структуру, хотя.

В качестве альтернативы, если вы счастливы использовать бета-качество, API-мог-программное обеспечение, изменяющее неподвижность, вы можете использовать Noda Time , проект, который я начал для переноса API Joda Time на .NET.

Это с точки зренияпредставление процесса ... что касается передачи информации, вам необходимо выяснить, что используют ваши партнеры по интеграции.Например, они могут хотят указать время UTC и имя часового пояса Олсена ... или они могут просто хотят смещение.

Включая смещение "current"с UTC может быть достаточно вместо того, чтобы включать полную информацию о часовом поясе, если вам нужно только узнать, какое местное время было для пользователя во время создания метки времени.Это просто означает, что вы не знаете, какое местное время было через 2 секунды ...

3 голосов
/ 25 мая 2011

Вместо DateTime используйте DateTimeOffset, который содержит информацию о часовом поясе смещение .

Что касается перехода на летнее время - вам нужно будет использовать База данных Ольсена .

См. этот связанный вопрос.

2 голосов
/ 25 мая 2011

Используйте время 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();
      }
  }

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...