fugit 0.1.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fugit might be problematic. Click here for more details.

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: []