Table of Contents
PostgreSQL
DO NOT configure time_zone in config/application_.rb. Instead, localize_date to user timezone.
# application_helper.rb def localize_date(date) I18n.l date.in_time_zone('Madrid'), format: "%d/%m/%Y %a, %H:%M" if date end
Convert date/time strings to timestamp with to_timestamp(..)
Query:
@activities = Activity.joins(:project).select('projects.name').where("start >= to_timestamp('#{params[:start]}', 'DD/MM/YYYY')").where("start <= to_timestamp('#{params[:ended]} 23:59:59', 'DD/MM/YYYY HH24:MI:SS')").group(:name).sum(:duration) @number_of_entries = Activity.where("start >= to_timestamp('#{params[:start]}', 'DD/MM/YYYY')").where("start <= to_timestamp('#{params[:ended]} 23:59:59','DD/MM/YYYY HH24:MI:SS')").count @total_duration = Activity.where("start >= to_timestamp('#{params[:start]}', 'DD/MM/YYYY')").where("start <= to_timestamp('#{params[:ended]} 23:59:59', 'DD/MM/YYYY HH24:MI:SS')").sum('duration')
Attention: Rails time zone <= vs => PG UTC
PostgreSQL save Ruby DateTime into timestamp UTC (WITHOUT timezone)
Function to_timestamp(date-time , format ) converts string date-time into timestamp WITH timezone, ie UTC+1 / UTC+2 summer
Working with time zone recommendations
http://www.elabs.se/blog/36-working-with-time-zones-in-ruby-on-rails
Configure: config.time_zone in config/application.rb
- Use: Time.zone.parse
- Use: 2.hours.ago
- Preferred Time (or DateTime) to Date because the former includes date info. Date doesn't include time info.
- Use: Date.today.in_time_zone. Never Date.today.to_time
- Quering with rails way (never SQL). Ex: Post.where([“posts.published_at > ?”, Time.current])
Cheat Sheet
DOs
2.hours.ago # => Fri, 02 Mar 2012 20:04:47 JST +09:00 1.day.from_now # => Fri, 03 Mar 2012 22:04:47 JST +09:00 Date.today.in_time_zone # => Fri, 02 Mar 2012 22:04:47 JST +09:00 Date.current # => Fri, 02 Mar Time.zone.parse("2012-03-02 16:05:37") # => Fri, 02 Mar 2012 16:05:37 JST +09:00 Time.zone.now # => Fri, 02 Mar 2012 22:04:47 JST +09:00 Time.current # Same thing but shorter. (Thank you Lukas Sarnacki pointing this out.) Time.zone.today # If you really can't have a Time or DateTime for some reason Time.current.utc.iso8601 # When supliyng an API (you can actually skip .zone here, but I find it better to always use it, than miss it when it's needed) Time.strptime(time_string, "%Y-%m-%dT%H:%M:%S%z").in_time_zone # If you can't use time.zone.parse
DON'Ts
Time.now # => Returns system time and ignores your configured time zone. Time.parse("2012-03-02 16:05:37") # => Will assume time string given is in the system's time zone. Time.strptime(time_string, "%Y-%m-%dT%H:%M:%S%z") # Same problem as with Time#parse. Date.today # This could be yesterday or tomorrow depending on the machine's time zone. Date.today.to_time # => # Still not the configured time zone.
Work with Time.zone
http://danilenko.org/2012/7/6/rails_timezones/
Server in UTC+4 Client in UTC-5
Time.zone = 'EST' DateTime.now.to_s # => "2012-07-06T13:30:00+04:00" Time.now.to_s # => "2012-07-06 13:30:00 +0400" Time.zone.now.to_s # => "2012-07-06 04:30:00 -0500"
Time.zone = 'EST' Time.now.end_of_day.to_s # => "2012-07-06 23:59:59 +0400" >><<<<>><< WRONG!!! Time.zone.now.end_of_day.to_s # => "2012-07-06 23:59:59 -0500" >><<<<>><< GOOD!!!
GOOD
Time.zone = 'EST' Time.now.in_time_zone.end_of_day.to_s # => "2012-07-06 23:59:59 -0500" Time.zone.now.end_of_day.to_s # => "2012-07-06 23:59:59 -0500"
Cheat sheet
Get current time
Time.zone.now Time.current
Get Day (Today, Yesterday, etc.)
Time.zone.today Time.zone.today - 1
Build time
Time.zone.local(2012, 6, 10, 12, 00)
Time From Timestamp
Time.zone.at(timestamp)
Parse Time (Simple)
Time.zone.parse(str)
Parse time with explicit format
Time.zone.parse(str, "%Y-%m-%d %H:%M %Z").in_time_zone #<<<<<< acceptable Time.zone.strptime(str, "%Y-%m-%d %H:%M") # <<<< better with gem time_zone_ext [[https://github.com/doz/time_zone_ext]]
Getting time for date
date.beggining_of_day
Testing dates in timezone with postgres
# factory.rb activation_date { Time.current.utc.iso8601 }