Aleksey Salow (w00dy) wrote,
Aleksey Salow
w00dy

Category:

О датах

Запишем даты в список проклятых тем в этом вашем вайти в которые никто не умеет. У всех с этими датами, временем, таймзонами выходит какая-то херня из-за чего всё едет к чертям и не работает.

Начать нужно с того что даты бывают разные и сильно зависят от контекста в котором их используют. Новый год в любой точке глобуса наступает 1 января, и в Владивостоке, и в Мариуполе, и в Нью-Йорке. Будильник настроенный на 9 утра должен звонить в 9 утра независимо от текущего местоположения. Но разговор по телефону назначенный на 9 утра в NY, в Киеве случится в 16 часов. Улавливаете мякотку?

Что делать, спросит читатель. Самое лучшее и универсальное решение: валить нафиг с этого вашего вайти. Сантехник, электрик, автомеханик, бариста на худой конец - пусть с датами разбирается кто-то другой. Решение похуже - забить. 83% разработчиков никогда в жизни не задумаются о таких сложных вопросах и у них всё будет работать. Не всегда правда, но то уже мелочи. Самое плохое решение - вот о нём и поговорим.

Я озвучу свой частный случай, ибо полного и универсального решения у меня нет, но думаю что оно и не надо. И так: сохраняйте контекст. Не обязательно в базе, можно (и наверное лучше), в ТЗ и сопроводительной документации. Нужно чётко понимать какие даты следуют за таймзонами, какие нет. При этом выбирайте правильные типы, дата это собирательное название для собсна даты, времени и даты с временем. При этом внезапно может оказаться что указывать нужно только дату, но при этом она должна ходить за таймзонами (как?). Что делать в коде: я не придумал ничего умнее чем написать кастомный материалайзер для EF6 и просто расставлять kind для дат на основании вручную проставленых атрибутов (метапрограммирование убер алес). Для тех кто ходит за таймзонами - UTC (они и в базе храняться как UTC). Для фиксированных - Local (в базе по хорошему хранить как date, time, datetimeoffset, но реальность вы и без меня знаете). Ещё написал свой конвертер в json, соответственно даты в UTC сериализуются с указанием таймзоны 'Z', даты в Local идут без таймзоны (почему-то Newtonsoft.Json так не умеет из коробки). В итоге на сайте они отображаются правильно, первые автомагически переводятся в таймзону клиента, вторые нет. Какие ещё есть подводные камни - вычисление интервалов. Часть дат у вас в UTC, часть фиксированы, это нужно помнить и учитывать. Ещё момент - входящие данные. Пользователь что-то ввёл - опять же не забывать правильно трактовать (наверное проще сделать через атрибуты и json converter, хотя хз, я на этот момент забил).

Да хранят вас боги времени :)

PS Никому электрик не нужен?
Subscribe

  • Пограммирование

    Две вещи которые не умеет абсолютное большинство UI погромиздов (тех кто так или иначе к нему прикасается): глобализация и поддержка различных dpi.…

  • Windows Update 1511

    Пришло большое обновление на винду. Из нового пока только заметил новую иконку у Safely Remove Hardware and Eject Media и Windows Spotlight на lock…

  • Windows 10: Про своп в винде

    В винде своп отключать нельзя. Я б даже больше сказал, ручное управление не имеет смысла, только system managed. Это, в принципе, всё что вам нужно…

  • Post a new comment

    Error

    default userpic

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.
  • 34 comments

  • Пограммирование

    Две вещи которые не умеет абсолютное большинство UI погромиздов (тех кто так или иначе к нему прикасается): глобализация и поддержка различных dpi.…

  • Windows Update 1511

    Пришло большое обновление на винду. Из нового пока только заметил новую иконку у Safely Remove Hardware and Eject Media и Windows Spotlight на lock…

  • Windows 10: Про своп в винде

    В винде своп отключать нельзя. Я б даже больше сказал, ручное управление не имеет смысла, только system managed. Это, в принципе, всё что вам нужно…