Re: [therubyracer] Running v8 with a specific time zone

115 views
Skip to first unread message

Charles Lowell

unread,
Jun 6, 2012, 5:28:18 AM6/6/12
to therub...@googlegroups.com

On Jun 5, 2012, at 5:25 PM, Isaac Cambron wrote:

I'm using The Ruby Racer to format some server-generated emails so that they're consistent with the web content I normally render in the user's browser. Specifically, I'm using the some fancy JS libraries to render dates, since I don't want to rewrite those libraries in Ruby. The trouble is that to generate the emails correctly on the server, those libraries need to need to run in the context of the users' individual time zones as they would in a browser, and not in server's time zone. So I need to externally specify the time zone, and I'm not sure how to do that.

I can probably hack around this in both the JS code and Ruby code, but by far the cleanest way is if I could just tell V8 what time zone to run in. Is that possible?

IOW:

irb(main):004:0> ctx = V8::Context.new                                      #  Is there something I can do here...
irb(main):005:0> ctx.eval("new Date().getTimezoneOffset()")
=> 0                                                                                        # ...to change this?


It looks like the only way that V8 supports this is to actually set the local timezone for your process, and then call the low-level C function:

 V8EXPORT static void DateTimeConfigurationChangeNotification();

which will cause V8 to re-read its timezone data (amongst other things) from the OS.

If that's something that you're willing to do, I can add the call from Ruby for you.

cheers,
Charles



Thanks,
Isaac

Charles Lowell 
thefrontside.net | twitter: @cowboyd | github: cowboyd




Isaac Cambron

unread,
Jun 6, 2012, 6:06:28 PM6/6/12
to therub...@googlegroups.com
Thanks for the reply. That sounds pretty heavyweight, but doable. I'm not sure how to change the TZ from inside the process, though. Is it just a matter of setting ENV["TZ"]?

Charles Lowell

unread,
Jun 7, 2012, 6:00:22 AM6/7/12
to therub...@googlegroups.com
On Jun 6, 2012, at 5:06 PM, Isaac Cambron wrote:

Thanks for the reply. That sounds pretty heavyweight, but doable. I'm not sure how to change the TZ from inside the process, though. Is it just a matter of setting ENV["TZ"]?

That appears to work, but it's hard to say for sure. I can go ahead and do this, but it might be a good idea to modify the fancy date formatting libraries to accomodate a timezone, rather than "trick" them by setting the OS timezone. Just a thought.

Also, it appears that this just works, although I'm not sure if v8 will add any extra caching down the line:

1.9.3p194 :003 > cxt.eval('new Date()')
 => 2012-06-07 04:57:17 -0500 
1.9.3p194 :004 > ENV['TZ'] = 'UTC'
 => "UTC" 
1.9.3p194 :005 > cxt.eval('new Date()')
 => 2012-06-07 09:57:27 +0000 
1.9.3p194 :006 > ENV['TZ'] = nil
 => nil 
1.9.3p194 :007 > cxt.eval('new Date()')
 => 2012-06-07 04:57:38 -0500 
1.9.3p194 :012 > ENV['TZ'] = 'Asia/Bahrain'
 => "Asia/Bahrain" 
1.9.3p194 :013 > cxt.eval('new Date()')
 => 2012-06-07 12:58:48 +0300 

Isaac Cambron

unread,
Jun 7, 2012, 6:38:22 PM6/7/12
to therub...@googlegroups.com
Yeah, I've certainly thought about that the option of explicit time zone support to the JS libraries (e.g. moment.js). Unfortunately, JS is pretty poor with TZ stuff in general and the libraries I'm using have specifically avoided the bloat required to support it across all the browsers.

I'll go ahead and try the ENV trick (I thought I'd tried it and it didn't work, but I'll give it another go), and would love the reloader method in case there's some caching added there later.

Thanks!
Isaac

Charles Lowell

unread,
Jun 8, 2012, 3:23:56 AM6/8/12
to therub...@googlegroups.com
On Jun 7, 2012, at 5:38 PM, Isaac Cambron wrote:

Yeah, I've certainly thought about that the option of explicit time zone support to the JS libraries (e.g. moment.js). Unfortunately, JS is pretty poor with TZ stuff in general and the libraries I'm using have specifically avoided the bloat required to support it across all the browsers.

It is there on master. You'll need to invoke it inside a locked and entered context. There isn't a super-clean interface to do this yet, 0.11 will have a simple context.enter which will lock, enter and yield for you.

begin
  lock = V8::C::Locker.new
  cxt.native.Enter()
  V8::C::Date::DateTimeConfigurationChangeNotification()
  cxt.Exit()
ensure
  lock.delete


cheers,
Charles

Isaac Cambron

unread,
Jun 9, 2012, 9:36:50 PM6/9/12
to therub...@googlegroups.com
Awesome, thanks a bunch!
Reply all
Reply to author
Forward
0 new messages