rufus-scheduler 3.4.2 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.txt +7 -0
- data/CREDITS.txt +1 -0
- data/Makefile +4 -0
- data/README.md +3 -2
- data/lib/rufus/scheduler.rb +36 -12
- data/lib/rufus/scheduler/jobs.rb +1 -3
- data/lib/rufus/scheduler/util.rb +151 -216
- data/rufus-scheduler.gemspec +6 -4
- metadata +30 -32
- data/TODO.txt +0 -151
- data/fail.txt +0 -2
- data/fail18.txt +0 -12
- data/lib/rufus/scheduler/cronline.rb +0 -498
- data/log.txt +0 -285
- data/n.txt +0 -38
- data/pics.txt +0 -15
- data/sofia.md +0 -89
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8c6844d5f77112580ff29651a33fe2bc3b9545f
|
4
|
+
data.tar.gz: 329289b1d8a476270440672b4efd71d4d41e976d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a7a056a68f73e62a54b44cbb40c3862e70b75cd92bfbe887ac39c8f72c7398798bb5062272d7d78b8aeeaf3083971276febfa36fb2e7e534b4cd9efb5b7e41a
|
7
|
+
data.tar.gz: a0e682b539d953cf706ee0d431dfd175994c67f8ddeeb61dc5e1d966bf5fd56e79b0c92d5f32e1abaf80fa1674a774d743cb4acc1b248125b55b000a98344d1a
|
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
= rufus-scheduler CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-scheduler - 3.5.0 released 2018-05-15
|
6
|
+
|
7
|
+
- Use fugit to parse durations
|
8
|
+
- Drop .parse_time_string and .parse_duration_string
|
9
|
+
- Use fugit to parse cronlines
|
10
|
+
|
11
|
+
|
5
12
|
== rufus-scheduler - 3.4.2 released 2017-05-24
|
6
13
|
|
7
14
|
(had yanked 3.4.1, going 3.4.2)
|
data/CREDITS.txt
CHANGED
@@ -58,6 +58,7 @@
|
|
58
58
|
|
59
59
|
== Feedback
|
60
60
|
|
61
|
+
- Gian - https://github.com/snmgian - cron vs :first clarification - gh-266
|
61
62
|
- Vito Laurenza - https://github.com/veetow - help debugging tz issues - gh-240
|
62
63
|
- Yoshimi Keiji - https://githuc.com/walf443 - v.3.3.3 mislabelling
|
63
64
|
- Alexander Deeb - https://github.com/adeeb1 - gh-230
|
data/Makefile
CHANGED
@@ -4,6 +4,10 @@ NAME = \
|
|
4
4
|
VERSION = \
|
5
5
|
$(shell ruby -e "s = eval(File.read(Dir['*.gemspec'][0])); puts s.version")
|
6
6
|
|
7
|
+
count_lines:
|
8
|
+
find lib -name "*.rb" | xargs cat | ruby -e "p STDIN.readlines.count { |l| l = l.strip; l[0, 1] != '#' && l != '' }"
|
9
|
+
find spec -name "*_spec.rb" | xargs cat | ruby -e "p STDIN.readlines.count { |l| l = l.strip; l[0, 1] != '#' && l != '' }"
|
10
|
+
cl: count_lines
|
7
11
|
|
8
12
|
gemspec_validate:
|
9
13
|
@echo "---"
|
data/README.md
CHANGED
@@ -128,6 +128,7 @@ Yes, issues can be reported in [rufus-scheduler issues](https://github.com/jmett
|
|
128
128
|
* [Passenger in-depth spawn methods](https://www.phusionpassenger.com/library/indepth/ruby/spawn_methods/)
|
129
129
|
* [Passenger in-depth spawn methods (smart spawning)](https://www.phusionpassenger.com/library/indepth/ruby/spawn_methods/#smart-spawning-hooks)
|
130
130
|
* [The scheduler comes up when running the Rails console or a Rake task](https://github.com/jmettraux/rufus-scheduler#avoid-scheduling-when-running-the-ruby-on-rails-console)
|
131
|
+
* [The job triggers twice](https://github.com/jmettraux/rufus-scheduler#lockfile--mylockfiletxt)
|
131
132
|
* [I don't get any of this, I just want it to work in my Rails application](#so-rails)
|
132
133
|
* [I get "zotime.rb:41:in `initialize': cannot determine timezone from nil"](#i-get-zotimerb41in-initialize-cannot-determine-timezone-from-nil)
|
133
134
|
|
@@ -376,7 +377,7 @@ Since, by default, jobs are triggered in their own new thread, job instances mig
|
|
376
377
|
|
377
378
|
To prevent overlap, one can set :overlap => false. Such a job will not trigger if one of its instance is already running.
|
378
379
|
|
379
|
-
The `:overlap` option is considered
|
380
|
+
The `:overlap` option is considered after the `:mutex` option when the scheduler is reviewing jobs for triggering.
|
380
381
|
|
381
382
|
### :mutex => mutex_instance / mutex_name / array of mutexes
|
382
383
|
|
@@ -415,7 +416,7 @@ This option is for repeat jobs (cron / every) only.
|
|
415
416
|
It's used to specify the first time after which the repeat job should trigger for the first time.
|
416
417
|
|
417
418
|
In the case of an "every" job, this will be the first time (modulo the scheduler frequency) the job triggers.
|
418
|
-
For a "cron" job,
|
419
|
+
For a "cron" job as well, the :first will point to the first time the job has to trigger, the following trigger time are then determined by the cron string.
|
419
420
|
|
420
421
|
```ruby
|
421
422
|
scheduler.every '2d', :first_at => Time.now + 10 * 3600 do
|
data/lib/rufus/scheduler.rb
CHANGED
@@ -4,20 +4,19 @@ require 'date' if RUBY_VERSION < '1.9.0'
|
|
4
4
|
require 'time'
|
5
5
|
require 'thread'
|
6
6
|
|
7
|
-
require '
|
7
|
+
require 'fugit'
|
8
8
|
|
9
9
|
|
10
10
|
module Rufus
|
11
11
|
|
12
12
|
class Scheduler
|
13
13
|
|
14
|
-
VERSION = '3.
|
14
|
+
VERSION = '3.5.0'
|
15
15
|
|
16
16
|
EoTime = ::EtOrbi::EoTime
|
17
17
|
|
18
18
|
require 'rufus/scheduler/util'
|
19
19
|
require 'rufus/scheduler/jobs'
|
20
|
-
require 'rufus/scheduler/cronline'
|
21
20
|
require 'rufus/scheduler/job_array'
|
22
21
|
require 'rufus/scheduler/locks'
|
23
22
|
|
@@ -238,9 +237,9 @@ module Rufus
|
|
238
237
|
opts[:_t] = Scheduler.parse(arg, opts)
|
239
238
|
|
240
239
|
case opts[:_t]
|
241
|
-
|
242
|
-
|
243
|
-
|
240
|
+
when ::Fugit::Cron then schedule_cron(arg, callable, opts, &block)
|
241
|
+
when ::EtOrbi::EoTime, Time then schedule_at(arg, callable, opts, &block)
|
242
|
+
else schedule_in(arg, callable, opts, &block)
|
244
243
|
end
|
245
244
|
end
|
246
245
|
|
@@ -252,8 +251,8 @@ module Rufus
|
|
252
251
|
opts[:_t] = Scheduler.parse(arg, opts)
|
253
252
|
|
254
253
|
case opts[:_t]
|
255
|
-
|
256
|
-
|
254
|
+
when ::Fugit::Cron then schedule_cron(arg, callable, opts, &block)
|
255
|
+
else schedule_every(arg, callable, opts, &block)
|
257
256
|
end
|
258
257
|
end
|
259
258
|
|
@@ -620,10 +619,35 @@ module Rufus
|
|
620
619
|
|
621
620
|
job = job_class.new(self, t, opts, block || callable)
|
622
621
|
|
623
|
-
fail ArgumentError.new(
|
624
|
-
|
625
|
-
|
626
|
-
) if job.respond_to?(:frequency) && job.frequency < @frequency
|
622
|
+
#fail ArgumentError.new(
|
623
|
+
# "job frequency (#{job.frequency}) is higher than " +
|
624
|
+
# "scheduler frequency (#{@frequency})"
|
625
|
+
#) if job.respond_to?(:frequency) && job.frequency < @frequency
|
626
|
+
#
|
627
|
+
# This was expensive
|
628
|
+
|
629
|
+
if (
|
630
|
+
! job.is_a?(Rufus::Scheduler::IntervalJob) &&
|
631
|
+
job.methods.include?(:next_time_from)
|
632
|
+
) then
|
633
|
+
|
634
|
+
nts = (1..365)
|
635
|
+
.inject([ job.send(:next_time_from, EtOrbi.now) ]) { |a, i|
|
636
|
+
a << job.send(:next_time_from, a.last); a }
|
637
|
+
deltas = []; prev = nts.shift
|
638
|
+
while (nt = nts.shift); deltas << (nt - prev).to_f; prev = nt; end
|
639
|
+
|
640
|
+
deltas = deltas[1..-1] \
|
641
|
+
if opts.keys.find { |k| k.to_s.match(/\Afirst/) }
|
642
|
+
#
|
643
|
+
# do not consider the first delta if there is a first, first_at,
|
644
|
+
# or first_in involved
|
645
|
+
|
646
|
+
fail ArgumentError.new(
|
647
|
+
"job frequency (~max #{deltas.min}s) is higher than " +
|
648
|
+
"scheduler frequency (#{@frequency})"
|
649
|
+
) if deltas.min < @frequency * 0.9
|
650
|
+
end
|
627
651
|
|
628
652
|
@jobs.push(job)
|
629
653
|
|
data/lib/rufus/scheduler/jobs.rb
CHANGED
@@ -612,9 +612,7 @@ module Rufus
|
|
612
612
|
|
613
613
|
super(scheduler, cronline, opts, block)
|
614
614
|
|
615
|
-
@cron_line =
|
616
|
-
opts[:_t] ||
|
617
|
-
(cronline.is_a?(CronLine) ? cronline : CronLine.new(cronline))
|
615
|
+
@cron_line = opts[:_t] || ::Fugit::Cron.parse(cronline)
|
618
616
|
|
619
617
|
set_next_time(nil)
|
620
618
|
end
|
data/lib/rufus/scheduler/util.rb
CHANGED
@@ -3,255 +3,190 @@ module Rufus
|
|
3
3
|
|
4
4
|
class Scheduler
|
5
5
|
|
6
|
-
|
7
|
-
# time and string methods
|
8
|
-
#++
|
9
|
-
|
10
|
-
def self.parse(o, opts={})
|
11
|
-
|
12
|
-
opts[:no_error] = true
|
13
|
-
|
14
|
-
parse_cron(o, opts) ||
|
15
|
-
parse_in(o, opts) || # covers 'every' schedule strings
|
16
|
-
parse_at(o, opts) ||
|
17
|
-
fail(ArgumentError.new("couldn't parse #{o.inspect} (#{o.class})"))
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.parse_cron(o, opts)
|
21
|
-
|
22
|
-
o.is_a?(CronLine) ? o : CronLine.new(o)
|
23
|
-
|
24
|
-
rescue ArgumentError => ae
|
25
|
-
|
26
|
-
return nil if opts[:no_error]
|
27
|
-
fail ae
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.parse_in(o, opts={})
|
31
|
-
|
32
|
-
#o.is_a?(String) ? parse_duration(o, opts) : o
|
33
|
-
|
34
|
-
return parse_duration(o, opts) if o.is_a?(String)
|
35
|
-
return o if o.is_a?(Numeric)
|
6
|
+
class << self
|
36
7
|
|
37
|
-
|
8
|
+
#--
|
9
|
+
# time and string methods
|
10
|
+
#++
|
38
11
|
|
39
|
-
|
12
|
+
def parse(o, opts={})
|
40
13
|
|
41
|
-
|
42
|
-
fail ae
|
43
|
-
end
|
14
|
+
opts[:no_error] = true
|
44
15
|
|
45
|
-
|
16
|
+
parse_cron(o, opts) ||
|
17
|
+
parse_in(o, opts) || # covers 'every' schedule strings
|
18
|
+
parse_at(o, opts) ||
|
19
|
+
fail(ArgumentError.new("couldn't parse #{o.inspect} (#{o.class})"))
|
20
|
+
end
|
46
21
|
|
47
|
-
|
48
|
-
return EoTime.make(o) if o.is_a?(Time)
|
49
|
-
EoTime.parse(o, opts)
|
22
|
+
def parse_cron(o, opts)
|
50
23
|
|
51
|
-
|
24
|
+
Fugit.parse_cron(o)
|
25
|
+
end
|
52
26
|
|
53
|
-
|
54
|
-
fail se
|
55
|
-
end
|
27
|
+
def parse_in(o, opts={})
|
56
28
|
|
57
|
-
|
58
|
-
[ 'y', 365 * 24 * 3600 ],
|
59
|
-
[ 'M', 30 * 24 * 3600 ],
|
60
|
-
[ 'w', 7 * 24 * 3600 ],
|
61
|
-
[ 'd', 24 * 3600 ],
|
62
|
-
[ 'h', 3600 ],
|
63
|
-
[ 'm', 60 ],
|
64
|
-
[ 's', 1 ]
|
65
|
-
]
|
66
|
-
DURATIONS2 = DURATIONS2M.dup
|
67
|
-
DURATIONS2.delete_at(1)
|
68
|
-
|
69
|
-
DURATIONS = DURATIONS2M.inject({}) { |r, (k, v)| r[k] = v; r }
|
70
|
-
DURATION_LETTERS = DURATIONS.keys.join
|
71
|
-
|
72
|
-
DU_KEYS = DURATIONS2M.collect { |k, v| k.to_sym }
|
73
|
-
|
74
|
-
# Turns a string like '1m10s' into a float like '70.0', more formally,
|
75
|
-
# turns a time duration expressed as a string into a Float instance
|
76
|
-
# (millisecond count).
|
77
|
-
#
|
78
|
-
# w -> week
|
79
|
-
# d -> day
|
80
|
-
# h -> hour
|
81
|
-
# m -> minute
|
82
|
-
# s -> second
|
83
|
-
# M -> month
|
84
|
-
# y -> year
|
85
|
-
# 'nada' -> millisecond
|
86
|
-
#
|
87
|
-
# Some examples:
|
88
|
-
#
|
89
|
-
# Rufus::Scheduler.parse_duration "0.5" # => 0.5
|
90
|
-
# Rufus::Scheduler.parse_duration "500" # => 0.5
|
91
|
-
# Rufus::Scheduler.parse_duration "1000" # => 1.0
|
92
|
-
# Rufus::Scheduler.parse_duration "1h" # => 3600.0
|
93
|
-
# Rufus::Scheduler.parse_duration "1h10s" # => 3610.0
|
94
|
-
# Rufus::Scheduler.parse_duration "1w2d" # => 777600.0
|
95
|
-
#
|
96
|
-
# Negative time strings are OK (Thanks Danny Fullerton):
|
97
|
-
#
|
98
|
-
# Rufus::Scheduler.parse_duration "-0.5" # => -0.5
|
99
|
-
# Rufus::Scheduler.parse_duration "-1h" # => -3600.0
|
100
|
-
#
|
101
|
-
def self.parse_duration(string, opts={})
|
29
|
+
#o.is_a?(String) ? parse_duration(o, opts) : o
|
102
30
|
|
103
|
-
|
104
|
-
|
105
|
-
s = s[1..-1] if mod == -1
|
31
|
+
return parse_duration(o, opts) if o.is_a?(String)
|
32
|
+
return o if o.is_a?(Numeric)
|
106
33
|
|
107
|
-
|
108
|
-
r = 0.0
|
34
|
+
fail ArgumentError.new("couldn't parse time point in #{o.inspect}")
|
109
35
|
|
110
|
-
|
111
|
-
ss += "#{f}#{d}"
|
112
|
-
r += f.to_f * (DURATIONS[d] || 1.0)
|
113
|
-
end
|
36
|
+
rescue ArgumentError => ae
|
114
37
|
|
115
|
-
if ss == '-' || ss != string.to_s.strip
|
116
38
|
return nil if opts[:no_error]
|
117
|
-
fail
|
39
|
+
fail ae
|
118
40
|
end
|
119
41
|
|
120
|
-
|
121
|
-
end
|
42
|
+
def parse_at(o, opts={})
|
122
43
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
#+
|
127
|
-
alias parse_duration_string parse_duration
|
128
|
-
alias parse_time_string parse_duration
|
129
|
-
end
|
44
|
+
return o if o.is_a?(EoTime)
|
45
|
+
return EoTime.make(o) if o.is_a?(Time)
|
46
|
+
EoTime.parse(o, opts)
|
130
47
|
|
48
|
+
rescue StandardError => se
|
131
49
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
# Rufus.to_duration 60 # => '1m'
|
136
|
-
# Rufus.to_duration 3661 # => '1h1m1s'
|
137
|
-
# Rufus.to_duration 7 * 24 * 3600 # => '1w'
|
138
|
-
# Rufus.to_duration 30 * 24 * 3600 + 1 # => "4w2d1s"
|
139
|
-
#
|
140
|
-
# It goes from seconds to the year. Months are not counted (as they
|
141
|
-
# are of variable length). Weeks are counted.
|
142
|
-
#
|
143
|
-
# For 30 days months to be counted, the second parameter of this
|
144
|
-
# method can be set to true.
|
145
|
-
#
|
146
|
-
# Rufus.to_duration 30 * 24 * 3600 + 1, true # => "1M1s"
|
147
|
-
#
|
148
|
-
# If a Float value is passed, milliseconds will be displayed without
|
149
|
-
# 'marker'
|
150
|
-
#
|
151
|
-
# Rufus.to_duration 0.051 # => "51"
|
152
|
-
# Rufus.to_duration 7.051 # => "7s51"
|
153
|
-
# Rufus.to_duration 0.120 + 30 * 24 * 3600 + 1 # => "4w2d1s120"
|
154
|
-
#
|
155
|
-
# (this behaviour mirrors the one found for parse_time_string()).
|
156
|
-
#
|
157
|
-
# Options are :
|
158
|
-
#
|
159
|
-
# * :months, if set to true, months (M) of 30 days will be taken into
|
160
|
-
# account when building up the result
|
161
|
-
# * :drop_seconds, if set to true, seconds and milliseconds will be trimmed
|
162
|
-
# from the result
|
163
|
-
#
|
164
|
-
def self.to_duration(seconds, options={})
|
165
|
-
|
166
|
-
h = to_duration_hash(seconds, options)
|
167
|
-
|
168
|
-
return (options[:drop_seconds] ? '0m' : '0s') if h.empty?
|
169
|
-
|
170
|
-
s =
|
171
|
-
DU_KEYS.inject('') { |r, key|
|
172
|
-
count = h[key]
|
173
|
-
count = nil if count == 0
|
174
|
-
r << "#{count}#{key}" if count
|
175
|
-
r
|
176
|
-
}
|
177
|
-
|
178
|
-
ms = h[:ms]
|
179
|
-
s << ms.to_s if ms
|
180
|
-
|
181
|
-
s
|
182
|
-
end
|
183
|
-
|
184
|
-
class << self
|
185
|
-
#-
|
186
|
-
# for compatibility with rufus-scheduler 2.x
|
187
|
-
#+
|
188
|
-
alias to_duration_string to_duration
|
189
|
-
alias to_time_string to_duration
|
190
|
-
end
|
191
|
-
|
192
|
-
# Turns a number of seconds (integer or Float) into a hash like in :
|
193
|
-
#
|
194
|
-
# Rufus.to_duration_hash 0.051
|
195
|
-
# # => { :ms => "51" }
|
196
|
-
# Rufus.to_duration_hash 7.051
|
197
|
-
# # => { :s => 7, :ms => "51" }
|
198
|
-
# Rufus.to_duration_hash 0.120 + 30 * 24 * 3600 + 1
|
199
|
-
# # => { :w => 4, :d => 2, :s => 1, :ms => "120" }
|
200
|
-
#
|
201
|
-
# This method is used by to_duration behind the scenes.
|
202
|
-
#
|
203
|
-
# Options are :
|
204
|
-
#
|
205
|
-
# * :months, if set to true, months (M) of 30 days will be taken into
|
206
|
-
# account when building up the result
|
207
|
-
# * :drop_seconds, if set to true, seconds and milliseconds will be trimmed
|
208
|
-
# from the result
|
209
|
-
#
|
210
|
-
def self.to_duration_hash(seconds, options={})
|
50
|
+
return nil if opts[:no_error]
|
51
|
+
fail se
|
52
|
+
end
|
211
53
|
|
212
|
-
|
54
|
+
# Turns a string like '1m10s' into a float like '70.0', more formally,
|
55
|
+
# turns a time duration expressed as a string into a Float instance
|
56
|
+
# (millisecond count).
|
57
|
+
#
|
58
|
+
# w -> week
|
59
|
+
# d -> day
|
60
|
+
# h -> hour
|
61
|
+
# m -> minute
|
62
|
+
# s -> second
|
63
|
+
# M -> month
|
64
|
+
# y -> year
|
65
|
+
# 'nada' -> millisecond
|
66
|
+
#
|
67
|
+
# Some examples:
|
68
|
+
#
|
69
|
+
# Rufus::Scheduler.parse_duration "0.5" # => 0.5
|
70
|
+
# Rufus::Scheduler.parse_duration "500" # => 0.5
|
71
|
+
# Rufus::Scheduler.parse_duration "1000" # => 1.0
|
72
|
+
# Rufus::Scheduler.parse_duration "1h" # => 3600.0
|
73
|
+
# Rufus::Scheduler.parse_duration "1h10s" # => 3610.0
|
74
|
+
# Rufus::Scheduler.parse_duration "1w2d" # => 777600.0
|
75
|
+
#
|
76
|
+
# Negative time strings are OK (Thanks Danny Fullerton):
|
77
|
+
#
|
78
|
+
# Rufus::Scheduler.parse_duration "-0.5" # => -0.5
|
79
|
+
# Rufus::Scheduler.parse_duration "-1h" # => -3600.0
|
80
|
+
#
|
81
|
+
def parse_duration(str, opts={})
|
82
|
+
|
83
|
+
d =
|
84
|
+
opts[:no_error] ?
|
85
|
+
Fugit::Duration.parse(str, opts) :
|
86
|
+
Fugit::Duration.do_parse(str, opts)
|
87
|
+
d ?
|
88
|
+
d.to_sec :
|
89
|
+
nil
|
90
|
+
end
|
213
91
|
|
214
|
-
|
215
|
-
|
216
|
-
|
92
|
+
# Turns a number of seconds into a a time string
|
93
|
+
#
|
94
|
+
# Rufus.to_duration 0 # => '0s'
|
95
|
+
# Rufus.to_duration 60 # => '1m'
|
96
|
+
# Rufus.to_duration 3661 # => '1h1m1s'
|
97
|
+
# Rufus.to_duration 7 * 24 * 3600 # => '1w'
|
98
|
+
# Rufus.to_duration 30 * 24 * 3600 + 1 # => "4w2d1s"
|
99
|
+
#
|
100
|
+
# It goes from seconds to the year. Months are not counted (as they
|
101
|
+
# are of variable length). Weeks are counted.
|
102
|
+
#
|
103
|
+
# For 30 days months to be counted, the second parameter of this
|
104
|
+
# method can be set to true.
|
105
|
+
#
|
106
|
+
# Rufus.to_duration 30 * 24 * 3600 + 1, true # => "1M1s"
|
107
|
+
#
|
108
|
+
# If a Float value is passed, milliseconds will be displayed without
|
109
|
+
# 'marker'
|
110
|
+
#
|
111
|
+
# Rufus.to_duration 0.051 # => "51"
|
112
|
+
# Rufus.to_duration 7.051 # => "7s51"
|
113
|
+
# Rufus.to_duration 0.120 + 30 * 24 * 3600 + 1 # => "4w2d1s120"
|
114
|
+
#
|
115
|
+
# (this behaviour mirrors the one found for parse_time_string()).
|
116
|
+
#
|
117
|
+
# Options are :
|
118
|
+
#
|
119
|
+
# * :months, if set to true, months (M) of 30 days will be taken into
|
120
|
+
# account when building up the result
|
121
|
+
# * :drop_seconds, if set to true, seconds and milliseconds will be
|
122
|
+
# trimmed from the result
|
123
|
+
#
|
124
|
+
def to_duration(seconds, options={})
|
125
|
+
|
126
|
+
#d = Fugit::Duration.parse(seconds, options).deflate
|
127
|
+
#d = d.drop_seconds if options[:drop_seconds]
|
128
|
+
#d = d.deflate(:month => options[:months]) if options[:months]
|
129
|
+
#d.to_rufus_s
|
130
|
+
|
131
|
+
to_fugit_duration(seconds, options).to_rufus_s
|
217
132
|
end
|
218
133
|
|
219
|
-
|
220
|
-
|
221
|
-
|
134
|
+
# Turns a number of seconds (integer or Float) into a hash like in :
|
135
|
+
#
|
136
|
+
# Rufus.to_duration_hash 0.051
|
137
|
+
# # => { :s => 0.051 }
|
138
|
+
# Rufus.to_duration_hash 7.051
|
139
|
+
# # => { :s => 7.051 }
|
140
|
+
# Rufus.to_duration_hash 0.120 + 30 * 24 * 3600 + 1
|
141
|
+
# # => { :w => 4, :d => 2, :s => 1.120 }
|
142
|
+
#
|
143
|
+
# This method is used by to_duration behind the scenes.
|
144
|
+
#
|
145
|
+
# Options are :
|
146
|
+
#
|
147
|
+
# * :months, if set to true, months (M) of 30 days will be taken into
|
148
|
+
# account when building up the result
|
149
|
+
# * :drop_seconds, if set to true, seconds and milliseconds will be
|
150
|
+
# trimmed from the result
|
151
|
+
#
|
152
|
+
def to_duration_hash(seconds, options={})
|
153
|
+
|
154
|
+
to_fugit_duration(seconds, options).to_rufus_h
|
222
155
|
end
|
223
156
|
|
224
|
-
|
157
|
+
# Used by both .to_duration and .to_duration_hash
|
158
|
+
#
|
159
|
+
def to_fugit_duration(seconds, options={})
|
225
160
|
|
226
|
-
|
161
|
+
d = Fugit::Duration
|
162
|
+
.parse(seconds, options)
|
163
|
+
.deflate
|
227
164
|
|
228
|
-
|
229
|
-
|
165
|
+
d = d.drop_seconds if options[:drop_seconds]
|
166
|
+
d = d.deflate(:month => options[:months]) if options[:months]
|
230
167
|
|
231
|
-
|
168
|
+
d
|
232
169
|
end
|
233
170
|
|
234
|
-
|
235
|
-
|
171
|
+
#--
|
172
|
+
# misc
|
173
|
+
#++
|
236
174
|
|
237
|
-
|
238
|
-
|
239
|
-
|
175
|
+
# Produces the UTC string representation of a Time instance
|
176
|
+
#
|
177
|
+
# like "2009/11/23 11:11:50.947109 UTC"
|
178
|
+
#
|
179
|
+
def utc_to_s(t=Time.now)
|
240
180
|
|
241
|
-
|
242
|
-
|
243
|
-
# like "2009/11/23 11:11:50.947109 UTC"
|
244
|
-
#
|
245
|
-
def self.utc_to_s(t=Time.now)
|
246
|
-
|
247
|
-
"#{t.utc.strftime('%Y-%m-%d %H:%M:%S')}.#{sprintf('%06d', t.usec)} UTC"
|
248
|
-
end
|
181
|
+
"#{t.utc.strftime('%Y-%m-%d %H:%M:%S')}.#{sprintf('%06d', t.usec)} UTC"
|
182
|
+
end
|
249
183
|
|
250
|
-
|
251
|
-
|
252
|
-
|
184
|
+
# Produces a hour/min/sec/milli string representation of Time instance
|
185
|
+
#
|
186
|
+
def h_to_s(t=Time.now)
|
253
187
|
|
254
|
-
|
188
|
+
"#{t.strftime('%H:%M:%S')}.#{sprintf('%06d', t.usec)}"
|
189
|
+
end
|
255
190
|
end
|
256
191
|
|
257
192
|
# Debugging tools...
|