ozone 0.3.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/.pryrc +6 -0
- data/.rubocop.yml +107 -0
- data/README.md +49 -27
- data/lib/ozone.rb +2 -3
- data/lib/ozone/version.rb +1 -1
- data/lib/time_builder.rb +80 -0
- data/ozone.gemspec +2 -0
- metadata +33 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 803c668d5479c838cb18101b0c29cef1e5737cff
|
4
|
+
data.tar.gz: 3dea45fbad4cbf0e96105f3877219d43b2224bd1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c82342df57042ed2932e909cca6421aefc3384fbe8fffac605b9446cc0068bf8a5012a1b54734440c2214f2a58c9786b339ab67d16730860b40bf51565e5ec7
|
7
|
+
data.tar.gz: 92505c2856f8348b1a2a5960ed8cdd91dba64db920fdfc5d34a0c5452a5fab368072b46d80b02edda668d6b41ec4fecde34fd618910a9f38164613749632a004
|
data/.gitignore
CHANGED
data/.pryrc
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
# Practice Fusion Rubocop Rules
|
2
|
+
AllCops:
|
3
|
+
# Exclude anything that isn't really part of our code.
|
4
|
+
Exclude:
|
5
|
+
- '**/*.gemspec'
|
6
|
+
- '**/Guardfile' # mostly copy/paste
|
7
|
+
- '**/Rakefile'
|
8
|
+
- 'bin/**/*'
|
9
|
+
- 'config/initializers/secret_token.rb' # long tokens
|
10
|
+
- 'db/**/*' # auto-generated
|
11
|
+
- 'spec/rails_helper.rb' # full of solecisms, mostly copy and paste
|
12
|
+
- 'spec/teaspoon_env.rb' # mostly copy and paste
|
13
|
+
- 'spec/vcr_cassettes/**/*'
|
14
|
+
- 'vendor/**/*'
|
15
|
+
DisplayCopNames: true
|
16
|
+
RunRailsCops: true
|
17
|
+
DisplayStyleGuide: true
|
18
|
+
|
19
|
+
# This is less volatile if methods change, and there's less busy work lining things up.
|
20
|
+
Style/AlignParameters:
|
21
|
+
EnforcedStyle: with_fixed_indentation
|
22
|
+
|
23
|
+
# Chain methods with trailing dots.
|
24
|
+
Style/DotPosition:
|
25
|
+
EnforcedStyle: trailing
|
26
|
+
|
27
|
+
# It's not really clearer to replace every if with a return if.
|
28
|
+
Style/GuardClause:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
# Would enforce do_y if x over if x / do y / end. As with GuardClause above,
|
32
|
+
# this enforces code organisation that doesn't necesarily make things clearer.
|
33
|
+
IfUnlessModifier:
|
34
|
+
Enabled: false
|
35
|
+
|
36
|
+
# Enforce single quotes everywhere except in specs (because there's a lot of
|
37
|
+
# human text with apostrophes in spec names, and using double quotes for all
|
38
|
+
# of those is more consistent. There shouldn't be much human-readable text in
|
39
|
+
# the application code: that is better moved to the locale files.
|
40
|
+
Style/StringLiterals:
|
41
|
+
EnforcedStyle: single_quotes
|
42
|
+
Exclude:
|
43
|
+
- 'spec/**/*'
|
44
|
+
|
45
|
+
# Trailing commas are totally fine.
|
46
|
+
Style/TrailingComma:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
# Just a preference to use %w[] over %w()
|
50
|
+
Style/PercentLiteralDelimiters:
|
51
|
+
PreferredDelimiters:
|
52
|
+
'%i': '[]'
|
53
|
+
'%w': '[]'
|
54
|
+
'%W': '[]'
|
55
|
+
|
56
|
+
# We can tolerate a little additional complexity
|
57
|
+
# http://c2.com/cgi/wiki?AbcMetric
|
58
|
+
Metrics/AbcSize:
|
59
|
+
Max: 24
|
60
|
+
Exclude:
|
61
|
+
- 'spec/**/*'
|
62
|
+
|
63
|
+
# We can tolerate a little additional complexity
|
64
|
+
# http://c2.com/cgi/wiki?CyclomaticComplexityMetric
|
65
|
+
Metrics/CyclomaticComplexity:
|
66
|
+
Max: 8
|
67
|
+
Exclude:
|
68
|
+
- 'spec/**/*'
|
69
|
+
|
70
|
+
# We can tolerate a little additional complexity
|
71
|
+
# http://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Metrics/PerceivedComplexity
|
72
|
+
Metrics/PerceivedComplexity:
|
73
|
+
Max: 8
|
74
|
+
Exclude:
|
75
|
+
- 'spec/**/*'
|
76
|
+
|
77
|
+
# Allow long lines in specs, as it's almost impossible to fit RSpec's
|
78
|
+
# expectations into 80 characters.
|
79
|
+
Metrics/LineLength:
|
80
|
+
Max: 120
|
81
|
+
Exclude:
|
82
|
+
- 'spec/**/*'
|
83
|
+
|
84
|
+
# Don't worry about long methods in specs.
|
85
|
+
Metrics/MethodLength:
|
86
|
+
Max: 20
|
87
|
+
Exclude:
|
88
|
+
- 'spec/**/*'
|
89
|
+
|
90
|
+
# Don't worry about long modules in specs.
|
91
|
+
Metrics/ModuleLength:
|
92
|
+
Exclude:
|
93
|
+
- 'spec/**/*'
|
94
|
+
|
95
|
+
# Prefer sensible naming to comments everywhere.
|
96
|
+
Documentation:
|
97
|
+
Description: Document classes and non-namespace modules.
|
98
|
+
Enabled: false
|
99
|
+
|
100
|
+
# Would enforce do_y if x over if x / do y / end. As with GuardClause above,
|
101
|
+
# this enforces code organisation that doesn't necesarily make things clearer.
|
102
|
+
IfUnlessModifier:
|
103
|
+
Enabled: false
|
104
|
+
|
105
|
+
# Don't allow assignment in conditionals, ever.
|
106
|
+
Lint/AssignmentInCondition:
|
107
|
+
AllowSafeAssignment: false
|
data/README.md
CHANGED
@@ -1,12 +1,5 @@
|
|
1
1
|
# ozone
|
2
|
-
|
3
|
-
=======
|
4
|
-
# Ozone
|
5
|
-
|
6
|
-
Given a ruby time, an offset (in minutes), and a boolean whether to observe daylight savings, Ozone provides two things:
|
7
|
-
|
8
|
-
1) Convert a ruby time to a string representation, adjusted by offset, and either abiding by or ignoring daylight savings.
|
9
|
-
2) Compare with a ruby time to see whether before or after, either abiding by or ignoring daylight savings.
|
2
|
+
Time-to-String and String-to-Time operations which operate using time zone offsets (in minutes) and a boolean which indicates whether or not DST is observed.
|
10
3
|
|
11
4
|
## Installation
|
12
5
|
|
@@ -24,6 +17,29 @@ Or install it yourself as:
|
|
24
17
|
|
25
18
|
$ gem install ozone
|
26
19
|
|
20
|
+
## Development
|
21
|
+
|
22
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
23
|
+
|
24
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
25
|
+
|
26
|
+
## Contributing
|
27
|
+
|
28
|
+
1. Fork it ( https://github.com/[my-github-username]/ozone/fork )
|
29
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
30
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
31
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
32
|
+
5. Create a new Pull Request
|
33
|
+
|
34
|
+
|
35
|
+
# Ozone::Time
|
36
|
+
|
37
|
+
Given a ruby time (UTC), an offset (in minutes), and a boolean whether to observe daylight savings, Ozone::Time provides two things:
|
38
|
+
|
39
|
+
1) Convert a ruby time to a string representation, adjusted by offset, and either abiding by or ignoring daylight savings.
|
40
|
+
2) Compare with a ruby time to see whether before or after, either abiding by or ignoring daylight savings.
|
41
|
+
|
42
|
+
|
27
43
|
## Usage
|
28
44
|
|
29
45
|
An instance of Ozone::Time can be compared with a ruby time.
|
@@ -59,33 +75,39 @@ ozone_time = Time.new(
|
|
59
75
|
=> true
|
60
76
|
```
|
61
77
|
|
62
|
-
|
63
|
-
is not being observed.
|
78
|
+
# Ozone::TimeBuilder
|
64
79
|
|
65
|
-
|
80
|
+
Given a datetime string, an offset (in minutes), and a boolean whether to observe daylight savings, Ozone::TimeBuilder builds a ruby time object (UTC). The TimeBuilder serves as an inverse to Ozone::Time which given a ruby time, can generate a string representation of that time.
|
66
81
|
|
67
|
-
|
68
|
-
> Ozone::Formatter.call(time: t, offset: -480, observes_dst: true)
|
69
|
-
=> "2014/07/17 17:30"
|
82
|
+
## Usage
|
70
83
|
|
71
|
-
|
72
|
-
|
84
|
+
`TimeBuilder` accepts four String formats as input to the `from_string` method:
|
85
|
+
- YYYY/MM/DD HH:MM
|
86
|
+
- YYYY/MM/DDTHH:MM
|
87
|
+
- YYYY-MM-DD HH:MM
|
88
|
+
- YYY-MM-DDTHH:MM
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
> builder = Ozone::TimeBuilder.new
|
92
|
+
#<Ozone::TimeBuilder:0x007fff4c6e9f30 @observes_dst=nil, @offset=nil, @time_str=nil>
|
93
|
+
> time = builder.from_string("2015-11-15 09:00").with_offset(-480).with_dst(false).build
|
94
|
+
=> 2015-11-15 08:00:00 UTC
|
73
95
|
```
|
74
96
|
|
75
|
-
|
97
|
+
# Ozone::Formatter
|
76
98
|
|
77
|
-
|
99
|
+
Takes a time, offset (from utc, in minutes), whether to use daylight savings, and a [time format](http://ruby-doc.org/core-2.2.0/Time.html#method-i-strftime). Default format is YYYY-MM-DD HH:MM.
|
78
100
|
|
79
|
-
##
|
101
|
+
## Usage
|
102
|
+
Since all operations are executing in UTC time, the time zone in the format string will *always* be UTC.
|
103
|
+
This functionality can also be accessed via the Ozone::Time#strftime method.
|
80
104
|
|
81
|
-
|
105
|
+
```ruby
|
106
|
+
> Ozone::Formatter.call(time: t, offset: -480, observes_dst: true)
|
107
|
+
=> "2014/07/17 17:30"
|
82
108
|
|
83
|
-
|
109
|
+
> Ozone::Formatter.call(time: t, offset: -480, observes_dst: false)
|
110
|
+
=> "2014/07/17 16:30"
|
111
|
+
```
|
84
112
|
|
85
|
-
## Contributing
|
86
113
|
|
87
|
-
1. Fork it ( https://github.com/[my-github-username]/ozone/fork )
|
88
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
89
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
90
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
91
|
-
5. Create a new Pull Request
|
data/lib/ozone.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'ozone/version'
|
2
|
-
|
3
2
|
require 'active_support/time'
|
4
3
|
|
5
4
|
module Ozone
|
@@ -18,8 +17,8 @@ module Ozone
|
|
18
17
|
@time = time
|
19
18
|
end
|
20
19
|
|
21
|
-
def <=>(
|
22
|
-
adjusted_time <=> to_ozone_time(
|
20
|
+
def <=>(other)
|
21
|
+
adjusted_time <=> to_ozone_time(other).adjusted_time
|
23
22
|
end
|
24
23
|
|
25
24
|
def before?(time_with_zone)
|
data/lib/ozone/version.rb
CHANGED
data/lib/time_builder.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'ozone/version'
|
2
|
+
require 'active_support/time'
|
3
|
+
|
4
|
+
module Ozone
|
5
|
+
class TimeBuilder
|
6
|
+
# Valid formats:
|
7
|
+
# YYYY/MM/DD 00:00,YYYY/MM/DDT00:00, YYYY-MM-DD 00:00, YYYY-MM-DDT00:00
|
8
|
+
DATETIME_FORMAT = %r[(\d{4}[/-]\d{2}[/-]\d{2})[ T](\d{2}:\d{2})]
|
9
|
+
|
10
|
+
def from_string(time_str)
|
11
|
+
@time_str = time_str
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def with_offset(offset)
|
16
|
+
@offset = offset
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def with_dst(observes_dst)
|
21
|
+
@observes_dst = observes_dst
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def build
|
26
|
+
fail StandardError, 'from_string() must be supplied a non-nil datetime string' unless @time_str.is_a?(String)
|
27
|
+
fail StandardError, 'from_string() argument should match YYYY/MM/DD HH:MM' unless DATETIME_FORMAT.match(@time_str)
|
28
|
+
fail StandardError, 'with_offset() must be supplied a number' unless @offset.is_a?(Numeric)
|
29
|
+
fail StandardError, 'with_dst() must be supplied a boolean' if @observes_dst.nil?
|
30
|
+
calculate_utc_time
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
PST = ActiveSupport::TimeZone['Pacific Time (US & Canada)']
|
36
|
+
|
37
|
+
def calculate_utc_time
|
38
|
+
date = DATETIME_FORMAT.match(@time_str)[1]
|
39
|
+
time = DATETIME_FORMAT.match(@time_str)[2]
|
40
|
+
|
41
|
+
# Build UTC time and add/subtract minutes to avoid timezone assumptions and automatic conversions
|
42
|
+
# Apply offsets manually based on @offset and whether or not DST is in effect in a zone known to observe
|
43
|
+
# DST during the specified date/time
|
44
|
+
utc = ::Time.parse("#{date}T#{time}+0000").utc
|
45
|
+
|
46
|
+
if during_dst(date, time) && @observes_dst
|
47
|
+
utc -= 60.minutes
|
48
|
+
end
|
49
|
+
|
50
|
+
if @offset > 0
|
51
|
+
utc + @offset.minutes
|
52
|
+
else
|
53
|
+
utc - @offset.minutes
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def during_dst(date, time)
|
58
|
+
pst_time = format '%sT%s-0800', date, time
|
59
|
+
during_dst_pst = ::Time.parse(pst_time).in_time_zone(PST).dst?
|
60
|
+
|
61
|
+
pdt_time = format '%%sT%s-0700', date, time
|
62
|
+
during_dst_pdt = ::Time.parse(pdt_time).in_time_zone(PST).dst?
|
63
|
+
|
64
|
+
# If during_dst_pdt is false and during_dst_pst is true, the time does not exist (hour skipped).
|
65
|
+
if !during_dst_pdt && during_dst_pst
|
66
|
+
fail StandardError 'The time specified occurs during a daylight savings time change and does not exist.'
|
67
|
+
end
|
68
|
+
|
69
|
+
# Both are true:
|
70
|
+
# The time is during DST (during_dst_pdt is true)
|
71
|
+
# Both are false:
|
72
|
+
# The time is not during DST (during_dst_pdt is false)
|
73
|
+
# during_dst_pdt is true, during_dst_pst if false:
|
74
|
+
# The time exists twice as it occurs during a shift back to standard time. In that case, assuming the earlier
|
75
|
+
# point in time (the one during DST) is acceptable.
|
76
|
+
# Therefore, it is safe to return only the value of during_dst_pdt
|
77
|
+
during_dst_pdt
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/ozone.gemspec
CHANGED
@@ -27,4 +27,6 @@ Gem::Specification.new do |spec|
|
|
27
27
|
spec.add_development_dependency "bundler", "~> 1.9"
|
28
28
|
spec.add_development_dependency "rake", "~> 10.0"
|
29
29
|
spec.add_development_dependency "rspec", "~> 3.2"
|
30
|
+
spec.add_development_dependency "pry"
|
31
|
+
spec.add_development_dependency "pry-byebug"
|
30
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ozone
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hubert Huang
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-08-
|
11
|
+
date: 2015-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -80,6 +80,34 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '3.2'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry-byebug
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
83
111
|
description:
|
84
112
|
email:
|
85
113
|
- hubert77@gmail.com
|
@@ -88,7 +116,9 @@ extensions: []
|
|
88
116
|
extra_rdoc_files: []
|
89
117
|
files:
|
90
118
|
- ".gitignore"
|
119
|
+
- ".pryrc"
|
91
120
|
- ".rspec"
|
121
|
+
- ".rubocop.yml"
|
92
122
|
- ".travis.yml"
|
93
123
|
- CODE_OF_CONDUCT.md
|
94
124
|
- Gemfile
|
@@ -99,6 +129,7 @@ files:
|
|
99
129
|
- bin/setup
|
100
130
|
- lib/ozone.rb
|
101
131
|
- lib/ozone/version.rb
|
132
|
+
- lib/time_builder.rb
|
102
133
|
- ozone.gemspec
|
103
134
|
homepage: https://github.com/practicefusion/ozone
|
104
135
|
licenses: []
|