Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Respect Time.zone #6

Merged
merged 7 commits into from

2 participants

@bradseefeld

This addresses the bug filed here: asterite/rgviz#1

Specs included.

I didnt 'fix' date parsing. I wasnt sure if this is something that should be addressed as I typically do not consider time zones when working with Date's. I am thinking the current date parsing is the expected behavior.

@asterite
Owner

Looks fine. GitHub says I can't merge it automatically, probably because I commited to master (I just overwrote Rgviz::Parser, but I like your way of subclassing it better).

How can I merge the two forks?

@bradseefeld

I am not entirely sure. I have not accepted a pull request before... I imagine there is a way to manually resolve the conflict? If not, you could always revert the commit.

@bradseefeld

I was reading on this a bit and I think the common approach is for me to merge the upstream master and resolve conflicts. My latest commit merges your changes.

@asterite asterite merged commit 53f627a into asterite:master
@asterite
Owner

There, I just pushed version 0.63 of this gem. I use to push gems often... I hope that doesn't slow down rubygems. :-P

@asterite
Owner

Hi Brad,

I'm not sure the pull request is correct. Try doing this:

  1. In spec/rgviz_rails/executor_spec.rb add the following to the before(:each) block:

    Time.zone = "Cairo"

Run the specs. You will see two tests fail because the label is incorrect. For the labels I use strftime of the parsed date/time values, but since you are changing their time by subtracting the timezone offset, it fails.

I'm not sure what's the point of subtracting the timezone offset. What's wrong about using Time.zone.parse to parse the time? If you are on a Rails app that's what you would expect to use... no? You wrote "TimeWithZone is not formatted as UTC when its used in ActiveRecord" but why do you need this? Is this a requirement of your app?

I need to understand more about this... I added the project to travis ci and it failed because Time.zone must be set to something different than GMT.

@bradseefeld

