@dmitrytut

Как лучше работать с временными зонами (timezones) в веб-приложениях?

Здравствуйте!

Собственно, довольно избитый вопрос, но все же хотел спросить, как вы работаете с временными зонами пользователя?
Для себя пока не могу выбрать из двух сценариев:
1. В БД хранить timezone пользователя, которую он указал в профиле, далее на ее основе производить манипуляции со временами.
2. Timezone (timezoneOffset - не суть важно) определять на клиенте при каждой загрузке веб-приложения, далее записать в cookie и передавать с каждым запросом на сервер.
* в БД все времена и даты хранятся в UTC.
Или есть какие-нибудь более удобные для пользователя и разработчика методы?
Спасибо.
  • Вопрос задан
  • 2757 просмотров
Решения вопроса 2
DmitriyEntelis
@DmitriyEntelis
Думаю за деньги
И тот и другой способ имеют право на жизнь.
2й наверно удобнее если пользователь может активно менять временную зону.
В то же время 1й на мой взгляд стабильнее и понятней пользователю.
Ответ написан
Комментировать
А зачем вам её вообще знать? Отдаёте timestamp в UTC, форматируете с помощью js в timezone клиента.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@dmitrytut Автор вопроса
В итоге выбрал 2-й вариант, т.е. timezone хранить в cookies.
Ниже представлю реализацию на ASP.Net Web Api (сервер) + JQuery (клиент)

Клиент (использовалась библиотека jquery.cookie):
function setTimezoneCookie() {
	var timezone_cookie = "tz";
	//  Инвертируем смещение (см. документацию к getTimezoneOffset)
	var timezone_offset = (new Date().getTimezoneOffset())*(-1);

	//Если нет - создаем
	if (!$.cookie(timezone_cookie)) {
		// проверка поддержки куков браузером
	    var isCookiesEnabled = 'isCookiesEnabled';
		$.cookie(isCookiesEnabled, true);
		if ($.cookie(isCookiesEnabled)) {
			// удаляем тестовые куки
		    $.cookie(isCookiesEnabled, null);
			// записываем timezone
			$.cookie(timezone_cookie, timezone_offset);
		}
	}
	else {
		// Если куки с timezone уже есть, но отличается, то записываем новое значение
		var storedOffset = parseInt($.cookie(timezone_cookie));
		var currentOffset = timezone_offset;
		if (storedOffset !== currentOffset) {
			$.cookie(timezone_cookie, timezone_offset);
		}
	}
}


Сервер:
Создаем HttpMessageHandler для перехвата куки:
public class TimezoneHandler : DelegatingHandler
    {
        static public string TimezoneToken = "tz";

        async protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
        {
            // Изначально, смещение относительно UTC нулевое
            int timezoneOffset = 0;

            // Получаем значение временной зоны из cookies
            var cookie = request.Headers.GetCookies(TimezoneToken).FirstOrDefault();
            if (cookie != null)
            {
                try
                {
                    timezoneOffset = Int32.Parse(cookie[TimezoneToken].Value);
                }
                catch (FormatException)
                {
                    // Ошибка в формате временного смещения - выставляем в нулевое
                    timezoneOffset = 0;
                }
            }

            // Сохраняем временное смещение в свойствах HTTP-запроса
            request.Properties[TimezoneToken] = timezoneOffset;

            // Продолжаем выполнение HTTP-запроса
            HttpResponseMessage response = await base.SendAsync(request, cancellationToken);

            return response;
        }
    }


Регистрируем обработчик в WebApiConfig.cs:
public static void Register(HttpConfiguration config)
{
...
     config.MessageHandlers.Add(new TimezoneHandler());
...
}


Используем в коде:
...
int? tzOffset = Request.Properties[TimezoneHandler.TimezoneToken] as int?;
...
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы