teasy 0.2.3 → 0.2.8
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 +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: []
|