Как работать с летним временем в Framework 2.0

Я разрабатываю приложение службы Windows, и мне нужно работать с летним временем, когда мой сервер приложений работает в одном часовом поясе, а сервер БД (фактически веб-служба) работает в другом.

Каждый раз, когда новые данные записываются в базу данных, они используют текущую локальную дату и время, которая отличается от даты и времени моего сервера приложений, поэтому, когда мне нужно найти результаты в БД, мне нужно увеличить/уменьшить смещение до дату и время найти, используя правильную дату и время, но при переходе на летнее время у меня возникают проблемы, потому что мне нужно изменить это смещение вручную, и это вызывает кучу проблем, поскольку нам нужно, чтобы кто-то следил за системой.

Я не хотел бы работать с какими-либо другими инструментами, веб-сайтами и т. д., чтобы получить эту информацию, нам просто нужно работать с материалами Microsoft.

Я искал способы работы с TimeZones в .NET 2.0, но ничего не нашел, мой вопрос: сталкивался ли кто-нибудь здесь с подобной ситуацией?


person Luiz Henrique    schedule 04.11.2013    source источник
comment
Похоже, что в базе данных хранится время входа в формате UTC может решить вашу проблему.   -  person Dan J    schedule 04.11.2013
comment
Я согласен с @DanJ, ​​обычно рекомендуется просто хранить все ваше время в zulu tim e (UTC) в вашей базе данных и позволять любым локальным клиентам выполнять преобразования при представлении вещей конечным пользователям.   -  person oerkelens    schedule 04.11.2013
comment
Вы абсолютно ограничены .Net 2.0? Можно ли использовать 3,5? Если нет, то разрешено ли вам вообще использовать библиотеку с открытым исходным кодом?   -  person Matt Johnson-Pint    schedule 05.11.2013


Ответы (3)


Я давно использую реестр Windows для получения смещений. Все локали хранятся там со смещениями на ближайшие годы. Эти данные автоматически обновляются, когда вы применяете пакеты обновлений и тому подобное.

Вот ссылка, в которой подробно описывается реализация более старого метода переноса информации о локали в реестр Windows — circa .net 2.0 .

person Ross Bush    schedule 04.11.2013

Было бы лучше использовать значение UTC для хранения в базе данных и преобразования в локальный или любой другой часовой пояс в приложении.

DateTime.Now.ToUniversalTime() DateTime.SpecifyKind(dt, DateTimeKind.Local);

http://msdn.microsoft.com/en-us/library/system.datetime.utcnow.aspx

Или вы можете создать LocaizedDateTime

========

Обновлено:

using System;
using System.Collections.Generic;

public class MyClass
{
    public static void RunSnippet()
    {
        LocalizedDateTime dt = LocalizedDateTime.FromUtc(DateTime.UtcNow);
        Console.WriteLine(dt.LocalDateTime.ToString("dd/MM/yyyy hhmmss"));
        Console.WriteLine(dt.UtcDateTime.ToString("dd/MM/yyyy hhmmss"));
    }

    #region Helper methods

    public static void Main()
    {
        try
        {
            RunSnippet();
        }
        catch (Exception e)
        {
            string error = string.Format("---\nThe following error occurred while executing the snippet:\n{0}\n---", e.ToString());
            Console.WriteLine(error);
        }
        finally
        {
            Console.Write("Press any key to continue...");
            Console.ReadKey();
        }
    }

    private static void WL(object text, params object[] args)
    {
        Console.WriteLine(text.ToString(), args);   
    }

    private static void RL()
    {
        Console.ReadLine(); 
    }

    private static void Break() 
    {
        System.Diagnostics.Debugger.Break();
    }

    #endregion
}

public class LocalizedDateTime
{
    private LocalizedDateTime(DateTime localDateTime)
    {
        LocalDateTime = DateTime.SpecifyKind(localDateTime, DateTimeKind.Local);
    }

    public DateTime UtcDateTime{
        get{
            return LocalDateTime.ToUniversalTime();
        }
    }

    public DateTime LocalDateTime{get; private set;}

    public static LocalizedDateTime FromLocal(DateTime localDateTime)
    {
        return new LocalizedDateTime(localDateTime);
    }

    public static LocalizedDateTime FromUtc(DateTime utcDateTime)
    {
        return new LocalizedDateTime(TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, TimeZoneInfo.Local));
    }
}
person Abhishek Shrestha    schedule 04.11.2013
comment
Этот код немного сумасшедший и мало что делает. Вы знаете, что DateTime.SpecifyKind не изменяет значение, верно? Зачем вам брать значение UTC и присваивать ему локальный тип? Это просто бессмысленно. - person Matt Johnson-Pint; 05.11.2013
comment
Мэтт, ты прав. Я указал тип не на той опоре. Я обновил код. Спасибо. - person Abhishek Shrestha; 05.11.2013
comment
Хорошо, я вижу, что вы сейчас делаете, но я не уверен, как это решает вопрос ОП. Кроме того, вы видели Noda Time? Для этого требуется .net 3.5, но я думаю, вы можете найти его типы более полезными, чем ваш класс LocalizedDateTime. - person Matt Johnson-Pint; 05.11.2013
comment
Это объект, который поддерживает локализованное значение с UTC, предполагая, что значения UTC сохранены в db. При получении данных из базы данных создайте экземпляр с помощью FromUtc, а при создании даты и времени в приложении для хранения в базе данных создайте экземпляр FromLocal. Используйте реквизит UtcDateTime или LocalDateTime по мере необходимости. например, при сохранении в базу данных пользователя UtcDateTime, при настройке календаря используйте LocalDateTime. Идея состоит в том, чтобы создать экземпляр, используя либо значение utc, либо локальное значение, и в вашем распоряжении есть как локальное значение, так и значение utc. Это может быть дополнительно расширено для выполнения операций типа datetime. - person Abhishek Shrestha; 05.11.2013
comment
Я понимаю, но ОП спросил об использовании других часовых поясов. Он хочет что-то вроде TimeZoneInfo, но из .net 2.0. Ваш код работает только с часовым поясом local. Поэтому, хотя я понимаю, что вы говорите, это не касается вопроса, размещенного здесь. - person Matt Johnson-Pint; 06.11.2013

Если вам нужно работать только с локальным часовым поясом компьютера, на котором выполняется ваш код .NET, вы можете использовать класс TimeZone, который присутствует в .NET, начиная с версии 1.1.

Однако я думаю, что вы спрашиваете о работе с другими часовыми поясами, отличными от местного часового пояса. Это обрабатывается с помощью TimeZoneInfo в .NET 3.5 и более поздних версиях, но недоступно для приложений .NET 2.0.

Лучшим решением (ИМХО) для работы с несколькими часовыми поясами в приложении .NET 2.0 является Библиотека TZ4NET. Он правильно реализует базу данных часовых поясов IANA и поддерживается на протяжении многих лет. Однако это сторонняя библиотека, и вы сказали, что не хотите использовать ничего, что не было создано Microsoft.

К сожалению, остается единственный вариант — вручную прочитать данные о часовом поясе из реестра Windows и реализовать собственный код для их интерпретации. Существует здесь хороший пост в блоге, в котором описывается, как TimeZoneInfo читает данные из реестра, и описываются используемые ключи реестра и данные. Полная реализация слишком широка для этого поста.

person Matt Johnson-Pint    schedule 10.07.2014