В какой-то момент своей жизни каждому разработчику приходится сталкиваться с проблемой, которую я называю «уйти со своего двора». Когда вы пишете код на своем компьютере, вы работаете в контролируемой среде. Но мир не управляется одними и теми же правилами, и у нас есть несколько проверок реальности, которые могут вызвать несколько головных болей.

Часовые пояса — одна из таких суровых реалий. Конечно, если мы говорим о показе даты публикации новости +/- несколько часов, это не конец света. Но бывают ситуации, когда +/- один час может вызвать серьезные проблемы, например, дублирование денежной транзакции.

Время приложения, время сервера, время базы данных, время клиента, время клиента и…

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

Мы должны остановиться и подумать о факторах, которые мы реально можем контролировать, и о тех, которые позволят масштабировать проект в будущем.

Для тех из нас, кто разрабатывает приложения в среде Rails, лучше предположить, что, хотя мы можем контролировать машину, на которой размещен сервер, эта возможность даже недоступна. Поэтому мы должны заботиться только о датах, хранящихся в приложении и в базе данных.

Связанный пост: Повторение: еще 4 совета по работе с часовыми поясами

С другой стороны, Rails, предвидя эти сценарии, хранит ВСЕ даты в базе данных в формате UTC (+0000), позже конвертируя даты в часовой пояс приложения.

Единственные даты, о которых мы должны заботиться, и единственные, над которыми мы должны работать, это те, которые указаны в заявке. Объединение любых других дат означает перемещение в неизведанные земли.

Настройка приложения Rails

Мы можем, если захотим, установить часовой пояс, отличный от стандартного (UTC) в config/application.rb в разделе config. time_zone (например: config.time_zone = 'Центральное время (США и Канада)'). Для каждой сериализации кортежа запросов, который мы делаем в базе данных с определенной датой, Rails самостоятельно изменит его на конкретный часовой пояс.

Излишне говорить, что эта опция полезна только в том случае, если наше приложение локализовано (зависит от времени).

Время применения/дата/время

Повторяющаяся ошибка при работе с часовыми поясами — не находит правильный способ запросить время у приложения. Такие инструкции, как Time.new, Time.now, Date.today или to_time предполагает, что пользователь запрашивает серверное время. Поэтому, если у нас войдет в привычку их использовать, а наши спецификации написаны одинаково, мы ошибочно предположим, что все работает идеально, и столкнемся с проблемами, когда окажемся в производственной среде с реальными данными.

Чтобы сообщить Rails, что нам нужна дата, установленная в часовом поясе приложения, который мы установили ранее, мы должны использовать убедительные методы.

TimeWithZone — это класс, который фактически позволит нам это сделать (ActiveSupport::TimeWithZone). И в существующих простых формах, используемых для их создания, у нас есть Time.zone.now/Time.zone.parse. Внутри Time.zone вызывает экземпляр типа ActiveSupport::TimeZone, в котором хранится часовой пояс, который мы установили по умолчанию, и запрос от это текущая дата или дата, которую мы хотим проанализировать. У нас также есть доступный Time.current, который будет запускать Time.zone.now внутри или с методом экземпляра in_time_zone Time, превращая Время в TimeWithZone из часового пояса по умолчанию.

DateTime — это более точное время, и оно также имеет собственное текущее значение.

Дата подачи заявки

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

См. также: Асинхронная обработка с использованием SQS и Shoryuken

В большинстве случаев, когда вы работаете с разными часовыми поясами, это приведет к переходу на Время.

Но если мы выбираем Date и хотим преобразовать экземпляр в Time, давайте вспомним, что Date.today.to_time вернет сервер Время, а Date.today.in_time_zone вернет приложение Время.

Если вы хотите узнать больше о часовых поясах, вы можете прочитать Реприза: еще 4 совета по работе с часовыми поясами. Когда вы закончите читать оба сообщения, считайте себя экспертом в этой теме!

Автор: Гастон Понти ([email protected])

www.wolox.com.ar