teasy 0.2.3 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -4
- data/.ruby-version +1 -1
- data/CHANGELOG.md +22 -0
- data/lib/teasy.rb +1 -1
- data/lib/teasy/ambiguous_time_handling.rb +3 -3
- data/lib/teasy/floating_time.rb +2 -1
- data/lib/teasy/period_not_found_handling.rb +4 -4
- data/lib/teasy/time_with_zone.rb +25 -17
- data/lib/teasy/version.rb +1 -1
- data/teasy.gemspec +8 -10
- data/test/teasy/time_with_zone_test.rb +4 -4
- metadata +20 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8bbffed19dc702847e0096485c0540b12ec6b28e4f5a14165ccb46ae13103a6
|
4
|
+
data.tar.gz: cc76f08f0630726cfc371ea2a4bc8142a4245f408ca5a358e544781e4d4b812a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d00df4b7245a715e319eefefa17392d9e5068a289937e8978d52b2e690b6368c79e1289a8f98b86cbbc9b7397ec636047837ccb7f74c6d544b553bbec2aa25b
|
7
|
+
data.tar.gz: d5d3c5d28d40941738d7ad3ac272c980993abe0e4dd1640d032755238bb7f1b9014653fb389ef9f875cca9c92ba194940097e46f4c6de04fc6614bec78c2e29c
|
data/.rubocop.yml
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
AllCops:
|
2
2
|
Exclude:
|
3
3
|
- teasy.gemspec
|
4
|
-
-
|
5
|
-
-
|
4
|
+
- "vendor/**/*"
|
5
|
+
- "test/**/*"
|
6
|
+
NewCops: enable
|
6
7
|
|
7
8
|
# Setting the line length to a maximum of 80 chars.
|
8
|
-
LineLength:
|
9
|
+
Layout/LineLength:
|
9
10
|
Enabled: true
|
10
11
|
Max: 80
|
11
|
-
Documentation:
|
12
|
+
Style/Documentation:
|
12
13
|
Enabled: false
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.7.1
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Change Log
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
Please group changes into `Added`, `Changed`, `Deprecated`, `Removed`, `Fixed`
|
5
|
+
and `Security` as described in [Keep a Changelog](http://keepachangelog.com/),
|
6
|
+
taking the above order into account.
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
|
10
|
+
|
11
|
+
________________________________________________________________________________
|
12
|
+
|
13
|
+
## [0.2.4] - 2018-04-20
|
14
|
+
|
15
|
+
### Added
|
16
|
+
- this Changelog
|
17
|
+
|
18
|
+
### Changed
|
19
|
+
- yield `zone` to block in `Teasy.with_zone`
|
20
|
+
- always use `Teasy.with_zone` internally when looking up the
|
21
|
+
`TZInfo::Timezone`. That way one could support other time zone names than the
|
22
|
+
TZInfo Identifier by making `Teasy.with_zone` convert those
|
data/lib/teasy.rb
CHANGED
@@ -37,9 +37,9 @@ module Teasy
|
|
37
37
|
# By returning nil TZInfo will raise TZInfo::AmbigousTime. It'd be
|
38
38
|
# better to raise our own error, but that would break the API that's out
|
39
39
|
# there. So that will have to wait for a 1.x release.
|
40
|
-
raise:
|
41
|
-
daylight_savings_time: ->(_time, periods)
|
42
|
-
standard_time:
|
40
|
+
raise: ->(_time, _periods) {},
|
41
|
+
daylight_savings_time: ->(_time, periods) { periods.select(&:dst?) },
|
42
|
+
standard_time: ->(_time, periods) { periods.reject(&:dst?) }
|
43
43
|
}.freeze
|
44
44
|
end
|
45
45
|
end
|
data/lib/teasy/floating_time.rb
CHANGED
@@ -58,6 +58,7 @@ module Teasy
|
|
58
58
|
def <=>(other)
|
59
59
|
return nil unless other.respond_to?(:to_time) &&
|
60
60
|
other.respond_to?(:utc_offset)
|
61
|
+
|
61
62
|
to_time - other.utc_offset <=> other.to_time.utc
|
62
63
|
end
|
63
64
|
|
@@ -113,7 +114,7 @@ module Teasy
|
|
113
114
|
|
114
115
|
def prefix_zone_info(format)
|
115
116
|
# prefixes zone directives with a % s.t. they are ignored in strftime
|
116
|
-
format.gsub(zone_directives_matcher) { |m|
|
117
|
+
format.gsub(zone_directives_matcher) { |m| "%#{m}" }
|
117
118
|
end
|
118
119
|
end
|
119
120
|
end
|
@@ -35,17 +35,17 @@ module Teasy
|
|
35
35
|
end
|
36
36
|
|
37
37
|
HANDLER = {
|
38
|
-
raise:
|
38
|
+
raise: ->(_time, _zone) { raise },
|
39
39
|
# the biggest change in offsets known to me is when Samoa went from -11
|
40
40
|
# to +13 (a full day!) so hopefully we're sure to leave the unknown
|
41
41
|
# period by adding/subtracting 3 days
|
42
|
-
next_period:
|
42
|
+
next_period: lambda do |time, zone|
|
43
43
|
period = zone.period_for_local(time + 3 * 86_400)
|
44
|
-
[period, period.start_transition.
|
44
|
+
[period, period.start_transition.at.to_time + period.utc_total_offset]
|
45
45
|
end,
|
46
46
|
previous_period: lambda do |time, zone|
|
47
47
|
period = zone.period_for_local(time - 3 * 86_400)
|
48
|
-
[period, period.end_transition.
|
48
|
+
[period, period.end_transition.at.to_time + period.utc_total_offset]
|
49
49
|
end
|
50
50
|
}.freeze
|
51
51
|
end
|
data/lib/teasy/time_with_zone.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'tzinfo'
|
4
|
+
require 'time'
|
4
5
|
require 'forwardable'
|
5
6
|
|
6
7
|
module Teasy
|
@@ -22,7 +23,7 @@ module Teasy
|
|
22
23
|
def initialize(year, month = nil, day = nil,
|
23
24
|
hour = nil, minute = nil, second = nil, usec_with_frac = nil,
|
24
25
|
zone = Teasy.default_zone)
|
25
|
-
@zone =
|
26
|
+
@zone = tzinfo_time_zone(zone)
|
26
27
|
@time = Time.utc(year, month, day, hour, minute, second, usec_with_frac)
|
27
28
|
@period = determine_period(@time, @zone)
|
28
29
|
end
|
@@ -46,17 +47,15 @@ module Teasy
|
|
46
47
|
end
|
47
48
|
|
48
49
|
def self.strptime(string, format, zone = Teasy.default_zone)
|
49
|
-
# rubocop:disable Style/DateTime
|
50
50
|
new(*DateTime._strptime(string, format).values, 'UTC').in_time_zone!(zone)
|
51
|
-
# rubocop:enable Style/DateTime
|
52
51
|
end
|
53
52
|
|
54
53
|
def in_time_zone!(zone = Teasy.default_zone)
|
55
54
|
time = utc_time
|
56
|
-
@zone =
|
55
|
+
@zone = tzinfo_time_zone(zone)
|
57
56
|
@time = @zone.utc_to_local(time)
|
58
57
|
@period = @zone.period_for_utc(time)
|
59
|
-
remove_instance_variable(:@local_time)
|
58
|
+
remove_instance_variable(:@local_time) if defined?(@local_time)
|
60
59
|
self
|
61
60
|
end
|
62
61
|
|
@@ -74,7 +73,7 @@ module Teasy
|
|
74
73
|
|
75
74
|
def utc!
|
76
75
|
@time = @zone.local_to_utc(@time, @period.dst?)
|
77
|
-
@zone =
|
76
|
+
@zone = tzinfo_time_zone('UTC')
|
78
77
|
@period = @zone.period_for_local(@time)
|
79
78
|
self
|
80
79
|
end
|
@@ -126,6 +125,7 @@ module Teasy
|
|
126
125
|
|
127
126
|
def <=>(other)
|
128
127
|
return nil unless other.respond_to? :to_time
|
128
|
+
|
129
129
|
to_time <=> other.to_time
|
130
130
|
end
|
131
131
|
|
@@ -142,7 +142,8 @@ module Teasy
|
|
142
142
|
end
|
143
143
|
|
144
144
|
def to_time
|
145
|
-
return @local_time
|
145
|
+
return @local_time if defined?(@local_time)
|
146
|
+
|
146
147
|
params = %i[year mon day hour min].map! { |m| @time.send(m) }
|
147
148
|
params << @time.sec + @time.subsec
|
148
149
|
@local_time = utc? ? Time.utc(*params) : Time.new(*params, utc_offset)
|
@@ -167,10 +168,10 @@ module Teasy
|
|
167
168
|
attr_reader :time, :period
|
168
169
|
|
169
170
|
# matches valid format directives for zones
|
170
|
-
ZONE_ABBREV = /(?<!%)%Z
|
171
|
-
ZONE_NO_COLON_OFFSET = /(?<!%)%z
|
172
|
-
ZONE_COLON_OFFSET = /(?<!%)%:z
|
173
|
-
ZONE_COLONS_OFFSET = /(?<!%)%::z
|
171
|
+
ZONE_ABBREV = /(?<!%)%Z/.freeze
|
172
|
+
ZONE_NO_COLON_OFFSET = /(?<!%)%z/.freeze
|
173
|
+
ZONE_COLON_OFFSET = /(?<!%)%:z/.freeze
|
174
|
+
ZONE_COLONS_OFFSET = /(?<!%)%::z/.freeze
|
174
175
|
|
175
176
|
def zone_directives_matcher
|
176
177
|
@zone_directives_matcher ||= Regexp.union(
|
@@ -195,17 +196,24 @@ module Teasy
|
|
195
196
|
format_with_zone
|
196
197
|
end
|
197
198
|
|
199
|
+
# rubocop:disable Style/OptionalBooleanParameter
|
198
200
|
def formatted_offset(offset_in_seconds, colon = false, seconds = false)
|
199
|
-
string_format = +'%s%02d:%02d'
|
200
|
-
string_format.concat(':%02d') if seconds
|
201
|
-
string_format.delete!(':') unless colon
|
202
|
-
|
203
201
|
sign = offset_in_seconds.negative? ? '-' : '+'
|
204
202
|
hours = offset_in_seconds.abs / 3600
|
205
203
|
minutes = (offset_in_seconds.abs % 3600) / 60
|
206
|
-
seconds = (offset_in_seconds.abs % 60)
|
207
204
|
|
208
|
-
|
205
|
+
separator = colon ? ':' : ''
|
206
|
+
string_format = ['%s%02d', '%02d', ('%02d' if seconds)]
|
207
|
+
.compact.join(separator)
|
208
|
+
args = [sign, hours, minutes, ((offset_in_seconds.abs % 60) if seconds)]
|
209
|
+
.compact
|
210
|
+
|
211
|
+
format(string_format, *args)
|
212
|
+
end
|
213
|
+
# rubocop:enable Style/OptionalBooleanParameter
|
214
|
+
|
215
|
+
def tzinfo_time_zone(time_zone)
|
216
|
+
Teasy.with_zone(time_zone) { |zone| TZInfo::Timezone.get(zone) }
|
209
217
|
end
|
210
218
|
end
|
211
219
|
# rubocop:enable Metrics/ClassLength
|
data/lib/teasy/version.rb
CHANGED
data/teasy.gemspec
CHANGED
@@ -1,33 +1,31 @@
|
|
1
|
-
|
2
|
-
require File.expand_path("../lib/teasy/version", __FILE__)
|
1
|
+
require File.expand_path('lib/teasy/version', __dir__)
|
3
2
|
|
4
3
|
Gem::Specification.new do |spec|
|
5
4
|
spec.name = 'teasy'
|
6
5
|
spec.version = Teasy::VERSION
|
7
6
|
spec.authors = ['Kai Kuchenbecker']
|
8
7
|
spec.email = ['Kai.Kuchenbecker@invision.de']
|
9
|
-
spec.summary =
|
10
|
-
spec.description =
|
8
|
+
spec.summary = 'Teasy intends to make handling time zones easy.'
|
9
|
+
spec.description = "Teasy builds on tzinfo to get time zone data and
|
11
10
|
provides time classes to ease working with time zones.
|
12
11
|
It provides TimeWithZone which is similiar to Rails'
|
13
12
|
ActiveSupport::TimeWithZone but with less quirks. And
|
14
13
|
it provides FloatingTime which is time without a zone.
|
15
|
-
|
14
|
+
"
|
16
15
|
spec.homepage = ''
|
17
16
|
spec.license = 'MIT'
|
18
17
|
|
19
18
|
spec.files = `git ls-files -z`.split("\x0")
|
20
19
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
21
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
22
20
|
spec.require_paths = ['lib']
|
23
21
|
spec.required_ruby_version = '> 2.0'
|
24
22
|
|
25
|
-
spec.add_runtime_dependency 'tzinfo', '~>
|
26
|
-
spec.add_runtime_dependency 'tzinfo-data', '~> 1.
|
23
|
+
spec.add_runtime_dependency 'tzinfo', '~> 2.0'
|
24
|
+
spec.add_runtime_dependency 'tzinfo-data', '~> 1.2020.1'
|
27
25
|
|
28
|
-
spec.add_development_dependency 'bundler'
|
29
|
-
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'bundler'
|
30
27
|
spec.add_development_dependency 'minitest'
|
31
28
|
spec.add_development_dependency 'minitest-reporters'
|
29
|
+
spec.add_development_dependency 'rake'
|
32
30
|
spec.add_development_dependency 'rubocop'
|
33
31
|
end
|
@@ -44,7 +44,7 @@ class TimeWithZoneTest < Minitest::Test
|
|
44
44
|
|
45
45
|
def test_constructor_defaults_to_teasy_default_zone
|
46
46
|
assert_equal Teasy.default_zone, @timestamptz.zone
|
47
|
-
Teasy.
|
47
|
+
Teasy.with_zone('Europe/Berlin') do
|
48
48
|
timestamptz = Teasy::TimeWithZone.new(*@params)
|
49
49
|
assert_equal 'Europe/Berlin', timestamptz.zone
|
50
50
|
end
|
@@ -243,7 +243,7 @@ class TimeWithZoneTest < Minitest::Test
|
|
243
243
|
def test_inspect
|
244
244
|
assert_equal '2042-04-02 00:30:45 UTC', @timestamptz.inspect
|
245
245
|
assert_equal '2042-04-02 00:30:45 +0200', @timestamptz_berlin.inspect
|
246
|
-
timestamptz = Teasy.
|
246
|
+
timestamptz = Teasy.with_zone('Europe/Berlin') do
|
247
247
|
Teasy::TimeWithZone.new(2042)
|
248
248
|
end
|
249
249
|
assert_equal '2042-01-01 00:00:00 +0100', timestamptz.inspect
|
@@ -386,7 +386,7 @@ class TimeWithZoneTest < Minitest::Test
|
|
386
386
|
end
|
387
387
|
|
388
388
|
def test_to_i
|
389
|
-
assert_instance_of
|
389
|
+
assert_instance_of Integer, @timestamptz.to_i
|
390
390
|
assert_equal 2_280_011_445, @timestamptz.to_i
|
391
391
|
assert_equal 2_280_004_245, @timestamptz_berlin.to_i
|
392
392
|
end
|
@@ -402,7 +402,7 @@ class TimeWithZoneTest < Minitest::Test
|
|
402
402
|
def test_to_s
|
403
403
|
assert_equal '2042-04-02 00:30:45 UTC', @timestamptz.to_s
|
404
404
|
assert_equal '2042-04-02 00:30:45 +0200', @timestamptz_berlin.to_s
|
405
|
-
timestamptz = Teasy.
|
405
|
+
timestamptz = Teasy.with_zone('Europe/Berlin') do
|
406
406
|
Teasy::TimeWithZone.new(2042)
|
407
407
|
end
|
408
408
|
assert_equal '2042-01-01 00:00:00 +0100', timestamptz.to_s
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: teasy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kai Kuchenbecker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tzinfo
|
@@ -16,58 +16,58 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: tzinfo-data
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.2020.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: 1.2020.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: minitest
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name: minitest
|
70
|
+
name: minitest-reporters
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: rake
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - ">="
|
@@ -122,6 +122,7 @@ files:
|
|
122
122
|
- ".gitignore"
|
123
123
|
- ".rubocop.yml"
|
124
124
|
- ".ruby-version"
|
125
|
+
- CHANGELOG.md
|
125
126
|
- Gemfile
|
126
127
|
- LICENSE.txt
|
127
128
|
- README.md
|
@@ -156,13 +157,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
157
|
- !ruby/object:Gem::Version
|
157
158
|
version: '0'
|
158
159
|
requirements: []
|
159
|
-
|
160
|
-
rubygems_version: 2.7.3
|
160
|
+
rubygems_version: 3.1.2
|
161
161
|
signing_key:
|
162
162
|
specification_version: 4
|
163
163
|
summary: Teasy intends to make handling time zones easy.
|
164
|
-
test_files:
|
165
|
-
- test/teasy/floating_time_test.rb
|
166
|
-
- test/teasy/teasy_test.rb
|
167
|
-
- test/teasy/time_with_zone_test.rb
|
168
|
-
- test/test_helper.rb
|
164
|
+
test_files: []
|