Сравнение времени RSpec не выполняется локально, передает CircleCI и Heroku

#ruby-on-rails #ruby #datetime #timezone

#ruby-on-rails #ruby #дата и время #Часовой пояс

Вопрос:

Мой тест rspec завершается с ошибкой на локальном компьютере между 6: 00 вечера и 6: 59 вечера, но проходит до 5: 59 вечера и после 7: 00 вечера на локальном компьютере,

Кажется, что оно передается CircleCI и Heroku, но я не знаю, завершаются ли CircleCI или Heroku сбоем в определенное время.

Я установил время своего локального компьютера на UTC, и оно кажется @subscription.current_period_end неправильным на 1 час.

Я подозреваю, что это как-то связано с тем, как мой локальный компьютер обрабатывает время по сравнению с CircleCI и Heroku. Есть идеи, как решить эту проблему?

Код:

 def get_proration_date
  Time.zone.now.to_i
end
  

Application.rb

 config.active_record.default_timezone = :utc
config.time_zone = "UTC"
  

Rspec

 it "should create upcoming_invoice with existing plan for the next_month if there are no changes to subscription(Mock Version)", live: false do
  create_stripe_elements
  stripe_gold_plan
  @subscription = payment_gateway.create_subscription(plan: silver_plan, user: user,
                   coupon_id: @coupon.stripe_id, source_id_or_token: default_card_token)
  invoice = payment_gateway.upcoming_invoice_for_update_plan(subscription: @subscription, to_plan: silver_plan,
            coupon_id: "", proration_date: get_proration_date)
  expect(invoice.lines.total_count).to eql(1)
  expect(invoice.amount_due).to eql(silver_plan.amount)
  expect(invoice.total).to eql(silver_plan.amount)
  expect(Time.zone.at(invoice.next_payment_attempt)).to eql(@subscription.current_period_end)
  delete_stripe_elements
end
  

Ошибка

Сбой / ошибка: ожидаемый (Time.zone.at (invoice.next_payment_attempt)).в eql (@subscription.current_period_end)

    expected: 2020-09-27 00:20:20.000000000  0000
        got: 2020-09-27 01:20:20.000000000  0000
 
   (compared using eql?)
 
   Diff:
   @@ -1,2  1,2 @@
   -Sun, 27 Sep 2020 00:20:20 UTC  00:00
    Sun, 27 Sep 2020 01:20:20 UTC  00:00
  

Комментарии:

1. Вы случайно не в США / Канаде по горному времени? Я предполагаю, что ваша машина настроена на горное время, которое в настоящее время составляет UTC — 6. Таким образом, после 6:00 вечера ваше местное время current_period_end.to_date (которое, вероятно, хранится в UTC) будет «завтра» по сравнению с Time.zone.new.to_date . После 7 часов вечера по местному времени вы снова попадаете в ту же дату. CircleCI и Heroku по умолчанию являются UTC, поэтому не показывают проблему. Либо преобразуйте оба в местный часовой пояс, либо сравните оба как UTC.

2. Вы можете использовать timecop для замораживания времени тестирования, это обеспечит согласованность

3. @rmlockerd, как мне установить UTC? Я думал, что у меня время UTC

Ответ №1:

Скорее всего, у вас ошибка в вычислениях времени, возможно, связанная с часовым поясом.

Запустите pry или byebug на своем локальном компьютере, когда сравнение времени завершается неудачно в тесте, и выясните, какое время является правильным. Затем выясните, почему другое время неверно, и исправьте это.

Ответ №2:

Рекомендуется всегда сохранять все в формате UTC. Временные метки журнала, временные метки платежей, даты аудита, что угодно. Выполните все свои вычисления даты и времени и интервалов, используя значения UTC. Таким образом, у вас никогда не возникнет проблем с выяснением того, что произошло, и порядка, в котором это произошло, даже если ваши пользователи находятся в разных часовых поясах, или они проверяют свою корзину покупок в 01:59:59 утром, когда вы переходите на летнее время осенью. Если у вас есть требование к отображению дат и времени для ваших пользователей, это проблема с презентацией, и вы всегда можете преобразовать значения UTC в их значения местного часового пояса для целей отображения.

Ответ №3:

Это была проблема с полосой. Они не завершают счет-фактуру до 1 часа после создания счета-фактуры, поэтому мне нужно было добавить час. @subscription.current_period_end 1.hour