Почему Date.yesterday () возвращает позавчера в рельсах? - PullRequest
0 голосов
/ 10 июля 2020

Меня немного смущает Date.yesterday(), например:

$ rails c
Loading development environment (Rails 6.0.3.2)
irb(main):001:0> Date.today
=> Fri, 10 Jul 2020
irb(main):002:0> Date.yesterday
=> Wed, 08 Jul 2020
irb(main):003:0> Time.now
=> 2020-07-10 03:54:46.02207138 +0530
irb(main):004:0>

введите описание изображения здесь

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

Что происходит в здесь?

Ответы [ 4 ]

3 голосов
/ 10 июля 2020

tl; dr: используйте Date.current и Time.current вместо Date.today и Time.now.

Ваше приложение имеет собственный часовой пояс Time.zone. Ruby не знает часовых поясов, но Rails знает. Rails частично обновляет Time и Date, чтобы знать часовые пояса, но не полностью. Любые методы, добавленные Rails, будут учитывать часовой пояс. Date.yesterday и Date.tomorrow, например. Встроенные Ruby методы, которые он оставляет в покое, например Date.today. Это вызывает некоторую путаницу .

Date.today дает сегодня по вашему местному часовому поясу +0530. Date.yesterday дает вчера в соответствии с часовым поясом вашего приложения, который, как я предполагаю, равен +0000 (UT C). 2020-07-10 03:54:46 +0530 - это 2020-07-09 22:24:46 UT C поэтому Date.yesterday - это 2020-07-08.

Используйте Date.current вместо Date.today. Date.yesterday - это тонкая обертка вокруг Date.current.yesterday. Точно так же используйте Time.current вместо Time.now.

В статье ThoughtBot It's About Time (Zones) подробно обсуждаются часовые пояса Rails и есть простые DO и НЕЛЬЗЯ избегать путаницы с часовыми поясами.

НЕ ИСПОЛЬЗУЙТЕ

  • Time.now
  • Date.today
  • Date.today. to_time
  • Time.parse («2015-07-04 17:05:37»)
  • Time.strptime (строка, «% Y-% m-% dT% H:% M :% S% z ")

ИСПОЛЬЗОВАТЬ

  • Time.current
  • 2.hours.a go
  • Time.zone.today
  • Date.current
  • 1.day.from_now
  • Time.zone.parse («2015-07-04 17:05:37»)
  • Time.strptime (строка, «% Y-% m-% dT% H:% M:% S% z»). In_time_zone
1 голос
/ 10 июля 2020

В вашем приложении Rails вы можете установить значение Time.zone или в конфигурации config.time_zone.

Если одно из этих значений настроено, Rails использует его следующим образом:

def yesterday
  ::Date.current.yesterday
end

def current
  ::Time.zone ? ::Time.zone.today : ::Date.today
end 

Это помощники ActiveSupport Date

1 голос
/ 10 июля 2020

Обязательно проверьте расположение сервера, на котором работает приложение. Значение Date.yesterday, скорее всего, будет зависеть от расположения сервера по отношению к международной линии дат. Например, хотя в Нью-Йорке еще четверг, 09.07.2020, в Новой Зеландии пятница, 10.07.2020.

0 голосов
/ 10 июля 2020

Так что это действительно результат неправильного часового пояса, в моем случае Time.zone.name вернул "UTC". Правильная зона для меня - Asia / Kolkata , чтобы проверить наличие часового пояса:

ActiveSupport::TimeZone::MAPPING.select { |x| x[/^kol/i] }

Что вернуло {"Kolkata"=>"Asia/Kolkata"} в моем случае.

  • Чтобы он вступил в силу временно, я установил Time.zone = 'Kolkata' в консоли rails.

  • Для постоянного эффекта добавил config.time_zone = 'Kolkata' к {project_root}/config/application.rb.

Это устранило проблему, и Date.yesterday(), Date.today() и Date.tomorrow() работают должным образом.

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