Using timezone javascript to set Time.zone

558 views
Skip to first unread message

Ben Perry

unread,
Jul 13, 2011, 10:47:22 AM7/13/11
to Ruby on Rails: Talk
I've got a javascript that provides me with the timezone for the
client. I want to use this to set Time.zone so that all my times
stored in the database are displayed in the timezone for the client.
So really simplistically

var timezone = jstz.determine_timezone().timezone
Time.zone = timezone.olson_tz

obviously this can't be done. I've taken a look on the web and can
only find 'solutions' over two years old and as ROR moves so fast I
thought someone may know of a better solution. So can anyone suggest a
simple solution?

Many thanks

Bill Walton

unread,
Jul 13, 2011, 10:53:50 AM7/13/11
to rubyonra...@googlegroups.com
Hi Ben,

It needs to be set on the server. You could do an AJAX call.

HTH,
Bill

Walter Lee Davis

unread,
Jul 13, 2011, 12:02:17 PM7/13/11
to rubyonra...@googlegroups.com

Or, you could do this all in JavaScript, and simply translate the
dates in the browser. Store -- and display -- one time zone, like UTC.
But then on the client, collect all your dates (wrap them in a
span.date or something that you can get using JS) and use the client's
notion of the time zone to adjust their display on screen.

$$('span.date').each(function(elm){
var d = new Date();
var offset = d.getTimeZoneOffset() * 3600 * 1000;
var adjusted = new Date(elm.innerHTML);
adjusted.setTime(adjusted.getTime() + offset);
elm.update(adjusted.toLocaleDateString());
});

Walter

>
> HTH,
> Bill
>
> --
> You received this message because you are subscribed to the Google
> Groups "Ruby on Rails: Talk" group.
> To post to this group, send email to rubyonrails-
> ta...@googlegroups.com.
> To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com
> .
> For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en
> .
>

Ben Perry

unread,
Jul 13, 2011, 12:15:21 PM7/13/11
to Ruby on Rails: Talk
Thanks for the replies.

The solution I've come up with for now is to use the javascript that
determines the timezone to store the timezone in a cookie using the
onload event. I then read it back out of the cookie in Rails with a
before_filter on application_controller.rb.

I'm not convinced its the best solution as obviously not everyone
turns cookies on, hmmm...

detect_timezone.js :
jstz.set_timezone_in_cookie = function () {
var tz_info = jstz.determine_timezone();
document.cookie="timezone =" + tz_info.timezone.olson_tz;
}

application_controller.rb :
before_filter :set_timezone
def set_timezone
Time.zone = request.cookies["timezone"]
end

Any thoughts? Many thanks.

Tim Shaffer

unread,
Jul 13, 2011, 12:30:47 PM7/13/11
to rubyonra...@googlegroups.com
You could do it with AJAX as well and store it in a session variable...

# routes.rb
post "timezone/set"

# timezone_controller.rb
def set
  session[:timezone] = params[:timezone]
end

# application_controller.rb
before_filter :set_timezone
def set_timezone
  Time.zone = session[:timezone]
end

# detect_timezone.js
$.post("/timezone/set", { timezone: jstz.determine_timezone().timezone.olson_tz } );

Ben Perry

unread,
Jul 14, 2011, 4:41:24 AM7/14/11
to Ruby on Rails: Talk
I'm very close but need a little help as my timezone controller set
function isn't being called. I can see the post call being made in the
console and I can see before a filter being run on the timezone
controller, but no set function.

#routes.rb
scope 'planbadmin' do
resources :timezone do
member do
post :set
end
end
end

# timezone_controller.rb
class TimezoneController < ApplicationController
def set
ldb("setting timezone = '#{params[:timezone]}'") #debug output
session[:timezone] = params[:timezone]
end
end

# application_controller.rb
before_filter :set_timezone
def set_timezone
ldb("setting timezone #{session[:timezone]}") #debug output
Time.zone = session[:timezone]
end

# detect_timezone.js
jstz.set_timezone_in_session = function () {
//prototype
new Ajax.Request("/planbadmin/timezone/set", {parameters:
{ timezone:jstz.determine_timezone().timezone.olson_tz }} );
}
onload = jstz.set_timezone_in_session();

