Как сохранить «DateTime.now» как текущий объект DateTime - PullRequest
0 голосов
/ 13 апреля 2020

Моя среда:

  • Ruby 2.6.3p62 (версия 20175-04-16 67580) [x86_64-darwin18]
  • Rails 6.0.2.1
  • MacOS X Mojave
  • psql
  • Версия Puma 4.3.3 (Ruby 2.6.3-p62)

По какой-то причине Rails сохраняет DateTime.now в моей базе данных за 7 часов в будущем:

2.6.3 :002 > DateTime.now
 => Sun, 12 Apr 2020 20:52:00 -0700
2.6.3 :003 > v.last_prompting = DateTime.now
 => Sun, 12 Apr 2020 20:52:05 -0700
2.6.3 :004 > v.save
   (0.1ms)  begin transaction
  Volunteer Update (0.3ms)  UPDATE "volunteers" SET "updated_at" = ?, "last_prompting" = ? WHERE "volunteers"."id" = ?  [["updated_at", "2020-04-13 03:52:10.964288"], ["last_prompting", "2020-04-13 03:52:05.779767"], ["id", 1]]
   (1.1ms)  commit transaction
 => true
2.6.3 :005 > v.last_prompting
 => Sun, 12 Apr 2020 20:52:05 PDT -07:00

Посмотрите на last_prompting и updated_at - оба они 13 апреля, а сегодня 12 апреля.

Но когда я проверяю время в консоли, оно делает правильную вещь:

2.6.3 :005 > v.last_prompting
 => Sun, 12 Apr 2020 20:52:05 PDT -07:00
2.6.3 :006 > v.last_prompting.future?
 => false
2.6.3 :007 > v.last_prompting.past?
 => true

Я пытаюсь написать метод для express как долго go было last_prompting:

def prompting_age
    return "never" if self.last_prompting == nil

    if self.last_prompting.between?(Time.now - 720.minutes, Time.now - 10.years)
      ">12 hrs"
    elsif self.last_prompting.between?(Time.now - 240.minutes, Time.now - 719.minutes)
      ">4 hrs"
    elsif self.last_prompting.between?(Time.now - 61.minutes, Time.now - 239.minutes)
      ">1 hr"
    elsif self.last_prompting.between?(Time.now, Time.now - 60.minutes)
      "<1 hr"
    else
      "weird"
    end
end

Каждый раз, когда я проверяю этот метод, он возвращает «странный». Я думаю, это потому, что Rails сообщает о будущем, но не делает это в консоли, когда я запускаю приложение через Puma.

1 Ответ

1 голос
/ 13 апреля 2020

При использовании between? аргумент min должен предшествовать max. По сути, вам просто нужно изменить порядок атрибутов.

Версия, использующая общую идиому Ruby, будет выглядеть так:

def prompting_age
  return "never" unless last_prompting

  if last_prompting.between?(10.years.ago, 12.hours.ago)
    ">12 hrs"
  elsif last_prompting.between?(12.hours.ago, 4.hours.ago)
    ">4 hrs"
  elsif last_prompting.between?(239.minutes.ago, 61.minutes.ago)
    ">1 hr"
  elsif last_prompting.between?(60.minutes.ago, Time.current)
    "<1 hr"
  else
    "weird"
  end
end

Изменения:

  • Нет нужно для self в вашем коде.
  • Нет явной проверки против == nil, поскольку nil уже неверно введен в Ruby
  • Измените Time.now - 720.minutes на 720.minutes.ago, что легче для чтения, сокращения и учета информации о часовом поясе. , И используйте Time.current вместо Time.now, чтобы также учитывать информацию о часовом поясе.

Кроме того, вы упускаете некоторые моменты времени при сравнении, например, одно условие до 60.minutes но следующий начинается в 61.minutes.ago. Это означает, что вы пропустите записи, например, запрос 60 минут и 10 секунд go.

. Для исправления я переписал бы код примерно так:

def prompting_age
  return "never" unless last_prompting

  if last_prompting.before?(12.hours.ago)
    ">12 hrs"
  elsif last_prompting.before?(4.hours.ago)
    ">4 hrs"
  elsif last_prompting.before?(60.minutes.ago)
    ">1 hr"
  elsif last_prompting.before?(Time.current)
    "<1 hr"
  else
    "weird"
  end
end

Примечание. что последняя версия имеет слегка измененное поведение. Он не возвращает «странный» для записей, запрашиваемых более 10 лет go, и это одна секунда от вашей версии. И то и другое нормально ...

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