tz_offset 0.0.2 → 0.0.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6caf2eb01f0a29365f5fa0e7b590a2fc6578d7d8
4
- data.tar.gz: bd8383c6df9c377fd99e0abdd20bf35dfb4d49e2
3
+ metadata.gz: d716ba97e8b1595d4bc8a4d3300ebed994d6949d
4
+ data.tar.gz: 578f31e9594e61aebea530d92682414e26b3f95e
5
5
  SHA512:
6
- metadata.gz: 83943865999ffb0dd7df78ae68cc9eb5fd9ed2337e0bbb71de722edead758a1f337507cabe205891122a833e1bb2ad405009bce172067a4eeb903efe1da31d2c
7
- data.tar.gz: 723be526b08eb9ab0a4479115357540207648bf8de5a6d3aa6b869c25e32965175efb50c62f7ddcd24a8c708ffd8d513f0d343c0000b13b0f2ea9e5bf1187fa9
6
+ metadata.gz: 5da76c72269067cb144806ea8002ed99cc5ac1ce9c6f070be0e8cf90c2f2b0ccaf9753da4d4bf51b3a47326969746d059f7ca197a0480d8d73ac08c2cf824ec3
7
+ data.tar.gz: 289a1b4ca57d650c84bac18aa0230734c631fa9a386fcc8b9224ffa3d3cce3ccfdfbed8427f12f9a13d76d9a408a667544352c5a7ce6b2f53a8971f498816a3c
data/CHANGELOG.md CHANGED
@@ -1,6 +1,13 @@
1
1
  TZOffset Changelog
2
2
  ==================
3
3
 
4
+ 0.0.3 - 2016-01-14
5
+ ------------------
6
+
7
+ * TZOffset is now detailed up to seconds;
8
+ * Add simple arithmetics (`+`, unary and binary `-`);
9
+ * Add some handy synonims (like `TZOffset.utc` and `TZOffset#utc?`).
10
+
4
11
  0.0.2 - 2016-10-25
5
12
  ------------------
6
13
 
data/README.md CHANGED
@@ -98,6 +98,13 @@ eet.opposite
98
98
  # => #<TZOffset +03:00 (EEST)>
99
99
  eet.opposite.now
100
100
  # => 2016-10-25 21:39:26 +0300
101
+
102
+ # Parsing time string into desired timezone
103
+ off = TZOffset.parse('-02:30')
104
+ off.parse('2014-10-01 12:30')
105
+ # => 2014-10-01 12:30:00 -0230
106
+ off.parse('12:30')
107
+ # => 2016-10-26 12:30:00 -0230
101
108
  ```
102
109
 
103
110
  ## Author
@@ -15,7 +15,7 @@ class TZOffset
15
15
  .load_file(PATH)
16
16
  .map { |row|
17
17
  TZOffset.new(
18
- row.fetch(:val),
18
+ row.fetch(:val) * 60,
19
19
  name: row.fetch(:abbr),
20
20
  description: row.fetch(:title),
21
21
  region: row.fetch(:region),
@@ -699,6 +699,11 @@
699
699
  :region: Phoenix Island
700
700
  :dst: false
701
701
  :val: 780
702
+ - :abbr: PHT
703
+ :title: Philippine Time
704
+ :region: Philippine
705
+ :dst: false
706
+ :val: 480
702
707
  - :abbr: PKT
703
708
  :title: Pakistan Standard Time
704
709
  :region: Pakistan
@@ -1,3 +1,3 @@
1
1
  class TZOffset
2
- VERSION = '0.0.2'.freeze
2
+ VERSION = '0.0.3'.freeze
3
3
  end
data/lib/tz_offset.rb CHANGED
@@ -18,10 +18,10 @@ require 'time'
18
18
  # ```
19
19
  #
20
20
  class TZOffset
21
- # Number of minutes in offset.
21
+ # Number of seconds in offset.
22
22
  #
23
23
  # @return [Fixnum]
24
- attr_reader :minutes
24
+ attr_reader :seconds
25
25
 
26
26
  # Symbolic offset name if available (like "EEST").
27
27
  #
@@ -43,59 +43,133 @@ class TZOffset
43
43
  # @return [String]
