简体   繁体   中英

Rails: Clarification (rules-of-thumb?) for Date/Time, to_time and time zones

tl;dr : what are the rules for working with Date, Time & Datetime so I'm assured consistency across my apps?

I'm trying to wrap my head around working with Dates & Times & Zones in Rails so I don't accidentally use UTC when I really want all "user facing" dates/times adjusted for time zone. I'm noticing what appears, to me at least, to be some inconsistency and I'm hoping to understand rules or logic behind them so I'm not "surprised" again.

1.9.3p194 :028 > e = Event.find(1)
  Event Load (0.3ms)  SELECT "events".* FROM "events" WHERE "events"."id" = $1 LIMIT 1  [["id", 1]]
 => #<Event id: 1, start_at: "2012-08-27 19:15:00", end_at: "2012-08-27 21:00:00", created_at: "2012-08-22 07:43:31", updated_at: "2012-08-23 03:01:59"> 

1.9.3p194 :037 > e.start_at              # <== start_at is DateTime in model
 => Mon, 27 Aug 2012 12:15:00 PDT -07:00  
1.9.3p194 :036 > e.start_at.to_time
 => 2012-08-27 19:15:00 UTC              ### <=== This is in UTC..  ok...

1.9.3p194 :034 > DateTime.now
 => Thu, 23 Aug 2012 10:44:16 -0700      # <=== Also a DateTime
1.9.3p194 :035 > DateTime.now.to_time
 => Thu, 23 Aug 2012 10:44:19 -0700      ### <=== But this is in Pacific Time ?!?

2 differing responses from to_time ? Or did I miss something?

The fairly cryptic documentation for DateTime's to_time doesn't make any mention of timezone:

to_time() Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class. If self has an offset other than 0, self will just be returned unaltered, since there's no clean way to map it to a Time.

So what are "rules" for getting consistent dates & times out of Rails?

I'm assuming you have a start_at column in your database. As a result e.start_at is not an instance of DateTime but an instance of Time . (Try calling e.start_at.class to see it)

Instead of using DateTime.now I'd recommend using Rails' Time.zone.now which will return the current time in the timezone defined in Time.zone .

1.9.3p125 :005 > Time.zone
 => (GMT+00:00) UTC 
1.9.3p125 :006 > Time.zone.now
 => Thu, 23 Aug 2012 20:10:34 UTC +00:00 
1.9.3p125 :007 > Time.zone = "Berlin"
 => "Berlin" 
1.9.3p125 :008 > Time.zone
 => (GMT+01:00) Berlin 
1.9.3p125 :009 > Time.zone.now
 => Thu, 23 Aug 2012 22:10:47 CEST +02:00 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM