Вопрос

Я работаю над проектом "система онлайн-напоминаний" (ASP.NET 2.0 (C #) / SQL Server 2005)

Поскольку это сервис напоминаний, который будет отправлять почту пользователям в определенные даты.Но проблема в том, что пользователи не из какой-то конкретной страны, они со всего мира и из разных часовых поясов.Теперь, когда я регистрируюсь, я запрашиваю часовой пояс пользователей точно так же, как Windows запрашивает наш часовой пояс во время установки.

Но я не получаю, если пользователь выбрал (+5.30) или что-то часовому поясу, тогда как обрабатывать эту зону раз в моем приложении ASP.NET .Как работать в зависимости от часового пояса.

И, пожалуйста, подскажите, есть ли какой - нибудь лучший способ обработки часовых поясов в этом приложении??

Спасибо

Это было полезно?

Решение

Первое, что нужно сделать, это убедиться, в каком часовом поясе находятся ваши данные.Я бы рекомендовал убедиться, что любая дата-время, которую вы сохраняете, хранится по времени UTC (используйте DateTime.ToUniversalTime() чтобы заполучить его).

Когда вы хотите сохранить напоминание для пользователя, вам понадобится текущее время UTC, добавьте или удалите разницу в часовых поясах пользователя и преобразуйте это новое время обратно в UTC;это то, что вы хотите сохранить в базе данных.

Затем, когда вы захотите проверить, нужно ли отправлять напоминания, вам просто нужно поискать в базе данных напоминания, которые нужно отправить сейчас, в соответствии со временем UTC;по сути, получите все напоминания, у которых есть временная метка, то есть до DateTime.Now.ToUniversalTime().

Обновить с некоторыми особенностями реализации:Вы можете получить список часовых поясов из TimeZoneInfo.GetSystemTimeZones() способ;вы можете использовать их для отображения списка часовых поясов для пользователя.Если вы храните Id используя свойство из выбранного часового пояса, вы можете создать из него экземпляр класса TimeZoneInfo и вычислить время UTC для заданного значения локальной даты / времени:

TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("<the time zone id>");
// May 7, 08:04:00
DateTime userDateTime = new DateTime(2009, 5, 7, 8, 4, 0);
DateTime utcDateTime = userDateTime.Subtract(tzi.BaseUtcOffset);

Другие советы

Я бы рекомендовал всегда используйте время UTC (GMT) на стороне сервера (в коде, базе данных и т.д.) И преобразует время из UTC в местное время для отображения Только.Это означает, что все временные манипуляции - включая экономию времени в базе данных, выполнение вычислений и т.д. - должны выполняться с использованием UTC.

Проблема в том, что:как ваш программный код узнает, каков часовой пояс клиентского браузера?Допустим, пользователь вводит некоторое значение даты / времени (например, 12/30/2009 14:30) в форме и отправляет ее на сервер.Предполагая, что пользователь указал местное время, откуда сервер знает, как преобразовать это значение в UTC?

Приложение может попросить пользователя указать часовой пояс (и сохранить его в постоянном файле cookie или базе данных), но это требует дополнительных усилий от пользователя, и вашему приложению потребуется реализовать логику и экраны для этого.Было бы лучше, если бы приложение могло автоматическое определение часового пояса клиента.

Я решил эту проблему с помощью JavaScript getTimezoneOffset Получение времени функция, которая является единственным API, который может сообщать серверу о разнице во времени между местным временем на клиенте и GMT.Поскольку это клиентский API, я сделал следующее:на стороне сервера проверьте, есть ли пользовательский файл cookie сеанса, содержащий значение временного смещения, и, если он недоступен, перезагрузите страницу (только во время вызовов GET, а не POST) с добавлением некоторой логики JavaScript для генерации временного смещения и сохранения его в файле cookie.Со стороны клиента это почти прозрачно (один раз во время сеанса я перезагружаю страницу в GET).Как только у меня есть смещение в файле cookie, я применяю его к функциям управления временем в зависимости от направления преобразования времени (UTC в местное время или местное время в UTC).

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

using My.Utilities.Web;
...

// Derive the form class from BaseForm instead of Page.
public class WebForm1: BaseForm
{
...
private void Page_Load(object sender, System.EventArgs e)
{
  // If we only want to load the page to generate the time
  // zone offset cookie, we do not need to do anything else.
  if (InitializeLocalTime())
    return;

  // Assume that txtStartDate is a TextBox control.
  if (!IsPostback)
  {
     // To display a date-time value, convert it from GMT (UTC)
     // to local time.
     DateTime startDate = GetStartDateFromDB(...);
     txtStartDate.Text  = FormatLocalDate(startDate);
     ...
  }
  else
  {
     // To save a date-time value, convert it from local
     // time to GMT (UTC).
     DateTime tempDate  = DateTime.Parse(txtStartDate.Text);
     DateTime startDate = ConvertLocalTimeToUtc(tempDate);
     SaveStartDateInDB(startDate, ...);
     ...
  }
}
...
}

Если вам нужна более подробная информация, ознакомьтесь с Самое время:Локализация времени в ASP.NET Приложениях статья (извините, но у меня нет прямой ссылки на статью на сайте издателя, поскольку asp.NetPro ограничивает доступ только для платных подписчиков;однако там есть ссылки на копии в формате PDF).Я хотел бы опубликовать образец из статьи, но я не хочу нарушать авторские права;однако, вот проект по созданию вспомогательной библиотеки это имеет весь необходимый функционал и документация (просто игнорируйте то, что вам не нужно).

Обновить:Статья была размещена в Интернете вместе с образцом проекта новым издателем здесь.

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

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

Возможно, вы захотите рассмотреть возможность использования DateTimeOffset Дата - время смещения структура вместо даты и времени, если вы используете framework 2.0 или более позднюю версию.

DateTimeOffset представляет собой момент времени относительно времени UTC, поэтому в этом случае с ним должно быть проще работать.

Есть 2 шага:

  • Обнаружение другого часового пояса на стороне клиента с помощью Javascript:

    var dt = new Date();
    var diffInMinutes = -dt.getTimezoneOffset();
    
  • Затем на стороне сервера используйте C # код для преобразования серверного времени в клиентское на основе обнаруженного выше смещения часового пояса:

------------------------;

string queryStr = Request.QueryString["diffInMinutes"];
int diffInMinutes = 0;
if (Int32.TryParse(queryStr, out diffInMinutes))
{
    clientTime = serverTime.ToUniversalTime().AddMinutes(diffInMinutes);
}

По сути, все, что вам нужно сделать, это добавить смещение (часы + минуты) к местному времени, введенному пользователем.Добавление смещения в основном дает вам дату и время в часовом поясе UTC (в основном GMT).

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

На этой странице есть несколько хороших примеров: http://msdn.microsoft.com/en-us/library/bb546099.aspx

Проблема в том, что смещение от UTC будет разным в разное время года - в каждом часовом поясе свои правила.(Я научился этому на собственном горьком опыте, когда разрабатывал приложение для планирования конференц-зала.)

Похоже, здесь есть встроенная поддержка: http://msdn.microsoft.com/en-us/library/system.timezoneinfo.converttime.aspx

Сам не пробовал, но, похоже, он обещает правильное преобразование с учетом перехода на летнее время.

Если нет, то вот (дорогой) коммерческий инструмент, который я использовал: http://www.worldtimeserver.com/time_zone_guide/

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top