Изменение даты в ASP.NET MVC C # на основе сохраненного часового пояса - PullRequest
3 голосов
/ 11 января 2011

У меня двоякий вопрос.

1) Я кодирую форум и не могу понять, как хранить часовые пояса для пользователей форума.Они смогут установить свой часовой пояс и соответствующим образом изменить все даты на форуме.Нужно ли создавать таблицу БД с именами часовых поясов и номером, чтобы настроить время сервера?Есть ли в .NET встроенная поддержка часовых поясов?

2) Как только я выяснил, как сохранить часовой пояс пользователя, а затем изменить объект DateTime на нужное время, мне нужен простой способпередать эту модифицированную дату для просмотра в MVC.Например, у меня есть следующий код:

List<Topic> topics = board.Topics.OrderByDescending(x => x.Replies.Any() 
                                                    ? x.Replies.OrderBy(y => y.PostedDate).Last().PostedDate 
                                                    : x.PostedDate).ToList();

Этот topics объект передается в представление как часть объекта модели представления.Представление перебирает Model.Topics и отображает список тем.Проблема в том, что я не хочу вносить изменения в часовой пояс в представлении, потому что я считаю, что это слишком большая ответственность для представления.Есть ли способ изменить дату темы в запросе LINQ?

Заранее спасибо!

Ответы [ 2 ]

7 голосов
/ 11 января 2011

Вы можете получить список часовых поясов System.TimeZoneInfo.

var timeZones = System.TimeZoneInfo.GetSystemTimeZones();

foreach ( var timeZone in timeZones )
{
  Console.WriteLine( "{0} - {1}", timeZone.Id,  timeZone.DisplayName );
}

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

Затем можно использовать TimeZoneInfo.ConvertTime для преобразования любого времени даты в часовой пояс пользователя.Предполагая, что вы знаете, в каком часовом поясе он был создан.

var now = DateTime.Now;
Console.WriteLine( now );
Console.WriteLine( System.TimeZoneInfo.ConvertTime( now, TimeZoneInfo.Local, TimeZoneInfo.FindSystemTimeZoneById( "China Standard Time" ) ) );

Что касается преобразования, вы можете сделать это в контроллере, а не в виде.Лучше всего было бы создать модель представления поверх темы, в которой вы выполняете преобразование.

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

Если вы устали от попыток выполнить преобразование в базе данных, вы сильно ограничите возможность выполнения кэширования объектов для данных, возвращаемых из базы данных.

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

0 голосов
/ 26 июля 2011

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

Мое полное решение следующим образом. Все время хранится как UTC в базе данных. Вы можете выбрать другой часовой пояс по умолчанию. Но тогда расчет усложняется. И если вы решили переместить хост в другую страну, это будет проблемой.

База данных

Во-первых, необходимо сохранить выбранный пользователем часовой пояс в некоторой таблице, которая содержит информацию о пользователе. В основном мы собираемся хранить TimeZoneInfo.Id (строковое значение). Это легко снова создать класс TimeZoneInfo.

Далее создайте пользовательскую функцию и установите return как datetime. Это будет использоваться во всей БД везде, где вам нужно время сервера. Код, как показано,

Create FUNCTION [dbo].[fnGetDateTime] ()

RETURNS datetime

AS

BEGIN

RETURN GETUTCDATE()


END

Это вернет время UTC. Мы можем использовать метод GETUTCDATE () сразу везде в БД. Но использование UDF дает гибкость в обслуживании.

Код

мы можем использовать расширяемость метода в Date-time Class. Поскольку это решение основано на asp.net, вычислить время сложно. Проблема в том, что здесь участвуют 3 стороны. БД Сервер, Веб-сервер и Пользователь. Каждый может быть в разных часовых поясах. Но нам нужно только ретранслировать выбранный пользователем часовой пояс и время UTC.

Я расширил DateTime Strucute двумя дополнительными методами.

Namespace Extensions
    Public Module ModDateTimeExtensions

        <System.Runtime.CompilerServices.Extension()> _
        Public Function GetUserTimeFromUTC(ByVal dtUtcTime As DateTime, ByVal id As String) As DateTime
            Return TimeZoneInfo.ConvertTimeFromUtc(dtUtcTime, TimeZoneInfo.FindSystemTimeZoneById(id))
        End Function

        <System.Runtime.CompilerServices.Extension()> _
        Public Function SetUserTimeToUTC(ByVal dtUserTime As DateTime, ByVal id As String) As DateTime
            Return TimeZoneInfo.ConvertTime(dtUserTime, TimeZoneInfo.FindSystemTimeZoneById(id), TimeZoneInfo.Utc)
        End Function

    End Module
End Namespace

Здесь важная вещь, которую не следует ретранслировать на часовой пояс веб-сервера для расчета.

Тогда в основном вы можете сделать преобразование, как показано ниже. Предполагая, что пользовательский часовой пояс установлен на «Тихоокеанское стандартное время». Это нужно извлечь из БД при входе пользователя в систему.

Dim dt as DateTime = FunctionToGetUTCTimeFromDB()

dt = dt.GetUserTimeFromUTC("Pacific Standard Time")

Если вы хотите сэкономить время пользователя в UTC, позвоните по номеру

Dim dt as DateTime = GetUserSelectedTimeFromUI()

dt = dt.SetUserTimeToUTC("Pacific Standard Time")

Это дает следующую гибкость,

Меньше кодирования и меньше изменений, если это необходимо реализовать в существующей системе.

Простота обслуживания.

В будущем, если вы захотите внедрить формат даты и времени, выбираемый пользователем, можете сделать то же самое с небольшими изменениями.

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