greenwich 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.rspec +1 -0
- data/.rvmrc +1 -0
- data/README.md +11 -9
- data/greenwich.gemspec +5 -3
- data/lib/greenwich.rb +3 -3
- data/lib/greenwich/rails.rb +75 -0
- data/lib/greenwich/time_with_zone.rb +26 -0
- data/lib/greenwich/utilities.rb +22 -0
- data/lib/greenwich/version.rb +1 -1
- data/spec/greenwich/utilities_spec.rb +85 -0
- data/spec/spec_helper.rb +9 -0
- metadata +34 -14
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use --create ruby-1.9.2-p180@greenwich
|
data/README.md
CHANGED
@@ -31,13 +31,14 @@ You add Greenwich to your models like so:
|
|
31
31
|
|
32
32
|
date_with_time_zone :field_name
|
33
33
|
|
34
|
+
Meta-Programming Magic
|
35
|
+
--------------------------------
|
36
|
+
|
34
37
|
By default Greenwich looks for a few different columns in your model depending on the
|
35
38
|
field name you passed in. Let's look at some examples.
|
36
39
|
|
37
|
-
|
38
|
-
--------------------------------
|
40
|
+
**DateTime Field Lookup**
|
39
41
|
|
40
|
-
** DateTime Field Lookup **
|
41
42
|
Greenwich will lookup `:field_name` based on a couple different standard column suffixes.
|
42
43
|
|
43
44
|
* `_at`
|
@@ -49,7 +50,8 @@ For example, if you specify:
|
|
49
50
|
|
50
51
|
Greenwich will look for the columns `start_at` and `start_datetime` (in that order).
|
51
52
|
|
52
|
-
**
|
53
|
+
**Time Zone Field Lookup**
|
54
|
+
|
53
55
|
Time Zone lookups default to a per-field or per-model specification. If you specify:
|
54
56
|
|
55
57
|
date_with_time_zone :start
|
@@ -59,9 +61,9 @@ find a field by that name, it will use `:time_zone`.
|
|
59
61
|
|
60
62
|
Usage
|
61
63
|
--------------------------------
|
62
|
-
* Note
|
64
|
+
* **Note:** _These examples assume the application's default time zone is set to UTC.
|
63
65
|
If you have modified the default time zone, directly accessing your DateTime field
|
64
|
-
will render it in _that_ time zone and not UTC.
|
66
|
+
will render it in _that_ time zone and not UTC._
|
65
67
|
|
66
68
|
When working with your instances, Greenwich will convert to the proper time zone when
|
67
69
|
you access it. So if you've previously saved a DateTime like this:
|
@@ -98,19 +100,19 @@ And again, asking Greenwich for the value of `start` will result in:
|
|
98
100
|
Issues
|
99
101
|
------
|
100
102
|
|
101
|
-
If you have problems, please create a [Github issue](https://github.com/jfelchner/
|
103
|
+
If you have problems, please create a [Github issue](https://github.com/jfelchner/greenwich/issues).
|
102
104
|
|
103
105
|
Credits
|
104
106
|
-------
|
105
107
|
|
106
108
|

|
107
109
|
|
108
|
-
|
110
|
+
greenwich is maintained by [The Kompanee, Ltd.](http://www.thekompanee.com)
|
109
111
|
|
110
112
|
The names and logos for The Kompanee are trademarks of The Kompanee, Ltd.
|
111
113
|
|
112
114
|
License
|
113
115
|
-------
|
114
116
|
|
115
|
-
|
117
|
+
greenwich is Copyright © 2011 The Kompanee. It is free software, and may be redistributed under the terms specified in the LICENSE file.
|
116
118
|
|
data/greenwich.gemspec
CHANGED
@@ -28,7 +28,9 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.require_paths = ["lib"]
|
29
29
|
#= Manifest =#
|
30
30
|
|
31
|
-
s.
|
32
|
-
|
33
|
-
s.add_development_dependency('
|
31
|
+
s.add_dependency('activerecord', '~> 3.0')
|
32
|
+
|
33
|
+
s.add_development_dependency('bundler', '~> 1.0')
|
34
|
+
s.add_development_dependency('rspec', '~> 2.6')
|
35
|
+
s.add_development_dependency('yard', '~> 0.7')
|
34
36
|
end
|
data/lib/greenwich.rb
CHANGED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'greenwich'
|
2
|
+
|
3
|
+
module Greenwich #:nodoc:
|
4
|
+
module Conversion #:nodoc:
|
5
|
+
def self.included(base) #:nodoc:
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def time_with_custom_time_zone(name, options = {})
|
11
|
+
time_zone_field = options[:time_zone] || Greenwich::Utilities.get_time_zone_field(name, column_names)
|
12
|
+
time_field = options[:time_field] || Greenwich::Utilities.get_time_field(name, column_names)
|
13
|
+
|
14
|
+
skip_time_zone_conversion_for_attributes << time_field
|
15
|
+
|
16
|
+
mapping = [ [time_field, 'truncated_time_as_string'], [time_zone_field, 'time_zone_name'] ]
|
17
|
+
|
18
|
+
composed_of name,
|
19
|
+
:class_name => 'ActiveSupport::TimeWithZone',
|
20
|
+
:mapping => mapping,
|
21
|
+
:allow_nil => true,
|
22
|
+
:constructor => Proc.new { |time, time_zone|
|
23
|
+
time_zone = ActiveSupport::TimeZone.new(time_zone) unless time_zone.is_a? ActiveSupport::TimeZone
|
24
|
+
time = time.to_time
|
25
|
+
|
26
|
+
ActiveSupport::TimeWithZone.new(nil, time_zone, time)
|
27
|
+
},
|
28
|
+
:converter => Proc.new { |value|
|
29
|
+
value[1] = ActiveSupport::TimeZone.new(value[1]) unless value[1].is_a? ActiveSupport::TimeZone
|
30
|
+
value[0] = value[0].to_time
|
31
|
+
|
32
|
+
ActiveSupport::TimeWithZone.new(nil, value[1], value[0])
|
33
|
+
}
|
34
|
+
|
35
|
+
define_method "#{time_field}=" do |time|
|
36
|
+
instance_eval do
|
37
|
+
time_zone = read_attribute(time_zone)
|
38
|
+
|
39
|
+
if time_zone.nil?
|
40
|
+
write_attribute(time_field, time.to_s)
|
41
|
+
else
|
42
|
+
self.send("#{name}=".to_sym, [time, time_zone])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
time_zone "#{name}_time_zone".to_sym, :for => name.to_sym if options[:time_zone] == time_zone_field
|
48
|
+
end
|
49
|
+
|
50
|
+
def time_zone(name, options = {})
|
51
|
+
options[:for] = [options[:for]].compact unless options[:for].is_a? Array
|
52
|
+
options[:for].map! { |v| [v, Greenwich::Utilities.get_time_field(v, column_names)] }
|
53
|
+
|
54
|
+
define_method "#{name}" do
|
55
|
+
ActiveSupport::TimeZone.new(read_attribute(name))
|
56
|
+
end
|
57
|
+
|
58
|
+
define_method "#{name}=" do |time_zone|
|
59
|
+
instance_eval do
|
60
|
+
time_zone = ActiveSupport::TimeZone.new(time_zone) unless time_zone.is_a? ActiveSupport::TimeZone || time_zone.nil?
|
61
|
+
time_zone = time_zone.name if time_zone.respond_to? :name
|
62
|
+
write_attribute(name, time_zone)
|
63
|
+
|
64
|
+
options[:for].each do |composed_field, time_field|
|
65
|
+
time = read_attribute(time_field)
|
66
|
+
self.send("#{composed_field}=".to_sym, [time, time_zone]) unless time.nil?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
ActiveRecord::Base.send :include, Greenwich::Conversion
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ActiveSupport
|
2
|
+
class TimeWithZone
|
3
|
+
def time_zone=(new_zone)
|
4
|
+
ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone.new(new_zone), time)
|
5
|
+
end
|
6
|
+
|
7
|
+
def time_zone_name
|
8
|
+
time_zone.name
|
9
|
+
end
|
10
|
+
|
11
|
+
def truncated_time
|
12
|
+
ActiveSupport::TimeWithZone.new(nil, ActiveSupport::TimeZone.new('UTC'), time)
|
13
|
+
end
|
14
|
+
|
15
|
+
def truncated_time_as_string
|
16
|
+
truncated_time.to_s
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class TimeZone
|
21
|
+
def freeze
|
22
|
+
tzinfo; utc_offset;
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Greenwich
|
2
|
+
module Utilities
|
3
|
+
def self.get_time_zone_field(name, columns)
|
4
|
+
target_columns = ["#{name}_time_zone", "time_zone"]
|
5
|
+
|
6
|
+
get_target_column(target_columns, columns)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.get_time_field(name, columns)
|
10
|
+
target_columns = ["#{name}_at", "#{name}_datetime", "#{name}_time"]
|
11
|
+
|
12
|
+
get_target_column(target_columns, columns)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def self.get_target_column(target_columns, all_columns)
|
17
|
+
target_columns.each {|col| return col if all_columns.include?(col) }
|
18
|
+
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/greenwich/version.rb
CHANGED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Greenwich::Utilities do
|
4
|
+
describe "#truncate" do
|
5
|
+
before { @expected_time = Time.utc(2011, 5, 13, 17, 31, 13, 0) }
|
6
|
+
|
7
|
+
context "when passed a String" do
|
8
|
+
it "returns the correct time if no offset is given" do
|
9
|
+
truncated = Greenwich::Utilities.truncate("2011-05-13 17:31:13")
|
10
|
+
truncated.should eql @expected_time
|
11
|
+
end
|
12
|
+
|
13
|
+
it "returns the correct time if an offset is given" do
|
14
|
+
truncated = Greenwich::Utilities.truncate("2011-05-13 17:31:13 -0600")
|
15
|
+
truncated.should eql @expected_time
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when passed a TimeWithZone" do
|
20
|
+
before { @time = Time.utc(2011, 5, 13, 17, 31, 13) }
|
21
|
+
|
22
|
+
it "returns the correct time if TimeWithZone is UTC" do
|
23
|
+
utc_time_zone = ActiveSupport::TimeZone.new('UTC')
|
24
|
+
time_with_zone = ActiveSupport::TimeWithZone.new(@time, utc_time_zone)
|
25
|
+
|
26
|
+
truncated = Greenwich::Utilities.truncate(time_with_zone)
|
27
|
+
truncated.should eql @expected_time
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns the correct time if TimeWithZone is not UTC" do
|
31
|
+
alaskan_time_zone = ActiveSupport::TimeZone.new('Alaska')
|
32
|
+
time_with_zone = ActiveSupport::TimeWithZone.new(nil, alaskan_time_zone, @time)
|
33
|
+
|
34
|
+
truncated = Greenwich::Utilities.truncate(time_with_zone)
|
35
|
+
truncated.should eql @expected_time
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context "when passed a DateTime" do
|
40
|
+
it "returns the correct time if DateTime is UTC" do
|
41
|
+
datetime = DateTime.civil(2011, 5, 13, 17, 31, 13, 0)
|
42
|
+
|
43
|
+
truncated = Greenwich::Utilities.truncate(datetime)
|
44
|
+
truncated.should eql @expected_time
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns the correct time if DateTime is not UTC" do
|
48
|
+
datetime = DateTime.civil(2011, 5, 13, 17, 31, 13, -0.25)
|
49
|
+
|
50
|
+
truncated = Greenwich::Utilities.truncate(datetime)
|
51
|
+
truncated.should eql @expected_time
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#get_time_zone" do
|
57
|
+
context "when passed a valid time zone" do
|
58
|
+
it "returns that time zone" do
|
59
|
+
time_zone = Greenwich::Utilities.get_time_zone(nil, 'foo')
|
60
|
+
time_zone.should eql 'foo'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when not passed a time zone" do
|
65
|
+
before { @time = Time.utc(2011, 5, 13, 17, 31, 13) }
|
66
|
+
|
67
|
+
context "and passed a TimeWithZone for the time" do
|
68
|
+
it "returns the time zone associated with the time" do
|
69
|
+
alaskan_time_zone = ActiveSupport::TimeZone.new('Alaska')
|
70
|
+
time_with_zone = ActiveSupport::TimeWithZone.new(nil, alaskan_time_zone, @time)
|
71
|
+
|
72
|
+
time_zone = Greenwich::Utilities.get_time_zone(time_with_zone, nil)
|
73
|
+
time_zone.should eql alaskan_time_zone
|
74
|
+
end
|
75
|
+
|
76
|
+
it "returns the time zone associated with the time" do
|
77
|
+
utc_time_zone = ActiveSupport::TimeZone.new('UTC')
|
78
|
+
|
79
|
+
time_zone = Greenwich::Utilities.get_time_zone(@time, nil)
|
80
|
+
time_zone.should eql utc_time_zone
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: greenwich
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,42 +10,53 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2011-07-
|
13
|
+
date: 2011-07-06 00:00:00.000000000 -05:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: activerecord
|
18
|
+
requirement: &2152414440 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '3.0'
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: *2152414440
|
16
27
|
- !ruby/object:Gem::Dependency
|
17
28
|
name: bundler
|
18
|
-
requirement: &
|
29
|
+
requirement: &2152413920 !ruby/object:Gem::Requirement
|
19
30
|
none: false
|
20
31
|
requirements:
|
21
32
|
- - ~>
|
22
33
|
- !ruby/object:Gem::Version
|
23
|
-
version: 1.0
|
34
|
+
version: '1.0'
|
24
35
|
type: :development
|
25
36
|
prerelease: false
|
26
|
-
version_requirements: *
|
37
|
+
version_requirements: *2152413920
|
27
38
|
- !ruby/object:Gem::Dependency
|
28
39
|
name: rspec
|
29
|
-
requirement: &
|
40
|
+
requirement: &2152413460 !ruby/object:Gem::Requirement
|
30
41
|
none: false
|
31
42
|
requirements:
|
32
43
|
- - ~>
|
33
44
|
- !ruby/object:Gem::Version
|
34
|
-
version: 2.6
|
45
|
+
version: '2.6'
|
35
46
|
type: :development
|
36
47
|
prerelease: false
|
37
|
-
version_requirements: *
|
48
|
+
version_requirements: *2152413460
|
38
49
|
- !ruby/object:Gem::Dependency
|
39
50
|
name: yard
|
40
|
-
requirement: &
|
51
|
+
requirement: &2152412980 !ruby/object:Gem::Requirement
|
41
52
|
none: false
|
42
53
|
requirements:
|
43
54
|
- - ~>
|
44
55
|
- !ruby/object:Gem::Version
|
45
|
-
version: 0.7
|
56
|
+
version: '0.7'
|
46
57
|
type: :development
|
47
58
|
prerelease: false
|
48
|
-
version_requirements: *
|
59
|
+
version_requirements: *2152412980
|
49
60
|
description: Store all of your times in the database as UTC but want to give your
|
50
61
|
users the ability to choose a custom time zone for each instance of a DateTime field?
|
51
62
|
email:
|
@@ -57,13 +68,20 @@ extra_rdoc_files:
|
|
57
68
|
- LICENSE
|
58
69
|
files:
|
59
70
|
- .gitignore
|
71
|
+
- .rspec
|
72
|
+
- .rvmrc
|
60
73
|
- Gemfile
|
74
|
+
- LICENSE
|
75
|
+
- README.md
|
61
76
|
- Rakefile
|
62
77
|
- greenwich.gemspec
|
63
78
|
- lib/greenwich.rb
|
79
|
+
- lib/greenwich/rails.rb
|
80
|
+
- lib/greenwich/time_with_zone.rb
|
81
|
+
- lib/greenwich/utilities.rb
|
64
82
|
- lib/greenwich/version.rb
|
65
|
-
-
|
66
|
-
-
|
83
|
+
- spec/greenwich/utilities_spec.rb
|
84
|
+
- spec/spec_helper.rb
|
67
85
|
has_rdoc: true
|
68
86
|
homepage: http://github.com/jfelchner/greenwich
|
69
87
|
licenses: []
|
@@ -90,4 +108,6 @@ rubygems_version: 1.6.2
|
|
90
108
|
signing_key:
|
91
109
|
specification_version: 3
|
92
110
|
summary: Allowing users to select dates with custom time zones since 2011.
|
93
|
-
test_files:
|
111
|
+
test_files:
|
112
|
+
- spec/greenwich/utilities_spec.rb
|
113
|
+
- spec/spec_helper.rb
|