В итоге выбрал 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?;
...