ubuntu server missing time zone in Rails app - ruby-on-rails

in the rails console, on one server i get
ActiveSupport::TimeZone.all.map(&:name).select{|x| x.downcase.include? "east"}
=> ["Indiana (East)"]
But in another I get
ActiveSupport::TimeZone.all.map(&:name).select{|x| x.downcase.include? "east"}
=> ["Eastern Time (US & Canada)", "Indiana (East)"]
What is the determinant of the available time zones in a Rails app?
Thanks
Kevin

Related

RSpec Time comparision fails locally, passes CircleCI and Heroku

My rspec test fails on local machine between 6:00pm and 6:59pm, but passes at before 5:59pm and after 7:00pm on the local machine,
It seems to pass on CircleCI and Heroku, but I do not know if CircleCI or Heroku fail at specific times.
I set my local computer time to UTC, and it seems #subscription.current_period_end is incorrect by 1 hour.
I suspect it has something to do with how my local machine handles the time vs CircleCi and Heroku. Any ideas how to address this issue?
Code:
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
Error
Failure/Error: expect(Time.zone.at(invoice.next_payment_attempt)).to 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
Most likely you have a bug in time calculations, potentially a time zone-related one.
Fire up pry or byebug on your local machine when the time comparison fails in the test and figure out which time is the correct one. Then figure out why the other time is wrong and fix that.
Suggest that you always store everything as UTC. Log timestamps, payment timestamps, audit dates, whatever. Do all your date and time calculations and intervals using the UTC values. That way you never ever have an issue with figuring out what happened, and the order in which it happened, even when your users are in different time zones, or they check out their shopping cart at 01:59:59 on the morning when you switch out of daylight saving time in the autumn. If you have a requirement to display dates and times to your users, this is a presentation issue and you can always convert the UTC values to their local timezone values for display purposes.
It was a stripe issue. They do not finalize an invoice until 1 hour after invoice is created, hence I needed to add an hour. #subscription.current_period_end+1.hour

timezone id to short timezone (pst, pdt, cst, etc)

I use Googles Timezone API to get TimeZoneID and I pass it to the ruby gem TZInfo to get the local time. How can I get the Timezones short name (PST, PDT, EST, etc...) from this info. I tried strftime(%Z) but that returns 'UTC'. This is a ruby on rails app.
TZInfo::Timezone#strftime ought to work:
require "tzinfo"
tz = TZInfo::Timezone.get("America/New_York")
puts tz.strftime("%Z")
If you tried that and it didn't work, that's mysterious.
Alternatively, you can use TZInfo::TimezonePeriod#abbreviation:
tz = TZInfo::Timezone.get('America/New_York')
period = tz.period_for_utc(Time.now.utc)
puts period.abbreviation

Single Sign-on - PingfFederate - How to set the date?

I noticed when PingFederate(PF) sends the date it is off by a day from my Rails app. It appears that the PF date is the one off by a day. For example in the PF SAML response I get:
<saml:Assertion ID="pEaf1kce93SpAxfIpuohOv6QP-T" IssueInstant="2014-05-03T03:15:20.020Z" Version="2.0" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
and
<saml:Conditions NotBefore="2014-05-03T03:10:20.021Z" NotOnOrAfter="2014-05-03T03:20:20.021Z">
whereas in Rails I get
Time.now = 2014-05-02 20:15:19 -0700
which makes me think that I need to set the date in PF. Note that PF is running on the same computer that the Rails app is running on.
Is there a way to set the date in PF?
The time is off as well. Is there a way in PF to set the time too?
SAML assertions are always in UTC. Which is what PingFed is using. Set your Rails application to use UTC as well.
I don't see why you think that the time is off. Your time from Rails is 2015 and -7. That means in UTC, it's tomorrow at 0315 - when it was issued. PingFed is setting an allowance of +/-5 minutes, so the SP should not accept it before 0310 or after 0320.
Your server and PingFed are correct so far...

Rails, how to get 1.day.from_now at a set time (morning)?

I currently queue my DelayedJob like so:
Delayed::Job.enqueue MyJob.new, 5, 1.day.from_now
I'm looking for a way to set a different execution time:
Tomorrow morning at 9:30am PST
Does Rails have a helper that can take care of this? Thanks
If your rails server is not running in PST/PDT:
Time.use_zone("Pacific Time (US & Canada)") { 1.day.from_now.beginning_of_day + 9.5.hours }
If it is already running in PST/PDT, you can shorten it to:
1.day.from_now.beginning_of_day + 9.5.hours
Have a look at Time and TimeZone for more info.

Excessive stat calls on /etc/localtime in Rails Application

I just straced my Rails-App and it produces a lot of
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2309, ...}) = 0
Calls (really a lot!).
In other contexts I've read that this is because the Timezone is not set.
Is there a way to "fix" this?
Best,
Tobias
It's not a ruby issue but rather a C / Linux issue:
Setting "TZ" ENV-Var will lead to no more stat calls on etc/localtime.
It wont have significant performance impacts though:
# irb
require 'benchmark'
Benchmark.measure { 10_000_000.times { Time.now } }
=> 17.880000 0.540000 18.420000 ( 21.535307)
# same with TZ=CET irb
=> 18.040000 0.550000 18.590000 ( 20.892542)
As #fabio said, you should report this to the Rails forums or mailinglist, because its probably a bug.
However, to set the time zone, in your config/environment.rb:
Rails::Initializer.run do |config|
config.time_zone = "Central Time (US & Canada)"
end
you can get available time zones with rake time:zones:us, rake time:zones:local, or rake time:zones:all (depending on where you are in the world.)

Resources