44
44
  attr_reader :region
45
45
 
46
- # @private
47
- MINUSES = /[−—–]/
46
+ class << self
47
+ # @private
48
+ MINUSES = /[−—–]/
48
49
 
49
- # Parses TZOffset from string. Understands several options like:
50
- #
51
- # * `GMT` (not all TZ names, just well-known
52
- # [abbreviations](https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations));
53
- # * `UTC+3` (or `GMT+3`);
54
- # * `+03:30`;
55
- # * ..and several combinations.
56
- #
57
- # @return [TZOffset]
58
- def self.parse(text)
59
- return ABBREV[text.upcase] if ABBREV.key?(text.upcase)
50
+ # Parses TZOffset from string. Understands several options like:
51
+ #
52
+ # * `GMT` (not all TZ names, just well-known
53
+ # [abbreviations](https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations));
54
+ # * `UTC+3` (or `GMT+3`);
55
+ # * `+03:30`;
56
+ # * ..and several combinations.
57
+ #
58
+ # @return [TZOffset]
59
+ def parse(text)
60
+ return ABBREV[text.upcase] if ABBREV.key?(text.upcase)
61
+
62
+ sec = parse_text(text.gsub(MINUSES, '-'))
63
+ sec && new(sec)
64
+ end
65
+
66
+ # Returns zero (UTC) offset.
67
+ #
68
+ # @return [TZOffset]
69
+ def zero
70
+ @zero ||= new(0)
71
+ end
72
+
73
+ alias_method :utc, :zero
74
+
75
+ private
76
+
77
+ def parse_text(text)
78
+ case text
79
+ when /^[A-Z]{3}$/
80
+ Time.zone_offset(text)
81
+ when /^(?:UTC|GMT)?([+-]\d{1,2}:?\d{2})$/
82
+ parse_zone_offset($1)
83
+
84
+ when /^(?<sign>[+-]?)(?<hours>\d{1,2})(:(?<minutes>\d{2})(:(?<seconds>\d{2}))?)?$/
85
+ parse_with_seconds(Regexp.last_match)
60
86
 
61
- text = text.gsub(MINUSES, '-')
62
- sec = case text
63
- when /^[A-Z]{3}$/
64
- Time.zone_offset(text)
65
- when /^(?:UTC|GMT)?([+-]\d{1,2}:?\d{2})$/
66
- offset = $1
67
- Time.zone_offset(offset.sub(/^([+-])(\d):/, '\10\2:'))
68
- when /^(?:UTC|GMT)?([+-]\d{1,2})/
69
- $1.to_i * 3600
70
- end
87
+ when /^(?:UTC|GMT)?([+-]\d{1,2})/
88
+ $1.to_i * 3600
89
+ end
90
+ end
91
+
92
+ def parse_zone_offset(offset)
93
+ Time.zone_offset(offset.sub(/^([+-])(\d):/, '\10\2:'))
94
+ end
71
95
 
72
- sec && new(sec / 60)
96
+ def parse_with_seconds(match)
97
+ (match[:sign] == '-' ? -1 : +1) *
98
+ (match[:hours].to_i * 3600 + match[:minutes].to_i * 60 + match[:seconds].to_i)
99
+ end
73
100
  end
74
101
 
75
- # Constructs offset from number of minutes. In most cases, you don't
102
+ # Constructs offset from number of seconds. In most cases, you don't
76
103
  # want to use it, but rather {TZOffset.parse}.
77
104
  #
78
- # @param minutes [Fixnum] Number of minutes in offset.
79
- def initialize(minutes, name: nil, description: nil, region: nil, isdst: nil)
80
- @minutes = minutes
105
+ # @param seconds [Fixnum] Number of seconds in offset.
106
+ def initialize(seconds, name: nil, description: nil, region: nil, isdst: nil)
107
+ @seconds = seconds
81
108
  @name = name
82
109
  @description = description
83
110
  @isdst = isdst
84
111
  @region = region
85
112
  end
86
113
 
114
+ # Minutes component of offset.
115
+ #
116
+ # @return [Integer]
117
+ def minutes
118
+ seconds.abs / 60 * (seconds <=> 0)
119
+ end
120
+
121
+ alias_method :to_i, :seconds
122
+
87
123
  # @return [String]
