date_time_attribute 0.0.4
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.
- checksums.yaml +15 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +19 -0
- data/.travis.yml +4 -0
- data/Gemfile +9 -0
- data/README.md +128 -0
- data/Rakefile +5 -0
- data/date_time_attribute.gemspec +23 -0
- data/lib/date_time_attribute.rb +108 -0
- data/lib/date_time_attribute/container.rb +81 -0
- data/spec/date_time_attribute/container_spec.rb +105 -0
- data/spec/date_time_attribute_spec.rb +205 -0
- data/spec/spec_helper.rb +12 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
ZWNmMGZkNmU3MjU3YmJlNmY5M2Y1OTE4ZTcxNjYxYjJjYzhjYzRmNQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ODIyYTdjYzg0NTEyZWRlYWY1NGJkOTNiNWEyNWZjNzIyYjRiMzgyNw==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YmFiMjNhNjIyYTcwOTJmNmZiYzQwY2E5OGI4ZjFjMzdhYmQ0NTkzYzllY2Ey
|
10
|
+
MWRiYjYxYjZlZDUzNjc4YmM0MjUzZDQ3MzY0NmQxNjg1ZjQ3MTAzZTViOThk
|
11
|
+
NmRjZjdkZTg0OGEwYjk4ZmYyYWQwNDYxMWU4YTZkZGU0ODY2NDk=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YmU4NjQxNDIzYjMxNDQzODZmYmI2MTRkZjY3NjQzYTE5NWI4NzQ3MTZiODM0
|
14
|
+
ZTIyNzE3ZTI5ZjJiNzBkYTRlNjNlNDg1NTE2N2I4ZDc2MjM4MTFlMTdkNDYz
|
15
|
+
NjU5NDVmNGEwMjc4NTFkYjJlNWU5YTQ5YTRlY2U3ZmRmNDkxZGM=
|
data/.coveralls.yml
ADDED
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
# DateTime attribute for Ruby!
|
2
|
+
[](http://badge.fury.io/rb/date_time_attribute)
|
3
|
+
[](https://travis-ci.org/einzige/date_time_attribute)
|
4
|
+
[](https://gemnasium.com/einzige/date_time_attribute)
|
5
|
+
[](https://coveralls.io/r/einzige/date_time_attribute)
|
6
|
+
|
7
|
+
Splits DateTime attribute access into two Data, Time and TimeZone attributes.
|
8
|
+
|
9
|
+
See also [ActiveRecord (Rails) version](https://github.com/einzige/date_time_attribute_rails).
|
10
|
+
|
11
|
+
## Install
|
12
|
+
|
13
|
+
```bash
|
14
|
+
gem install date_time_attribute
|
15
|
+
```
|
16
|
+
|
17
|
+
## Enjoy
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
require 'date_time_attribute'
|
21
|
+
|
22
|
+
class Task
|
23
|
+
include DateTimeAttribute
|
24
|
+
date_time_attribute :due_at
|
25
|
+
end
|
26
|
+
|
27
|
+
task = Task.new
|
28
|
+
task.due_at # => nil
|
29
|
+
|
30
|
+
# Date set
|
31
|
+
task.due_at_date = '2001-02-03'
|
32
|
+
task.due_at_date # => 2001-02-03 00:00:00 +0700
|
33
|
+
task.due_at_time # => 2001-02-03 00:00:00 +0700
|
34
|
+
task.due_at # => 2001-02-03 00:00:00 +0700
|
35
|
+
|
36
|
+
# Time set
|
37
|
+
task.due_at_time = '10:00pm'
|
38
|
+
task.due_at_time # => 2013-12-02 22:00:00 +0800
|
39
|
+
task.due_at_date # => 2001-02-03 00:00:00 +0700
|
40
|
+
task.due_at # => 2001-02-03 22:00:00 +0700
|
41
|
+
|
42
|
+
# Time zone is applied as set
|
43
|
+
task.due_at_time_zone = 'Moscow'
|
44
|
+
task.due_at # => Mon, 03 Feb 2013 22:00:00 MSK +04:00
|
45
|
+
task.due_at_time_zone = 'London'
|
46
|
+
task.due_at # => Mon, 03 Feb 2013 22:00:00 GMT +00:00
|
47
|
+
```
|
48
|
+
|
49
|
+
You can also use it with already existing/initialized attributes
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
class Task
|
53
|
+
include DateTimeAttribute
|
54
|
+
|
55
|
+
attr_accessor :due_at
|
56
|
+
date_time_attribute :due_at
|
57
|
+
|
58
|
+
def initialize
|
59
|
+
self.due_at = Time.zone.now.tomorrow
|
60
|
+
end
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
## Using time zones
|
65
|
+
|
66
|
+
Default time zone can be applied to an attribute:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
class Task
|
70
|
+
include DateTimeAttribute
|
71
|
+
date_time_attribute :due_at, time_zone: 'Moscow'
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
class Task
|
77
|
+
include DateTimeAttribute
|
78
|
+
date_time_attribute :due_at, time_zone: Proc.new { 'Moscow' }
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
class Task
|
84
|
+
include DateTimeAttribute
|
85
|
+
date_time_attribute :due_at, time_zone: :my_time_zone
|
86
|
+
|
87
|
+
def my_time_zone
|
88
|
+
self.in_da_moscow? ? 'Moscow' : 'Birobidgan'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
You can also explicitly set timezone:
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
Time.zone = 'Krasnoyarsk'
|
97
|
+
task.due_at # => nil
|
98
|
+
task.due_at_time = '02:00am'
|
99
|
+
task.due_at # => Mon, 02 Dec 2013 02:00:00 KRAT +08:00
|
100
|
+
task.due_at_time_zone = 'Moscow'
|
101
|
+
task.due_at # => Mon, 02 Dec 2013 02:00:00 MSK +04:00
|
102
|
+
```
|
103
|
+
|
104
|
+
## Using Chronic gem
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
DateTimeAttribute.parser = Chronic
|
108
|
+
|
109
|
+
task.due_at_date = 'next saturday'
|
110
|
+
task.due_at_time = '10:00pm'
|
111
|
+
```
|
112
|
+
|
113
|
+
## Advanced usage
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
my_date_time = DateTimeAttribute::Container.new
|
117
|
+
my_date_time.date_time # => nil
|
118
|
+
my_date_time.date = '2001-02-03'
|
119
|
+
my_date_time.date_time # => 2001-02-03 00:00:00 +0700
|
120
|
+
my_date_time.dime = '10:00pm'
|
121
|
+
my_date_time.date_time # => 2001-02-03 22:00:00 +0700
|
122
|
+
|
123
|
+
# ...same as described above
|
124
|
+
```
|
125
|
+
|
126
|
+
## See also
|
127
|
+
|
128
|
+
[ActiveRecord (Rails) version](https://github.com/einzige/date_time_attribute_rails)
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{date_time_attribute}
|
5
|
+
s.version = "0.0.4"
|
6
|
+
|
7
|
+
s.date = %q{2013-11-22}
|
8
|
+
s.authors = ["Sergei Zinin"]
|
9
|
+
s.email = %q{szinin@gmail.com}
|
10
|
+
s.homepage = %q{http://github.com/einzige/date_time_attribute}
|
11
|
+
|
12
|
+
s.licenses = ["MIT"]
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
s.extra_rdoc_files = ["README.md"]
|
17
|
+
|
18
|
+
s.description = %q{Allows to assign date and time attributes separately for a DateTime attribute in your model instance. Plays with time zones as well.}
|
19
|
+
s.summary = %q{Splits DateTime attribute access into three separate Data, Time and TimeZone attributes}
|
20
|
+
|
21
|
+
s.add_runtime_dependency 'activesupport', ">= 3.0.0"
|
22
|
+
s.add_development_dependency 'bundler'
|
23
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_support'
|
3
|
+
require 'active_support/duration'
|
4
|
+
require 'date_time_attribute/container'
|
5
|
+
|
6
|
+
module DateTimeAttribute
|
7
|
+
VERSION = '0.0.4'
|
8
|
+
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
def self.parser
|
12
|
+
DateTimeAttribute::Container.parser
|
13
|
+
end
|
14
|
+
|
15
|
+
# @param val Any adapter responding to #parse
|
16
|
+
def self.parser=(val)
|
17
|
+
DateTimeAttribute::Container.parser = val
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param [Symbol] attribute
|
21
|
+
# @return [Container]
|
22
|
+
def date_time_container(attribute)
|
23
|
+
(@date_time_container ||= {})[attribute] ||= DateTimeAttribute::Container.new(send(attribute))
|
24
|
+
end
|
25
|
+
|
26
|
+
# @param [String, Symbol, Proc, nil] zone Time zone
|
27
|
+
def in_time_zone(zone)
|
28
|
+
case zone
|
29
|
+
when nil
|
30
|
+
yield
|
31
|
+
when ActiveSupport::TimeZone, String
|
32
|
+
old_zone = Time.zone
|
33
|
+
Time.zone = zone
|
34
|
+
yield(zone).tap { Time.zone = old_zone }
|
35
|
+
when Proc, Symbol
|
36
|
+
old_zone = Time.zone
|
37
|
+
zone = instance_eval(&(zone.to_proc))
|
38
|
+
Time.zone = zone
|
39
|
+
yield(zone).tap { Time.zone = old_zone }
|
40
|
+
else
|
41
|
+
raise ArgumentError, "Expected timezone, got #{zone.inspect}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module ClassMethods
|
46
|
+
|
47
|
+
# @param [Symbol] attribute Attribute name
|
48
|
+
# @param [Hash<Symbol>] opts
|
49
|
+
# @option opts [String, Symbol, Proc, nil] :time_zone
|
50
|
+
def date_time_attribute(*attributes)
|
51
|
+
opts = attributes.extract_options!
|
52
|
+
time_zone = opts[:time_zone]
|
53
|
+
|
54
|
+
attributes.each do |attribute|
|
55
|
+
attribute = attribute.to_sym
|
56
|
+
|
57
|
+
# ActiveRecord issue: https://rails.lighthouseapp.com/projects/8994/tickets/4317-inconsistent-method_defined-bevahiour
|
58
|
+
if !(method_defined?(attribute) || (respond_to?(:attribute_method?) && attribute_method?(attribute)))
|
59
|
+
attr_accessor attribute
|
60
|
+
end
|
61
|
+
|
62
|
+
define_method("#{attribute}_date") do
|
63
|
+
in_time_zone(time_zone) do |time_zone|
|
64
|
+
date_time_container(attribute).in_time_zone(time_zone).date
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
define_method("#{attribute}_time") do
|
69
|
+
in_time_zone(time_zone) do |time_zone|
|
70
|
+
date_time_container(attribute).in_time_zone(time_zone).time
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
define_method("#{attribute}_time_zone") do
|
75
|
+
in_time_zone(time_zone) do |time_zone|
|
76
|
+
date_time_container(attribute).in_time_zone(time_zone).time_zone
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
define_method("#{attribute}_date=") do |val|
|
81
|
+
in_time_zone(time_zone) do |time_zone|
|
82
|
+
container = date_time_container(attribute).in_time_zone(time_zone)
|
83
|
+
(container.date = val).tap do
|
84
|
+
self.send("#{attribute}=", container.date_time)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
define_method("#{attribute}_time=") do |val|
|
90
|
+
in_time_zone(time_zone) do |time_zone|
|
91
|
+
container = date_time_container(attribute).in_time_zone(time_zone)
|
92
|
+
(container.time = val).tap do
|
93
|
+
self.send("#{attribute}=", container.date_time)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
define_method("#{attribute}_time_zone=") do |val|
|
99
|
+
in_time_zone(val) do |time_zone|
|
100
|
+
container = date_time_container(attribute).in_time_zone(time_zone)
|
101
|
+
self.send("#{attribute}=", container.date_time)
|
102
|
+
container.time_zone
|
103
|
+
end if val
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'active_support/core_ext/object/try'
|
2
|
+
require 'active_support/core_ext/time/zones'
|
3
|
+
require 'active_support/core_ext/module/delegation'
|
4
|
+
|
5
|
+
module DateTimeAttribute
|
6
|
+
class Container < Struct.new(:date_time, :date, :time, :time_zone)
|
7
|
+
delegate :year, :month, :day, :hour, to: :date_time
|
8
|
+
|
9
|
+
# @param [String] time_zone
|
10
|
+
# @return [Container] self
|
11
|
+
def in_time_zone(time_zone)
|
12
|
+
self.time_zone = time_zone
|
13
|
+
update_date_time
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [String, nil]
|
18
|
+
def time_zone
|
19
|
+
@time_zone
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param [String] val
|
23
|
+
def time_zone=(val)
|
24
|
+
(@time_zone = val).tap { update_date_time }
|
25
|
+
end
|
26
|
+
|
27
|
+
# @param [String, Date, Time, DateTime, nil] val
|
28
|
+
def date=(val)
|
29
|
+
@date = parse(val)
|
30
|
+
update_date_time
|
31
|
+
@date
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param [String, Date, Time, DateTime, nil] val
|
35
|
+
def time=(val)
|
36
|
+
@time = parse(val)
|
37
|
+
update_date_time
|
38
|
+
@time
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [Date, String]
|
42
|
+
def date
|
43
|
+
@date || date_time
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Time, String]
|
47
|
+
def time
|
48
|
+
@time || date_time
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.parser
|
52
|
+
@parser || Time.zone || Time
|
53
|
+
end
|
54
|
+
|
55
|
+
# @param val Parser used for parsing date/time string values
|
56
|
+
def self.parser=(val)
|
57
|
+
@parser = val
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def parse(val)
|
63
|
+
case val
|
64
|
+
when String
|
65
|
+
self.class.parser.parse(val)
|
66
|
+
when Date, Time, DateTime, ActiveSupport::TimeWithZone
|
67
|
+
val
|
68
|
+
when nil
|
69
|
+
else
|
70
|
+
raise ArgumentError, "Expected Date, Time, String, got #{val.class.name}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def update_date_time
|
75
|
+
if @date || @time
|
76
|
+
date_time = self.class.parser.parse("#{date.try(:strftime, '%Y-%m-%d')} #{time.try(:strftime, '%H:%M')}")
|
77
|
+
self.date_time = time_zone ? date_time.in_time_zone(time_zone) : date_time
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DateTimeAttribute::Container do
|
4
|
+
subject { described_class.new(Time.now) }
|
5
|
+
|
6
|
+
its(:year) { should == Time.now.year }
|
7
|
+
its(:month) { should == Time.now.month }
|
8
|
+
its(:day) { should == Time.now.day }
|
9
|
+
its(:hour) { should == Time.now.hour }
|
10
|
+
|
11
|
+
describe 'setters' do
|
12
|
+
before do
|
13
|
+
Time.zone = 'Pacific Time (US & Canada)'
|
14
|
+
end
|
15
|
+
|
16
|
+
subject(:target) { described_class.new(date_time, date, time) }
|
17
|
+
|
18
|
+
let(:date_time) { nil }
|
19
|
+
|
20
|
+
before do
|
21
|
+
target.date_time = date_time
|
22
|
+
target.date = date
|
23
|
+
target.time = time
|
24
|
+
end
|
25
|
+
|
26
|
+
context "nothing set" do
|
27
|
+
let(:date_time) { nil }
|
28
|
+
let(:date) { nil }
|
29
|
+
let(:time) { nil }
|
30
|
+
|
31
|
+
its(:date_time) { should be_nil }
|
32
|
+
end
|
33
|
+
|
34
|
+
context "time set" do
|
35
|
+
let(:date) { nil }
|
36
|
+
let(:time) { '23:00' }
|
37
|
+
|
38
|
+
its(:year) { should == Time.zone.now.year }
|
39
|
+
its(:month) { should == Time.zone.now.month }
|
40
|
+
its(:day) { should == Time.zone.now.day }
|
41
|
+
its(:hour) { should == 23 }
|
42
|
+
end
|
43
|
+
|
44
|
+
context "date set" do
|
45
|
+
let(:date) { '2001-02-03' }
|
46
|
+
let(:time) { nil }
|
47
|
+
|
48
|
+
its(:year) { should == 2001 }
|
49
|
+
its(:month) { should == 2 }
|
50
|
+
its(:day) { should == 3 }
|
51
|
+
|
52
|
+
it 'does not use current timezone' do
|
53
|
+
subject.hour.should == 0
|
54
|
+
end
|
55
|
+
|
56
|
+
context "time set" do
|
57
|
+
let(:date) { '2001-02-03' }
|
58
|
+
let(:time) { '10:00pm' }
|
59
|
+
|
60
|
+
its(:year) { should == 2001 }
|
61
|
+
its(:month) { should == 2 }
|
62
|
+
its(:day) { should == 3 }
|
63
|
+
its(:hour) { should == 22 }
|
64
|
+
|
65
|
+
context "non string values" do
|
66
|
+
let(:date) { Date.new(2001, 02, 03) }
|
67
|
+
let(:time) { Time.new(2001, 02, 03, 04, 05) }
|
68
|
+
|
69
|
+
its(:year) { should == 2001 }
|
70
|
+
its(:month) { should == 2 }
|
71
|
+
its(:day) { should == 3 }
|
72
|
+
its(:hour) { should == 4 }
|
73
|
+
end
|
74
|
+
|
75
|
+
context "time zone set" do
|
76
|
+
its(:year) { should == 2001 }
|
77
|
+
its(:month) { should == 2 }
|
78
|
+
|
79
|
+
specify do
|
80
|
+
expect { subject.time_zone = 'Moscow' }.to change { subject.time_zone }.from(nil).to('Moscow')
|
81
|
+
end
|
82
|
+
|
83
|
+
specify do
|
84
|
+
expect { subject.time_zone = 'Moscow' }.to change { subject.day }.from(3).to(4)
|
85
|
+
end
|
86
|
+
|
87
|
+
specify do
|
88
|
+
expect { subject.time_zone = 'Moscow' }.to change { subject.hour }.from(22).to(9)
|
89
|
+
end
|
90
|
+
|
91
|
+
context "different environment timezone set" do
|
92
|
+
before do
|
93
|
+
Time.zone = 'Krasnoyarsk'
|
94
|
+
end
|
95
|
+
|
96
|
+
its(:year) { should == 2001 }
|
97
|
+
its(:month) { should == 2 }
|
98
|
+
its(:day) { should == 3 }
|
99
|
+
its(:hour) { should == 22 }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,205 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DateTimeAttribute do
|
4
|
+
before do
|
5
|
+
Time.zone = 'Pacific Time (US & Canada)'
|
6
|
+
end
|
7
|
+
|
8
|
+
describe ".parser" do
|
9
|
+
its(:parser) { should == Time.zone }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '.date_time_attribute' do
|
13
|
+
let(:dummy_class) do
|
14
|
+
Class.new do
|
15
|
+
include DateTimeAttribute
|
16
|
+
date_time_attribute :due_at, :created_at
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
subject(:target) { dummy_class.new }
|
21
|
+
|
22
|
+
it { should respond_to :due_at }
|
23
|
+
it { should respond_to :due_at_time }
|
24
|
+
it { should respond_to :due_at_date }
|
25
|
+
it { should respond_to :created_at }
|
26
|
+
it { should respond_to :created_at_time }
|
27
|
+
it { should respond_to :created_at_date }
|
28
|
+
|
29
|
+
describe "values" do
|
30
|
+
let(:due_at) { nil }
|
31
|
+
let(:date) { nil }
|
32
|
+
let(:time) { nil }
|
33
|
+
let(:time_zone) { nil }
|
34
|
+
subject(:date_time) { target.due_at }
|
35
|
+
|
36
|
+
before do
|
37
|
+
target.due_at = due_at
|
38
|
+
target.due_at_date = date
|
39
|
+
target.due_at_time = time
|
40
|
+
target.due_at_time_zone = time_zone
|
41
|
+
end
|
42
|
+
|
43
|
+
context "nothing set" do
|
44
|
+
let(:due_at) { nil }
|
45
|
+
let(:date) { nil }
|
46
|
+
let(:time) { nil }
|
47
|
+
|
48
|
+
it { should be_nil }
|
49
|
+
end
|
50
|
+
|
51
|
+
context "date_time set" do
|
52
|
+
let(:due_at) { Time.zone.now }
|
53
|
+
it { should_not be_nil }
|
54
|
+
end
|
55
|
+
|
56
|
+
context "time set" do
|
57
|
+
let(:date) { nil }
|
58
|
+
let(:time) { '23:00' }
|
59
|
+
|
60
|
+
its(:year) { should == Time.zone.now.year }
|
61
|
+
its(:month) { should == Time.zone.now.month }
|
62
|
+
its(:day) { should == Time.zone.now.day }
|
63
|
+
its(:hour) { should == 23 }
|
64
|
+
end
|
65
|
+
|
66
|
+
context "date set" do
|
67
|
+
let(:date) { '2001-02-03' }
|
68
|
+
let(:time) { nil }
|
69
|
+
|
70
|
+
its(:year) { should == 2001 }
|
71
|
+
its(:month) { should == 2 }
|
72
|
+
its(:day) { should == 3 }
|
73
|
+
its(:hour) { should == 0 }
|
74
|
+
|
75
|
+
context "time set" do
|
76
|
+
let(:date) { '2001-02-03' }
|
77
|
+
let(:time) { '10:00pm' }
|
78
|
+
|
79
|
+
its(:year) { should == 2001 }
|
80
|
+
its(:month) { should == 2 }
|
81
|
+
its(:day) { should == 3 }
|
82
|
+
its(:hour) { should == 22 }
|
83
|
+
|
84
|
+
context "timezone set explicitly" do
|
85
|
+
let(:time_zone) { 'Krasnoyarsk' }
|
86
|
+
|
87
|
+
its(:year) { should == 2001 }
|
88
|
+
its(:month) { should == 2 }
|
89
|
+
its(:day) { should == 3 }
|
90
|
+
its(:hour) { should == 22 }
|
91
|
+
|
92
|
+
specify do
|
93
|
+
subject.time_zone.name.should == 'Krasnoyarsk'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "time zone set on attribute" do
|
98
|
+
let(:dummy_class) do
|
99
|
+
Class.new do
|
100
|
+
include DateTimeAttribute
|
101
|
+
date_time_attribute :due_at, time_zone: 'Moscow'
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
its(:year) { should == 2001 }
|
106
|
+
its(:month) { should == 2 }
|
107
|
+
its(:day) { should == 3 }
|
108
|
+
its(:hour) { should == 22 }
|
109
|
+
|
110
|
+
specify do
|
111
|
+
subject.time_zone.name.should == 'Moscow'
|
112
|
+
end
|
113
|
+
|
114
|
+
context "timezone set explicitly" do
|
115
|
+
let(:time_zone) { 'Krasnoyarsk' }
|
116
|
+
|
117
|
+
its(:year) { should == 2001 }
|
118
|
+
its(:month) { should == 2 }
|
119
|
+
its(:day) { should == 3 }
|
120
|
+
its(:hour) { should == 22 }
|
121
|
+
|
122
|
+
specify do
|
123
|
+
subject.time_zone.name.should == 'Krasnoyarsk'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context "different timezone set" do
|
128
|
+
before do
|
129
|
+
Time.zone = 'Krasnoyarsk'
|
130
|
+
end
|
131
|
+
|
132
|
+
its(:year) { should == 2001 }
|
133
|
+
its(:month) { should == 2 }
|
134
|
+
its(:day) { should == 3 }
|
135
|
+
its(:hour) { should == 22 }
|
136
|
+
|
137
|
+
specify do
|
138
|
+
subject.time_zone.name.should == 'Moscow'
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "timezone proc given" do
|
143
|
+
let(:dummy_class) do
|
144
|
+
Class.new do
|
145
|
+
include DateTimeAttribute
|
146
|
+
date_time_attribute :due_at, time_zone: Proc.new { 'Moscow' }
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
its(:year) { should == 2001 }
|
151
|
+
its(:month) { should == 2 }
|
152
|
+
its(:day) { should == 3 }
|
153
|
+
its(:hour) { should == 22 }
|
154
|
+
|
155
|
+
specify do
|
156
|
+
subject.time_zone.name.should == 'Moscow'
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context "timezone method given" do
|
161
|
+
let(:dummy_class) do
|
162
|
+
Class.new do
|
163
|
+
include DateTimeAttribute
|
164
|
+
date_time_attribute :due_at, time_zone: :tz
|
165
|
+
|
166
|
+
def tz
|
167
|
+
'Moscow'
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
its(:year) { should == 2001 }
|
173
|
+
its(:month) { should == 2 }
|
174
|
+
its(:day) { should == 3 }
|
175
|
+
its(:hour) { should == 22 }
|
176
|
+
|
177
|
+
specify do
|
178
|
+
subject.time_zone.name.should == 'Moscow'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context "nil timezone" do
|
183
|
+
let(:dummy_class) do
|
184
|
+
Class.new do
|
185
|
+
include DateTimeAttribute
|
186
|
+
date_time_attribute :due_at, time_zone: :tz
|
187
|
+
|
188
|
+
def tz
|
189
|
+
nil
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
it { should be_a(Time) }
|
195
|
+
its(:year) { should == 2001 }
|
196
|
+
its(:month) { should == 2 }
|
197
|
+
its(:day) { should == 3 }
|
198
|
+
its(:hour) { should == 22 }
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: date_time_attribute
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sergei Zinin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Allows to assign date and time attributes separately for a DateTime attribute
|
42
|
+
in your model instance. Plays with time zones as well.
|
43
|
+
email: szinin@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files:
|
47
|
+
- README.md
|
48
|
+
files:
|
49
|
+
- .coveralls.yml
|
50
|
+
- .gitignore
|
51
|
+
- .travis.yml
|
52
|
+
- Gemfile
|
53
|
+
- README.md
|
54
|
+
- Rakefile
|
55
|
+
- date_time_attribute.gemspec
|
56
|
+
- lib/date_time_attribute.rb
|
57
|
+
- lib/date_time_attribute/container.rb
|
58
|
+
- spec/date_time_attribute/container_spec.rb
|
59
|
+
- spec/date_time_attribute_spec.rb
|
60
|
+
- spec/spec_helper.rb
|
61
|
+
homepage: http://github.com/einzige/date_time_attribute
|
62
|
+
licenses:
|
63
|
+
- MIT
|
64
|
+
metadata: {}
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 2.1.5
|
82
|
+
signing_key:
|
83
|
+
specification_version: 4
|
84
|
+
summary: Splits DateTime attribute access into three separate Data, Time and TimeZone
|
85
|
+
attributes
|
86
|
+
test_files: []
|