handling rails + postgres and timezones

限于喜欢 提交于 2019-12-11 05:59:25

问题


I have an application which uses many different timezones... it sets them in a controller and they change depending on the user. All the times are stored in UTC without a timestamp etc.

My understanding is this is the normal way for Rails to handle timezones. This works fine 99% of the time until i need to do something directly with Postgres then the Timezone becomes a problem.

For example this query is completely wrong except for GMT, for example in Central Time Zone, depending on the hour set, it gets the wrong day:

Events.where("EXTRACT(dow FROM start_at)", Date.today.wday)

Where I'm trying to find all the dates that fall on a certain day.

I'm trying to do something like this. I don't need to search between timezones (they won't be mixed), but I do need to specify the timezone if it's not UTC to get correct results.

User.events.where("EXTRACT(dow FROM start_at AT TIME ZONE ?) = ?", 'UTC', Date.today.wday)

But I'm not sure how to use Time.zone to give me something that will work with TIME ZONE in Postgres.

Time.zone.tzinfo sometimes works... Postgres will work with 'Europe/Warsaw' but Rails returns 'Europe - Warsaw'

In general I'm not having much luck with timezones, any pointers would be appreciated.


回答1:


Maybe someone else has a better overall solution, but what you need for the particular query is

Time.zone.tzinfo.identifier

Or, in your example:

User.events.where("EXTRACT(dow FROM start_at AT TIME ZONE ?) = ?", Time.zone.tzinfo.identifier, Date.today.wday)



回答2:


Try using the Ruby TZInfo gem directly, instead of using Rails ActiveSupport::TimeZone.

Alternatively, use the MAPPING constant, as shown in the ActiveSupport::TimeZone documentation, which will take you from a Rails time zone key back to the standard IANA time zone identifier used by Postgres and others.




回答3:


As Matt Johnson suggested use TZInfo gem directly. This way you can get the correctly formatted time zone identifiers you need to query with PostgreSQL.

For example if you use:

TZInfo::Timezone.all_country_zone_identifiers

This will return an array of correct IANA/Olson time zone identifiers. In other words you will get the correct 'Europe/Warsaw' NOT 'Europe - Warsaw'.



来源:https://stackoverflow.com/questions/19163862/handling-rails-postgres-and-timezones

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!