fugit 0.1.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: abef59b5a960f5a9ed236dc1395bc3fd7b0d0a2e
4
- data.tar.gz: d67e8a8c23cf0a7d61f26826e390a0bbf5a0e184
3
+ metadata.gz: 23a78b668f05dc4bbe20ff46e0596a1211767f8a
4
+ data.tar.gz: a93498a901fa05952adf0afa0362ca5621a24b3b
5
5
  SHA512:
6
- metadata.gz: e3f6589fbb9f41615f1826cd823f286f5f274f85784ba287f9898de93a94152f4fdf627b493043b45b4745d5cc13995b9e82bf8109d8b7b2a686cda28d65b19d
7
- data.tar.gz: 3bc24d23a8a5f1b0e9bd5e115e27c9b30a7f0f49c9ecfef1f9116269c19f97226f56832e5e7ac9e469a2a2e7167a98c7495c74f2c6ed27895b1d83832aa7b2d7
6
+ metadata.gz: a059da28856f3695800f15449b2245c844a3927170a2df6f9b09081570dfaa7239c4e240dca42d518828a615bc9ad73331d34e83948e352bd7eda18aa8edbb77
7
+ data.tar.gz: 7588ef1425a8c11e3663ea2ec5de69d1f9ff76ff947a2871f9cc33b4479f7595c340a1058fb3b5f287a29b589d4ec30404167f4926b02efc41508642d9106130
@@ -0,0 +1,8 @@
1
+
2
+ # fugit CHANGELOG.md
3
+
4
+
5
+ ## fugit 0.9.0 released 2017-01-03
6
+
7
+ * Initial release
8
+
@@ -0,0 +1,7 @@
1
+
2
+ # fugit credits
3
+
4
+ Many thanks to all the rufus-scheduler contributors and people who gave feedback.
5
+
6
+ https://github.com/jmettraux/rufus-scheduler/blob/master/CREDITS.txt
7
+
data/README.md CHANGED
@@ -1,6 +1,46 @@
1
1
 
2
2
  # fugit
3
3
 
