Context
I have a Rails API that is deployed at different locations, thus, using 2 different timezones: Pacific/Noumea (+11:00) and Pacific/Tahiti (-10:00).
I've configure both server to use the correct timezone:
config.time_zone = ENV.fetch('APP_TIMEZONE', 'Pacific/Noumea')
Problem
The API is validating some date range (start_at
and end_at
).
class DatesRangeValidator < ActiveModel::Validator
def validate(record)
check_end_at_is_before_now(record)
check_end_at_is_before_start_at(record)
end
protected
def check_end_at_is_before_now(record)
return if record.end_at.blank? || record.end_at > Time.zone.now
record.errors.add(
:end_at,
I18n.t("activerecord.errors.models.#{record.class.name.underscore}.attributes.end_at.before_now")
)
end
def check_end_at_is_before_start_at(record)
return if record.end_at.blank? || record.start_at.blank?
return if record.end_at > record.start_at
record.errors.add(
:end_at,
I18n.t("activerecord.errors.models.#{record.class.name.underscore}.attributes.end_at.before_start_at")
)
end
end
When using Pacific/Noumea timezone, it works fine because the offset is positive.
For example, when testing, the local time is 2025-03-18 10:14:00 +11:00
:
- from the UI, user set
end_at
as2025-03-18 10:16
- the value received in
params
is{"end_at"=>"2025-03-17T23:16:00.000Z"}
- Internally in the validator, Rails convert that date as
2025-03-18 10:16:00 +1100
which returns true
because 2025-03-18 10:16:00 +1100 > 2025-03-18 10:14:00 +11:00
.
However, when doing the same thing with Pacific/Tahiti
, it does not works.
Local time is 2025-03-17 13:19:00 -10:00
:
- from the UI, user set
end_at
as2025-03-17 13:25
- the value received in
params
is{"end_at"=>"2025-03-17T02:25:00.000Z"}
- Internally in the validator, Rails convert that date as
2025-03-16 16:25:00 -1000
which returns false
because 2025-03-16 16:25:00 -1000 < 2025-03-17 13:19:00 -10:00
.
What am I missing ? How to handle it ?