Независимое от времени время сопоставление даты в рельсах

Рассмотрим следующий случай. У меня есть модель ваучера с областью времени datetime : before_activation_due , lambda { | пользователь | где ( 'activation_due_date>?' , Time . current . to_utc + user . utc_offset ) } поле и модель пользователя, которая имеет самую последнюю информацию о своем местоположении (часовой пояс, смещение по UTC).
Я хочу проверить, запрашивает ли он активацию ваучера до наступления срока в любом из доступных часовых поясов, Например, если установленная дата установлена ??на 28.08.2018 23:59 UTC Я хочу, чтобы моя область действия before_activation_due проверяла, запрашивает ли он что-то до 28.08.2018 - 23:59 в своем текущем часовом поясе, поэтому моя дата не была зафиксирована - это зависит от местоположения пользователей. В одном месте это может быть после установленного срока, а в другом - раньше.
Я пробовал следующий подход.

модели / voucher.rb

activation_due_date

Мои вопросы:

  1. Правильно ли это? Если нет, то каков надлежащий способ справиться с такими случаями?

  2. Как проверить такую ??область? Текущая временная метка, вероятно, берется с сервера базы данных при сравнении дат во время выполнения запроса, поэтому я не уверен, как издеваться над этим в моих спецификациях.

Заранее спасибо.

ruby-on-rails,postgresql,datetime,activerecord,timezone,

0

Ответов: 2


1 принят

Один из подходов состоит в том, чтобы преобразовать activation_due_dateв часовой пояс пользователя. Как вы говорите, «моя дата не зафиксирована - это зависит от местоположения пользователей».

Чтобы сделать это как область применения, проще всего использовать функции часовых поясов ваших баз данных. Это зависит от того, какую базу данных вы используете, но в PostgreSQL это будет примерно так:

where('activation_due_date AT TIME ZONE ? > NOW() ', user.timezone)


Еще проще было бы провести сравнение строк

where('to_char(activation_due_date, 'YYYYMMDDHH24MISS') > ?', Time.current.in_time_zone(user.timezone).strftime('%Y%m%d%H%M%S');

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


3

Вы можете сохранить только часовой пояс пользователя, а не смещение, а затем выполните:

where('activation_due_date > ? ', Time.now.utc.in_time_zone(user.timezone))

где часовой пояс - любой действительный часовой пояс, показанный в

rake time:zones

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

Чтобы протестировать это, вы можете вручную вставить любую дату, которую хотите в свою базу данных. Затем вы можете использовать драгоценный камень, например https://github.com/travisjeffery/timecop, чтобы проехать вовремя до этого момента и проверить свою область:

Voucher.create(activation_due_date: '2018-01-02 00:00:00')
format = '%Y-%m-%d %H:%M:%S %Z'
time = DateTime.strptime("2018-01-02 00:00:00 Central Time (US & Canada)",format)
Timecop.travel(time)
Voucher.before_activation_due.all ...
рубин-на-рельсы, PostgreSQL, дата и время, ActiveRecord, часовой пояс,
Похожие вопросы