Кошмар даты и времени, какой-нибудь тщательный модуль или контроль в C #, чтобы облегчить боль? - PullRequest
0 голосов
/ 28 ноября 2009

снова я должен создать модуль даты, и снова я живу в ужасе от его совершенствования, это я или дата и время самые грязные животные в профессии программиста, это зверь, скрывающийся за дверью, который я желаю, чтобы я никогда не иметь дело с: (

Кто-нибудь знает великий источник, из которого я могу узнать, который имеет дело с датами в следующих аспектах:

  • пользователь вводит дату, время и часовой пояс
  • система переводит в универсальное время и экономит в источнике данных
  • система извлекает универсальное время, преобразованное в местное время, выбранное разработчиком (не по местоположению сервера или клиента, которое может не подходить для отображения)
  • система должна учитывать различия в летнем времени
  • не может полагаться на синтаксический анализ «DateTime», так как он анализируется богемно относительно времени локального сервера
  • должен давать возможность разработчику иметь дело с обеими формами: дата-время и строковые объекты

Я посмотрел на blogengine.net, чтобы увидеть, как они справляются, но это слишком, они сохраняют разницу во времени в часах в источнике данных настроек, это абсолютно неточно ... какие-либо источники, чтобы помочь?

Я уже далеко зашел в создании необходимых методов, которые используют CultureInfo, TimeZoneInfo, DateTimeOffset ... но когда я проверял его, он не удался! признателен за помощь

EDIT:

Сжав еще немного, я сузил это до:

public string PrettyDate(DateTime s, string format)
{
    // this one parses to local then returns according to timezone as a string
    s = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(s, "AUS Eastern Standard Time");
    CultureInfo Culture = CultureInfo.CreateSpecificCulture("en-au");
    return s.ToString(format , Culture);
}

проблема в том, что я знаю, что переданная дата - время UTC, потому что я использую

DateTimeOffset.Parse(s, _dtfi).UtcDateTime;
// where dtfi has "yyyy-MM-ddTHH:mmzzz" as its FullDateTimePattern

когда я вызываю функцию в моем datetime, вот так:

AuDate.Instance.PrettyDate(el.EventDate,"yyyy-MM-dd HH:mm zzz");

на моей машине я получаю:

2009-11-26 15:01 +11:00

на сервере я получаю:

2009-11-26 15:01 -08:00

Я нахожу это очень странным! почему часовой пояс неверный? все остальное на месте! я что-то пропустил?

Ответы [ 4 ]

3 голосов
/ 28 ноября 2009

Мои комментарии к вашим указателям.

  • пользователь вводит дату, время и часовой пояс
    @ ОК, не проблема

  • система переводит в универсальное время и сохраняет в источнике данных
    @ ОК, без проблем

  • система извлекает универсальное время, преобразованное в местное время, выбранное разработчиком (не по местоположению сервера или клиента, которое может не подходить для отображения)
    @ Это требование? Почему бы просто не восстановить как универсальное время

  • система должна учитывать разницу в летнем времени
    @ Может обрабатываться DaylightTime Class , TimeZone Class и т. Д.

  • не может полагаться на синтаксический анализ «DateTime», так как он анализирует богемно относительно времени локального сервера
    @ Тогда не полагайтесь на разбор DateTime

  • должен давать возможность разработчику иметь дело с обеими формами: дата-время и строковые объекты
    @ DateTime Class в качестве основы должен быть достаточно хорошим, используйте TimeZone / TimeZoneInfo / DaylightTime / DateTimeOffset и т. Д., Чтобы увеличить его

2 голосов
/ 28 ноября 2009

На самом деле, я считаю, что функциональность даты / времени .NET довольно приятна. Я озадачен вашими проблемами с этим.

Что именно вы пытаетесь сделать, что DateTimeOffset и TimeZoneInfo не могут сделать для вас?

  • «Пользователь вводит дату и время» - проверьте! Либо DateTime, либо DateTimeOffset будет работать здесь.
  • «Система переводит на универсальное время и экономит в источнике данных» - Проверить! Опять же, DateTime или DateTimeOffset будут работать для вас, хотя большинству серверных баз данных потребуется некоторая специальная обработка, если вы хотите сохранить смещения часового пояса. Если вы уже преобразуете его в UTC, просто сохраните его как поле datetime в SQL Server или эквивалент в другой RDBMS и не беспокойтесь о сохранении факта, что это UTC.
  • «Система извлекает универсальное время, преобразованное в местное время, выбранное разработчиком» - Проверить! Просто создайте TimeZoneInfo для желаемого местного времени, а затем позвоните TimeZoneInfo.ConvertTime.
  • «Система должна учитывать различия в летнем времени» - Проверьте! Вот для чего TimeZoneInfo.AdjustmentRule.
  • «Нельзя полагаться на синтаксический анализ« DateTime », так как он анализирует богемно относительно времени локального сервера» - ??? Во-первых, «богемный» даже не слово. И вы можете настроить, как дата / время анализируются с DateTime.ParseExact.
  • «Должен дать разработчику возможность работать в обеих формах: дата-время и строковые объекты» - Почему? Что плохого в том, чтобы хранить только одно внутреннее представление, а затем преобразовывать только на входе и выходе? Я не могу представить себе какую-либо операцию со значениями даты / времени, которая была бы упрощена, если бы она выполнялась со строкой.

Короче говоря, я думаю, что вы просто понимаете сложности обработки данных даты / времени в целом.

2 голосов
/ 28 ноября 2009

Я чувствую вашу боль - вот почему я участвую в проекте Noda Time по созданию полнофункционального API даты и времени для .NET. Тем не менее, это только отрывается от земли. Если вы все еще застряли в течение года, мы надеемся, что Noda Time будет ответом:)

Нормальная ситуация с .NET лучше, чем была сейчас, когда у нас есть DateTimeOffset и TimeZoneInfo, но этого все еще не хватает.

Пока вы правильно используете TimeZoneInfo дважды, все должно быть хорошо. Я не уверен, что синтаксический анализ DateTime должен быть слишком плохим - я думаю должен проанализировать его как DateTimeKind.Unspecified, если вы не укажете что-либо еще в данных. Затем вы можете конвертировать его в UTC, используя TimeZoneInfo.

Не могли бы вы предоставить короткую, но полную программу, которая показывает проблемы, с которыми вы столкнулись?

0 голосов
/ 29 ноября 2009

Благодаря Джону Скиту, который поставил меня на правильный путь, я никогда не знал этого раньше, но теперь я знаю, что DateTime объект не содержит в себе информацию о часовом поясе ВСЕ! поэтому всякий раз, когда я его использую, я уже теряю информацию о смещении даты и времени, однако объект DateTimeOffset сохраняет бит часового пояса, поэтому все мои объекты должны использовать его, я действительно думал, что объект datetimeoffset будет немного ограничивать чтобы задать вопрос о том, что отличается между datetime и datetimeoffset, я должен был это сделать!

Теперь я использую следующий код для получения нужной зоны:

string s = "2009-11-26T04:01:00.0000000Z";
DateTimeOffset d = DateTimeOffset.Parse(s);

TimeZoneInfo LocalTimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("AUS Eastern Standard Time");
DateTimeOffset newdate = TimeZoneInfo.ConvertTime(d, LocalTimeZoneInfo);
return newdate.ToString("yyyy-MM-dd HH:mm zzz");

спасибо всем за ваш вклад

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