4
+ [![Build Status](https://secure.travis-ci.org/floraison/fugit.svg)](http://travis-ci.org/floraison/fugit)
5
+ [![Gem Version](https://badge.fury.io/rb/fugit.svg)](http://badge.fury.io/rb/fugit)
6
+
7
+ Time tools for [flor](https://github.com/floraison/flor) and the floraison project.
8
+
9
+ ## `Fugit::Cron`
10
+
11
+ ```ruby
12
+ require 'fugit'
13
+
14
+ c = Fugit::Cron.parse('0 0 * * sun')
15
+
16
+ p Time.now # => 2017-01-03 09:53:27 +0900
17
+
18
+ p c.next_time # => 2017-01-08 00:00:00 +0900
19
+ ```
20
+
21
+ Example of cron strings understood by fugit:
22
+ ```ruby
23
+ '5 0 * * *' # 5 minutes after midnight, every day
24
+ '15 14 1 * *' # at 1415 on the 1st of every month
25
+ '0 22 * * 1-5' # at 2200 on weekdays
26
+ '0 22 * * mon-fri' # idem
27
+ '23 0-23/2 * * *' # 23 minutes after 00:00, 02:00, 04:00, ...
28
+
29
+ '@yearly' # turns into '0 0 1 1 *'
30
+ '@monthly' # turns into '0 0 1 * *'
31
+ '@weekly' # turns into '0 0 * * 0'
32
+ '@daily' # turns into '0 0 * * *'
33
+ '@midnight' # turns into '0 0 * * *'
34
+ '@hourly' # turns into '0 * * * *'
35
+
36
+ '0 0 L * *' # last day of month at 00:00
37
+ '0 0 last * *' # idem
38
+ '0 0 -7-L * *' # from the seventh to last to the last day of month at 00:00
39
+
40
+ # and more...
41
+ ```
42
+
4
43
  ## LICENSE
5
44
 
6
45
  MIT, see [LICENSE.txt](LICENSE.txt)
46
+
@@ -12,10 +12,10 @@ Gem::Specification.new do |s|
12
12
  s.email = [ 'jmettraux+flor@gmail.com' ]
13
13
  s.homepage = 'http://github.com/floraison/fugit'
14
14
  s.license = 'MIT'
15
- s.summary = 'time oriented utils for flor'
15
+ s.summary = 'time tools for flor'
16
16
 
17
17
  s.description = %{
18
- time oriented utilities for flor and the floraison project
18
+ Time tools for flor and the floraison project. Cron parsing and occurence computing. Timestamps and more.
19
19
  }.strip
20
20
 
21
21
  #s.files = `git ls-files`.split("\n")
@@ -26,7 +26,7 @@ time oriented utilities for flor and the floraison project
26
26
  ]
27
27
 
28
28
  #s.add_runtime_dependency 'tzinfo'
29
- s.add_runtime_dependency 'raabro', '>= 1.1.2'
29
+ s.add_runtime_dependency 'raabro', '>= 1.1.3'
30
30
 
31
31
  s.add_development_dependency 'rspec', '~> 3.4'
32
32
 
@@ -25,6 +25,13 @@
25
25
 
26
26
  module Fugit
27
27
 
28
- VERSION = '0.1.0'
28
+ VERSION = '0.9.0'
29
29
  end
30
30
 
31
+ require 'time'
32
+
33
+ require 'raabro'
34
+
35
+ require 'fugit/misc'
36
+ require 'fugit/cron'
37
+
@@ -0,0 +1,440 @@
1
+ #--
2
+ # Copyright (c) 2017-2017, John Mettraux, jmettraux+flor@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Fugit
27
+
28
+ class Cron
29
+
30
+ SPECIALS = {
31
+ '@reboot' => :reboot,
32
+ '@yearly' => '0 0 1 1 *',
33
+ '@annually' => '0 0 1 1 *',
34
+ '@monthly' => '0 0 1 * *',
35
+ '@weekly' => '0 0 * * 0',
36
+ '@daily' => '0 0 * * *',
37
+ '@midnight' => '0 0 * * *',
38
+ '@hourly' => '0 * * * *',
39
+ }
40
+
41
+ attr_reader :original
42
+
43
+ attr_reader :minutes, :hours, :monthdays, :months, :weekdays
44
+
45
+ def self.new(original)
46
+
47
+ parse(original)
48
+ end
49
+
50
+ def to_cron_s
51
+
52
+ @cron_s ||=
53
+ [
54
+ (@minutes || [ '*' ]).join(','),
55
+ (@hours || [ '*' ]).join(','),
56
+ (@monthdays || [ '*' ]).join(','),
57
+ (@months || [ '*' ]).join(','),
58
+ (@weekdays || [ [ '*' ] ]).map { |d| d.compact.join('#') }.join(',')
59
+ ].join(' ')
60
+ end
61
+
62
+ def self.parse(s)
63
+
64
+ original = s
65
+ s = SPECIALS[s] || s
66
+
67
+ #p s; Raabro.pp(Parser.parse(s, debug: 3))
68
+ h = Parser.parse(s)
69
+
70
+ fail ArgumentError.new(
71
+ "couldn't parse #{original.inspect}"
72
+ ) unless h
73
+
74
+ self.allocate.send(:init, s, h)
75
+ end
76
+
77
+ class NextTime # TODO at some point, use ZoTime
78
+
79
+ def initialize(t)
80
+ @t = t.is_a?(NextTime) ? t.time : t
81
+ end
82
+
83
+ def time; @t; end
84
+
85
+ %w[ year month day wday hour min sec ]
86
+ .collect(&:to_sym).each { |k| define_method(k) { @t.send(k) } }
87
+
88
+ def inc(i)
89
+ u = @t.utc?
90
+ @t = ::Time.at(@t.to_i + i)
91
+ @t = @t.utc if u
92
+ self
93
+ end
94
+ def dec(i); inc(-i); end
95
+
96
+ def inc_month
97
+ y = @t.year
98
+ m = @t.month + 1
99
+ if m == 13; m = 1; y += 1; end
100
+ @t = Time.send((@t.utc? ? :utc : :local), y, m)
101
+ self
102
+ end
103
+ def inc_day; inc((24 - @t.hour) * 3600 - @t.min * 60 - @t.sec); end
104
+ def inc_hour; inc((60 - @t.min) * 60 - @t.sec); end
105
+ def inc_min; inc(60 - @t.sec); end
106
+
107
+ def dec_month
108
+ dec(@t.day * 24 * 3600 + @t.hour * 3600 + @t.min * 60 + @t.sec + 1)
109
+ end
110
+ def dec_day; dec(@t.hour * 3600 + @t.min * 60 + @t.sec + 1); end
111
+ def dec_hour; dec(@t.min * 60 + @t.sec + 1); end
112
+ def dec_min; dec(@t.sec + 1); end
113
+ def dec_sec; dec(@t.sec); end
114
+
115
+ def count_weeks(inc)
116
+ c = 0
117
+ t = @t
118
+ until t.month != @t.month
119
+ c += 1
120
+ t += inc * (7 * 24 * 3600)
121
+ end
122
+ c
123
+ end
124
+
125
+ def wday_in_month
126
+ [ count_weeks(-1), - count_weeks(1) ]
127
+ end
128
+ end
129
+
130
+ def month_match?(nt); ( ! @months) || @months.include?(nt.month); end
131
+ def hour_match?(nt); ( ! @hours) || @hours.include?(nt.hour); end
132
+ def min_match?(nt); ( ! @minutes) || @minutes.include?(nt.min); end
133
+
134
+ def weekday_match?(nt)
135
+
136
+ #p @weekdays
137
+ #p [ nt.day, nt.wday ]
138
+ return true if @weekdays.nil?
139
+
140
+ wd, hsh = @weekdays.find { |wd, hsh| wd == nt.wday }
141
+
142
+ return false unless wd
143
+ return true if hsh.nil?
144
+
145
+ phsh, nhsh = nt.wday_in_month
146
+
147
+ if hsh > 0
148
+ hsh == phsh # positive wday, from the beginning of the month
149
+ else
150
+ hsh == nhsh # negative wday, from the end of the month, -1 == last
151
+ end
152
+ end
153
+
154
+ def monthday_match?(nt)
155
+
156
+ return true if @monthdays.nil?
157
+
158
+ last = (NextTime.new(nt).inc_month.time - 24 * 3600).day + 1
159
+
160
+ @monthdays
161
+ .collect { |d| d < 1 ? last + d : d }
162
+ .include?(nt.day)
163
+ end
164
+
165
+ def day_match?(nt)
166
+
167
+ return weekday_match?(nt) || monthday_match?(nt) \
168
+ if @weekdays && @monthdays
169
+
170
+ return false unless weekday_match?(nt)
171
+ return false unless monthday_match?(nt)
172
+
173
+ true
174
+ end
175
+
176
+ def match?(t)
177
+
178
+ t = NextTime.new(t)
179
+
180
+ month_match?(t) && day_match?(t) && hour_match?(t) && min_match?(t)
181
+ end
182
+
183
+ def next_time(from=Time.now)
184
+
185
+ nt = NextTime.new(from)
186
+
187
+ loop do
188
+ #p Fugit.time_to_s(nt.time)
189
+ month_match?(nt) || (nt.inc_month; next)
190
+ day_match?(nt) || (nt.inc_day; next)
191
+ hour_match?(nt) || (nt.inc_hour; next)
192
+ min_match?(nt) || (nt.inc_min; next)
193
+ break
194
+ end
195
+
196
+ nt.time
197
+ end
198
+
199
+ def previous_time(from=Time.now)
200
+
201
+ nt = NextTime.new(from)
202
+
203
+ loop do
204
+ #p Fugit.time_to_s(nt.time)
205
+ month_match?(nt) || (nt.dec_month; next)
206
+ day_match?(nt) || (nt.dec_day; next)
207
+ hour_match?(nt) || (nt.dec_hour; next)
208
+ min_match?(nt) || (nt.dec_min; next)
209
+ nt.dec_sec
210
+ break
211
+ end
212
+
213
+ nt.time
214
+ end
215
+
216
+ # Returns [ min delta, max delta, occurence count ]
217
+ # Computes for a non leap year (2017).
218
+ #
219
+ def frequency(year=2017)
220
+
221
+ FREQUENCY_CACHE["#{to_cron_s}|#{year}"] ||=
222
+ begin
223
+ deltas = []
224
+
225
+ t0 = nil
226
+ loop do
227
+ t1 = next_time(t0 || Time.parse("#{year}-01-01"))
228
+ deltas << (t1 - t0).to_i + 60 if t0
229
+ break if t1.year > year
230
+ t0 = t1 + 60
231
+ end
232
+
233
+ [ deltas.min, deltas.max, deltas.size ]
234
+ end
235
+ end
236
+
237
+ protected
238
+
239
+ FREQUENCY_CACHE = {}
240
+
241
+ def init(original, h)
242
+
243
+ @original = original
244
+
245
+ determine_minutes(h[:min])
246
+ determine_hours(h[:hou])
247
+ determine_monthdays(h[:dom])
248
+ determine_months(h[:mon])
249
+ determine_weekdays(h[:dow])
250
+
251
+ self
252
+ end
253
+
254
+ def expand(min, max, r)
255
+
256
+ sta, edn, sla = r
257
+
258
+ sla = nil if sla == 1 # don't get fooled by /1
259
+
260
+ return [ nil ] if sta.nil? && edn.nil? && sla.nil?
261
+ return [ sta ] if sta && edn.nil?
262
+
263
+ sla = 1 if sla == nil
264
+ sta = min if sta == nil
265
+ edn = max if edn == nil
266
+ sta, edn = edn, sta if sta > edn
267
+
268
+ (sta..edn).step(sla).to_a
269
+ end
270
+
271
+ def compact(key)
272
+
273
+ arr = instance_variable_get(key)
274
+
275
+ return instance_variable_set(key, nil) if arr.include?(nil)
276
+ # reductio ad astrum
277
+
278
+ arr.uniq!
279
+ arr.sort!
280
+ end
281
+
282
+ def determine_minutes(mins)
283
+ @minutes = mins.inject([]) { |a, r| a.concat(expand(0, 59, r)) }
284
+ compact(:@minutes)
285
+ end
286
+
287
+ def determine_hours(hous)
288
+ @hours = hous.inject([]) { |a, r| a.concat(expand(0, 23, r)) }
289
+ @hours = @hours.collect { |h| h == 24 ? 0 : h }
290
+ compact(:@hours)
291
+ end
292
+
293
+ def determine_monthdays(doms)
294
+ @monthdays = doms.inject([]) { |a, r| a.concat(expand(1, 31, r)) }
295
+ compact(:@monthdays)
296
+ end
297
+
298
+ def determine_months(mons)
299
+ @months = mons.inject([]) { |a, r| a.concat(expand(1, 12, r)) }
300
+ compact(:@months)
301
+ end
302
+
303
+ def determine_weekdays(dows)
304
+
305
+ @weekdays = dows.inject([]) { |a, r|
306
+ aa = expand(0, 7, r)
307
+ if hsh = r[3]
308
+ a.concat([ [ aa.first, hsh ] ])
309
+ else
310
+ a.concat(aa.collect { |i| [ i, nil ] })
311
+ end
312
+ }
313
+
314
+ @weekdays =
315
+ if @weekdays.include?([ nil, nil ])
316
+ nil
317
+ else
318
+ @weekdays
319
+ .collect { |d, h| [ d == 7 ? 0 : d, h ] }
320
+ .uniq { |d| d.join('#') }
321
+ .sort_by { |d| d.join('#') }
322
+ end
323
+ end
324
+
325
+ module Parser include Raabro
326
+
327
+ WEEKDAYS = %w[ sun mon tue wed thu fri sat ]
328
+ MONTHS = %w[ - jan feb mar apr may jun jul aug sep oct nov dec ]
329
+
330
+ def s(i); rex(:s, i, /[ \t]+/); end
331
+ def star(i); str(:star, i, '*'); end
332
+ def hyphen(i); str(nil, i, '-'); end
333
+ def comma(i); str(nil, i, ','); end
334
+
335
+ def slash(i); rex(:slash, i, /\/\d\d?/); end
336
+
337
+ def core_min(i); rex(:min, i, /[0-5]?\d/); end
338
+ def core_hou(i); rex(:hou, i, /(2[0-4]|[01]?[0-9])/); end
339
+ def core_dom(i); rex(:dom, i, /(-?(3[01]|[012]?[0-9])|last|l)/i); end
340
+ def core_mon(i); rex(:mon, i, /(1[0-2]|0?[0-9]|#{MONTHS[1..-1].join('|')})/i); end
341
+ def core_dow(i); rex(:dow, i, /([0-7]|#{WEEKDAYS.join('|')})/i); end
342
+
343
+ def dow_hash(i); rex(:hash, i, /#(-?[1-5]|last|l)/i); end
344
+
345
+ def min(i); core_min(i); end
346
+ def hou(i); core_hou(i); end
347
+ def dom(i); core_dom(i); end
348
+ def mon(i); core_mon(i); end
349
+ def dow(i); core_dow(i); end
350
+
351
+ def _min(i); seq(nil, i, :hyphen, :min); end
352
+ def _hou(i); seq(nil, i, :hyphen, :hou); end
353
+ def _dom(i); seq(nil, i, :hyphen, :dom); end
354
+ def _mon(i); seq(nil, i, :hyphen, :mon); end
355
+ def _dow(i); seq(nil, i, :hyphen, :dow); end
356
+
357
+ # r: range
358
+ def r_min(i); seq(nil, i, :min, :_min, '?'); end
359
+ def r_hou(i); seq(nil, i, :hou, :_hou, '?'); end
360
+ def r_dom(i); seq(nil, i, :dom, :_dom, '?'); end
361
+ def r_mon(i); seq(nil, i, :mon, :_mon, '?'); end
362
+ def r_dow(i); seq(nil, i, :dow, :_dow, '?'); end
363
+
364
+ # sor: star or range
365
+ def sor_min(i); alt(nil, i, :star, :r_min); end
366
+ def sor_hou(i); alt(nil, i, :star, :r_hou); end
367
+ def sor_dom(i); alt(nil, i, :star, :r_dom); end
368
+ def sor_mon(i); alt(nil, i, :star, :r_mon); end
369
+ def sor_dow(i); alt(nil, i, :star, :r_dow); end
370
+
371
+ # sorws: star or range with[out] slash
372
+ def sorws_min(i); seq(nil, i, :sor_min, :slash, '?'); end
373
+ def sorws_hou(i); seq(nil, i, :sor_hou, :slash, '?'); end
374
+ def sorws_dom(i); seq(nil, i, :sor_dom, :slash, '?'); end
375
+ def sorws_mon(i); seq(nil, i, :sor_mon, :slash, '?'); end
376
+ def sorws_dow(i); seq(nil, i, :sor_dow, :slash, '?'); end
377
+
378
+ def h_dow(i); seq(nil, i, :core_dow, :dow_hash); end
379
+
380
+ def _sorws_dow(i); alt(nil, i, :h_dow, :sorws_dow); end
381
+
382
+ def list_min(i); jseq(:min, i, :sorws_min, :comma); end
383
+ def list_hou(i); jseq(:hou, i, :sorws_hou, :comma); end
384
+ def list_dom(i); jseq(:dom, i, :sorws_dom, :comma); end
385
+ def list_mon(i); jseq(:mon, i, :sorws_mon, :comma); end
386
+ def list_dow(i); jseq(:dow, i, :_sorws_dow, :comma); end
387
+
388
+ def lmin_(i); seq(nil, i, :list_min, :s); end
389
+ def lhou_(i); seq(nil, i, :list_hou, :s); end
390
+ def ldom_(i); seq(nil, i, :list_dom, :s); end
391
+ def lmon_(i); seq(nil, i, :list_mon, :s); end
392
+ alias ldow list_dow
393
+
394
+ def cron(i); seq(:cron, i, :lmin_, :lhou_, :ldom_, :lmon_, :ldow); end
395
+
396
+ def to_i(k, t)
397
+
398
+ s = t.string.downcase
399
+
400
+ (k == :mon && MONTHS.index(s)) ||
401
+ (k == :dow && WEEKDAYS.index(s)) ||
402
+ (k == :dom && s[0, 1] == 'l' && -1) || # L, l, last
403
+ s.to_i
404
+ end
405
+
406
+ def rewrite_entry(t)
407
+
408
+ k = t.name
409
+
410
+ t.children.select { |ct| ct.children.any? }.inject([]) { |a, ct|
411
+
412
+ xts = ct.gather(k)
413
+ #xts.each { |xt| Raabro.pp(xt) }
414
+ range = xts.any? ? xts.collect { |xt| to_i(k, xt) } : []
415
+ while range.size < 2; range << nil; end
416
+
417
+ st = ct.lookup(:slash)
418
+ range << (st ? st.string[1..-1].to_i : nil)
419
+
420
+ if k == :dow && ht = ct.lookup(:hash)
421
+ hs = ht.string.downcase
422
+ range << ((hs[1, 1] == 'l') ? -1 : hs[1..-1].to_i)
423
+ end
424
+
425
+ a << range
426
+
427
+ a
428
+ }
429
+ end
430
+
431
+ SYMS = %w[ min hou dom mon dow ].collect(&:to_sym)
432
+
433
+ def rewrite_cron(t)
434
+
435
+ SYMS.inject({}) { |h, k| h[k] = rewrite_entry(t.lookup(k)); h }
436
+ end
437
+ end
438
+ end
439
+ end
440
+
@@ -0,0 +1,56 @@
1
+ #--
2
+ # Copyright (c) 2017-2017, John Mettraux, jmettraux+flor@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ # THE SOFTWARE.
21
+ #
22
+ # Made in Japan.
23
+ #++
24
+
25
+
26
+ module Fugit
27
+
28
+ def self.isostamp(show_date, show_time, show_usec, time)
29
+
30
+ t = time || Time.now
31
+ s = StringIO.new
32
+
33
+ s << t.strftime('%Y-%m-%d') if show_date
34
+ s << t.strftime('T%H:%M:%S') if show_time
35
+ s << sprintf('.%06d', t.usec) if show_time && show_usec
36
+ s << 'Z' if show_time && time.utc?
37
+
38
+ s.string
39
+ end
40
+
41
+ def self.time_to_s(t)
42
+
43
+ isostamp(true, true, false, t)
44
+ end
45
+
46
+ def self.time_to_plain_s(t=Time.now)
47
+
48
+ s = StringIO.new
49
+
50
+ s << t.strftime('%Y-%m-%d %H:%M:%S')
51
+ s << ' Z' if t.utc?
52
+
53
+ s.string
54
+ end
55
+ end
56
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fugit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-01 00:00:00.000000000 Z
11
+ date: 2017-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: raabro
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '>='
18
18
  - !ruby/object:Gem::Version
19
- version: 1.1.2
19
+ version: 1.1.3
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: 1.1.2
26
+ version: 1.1.3
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,7 +38,8 @@ dependencies:
38
38
  - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: '3.4'
41
- description: time oriented utilities for flor and the floraison project
41
+ description: Time tools for flor and the floraison project. Cron parsing and occurence
42
+ computing. Timestamps and more.
42
43
  email:
43
44
  - jmettraux+flor@gmail.com
44
45
  executables: []
@@ -46,9 +47,13 @@ extensions: []
46
47
  extra_rdoc_files: []
47
48
  files:
48
49
  - Makefile
50
+ - lib/fugit/cron.rb
51
+ - lib/fugit/misc.rb
49
52
  - lib/fugit.rb
50
53
  - fugit.gemspec
51
54
  - LICENSE.txt
55
+ - CHANGELOG.md
56
+ - CREDITS.md
52
57
  - README.md
53
58
  homepage: http://github.com/floraison/fugit
54
59
  licenses:
@@ -73,5 +78,5 @@ rubyforge_project:
73
78
  rubygems_version: 2.0.14
74
79
  signing_key:
75
80
  specification_version: 4
76
- summary: time oriented utils for flor
81
+ summary: time tools for flor
77
82
  test_files: []