Как работать с часовыми поясами в ASP.NET?

В вашем простом примере i++ и (i)++ нет никакой разницы, как отмечено в ответе Эрика Постпишила.

Однако это различие действительно имеет смысл, если вы разыменовываете переменную-указатель с помощью оператора * и используете оператор приращения; есть разница между *p++ и (*p)++.

Предыдущий оператор разыменовывает указатель, а затем увеличивает сам указатель; последний оператор разыменовывает указатель, а затем увеличивает разыменованное значение.

27
задан marc_s 30 April 2015 в 09:02
поделиться

6 ответов

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

Когда вы хотите сохранить напоминание для пользователя, вам потребуется текущее время в формате 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);
27
ответ дан 28 November 2019 в 05:08
поделиться

You may want to look at using the DateTimeOffset structure instead of the DateTime if you are on framework 2.0 or later.

The DateTimeOffset represents a point in time relative to UTC time, so it should be easier to work with in this case.

2
ответ дан 28 November 2019 в 05:08
поделиться

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

Проблема в том, как ваш программный код знает, какой часовой пояс находится в браузере клиента? Допустим, пользователь вводит в форму некоторое значение даты / времени (например, 30.12.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). Я хотел бы опубликовать образец из статьи, но я не хочу нарушать авторские права; тем не менее, вот проект по созданию вспомогательной библиотеки , которая имеет всю необходимую функциональность и документацию (просто игнорируйте то, что вам не нужно).

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

17
ответ дан 28 November 2019 в 05:08
поделиться

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

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

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

0
ответ дан 28 November 2019 в 05:08
поделиться

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

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

3
ответ дан 28 November 2019 в 05:08
поделиться

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

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

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

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

0
ответ дан 28 November 2019 в 05:08
поделиться
Другие вопросы по тегам:

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