I had not given any consideration to labels. :(

My comments regarding TimeZoneWith might be best understood with an example. Suppose 1:00am is sent to the server in a query. If we use Time.zone.parse, this would be parsed as 1:00am PST (my timezone) and would be correct. The parsed time object is a TimeWithZone. When this value gets used in SQL via ActiveRecord, it has a string value of "1:00am" again. The correct value should be 1:00am - 7 hours (the UTC offset for PST). Essentially, TimeWithZone does not respect the timezone that our db is in. So SQL queries end up being off by some offset.

The goal of subtracting the offset is to get the time into the correct UTC time since this is the internal representation of Time anyway. I am on vacation now so I wont be able to really look into this further until next week. If this is urgent, hopefully my comments help shed some light on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 8, 2012
  1. Respect the time zone

    Brad Seefeld authored
  2. Merge remote-tracking branch 'upstream/master'

    Brad Seefeld authored
  3. Revert "Respect the time zone"

    Brad Seefeld authored
    This reverts commit c342858.
Commits on Mar 9, 2012
  1. Updated rgviz

    Brad Seefeld authored
  2. Added customized parser to handle time zones

    Brad Seefeld authored
  3. We want to subtract the offset - not add it.

    Brad Seefeld authored
  4. Fixed merge conflicts

    Brad Seefeld authored
This page is out of date. Refresh to see the latest.
View
10 Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- rgviz-rails (0.60.1)
+ rgviz-rails (0.61)
rails
rgviz
@@ -46,7 +46,7 @@ GEM
journey (1.0.3)
json (1.6.5)
machinist (1.0.6)
- mail (2.4.1)
+ mail (2.4.3)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
@@ -54,7 +54,7 @@ GEM
multi_json (1.1.0)
polyglot (0.3.3)
rack (1.4.1)
- rack-cache (1.1)
+ rack-cache (1.2)
rack (>= 0.4)
rack-ssl (1.3.2)
rack
@@ -78,7 +78,7 @@ GEM
rake (0.9.2.2)
rdoc (3.12)
json (~> 1.4)
- rgviz (0.42)
+ rgviz (0.43)
rspec (2.8.0)
rspec-core (~> 2.8.0)
rspec-expectations (~> 2.8.0)
@@ -97,7 +97,7 @@ GEM
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
- tzinfo (0.3.31)
+ tzinfo (0.3.32)
PLATFORMS
ruby
View
20 lib/rgviz_rails.rb
@@ -1,18 +1,8 @@
-require 'rgviz'
-require 'rgviz_rails/init.rb'
-require 'rgviz_rails/executor.rb'
-require 'rgviz_rails/js_renderer.rb'
-require 'rgviz_rails/tqx.rb'
-
-class Rgviz::Parser
- def parse_time(string)
- Time.zone.parse string
- end
-
- def parse_date(string)
- parse_time(string).to_date
- end
-end
+require "rgviz_rails/init"
+require "rgviz_rails/executor"
+require "rgviz_rails/js_renderer"
+require "rgviz_rails/tqx"
+require "rgviz_rails/parser"
module RgvizRails
end
View
4 lib/rgviz_rails/executor.rb
@@ -27,8 +27,8 @@ def initialize(model_class)
def execute(query, options = {})
@query = query
- @query = Parser.parse(@query, options) unless @query.kind_of?(Query)
-
+ @query = RgvizRails::Parser.parse(@query, options) unless @query.kind_of?(Query)
+
@table = Table.new
@extra_conditions = options[:conditions]
View
23 lib/rgviz_rails/parser.rb
@@ -0,0 +1,23 @@
+module RgvizRails
+ class Parser < Rgviz::Parser
+ def self.parse(string, options = {})
+ new(string, options).parse
+ end
+
+ protected
+
+ def parse_time(time_string)
+ time = Time.parse(time_string)
+
+ # Honor the user's time zone if possible. We add the offset instead of using
+ # Time.zone.parse because we do not want a TimeWithZone object. TimeWithZone is not
+ # formatted as UTC when its used in ActiveRecord. We want the UTC
+ # (or system time zone time) time for the given local time.
+ if Time.zone
+ time -= Time.zone.utc_offset.seconds
+ end
+
+ time
+ end
+ end
+end
View
2  lib/rgviz_rails/view_helper.rb
@@ -87,7 +87,7 @@ def s.encode_json(options = {})
url = url_for url unless custom_executor
# Parse the query
- query = Parser.parse query, :extensions => extensions
+ query = RgvizRails::Parser.parse query, :extensions => extensions
# And replace the html_ and javascript_ magic names
query.accept visitor
View
1  rgviz-rails.gemspec
@@ -15,6 +15,7 @@ spec = Gem::Specification.new do |s|
"lib/rgviz_rails.rb",
"lib/rgviz_rails/executor.rb",
"lib/rgviz_rails/js_renderer.rb",
+ "lib/rgviz_rails/parser.rb",
"lib/rgviz_rails/tqx.rb",
"lib/rgviz_rails/view_helper.rb",
"lib/rgviz_rails/adapters/mysql_adapter.rb",
View
61 spec/rgviz_rails/parser_spec.rb
@@ -0,0 +1,61 @@
+require "spec_helper"
+
+describe RgvizRails::Parser do
+ describe :parse_time do
+ before :all do
+ @format = "%B %d, %Y %H:%M:%S"
+ end
+
+ # Provide a proxy for testing the otherwise protected method
+ class RgvizRails::Parser
+ def public_parse_time(time_string)
+ parse_time(time_string)
+ end
+ end
+
+ before :each do
+ @parser = RgvizRails::Parser.new("select *")
+ end
+
+ context :default_time_zone do
+ before :each do
+ Time.zone = nil
+ end
+
+ it "parses a time string" do
+ now = Time.now
+ @parser.public_parse_time(now.strftime(@format)).to_i.should == now.to_i
+ end
+ end
+
+ context :custom_time_zone do
+
+ def parse_with_zone(time_zone)
+ Time.zone = time_zone
+ now = Time.now
+ parsed = @parser.public_parse_time(now.strftime(@format))
+ (now.to_i - parsed.to_i).should == Time.zone.utc_offset
+ end
+
+ it "parses a time string with the Pacific time zone" do
+ parse_with_zone("Pacific Time (US & Canada)")
+ end
+
+ it "parses a time string with the Cairo time zone" do
+ parse_with_zone("Cairo")
+ end
+
+ it "parses a string with the London time zone" do
+ parse_with_zone("London")
+ end
+
+ it "parses a string with the Sydney time zone" do
+ parse_with_zone("Sydney")
+ end
+
+ it "parses a string with the Central time zone" do
+ parse_with_zone("Central Time (US & Canada)")
+ end
+ end
+ end
+end
View
37 spec/spec_helper.rb
@@ -1,13 +1,13 @@
-$:.unshift(File.dirname(__FILE__) + '/../lib')
+$:.unshift(File.dirname(__FILE__) + "/../lib")
-require 'rubygems'
-require 'logger'
+require "rubygems"
+require "logger"
+require "rails/all"
+require "active_record"
-require 'active_record'
-
-ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ':memory:')
-#ActiveRecord::Base.establish_connection(:adapter => 'mysql2', :database => 'rgviz_rails', :username => 'root', :password => '')
-#ActiveRecord::Base.establish_connection(:adapter => 'postgresql', :database => 'rgviz_rails', :username => 'postgres', :password => '###', :host => '/var/run/postgresql/')
+ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
+#ActiveRecord::Base.establish_connection(:adapter => "mysql2", :database => "rgviz_rails", :username => "root", :password => "")
+#ActiveRecord::Base.establish_connection(:adapter => "postgresql", :database => "rgviz_rails", :username => "postgres", :password => "###", :host => "/var/run/postgresql/")
ActiveRecord::Schema.define do
create_table "cities", :force => true do |t|
@@ -40,18 +40,15 @@
end
end
-require File.dirname(__FILE__) + '/models/person'
-require File.dirname(__FILE__) + '/models/city'
-require File.dirname(__FILE__) + '/models/country'
-require File.dirname(__FILE__) + '/models/foo'
-require File.dirname(__FILE__) + '/models/foo_bar'
-
-require File.dirname(__FILE__) + '/blueprints'
+require File.dirname(__FILE__) + "/models/person"
+require File.dirname(__FILE__) + "/models/city"
+require File.dirname(__FILE__) + "/models/country"
+require File.dirname(__FILE__) + "/models/foo"
+require File.dirname(__FILE__) + "/models/foo_bar"
-require 'rgviz'
-require 'rgviz_rails/executor'
+require File.dirname(__FILE__) + "/blueprints"
-RAILS_ENV = 'test'
+require "rgviz"
+require "rgviz_rails"
-# Add this directory so the ActiveSupport autoloading works
-#ActiveSupport::Dependencies.load_paths << File.dirname(__FILE__)
+RAILS_ENV = "test"
Something went wrong with that request. Please try again.