easy_time 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ # These class methods are for converting most date or time formats to a Time
4
+ class EasyTime
5
+ class << self
6
+ # convert(time) converts most date and time objects or strings into a Time object
7
+ #
8
+ # convert() # => Time.now
9
+ # convert(String) # => detect time style and parse accordingly
10
+ # convert(EasyTime) # => EasyTime.time
11
+ # convert(Time) # => Time
12
+ # convert(Date) # => Time.iso8601(Date.iso8601)
13
+ # convert(DateTime) # => Time.iso8601(DateTime.iso8601)
14
+ # convert([yyyy,mm,dd,...]) # => Time.new(yyyy,mm,dd,...)
15
+ # convert(3.weeks.ago) # => value.to_time [ActiveSupport::TimeWithZone]
16
+ # convert(2.months) # => Time.now + duration [ActiveSupport::Duration]
17
+ #
18
+ # When a string is used as an argument, it is examined for several date-time patterns
19
+ # and a corresponding parser is used; when all else fails, `Time.parse` is used.
20
+ #
21
+ # The following time format patterns are checked:
22
+ # rfc2822 - used in Emails
23
+ # httpdate - used in web logs (a variant of rfc822, with symbolic timezones)
24
+ # xmlschema - used in XML schemas (a strict subset of iso8601)
25
+ # iso8601 - used in many systems
26
+ #
27
+ # Time/Date string examples:
28
+ # httpdate: Thu, 06 Oct 2011 02:26:12 GMT
29
+ # rf2822: Wed, 05 Oct 2011 22:26:12 -0400
30
+ # xmlschema: 2011-10-05T22:26:12-04:00
31
+ # xmlschema: YYYY-MM-DD or YYYYMMDD
32
+ # iso8601: CCYY-MM-DDThh:mm:ss.sssTZD
33
+ # iso8601 date: YYYY-MM YYYY-DDD or YYYYDDD or YYYYMMDD
34
+ # iso8601 time: hh:mm:ss.ssss or hhmmss.sss or hh:mm:ss or hh:mm or hhmmss or hhmm or hh
35
+ # iso8601 zone: Z or +-HH:MM or +-HHMM
36
+ #
37
+ # When an Integer or Float is used a time value, it is passed to `Time.at`, which interprets
38
+ # the value as being the number of seconds since the Epoch (1970).
39
+
40
+ # @param arg [String, EasyTime, Time, Date, DateTime, Array<Integer>, Duration]
41
+ # various kinds of date and time values
42
+ # @param coerce [Boolean] if true, coerce the `arg` into a Time object _(default: true)_
43
+ # @return [Time]
44
+ def convert(arg, coerce = true)
45
+ case arg
46
+ when String
47
+ parse_string(arg) # parse the string value into an EasyTime object
48
+ when Array
49
+ ::Time.new(*arg) # convert Time arguments: [yyyy, mm, dd, hh, MM, SS]
50
+ when ::EasyTime
51
+ arg.time # extract the EasyTime value
52
+ when ActiveSupport::TimeWithZone
53
+ arg.to_time # convert the TimeWithZone value to a Time object
54
+ when ActiveSupport::Duration
55
+ coerce ? Time.now + arg : arg # coerced duration objects are relative to "now"
56
+ when ::Time
57
+ arg # accept Time objects as-as
58
+ when ::Date, ::DateTime
59
+ ::Time.iso8601(arg.iso8601) # convert Date and DateTime objects via ISO8601 formatting
60
+ when NilClass
61
+ ::Time.now # a nil object means "now"
62
+ when Numeric
63
+ coerce ? Time.at(arg) : arg # if coerced, treat as seconds-since-Epoch
64
+ else
65
+ raise ArgumentError, "EasyTime: unknown value: '#{arg.inspect}'"
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ def parse_string(time_str)
72
+ parser = time_format_style(time_str)
73
+ # invoke the found parser format, otherwise use the fall-back general-purpose parser
74
+ (parser && ::Time.send(parser, time_str) rescue nil) || ::Time.parse(time_str)
75
+ end
76
+
77
+ public
78
+
79
+ # A regexp pattern to match the date part of an ISO8601 time string
80
+ ISO_DATE_RE = /(?: \d{4}-\d\d-\d\d # yyyy-mm-dd
81
+ | \d{4}-\d\d # yyyy-mm
82
+ | \d{4}-\d{3} # yyyy-ddd
83
+ | \d{7,8} # yyyymmdd or yyyyddd
84
+ | --\d\d-?\d\d # --mm-dd or --mmdd
85
+ )
86
+ /x.freeze
87
+
88
+ # A regexp pattern to match the time part of an ISO8601 time string
89
+ ISO_TIME_RE = /(?:
90
+ (?:
91
+ (?: \d\d:\d\d:\d\d # hh:mm:ss
92
+ | \d{6} # hhmmss
93
+ )
94
+ (?: \.\d+ )? # optional .sss
95
+ )
96
+ | \d\d:?\d\d # hh:mm or hhmm
97
+ | \d{2} # hh
98
+ )
99
+ /x.freeze
100
+
101
+ # A regexp pattern to match the timezone part of an ISO8601 time string
102
+ ISO_ZONE_RE = /(?: Z # Z for zulu (GMT = 0)
103
+ | [+-] \d\d:?\d\d # +-HH:MM or +-HHMM
104
+ )
105
+ /x.freeze
106
+
107
+ # A regexp pattern to match an ISO8601 time string.
108
+ # @see https://en.wikipedia.org/wiki/ISO_8601
109
+ ISO8601_RE = / #{ISO_DATE_RE} T #{ISO_TIME_RE} #{ISO_ZONE_RE} /x.freeze
110
+
111
+ # A regexp pattern to match an RFC2822 time string _(used in Email messages and systems)_
112
+ RFC2822_RE = /\w{3}, \s # Wed,
113
+ \d{1,2} \s # 01 or 1
114
+ \w{3} \s # Oct
115
+ \d{4} \s # 2020
116
+ \d\d:\d\d:\d\d \s # HH:MM:SS
117
+ [+-]\d\d:?\d\d # +-HH:MM or +-HHHMM (zone)
118
+ /x.freeze
119
+
120
+ # A regexp pattern to match an HTTPDate time string _(used in web server transactions and logs)_
121
+ HTTPDATE_RE = /\w{3}, \s # Wed,
122
+ \d{1,2} \s # 01 or 1
123
+ \w{3} \s # Oct
124
+ \d{4} \s # 2020
125
+ \d\d:\d\d:\d\d \s # HH:MM:SS
126
+ \w+ # GMT
127
+ /x.freeze
128
+
129
+ # A regexp pattern to match an XMLSchema time string _(used in XML documents)_
130
+ XMLSCHEMA_RE = /\d{4}-\d\d-\d\d # yyyy-mm-dd
131
+ T
132
+ \d\d:\d\d:\d\d # HH:MM:SS
133
+ [+-] # +-
134
+ \d\d:\d\d # HH:MM
135
+ /x.freeze
136
+
137
+ # this method returns parser class methods in the Time class for
138
+ # corresponding time format patterns
139
+ def time_format_style(str)
140
+ case str
141
+ when RFC2822_RE then :rfc2822
142
+ when HTTPDATE_RE then :httpdate
143
+ when XMLSCHEMA_RE then :xmlschema
144
+ when ISO8601_RE then :iso8601
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,3 @@
1
+ class EasyTime
2
+ VERSION = "0.1.2"
3
+ end
metadata ADDED
@@ -0,0 +1,304 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: easy_time
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Alan Stebbens
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-04-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.1.4
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.1.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: fuubar
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.5.0
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 2.5.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: guard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-byebug
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: rake
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'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec_junit
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rspec_junit_formatter
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: redcarpet
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: 0.82.0
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: 0.82.0
181
+ - !ruby/object:Gem::Dependency
182
+ name: simplecov
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: terminal-notifier-guard
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ - !ruby/object:Gem::Dependency
210
+ name: yard
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: 0.9.24
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: 0.9.24
223
+ - !ruby/object:Gem::Dependency
224
+ name: activesupport
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - ">="
228
+ - !ruby/object:Gem::Version
229
+ version: '0'
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - ">="
235
+ - !ruby/object:Gem::Version
236
+ version: '0'
237
+ description: |2+
238
+
239
+ A class that wraps the Time class and makes it easy to work with most
240
+ known time values, including various time strings, automatically
241
+ converting them to Time values, and perform tolerant comparisons.
242
+ Several time classes, and the String class, are extended with the
243
+ ".easy_time" method to perform an auto-conversion. A tolerant comparison
244
+ allows for times from differing systems to be compared, even when the
245
+ systems are out of sync, using the relationship operators and methods
246
+ like "newer?", "older?", "same?" and "between?". A tolerant comparison
247
+ for equality is where the difference of two values is less than the
248
+ tolerance value (1 minute by default). The tolerance can be configured,
249
+ even set to zero. Finally, all of the Time class and instance methods
250
+ are available on the EasyTime class and instances.
251
+
252
+ email:
253
+ - aks@stebbens.org
254
+ executables:
255
+ - console
256
+ - setup
257
+ extensions: []
258
+ extra_rdoc_files: []
259
+ files:
260
+ - ".circleci/config.yml"
261
+ - ".gitignore"
262
+ - ".rspec"
263
+ - ".rubocop.yml"
264
+ - ".travis.yml"
265
+ - ".yardopts"
266
+ - Gemfile
267
+ - Gemfile.lock
268
+ - Guardfile
269
+ - LICENSE.txt
270
+ - README.md
271
+ - Rakefile
272
+ - bin/console
273
+ - bin/setup
274
+ - easy_time.gemspec
275
+ - lib/easy_time.rb
276
+ - lib/easy_time/convert.rb
277
+ - lib/easy_time/version.rb
278
+ homepage: https://github.com/aks/easy_time
279
+ licenses:
280
+ - MIT
281
+ metadata:
282
+ allowed_push_host: https://rubygems.org
283
+ homepage_uri: https://github.com/aks/easy_time
284
+ source_code_uri: https://github.com/aks/easy_time
285
+ post_install_message:
286
+ rdoc_options: []
287
+ require_paths:
288
+ - lib
289
+ required_ruby_version: !ruby/object:Gem::Requirement
290
+ requirements:
291
+ - - ">="
292
+ - !ruby/object:Gem::Version
293
+ version: 2.3.0
294
+ required_rubygems_version: !ruby/object:Gem::Requirement
295
+ requirements:
296
+ - - ">="
297
+ - !ruby/object:Gem::Version
298
+ version: '0'
299
+ requirements: []
300
+ rubygems_version: 3.1.2
301
+ signing_key:
302
+ specification_version: 4
303
+ summary: Easy auto-conversion of most date and time values with tolerant-comparisons
304
+ test_files: []