#console output
Started POST "/planbadmin/timezone/set" for 127.0.0.1 at 2011-07-14
09:38:13 +01
00
Processing by TimezoneController#set as JS
Parameters: {"timezone"=>"Europe/London"}
←[1m←[36mUser Load (117.0ms)←[0m ←[1mSELECT TOP (1) [users].* FROM
[users] WH
ERE ([users].[userid] = N'benp')←[0m
Redirected to http://localhost/planbadmin/planb
Completed 302 Found in 140ms

Started GET "/planbadmin/planb" for 127.0.0.1 at 2011-07-14 09:38:13
+0100
Processing by PlanbController#index as HTML
===> C:/Projects/PLANB/interface/1.5.5/app/controllers/
application_controller.rb
:68:in `set_timezone': setting timezone = ''
Rendered planb/index.html.erb within layouts/application (5.0ms)
Completed 200 OK in 35ms (Views: 35.0ms | ActiveRecord: 0.0ms)

Many thanks

Tim Shaffer

unread,
Jul 14, 2011, 8:07:44 AM7/14/11
to rubyonra...@googlegroups.com
#routes.rb
  scope 'planbadmin' do
    resources :timezone do
      member do
        post  :set
      end
    end
  end

That's your problem there. By putting the "set" method under member, it's expecting it to be called for a timezone such as "/timezone/:id/set"

If you're going to set it up as a resource in routes, you probably want to use "collection" instead of "member" so it can be accessed via "/timezone/set"

You can run "rake routes" from the command line and you can see what it is expecting.

Of course the other option is just to add this one line to your routes instead of the resources snippet above:

post "timezone/set"

Ben Perry

unread,
Jul 14, 2011, 9:57:39 AM7/14/11
to Ruby on Rails: Talk
Hmm, so I've updated the routes

#routes.rb
scope 'planbadmin' do
... #removed the timezone resource
end
post "timezone/set"

and the rake routes output is now
timezone_set POST /timezone/set(.:format)
{:controller=>"timezone", :action=>"set"}

the console output is still exactly the same and the timezone set
function still isn't being called. Have you any other pointers? Again
thanks for your help with this its very much appreciated.

Ben Perry

unread,
Jul 14, 2011, 11:14:55 AM7/14/11
to Ruby on Rails: Talk
OK finally cracked it. Problem was with filters being run first in
application_controller.rb. The timezone_controller.rb set function was
being ignored as result of them. So

#routes.rb
scope 'planbadmin' do
resources :timezone do
collection do
post :set
end
end
end

#timezone_controller.rb
class TimezoneController < ApplicationController
skip_before_filter :admin, :authorise

def set
session[:timezone] = params[:timezone]
redirect_to(:controller => "planb")
end
end

Just a quick one, if I don't have that redirect it barfs about a
missing template. Is there a neat way around it?

Thanks VERY much for all the help.

Tim Shaffer

unread,
Jul 14, 2011, 11:45:50 AM7/14/11
to rubyonra...@googlegroups.com
You can use "render :nothing => true" instead

DHAMODHARAN N

unread,
Jul 16, 2011, 4:48:13 AM7/16/11
to rubyonra...@googlegroups.com
Hello friends,


On Thu, Jul 14, 2011 at 9:15 PM, Tim Shaffer <timsh...@me.com> wrote:
You can use "render :nothing => true" instead

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/E7glokNtpDcJ.

To post to this group, send email to rubyonra...@googlegroups.com.

DHAMODHARAN N

unread,
Jul 16, 2011, 4:52:16 AM7/16/11
to rubyonra...@googlegroups.com

DHAMODHARAN N

unread,
Jul 16, 2011, 5:05:38 AM7/16/11
to rubyonra...@googlegroups.com
Hello friends,

I forgot to download https://bitbucket.org/pellepim/jstimezonedetect/downloads detect_timezone.js.
Message has been deleted

DHAMODHARAN N

unread,
Jul 20, 2011, 6:43:38 AM7/20/11
to rubyonra...@googlegroups.com
Hello Ben Perry,
 
 I download js from https://bitbucket.org/pellepim/jstimezonedetect/get/tip.zip

On Sat, Jul 16, 2011 at 8:24 PM, Ben Perry <b3np...@gmail.com> wrote:
Are you sure you're using the latest version of the
detect_timezone.js? When I was working on this I downloaded another
older version that didn't define the class jstz namespace.


On Jul 16, 10:05 am, DHAMODHARAN N <dhams...@gmail.com> wrote:
> Hello friends,
>
>
>
>
>
>
>
>
> On Sat, Jul 16, 2011 at 2:22 PM, DHAMODHARAN N <dhams...@gmail.com> wrote:
> > Hello friends,
>
> >   I am trying to get timezone in browser produce below error.
> > jstz is not defined
> > jstz.set_timezone_in_session = function () {
>
> > My code:
>
> > jstz.set_timezone_in_session = function () {
> >   $.post("/timezone/set", { timezone:
> >  jstz.determine_timezone().timezone.olson_tz } );
> > }
> > onload = jstz.set_timezone_in_session();
>
> > I am using JQuery.
>
> > If any one known about this suggestion me.
>
> >       Thanks,
> > Dhamodharan.N
>
Reply all
Reply to author
Forward
0 new messages