How Does Rails Know My Timezone

How does Rails know my timezone?

From gettimeofday(), or so the ruby MRI source would have me believe:

int __cdecl
gettimeofday(struct timeval *tv, struct timezone *tz)
{
FILETIME ft;

GetSystemTimeAsFileTime(&ft);
filetime_to_timeval(&ft, tv);

return 0;
}

Per comment, this is a C function, called by the ruby date routines under the hood. You do not call the method yourself, rather you call the ruby methods you are calling.

rails active record time zone

Rails stores all timestamps in UTC in the database. When you type those commands on console it converts the timestamp to your specific timezone.

http://api.rubyonrails.org/classes/ActiveRecord/Timestamp.html

I your particular case 2014-08-28 15:58:26 UTC is same as 2014-08-28 21:28:26 IST.

Saving all timestamps as UTC makes the data consistent, and has less scope for ambiguity. You can then do all the conversions based on the timezone of your choice.

Rails: how get current time zone compatible with ActiveSupport::TimeZone[zone].parse()?

Use Time.zone.name, not Time.zone.to_s

[1] pry(main)> Time.zone.to_s
=> "(GMT-05:00) Eastern Time (US & Canada)"
[2] pry(main)> Time.zone.name
=> "Eastern Time (US & Canada)"
[3] pry(main)> ActiveSupport::TimeZone[Time.zone.name]
=> (GMT-05:00) Eastern Time (US & Canada)

As for how I got this (as requested), I just know the name method exists on Time.zone. If I didn't know this by heart though, I will check the docs. If it's not in there as you say (and it is, here), I typically inspect the class/module/object with Pry. Pry is an alternative to irb that lets me do something like

[1] pry(main)> cd Time.zone
[2] pry(#<ActiveSupport::TimeZone>):1> ls -m
Comparable#methods: < <= == > >= between?
ActiveSupport::TimeZone#methods: <=> =~ at formatted_offset local local_to_utc name now parse period_for_local period_for_utc to_s today tzinfo utc_offset utc_to_local
self.methods: __pry__
[3] pry(#<ActiveSupport::TimeZone>):1> name
=> "Eastern Time (US & Canada)"

ls -m on line [2] above prints methods on the object (if you scroll right you'll see name listed there). You can see in [3] I can call name directly on the Time.zone object I'm inside of and get the output you're looking for.

How do I make Rails use the system time by default?

In the absence of a native Rails option for my desired configuration, I chose to use the following:

config.time_zone = File.read('/etc/timezone').strip

It isn't pretty, but since our server configurations are tightly controlled, it will work for now.

Rails 4 local Time shown according to local time zone

Rails always saves times in UTC (universal time), and the server has a setting which tells it which timezone it (the server) is running in.

To show different times to the client, Rails (which runs on the server) will need to know which time zone the client is in. This isn't in a standard request header so you will need to get them to submit the information somehow. Once you know their timezone you can ensure that you always show times to the user using their timezone - there are helpers for this.

Getting their timezone can be done explicitly, eg by giving them a timezone dropdown in their "My Account" page, and then saving that in their user record, and/or by making it more upfront and forcing them to choose one in a popup, if you don't know it.

Or, you can do it for them using Javascript, passing it through in a cookie. See this article for an example of how to do it.

http://thisbythem.com/blog/clientside-timezone-detection/

Finding out if any time zone is in midnight currently

Your phrasing is a little ambiguous ("any X time zone"), so I'll address another possible interpretation:

If you'd like to check whether "it's midnight somewhere", with "midnight" understood broadly to mean any time from 00:00 to 00:59, a simple one-liner is

ActiveSupport::TimeZone.all.any?{ |time| time.now.hour.zero? }

To check that it's precisely 00:00 (or 00:00:00, although I can't imagine why you would want to do that...), add the appropriate conditions to the boolean block:

ActiveSupport::TimeZone.all.any?{ |time| time.now.hour.zero? && time.now.min.zero? }

You can probably leave off the ActiveSupport:: when calling TimeZone.all from within your Rails app.

[source]

Rails: How do I get created_at to show the time in my current time zone?

It's the timezone issue. Time.now prints time in your local time zone while the rails is reporting it in UTC. See config/environment.rb, it will have config.time_zone = "UTC"

>> Ticket.create(...)
>> Ticket.last.created_at.utc
=> Thu, 31 Dec 2009 04:41:58 UTC +00:00
>> Time.now.utc
=> Thu Dec 31 04:42:18 UTC 2009
>> Time.now
=> Wed Dec 30 20:44:50 -0800 2009

You can set the TimeZone in environment.rb to avoid confusion.

# config/environment.rb
config.time_zone = "Central Time (US & Canada)"

Rails : Given that my database is in UTC, and my Time.zone US Eastern, how do I save a time in US Pacific?

Cracked it!

Basically, the string that is submitted to params is representing a time in a Hotel's timezone. We have to use the built in 'use_zone' method to temporarily set the global Time.zone to that Hotel's.

We then pass the method a block where we produce the value that Rails is expecting, by using the timezone of the Hotel, rather than the User. That means that Rails' conversion to UTC results in the correct time in the db - as the time entered on the form has been converted to the Users timezone. The offsets have cancelled each other out, effectively.

@document.created_at = Time.use_zone(@current_hotel.timezone) {Time.zone.parse("#{params[:document][:created_at]}").in_time_zone(@current_hotel.timezone)}

We're basically changing the timezone of the Time object here without converting the actual time of that Time object when the timezone changes. (Good luck parsing that sentence!)

This looks to be working fine for me, but I've been looking at this for too long and I'd love to see a better way/more Rails-ey way of doing this!

Set current Time.zone in Rails?

Here's the working googled answer:

min = cookies[:timezone].to_i
Time.zone = ActiveSupport::TimeZone[-min.minutes]

Just to make it clear, the javascript part:

if(!($.cookie('timezone'))) {
current_time = new Date();
$.cookie('timezone', current_time.getTimezoneOffset(), { path: '/', expires: 10 } );
}


Related Topics



Leave a reply



Submit