88
124
  def inspect
89
- if name
90
- '#<%s %s%02i:%02i (%s)>' % [self.class.name, sign, *minutes.abs.divmod(60), name]
91
- else
92
- '#<%s %s%02i:%02i>' % [self.class.name, sign, *minutes.abs.divmod(60)]
93
- end
125
+ nm = name ? " (#{name})" : ''
126
+
127
+ '#<%s %s%02i:%02i%s%s>' %
128
+ [self.class.name, sign, *minutes.abs.divmod(60), inspectable_seconds, nm]
94
129
  end
95
130
 
96
131
  # @return [String]
97
132
  def to_s
98
- '%s%02i:%02i' % [sign, *minutes.abs.divmod(60)]
133
+ '%s%02i:%02i%s' % [sign, *minutes.abs.divmod(60), inspectable_seconds]
134
+ end
135
+
136
+ # @return [TZOffset] Offset negated.
137
+ def -@
138
+ TZOffset.new(-seconds)
139
+ end
140
+
141
+ # Sums offset with other or just number of seconds.
142
+ #
143
+ # @example
144
+ # TZOffset.parse('+2') + TZOffset.parse('+5')
145
+ # # => #<TZOffset +07:00>
146
+ # TZOffset.parse('+2') + 1200
147
+ # # => #<TZOffset +02:20>
148
+ #
149
+ # @return [TZOffset]
150
+ def +(other)
151
+ case other
152
+ when TZOffset
153
+ TZOffset.new(seconds + other.seconds)
154
+ when Numeric
155
+ TZOffset.new(seconds + other)
156
+ else
157
+ fail ArgumentError, "Can't sum with #{other.class}"
158
+ end
159
+ end
160
+
161
+ # Substracts other offset or number of seconds.
162
+ #
163
+ # @example
164
+ # TZOffset.parse('+2') - TZOffset.parse('+5')
165
+ # # => #<TZOffset -03:00>
166
+ # TZOffset.parse('+2') - 1200
167
+ # # => #<TZOffset +01:40>
168
+ #
169
+ # @return [TZOffset]
170
+ def -(other)
171
+ other.respond_to?(:-@) or fail ArgumentError, "Can't subtract #{other.class} from TZOffset"
172
+ self + -other
99
173
  end
100
174
 
101
175
  # If offset is symbolic (e.g., "EET", not just "+02:00"), returns whether it is daylight
@@ -106,9 +180,16 @@ class TZOffset
106
180
  @isdst
107
181
  end
108
182
 
183
+ # If this offset is zero (UTC).
184
+ def zero?
185
+ @seconds.zero?
186
+ end
187
+
188
+ alias_method :utc?, :zero?
189
+
109
190
  # @return [Boolean]
110
191
  def <=>(other)
111
- other.is_a?(TZOffset) or raise ArgumentError, "Can't compare TZOffset with #{other.class}"
192
+ return nil unless other.is_a?(TZOffset)
112
193
  minutes <=> other.minutes
113
194
  end
114
195
 
@@ -132,7 +213,7 @@ class TZOffset
132
213
  # @param tm [Time] Time object to convert (with any offset);
133
214
  # @return [Time] Converted object.
134
215
  def convert(tm)
135
- t = tm.getutc + minutes * 60
216
+ t = tm.getutc + seconds
136
217
 
137
218
  # FIXME: usec are lost
138
219
  mk(t.year, t.month, t.day, t.hour, t.min, t.sec)
@@ -189,12 +270,16 @@ class TZOffset
189
270
 
190
271
  private
191
272
 
273
+ def inspectable_seconds
274
+ (seconds.abs % 60).zero? ? '' : ':%02i' % (seconds.abs % 60)
275
+ end
276
+
192
277
  def sign
193
278
  minutes < 0 ? '-' : '+'
194
279
  end
195
280
 
196
281
  def mk(*components)
197
- Time.new(*components, to_s)
282
+ Time.new(*components, to_i)
198
283
  end
199
284
  end
200
285
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tz_offset
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Shepelev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-26 00:00:00.000000000 Z
11
+ date: 2017-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubocop