C #: Убедитесь, что DateTime.Now возвращает время по Гринвичу + 1 - PullRequest
11 голосов
/ 10 июля 2009

Я использую DateTime.Now, чтобы показать что-то в соответствии с сегодняшней датой, и при локальной работе (Мальта, Европа) время отображается правильно (очевидно, из-за часового пояса), но, конечно, когда я загружаю его на свой хостинг-сервер (США)), DateTime.Now не соответствует правильному часовому поясу.

Следовательно, в моем коде как я могу преобразовать DateTime.Now для правильного возврата времени из GMT + 1 часового пояса ?

Ответы [ 3 ]

16 голосов
/ 10 июля 2009

Используйте класс TimeZoneInfo, найденный в System.Core;

Для этого вы должны установить DateTimeKind в DateTimeKind.Utc.

DateTime MyTime = new DateTime(1990, 12, 02, 19, 31, 30, DateTimeKind.Utc);

DateTime MyTimeInWesternEurope = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(MyTime, "W. Europe Standard Time");

Только если вы используете .Net 3.5!

15 голосов
/ 10 июля 2009

Это зависит от того, что вы подразумеваете под «часовой пояс GMT + 1». Вы имеете в виду постоянно UTC + 1 или UTC + 1 или UTC + 2 в зависимости от летнего времени?

Если вы используете .NET 3.5, используйте TimeZoneInfo, чтобы получить соответствующий часовой пояс, затем используйте:

// Store this statically somewhere
TimeZoneInfo maltaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("...");
DateTime utc = DateTime.UtcNow;
DateTime malta = TimeZoneInfo.ConvertTimeFromUtc(utc, maltaTimeZone );

Вам нужно будет определить системный идентификатор для часового пояса Мальты, но это легко сделать, запустив этот код локально:

Console.WriteLine(TimeZoneInfo.Local.Id);

Судя по вашим комментариям, этот бит будет неактуален, но только для других ...

Если вы не используете .NET 3.5, вам придется самостоятельно отработать переход на летнее время. Если честно, самый простой способ сделать это будет простой таблицей поиска. Отработайте изменения DST на следующие несколько лет, затем напишите простой метод, чтобы вернуть смещение в определенное время UTC с жестко закодированным списком. Возможно, вы просто захотите отсортировать List<DateTime> с известными изменениями и чередовать от 1 до 2 часов, пока ваша дата не станет после последнего изменения:

// Be very careful when building this list, and make sure they're UTC times!
private static readonly IEnumerable<DateTime> DstChanges = ...;

static DateTime ConvertToLocalTime(DateTime utc)
{
    int hours = 1; // Or 2, depending on the first entry in your list
    foreach (DateTime dstChange in DstChanges)
    {
        if (utc < dstChange)
        {
            return DateTime.SpecifyKind(utc.AddHours(hours), DateTimeKind.Local);
        }
        hours = 3 - hours; // Alternate between 1 and 2
    }
    throw new ArgumentOutOfRangeException("I don't have enough DST data!");
}
5 голосов
/ 10 июля 2009

Я не думаю, что вы можете установить в своем коде свойство, которое заставит DateTime.Now возвращать что-либо, кроме текущего времени компьютера, на котором выполняется код. Если вы хотите иметь возможность всегда получать другое время, вам, вероятно, нужно будет включить другую функцию. Вы можете совершить круговое путешествие по UTC и добавить желаемое смещение:

private static DateTime GetMyTime()
{
    return DateTime.UtcNow.AddHours(1);
}

(пример кода обновлен после комментария Люка о внутренней работе DateTime.Now)

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