ago 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +23 -0
- data/History.txt +26 -0
- data/Manifest.txt +9 -0
- data/README.txt +410 -0
- data/Rakefile +22 -0
- data/bin/ago +3 -0
- data/lib/ago.rb +185 -0
- data/lib/numbers.rb +78 -0
- data/test/test_ago.rb +8 -0
- metadata +74 -0
data/.autotest
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'autotest/restart'
|
4
|
+
|
5
|
+
# Autotest.add_hook :initialize do |at|
|
6
|
+
# at.extra_files << "../some/external/dependency.rb"
|
7
|
+
#
|
8
|
+
# at.libs << ":../some/external"
|
9
|
+
#
|
10
|
+
# at.add_exception 'vendor'
|
11
|
+
#
|
12
|
+
# at.add_mapping(/dependency.rb/) do |f, _|
|
13
|
+
# at.files_matching(/test_.*rb$/)
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# %w(TestA TestB).each do |klass|
|
17
|
+
# at.extra_class_map[klass] = "test/test_misc.rb"
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
|
21
|
+
# Autotest.add_hook :run_command do |at|
|
22
|
+
# system "rake build"
|
23
|
+
# end
|
data/History.txt
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
== 0.1.5 / 2009-06-20
|
3
|
+
|
4
|
+
* 1 minor improvement
|
5
|
+
Finish documentation
|
6
|
+
|
7
|
+
== 0.1.4 / 2009-06-20
|
8
|
+
|
9
|
+
* 2 minor Improvements
|
10
|
+
|
11
|
+
Add remainder of Time documenation
|
12
|
+
* Fix bug on :now default
|
13
|
+
|
14
|
+
== 0.1.3 / 2009-06-20
|
15
|
+
|
16
|
+
Add documentation to README.txt
|
17
|
+
|
18
|
+
== 0.1.2 / 2009-06-20
|
19
|
+
|
20
|
+
Make Ago the master module
|
21
|
+
* Rename :cal argument to :calendar
|
22
|
+
* Move Order and Units from Time to Ago
|
23
|
+
|
24
|
+
== 0.1.1 / 2009-06-20
|
25
|
+
|
26
|
+
Create Rakefile
|
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,410 @@
|
|
1
|
+
=Ago
|
2
|
+
* by Mike Zazaian
|
3
|
+
* http://ago.rubyforge.org
|
4
|
+
|
5
|
+
|
6
|
+
== DESCRIPTION
|
7
|
+
|
8
|
+
Easy conversion of Time objects to human-readable format.
|
9
|
+
|
10
|
+
|
11
|
+
== FEATURES/PROBLEMS:
|
12
|
+
|
13
|
+
* Convert Time objects to a human-readable format.
|
14
|
+
* Convert Fixnum, Bignum, and Floats objects into Time objects
|
15
|
+
|
16
|
+
|
17
|
+
== SYNOPSIS:
|
18
|
+
|
19
|
+
=== Intro
|
20
|
+
|
21
|
+
Ago allows you to convert any Time objecto a simple, human-readable
|
22
|
+
format, like this:
|
23
|
+
|
24
|
+
t = Time.new
|
25
|
+
=> Sat Jun 20 18:09:16 +1000 2009
|
26
|
+
|
27
|
+
t.ago
|
28
|
+
=> "2 seconds ago"
|
29
|
+
|
30
|
+
You can also print out the NUMBER OF SECONDS in various units of
|
31
|
+
time, like this:
|
32
|
+
|
33
|
+
2.years
|
34
|
+
=> 63072000
|
35
|
+
|
36
|
+
3.months
|
37
|
+
=> 7776000
|
38
|
+
|
39
|
+
50.weeks
|
40
|
+
=> 30240000
|
41
|
+
|
42
|
+
And then, if you want, convert those units into Time objects:
|
43
|
+
|
44
|
+
2.years.ago
|
45
|
+
=> Thu Jun 21 18:26:59 +1000 2007
|
46
|
+
|
47
|
+
3.months.ago
|
48
|
+
=> Sun Mar 22 19:28:05 +1100 2009
|
49
|
+
|
50
|
+
|
51
|
+
=== Time to human-readable format
|
52
|
+
|
53
|
+
Ago works by calculating the difference in the number of seconds
|
54
|
+
between the given Time object and Time.now, then dividing by the
|
55
|
+
number of seconds in each unit:
|
56
|
+
|
57
|
+
* Years
|
58
|
+
* Months
|
59
|
+
* Weeks
|
60
|
+
* Days
|
61
|
+
* Hours
|
62
|
+
* Minutes
|
63
|
+
* Seconds
|
64
|
+
|
65
|
+
By default, Ago will start with the largest divisible unit, then go
|
66
|
+
down the line until all of the seconds have been accounted for.
|
67
|
+
|
68
|
+
If you, for example, had a Time object for January 1st, 1971, you
|
69
|
+
could see how many years had passed like this:
|
70
|
+
|
71
|
+
t = Time.new - 38.years - 6.months
|
72
|
+
=> Fri Jan 01 18:30:03 +1000 1971
|
73
|
+
|
74
|
+
t.ago
|
75
|
+
=> "38 years ago"
|
76
|
+
|
77
|
+
By default, Ago will show only the LARGEST UNIT in the time object.
|
78
|
+
In this case, there are 38 years in the 't' Time object, so it only
|
79
|
+
prints that number.
|
80
|
+
|
81
|
+
|
82
|
+
==== The :focus Option
|
83
|
+
|
84
|
+
If you want to access the smaller numbers, you can use the :focus
|
85
|
+
option, like this:
|
86
|
+
|
87
|
+
t.ago(:focus => :second)
|
88
|
+
=> "38 years, 6 months, 9 minutes, 8 seconds ago"
|
89
|
+
|
90
|
+
The value for focus can be either one of the units of time as a
|
91
|
+
Symbol (:year, :month, :week, :day, :hour, :minute, :second), like this:
|
92
|
+
|
93
|
+
t.ago(:focus => :month)
|
94
|
+
=> "38 years, 3 months ago"
|
95
|
+
|
96
|
+
OR, the value can be a Fixnum, which indicates how many units IN
|
97
|
+
ADDITION TO THE FIRST UNIT the Ago module will print out:
|
98
|
+
|
99
|
+
t.ago(:focus => 3)
|
100
|
+
=> "38 years, 6 months, 9 minutes, 8 seconds ago"
|
101
|
+
|
102
|
+
t.ago(:focus => 2)
|
103
|
+
=> "38 years, 6 months, 9 minutes ago"
|
104
|
+
|
105
|
+
t.ago(:focus => 0)
|
106
|
+
=> "38 years ago"
|
107
|
+
|
108
|
+
Don't worry if the number is greater than the number of possible
|
109
|
+
units in the Time object, Ago will just ignore the extra places:
|
110
|
+
|
111
|
+
t.ago(:focus => 6)
|
112
|
+
=> "4 days, 20 hours, 59 minutes, 40 seconds ago"
|
113
|
+
|
114
|
+
Make sure that number value is between 0 and 6, though, or Ago will
|
115
|
+
throw an error at you:
|
116
|
+
|
117
|
+
t.ago :focus => 3000
|
118
|
+
ArgumentError: :focus => value must either be a number between 0 and
|
119
|
+
6 (inclusive), or one of the following symbols: :year, :month, :week,
|
120
|
+
:day, :hour, :minute, and :second.
|
121
|
+
from ./ago.rb:89:in `ago'
|
122
|
+
from ./ago.rb:86:in `each'
|
123
|
+
from ./ago.rb:86:in `ago'
|
124
|
+
|
125
|
+
|
126
|
+
==== The :start_at Option
|
127
|
+
|
128
|
+
:start_at works in much the same way that the :focus option works,
|
129
|
+
but measures where the output starts rather than where it ends.
|
130
|
+
|
131
|
+
If you wanted to see how many months there were since January 1st,
|
132
|
+
1971, for example, you could do this:
|
133
|
+
|
134
|
+
t.ago(:start_at => :month)
|
135
|
+
=> "468 months ago"
|
136
|
+
|
137
|
+
or, if you wanted to see the number of days:
|
138
|
+
|
139
|
+
t.ago(:start_at => :day)
|
140
|
+
=> "14050 days ago"
|
141
|
+
|
142
|
+
And while the Symbol arguments for :start_at work similarly to those
|
143
|
+
in :focus, the numerical arguments work differently.
|
144
|
+
|
145
|
+
While the numerical arguments in :focus indicate how many ADDITIONAL
|
146
|
+
UNITS are printed, the numerical arguments for :start_at are just
|
147
|
+
codes for their Symbol counterparts, like this:
|
148
|
+
|
149
|
+
Year: 0
|
150
|
+
Month: 1
|
151
|
+
Week: 2
|
152
|
+
Day: 3
|
153
|
+
Hour: 4
|
154
|
+
Minute: 5
|
155
|
+
Second: 6
|
156
|
+
|
157
|
+
So if you want to see how many months ago January 1, 1971 occurred,
|
158
|
+
this is also a valid way to call the function:
|
159
|
+
|
160
|
+
t.ago(:start_at => 1)
|
161
|
+
=> "468 months ago"
|
162
|
+
|
163
|
+
|
164
|
+
==== Combining :focus and :start_at
|
165
|
+
|
166
|
+
Let's say you had a Time object for about 40 years ago, give or take,
|
167
|
+
and you wanted to see how many months ago it was, but also how many
|
168
|
+
weeks, days and hours. You could call it like this:
|
169
|
+
|
170
|
+
t.ago(:start_at => :month, :focus => :hour)
|
171
|
+
=> "486 months, 4 weeks, 1 day, 16 hours ago"
|
172
|
+
|
173
|
+
OR:
|
174
|
+
|
175
|
+
t.ago(:start_at => :month, :focus => 3)
|
176
|
+
=> "486 months, 4 weeks, 1 day, 16 hours ago"
|
177
|
+
|
178
|
+
OR:
|
179
|
+
|
180
|
+
t.ago(:start_at => 1, :focus => 3)
|
181
|
+
=> "486 months, 4 weeks, 1 day, 16 hours ago"
|
182
|
+
|
183
|
+
|
184
|
+
==== The :now Option
|
185
|
+
|
186
|
+
Ago automatically assumes that you want to calculate the difference
|
187
|
+
between the given Time object and NOW (Time now).
|
188
|
+
|
189
|
+
But suppose you wanted NOW to be some other point in time. Say,
|
190
|
+
three weeks ago. Then you could do this:
|
191
|
+
|
192
|
+
t = Time.now
|
193
|
+
=> Sat Jun 20 19:38:38 +1000 2009
|
194
|
+
|
195
|
+
t.ago(:now => 3.weeks.ago)
|
196
|
+
=> "2 weeks from now"
|
197
|
+
|
198
|
+
Weird that it printed "2 weeks from now" instead of three? Not
|
199
|
+
really. If you're running this in IRB, then a couple of seconds
|
200
|
+
probably passed between "t = Time.now" and "t.ago(:now => 3.weeks.ago)".
|
201
|
+
|
202
|
+
To see more precisely how long 3.weeks.ago is, you'd have to use
|
203
|
+
the :focus option:
|
204
|
+
|
205
|
+
t.ago(:now => 3.weeks.ago, :focus => :second)
|
206
|
+
=> "2 weeks, 6 days, 23 hours, 59 minutes, 56 seconds from now"
|
207
|
+
|
208
|
+
That's more like it. Note that the value for :now => can be any Time
|
209
|
+
object, even Time.now (not that you'd want to do this).
|
210
|
+
|
211
|
+
|
212
|
+
==== The :calendar Option
|
213
|
+
|
214
|
+
By default, Ago uses this BASIC calendar structure:
|
215
|
+
|
216
|
+
Year: 365 Days
|
217
|
+
Month: 30 Days
|
218
|
+
Week: 7 Days
|
219
|
+
Day: 24 Hours
|
220
|
+
Hour: 60 Minutes
|
221
|
+
Minute: 60 Seconds
|
222
|
+
Second: 1 Second
|
223
|
+
|
224
|
+
The basic calendar structure works fine when calculating small amounts
|
225
|
+
of time, because they're strong approximations for what would be
|
226
|
+
considered the average year.
|
227
|
+
|
228
|
+
When you're calculating larger amounts of time, however, you might
|
229
|
+
want a bit more accuracy. In this case you might want to use the
|
230
|
+
*GREGORIAN CALENDAR*, which uses these units of time:
|
231
|
+
|
232
|
+
Year: 365.2425 Days
|
233
|
+
Month: 30.436875 Days
|
234
|
+
Week: 7.02389423076923 Days
|
235
|
+
|
236
|
+
This might not seem like a huge difference, when calculating several
|
237
|
+
months or years it starts to add up:
|
238
|
+
|
239
|
+
t = Time.now - 60.years
|
240
|
+
=> Tue Jul 05 19:58:15 +1000 1949
|
241
|
+
|
242
|
+
t.ago :focus => :second
|
243
|
+
=> "60 years, 18 seconds ago"
|
244
|
+
|
245
|
+
t.ago :focus => :second, :calendar => :gregorian
|
246
|
+
=> "59 years, 11 months, 2 weeks, 1 day, 20 hours, 8 minutes, 20 seconds ago"
|
247
|
+
|
248
|
+
This example simply demonstrates the difference betwen the :basic and
|
249
|
+
the :gregorian calendars. The problem is that the 60.years function
|
250
|
+
is also using the :basic calendar, so it stands to reason that t.ago
|
251
|
+
produces the boring response of "60 years, 18 seconds ago".
|
252
|
+
|
253
|
+
To really see the difference between them, we'd need to use some
|
254
|
+
point in time, such as 3 billion seconds ago:
|
255
|
+
|
256
|
+
t = Time.now - 3000000000
|
257
|
+
=> Thu May 28 15:15:22 +1000 1914
|
258
|
+
|
259
|
+
t.ago :focus => :second, :calendar => :basic
|
260
|
+
=> "95 years, 1 month, 2 weeks, 3 days, 5 hours, 20 minutes, 10 seconds ago"
|
261
|
+
|
262
|
+
t.ago :focus => :second, :calendar => :gregorian
|
263
|
+
=> "95 years, 3 weeks, 3 days, 2 hours, 43 minutes, 8 seconds ago"
|
264
|
+
|
265
|
+
Sure, it's only a 3 week difference over 95 years, but they're three
|
266
|
+
weeks that never actually occurred.
|
267
|
+
|
268
|
+
Using the Gregorian calendar is also a bit more accurate because it
|
269
|
+
converts Time.now to a Float rather than a Fixnum. This means that
|
270
|
+
Time.now is calculated down to 100,000 microseconds:
|
271
|
+
|
272
|
+
Time.now.to_f
|
273
|
+
=> 1245495041.70918
|
274
|
+
|
275
|
+
|
276
|
+
=== Numbers to Time
|
277
|
+
|
278
|
+
==== Fixnums
|
279
|
+
|
280
|
+
The other aspect of the Ago method, which you've already explored a
|
281
|
+
little bit, is the ability to convert units of time to seconds
|
282
|
+
and time objects, like this:
|
283
|
+
|
284
|
+
5.years
|
285
|
+
=> 157680000
|
286
|
+
|
287
|
+
3.months
|
288
|
+
=> 7776000
|
289
|
+
|
290
|
+
6.weeks.ago
|
291
|
+
=> Sat May 09 21:11:25 +1000 2009
|
292
|
+
|
293
|
+
20.hours.from_now
|
294
|
+
=> Sun Jun 21 17:12:01 +1000 2009
|
295
|
+
|
296
|
+
These methods work the same in pretty much every case, except that
|
297
|
+
the years, months, and weeks methods can take the :calendar
|
298
|
+
option in the manner as we saw above, like this:
|
299
|
+
|
300
|
+
5.years :calendar => :basic
|
301
|
+
=> 157680000
|
302
|
+
|
303
|
+
5.years :calendar => :gregorian
|
304
|
+
=> 157784760.0
|
305
|
+
|
306
|
+
5.years(:calendar => :gregorian).ago
|
307
|
+
=> Sun Jun 20 16:09:46 +1000 2004
|
308
|
+
|
309
|
+
5.years(:calendar => :gregorian).from_now
|
310
|
+
=> Sat Jun 21 02:22:15 +1000 2014
|
311
|
+
|
312
|
+
|
313
|
+
==== Floats and Bignums
|
314
|
+
|
315
|
+
The Ago::Numbers methods are also included in the Float and Bignum
|
316
|
+
classes, and can be called from those as well, such as:
|
317
|
+
|
318
|
+
3.2.months.from_now
|
319
|
+
=> Thu Sep 24 21:18:59 +1000 2009
|
320
|
+
|
321
|
+
24.6.years.ago
|
322
|
+
=> Mon Nov 19 22:19:44 +1100 1984
|
323
|
+
|
324
|
+
500.3482.weeks.from_now
|
325
|
+
=> Tue Jan 22 08:50:19 +1100 2019
|
326
|
+
|
327
|
+
OR, to use Bignums:
|
328
|
+
|
329
|
+
100000000000.class
|
330
|
+
=> Bignum
|
331
|
+
|
332
|
+
100000000000.minutes
|
333
|
+
=> 6000000000000
|
334
|
+
|
335
|
+
3000000000000.weeks :calendar => :gregorian
|
336
|
+
=> 1.82059338461538e+18
|
337
|
+
|
338
|
+
300000000000000.years(:calendar => :gregorian)
|
339
|
+
=> 9.4670856e+21
|
340
|
+
|
341
|
+
THE CAVEAT here is that you can't use the .ago or .from_now methods
|
342
|
+
on Bignums, because they're out of range for the Time class:
|
343
|
+
|
344
|
+
100000000000.class
|
345
|
+
=> Bignum
|
346
|
+
|
347
|
+
100000000000.seconds.ago
|
348
|
+
RangeError: time - 100000000000.000000 out of Time range
|
349
|
+
from ./numbers.rb:6:in `-'
|
350
|
+
from ./numbers.rb:6:in `ago'
|
351
|
+
|
352
|
+
|
353
|
+
== REQUIREMENTS:
|
354
|
+
|
355
|
+
You must have rubygems installed to use Ago as a gem. To install
|
356
|
+
Rubygems on a debian or ubuntu linux system, do:
|
357
|
+
|
358
|
+
sudo aptitude update && sudo aptitude install rubygems
|
359
|
+
|
360
|
+
== INSTALL:
|
361
|
+
|
362
|
+
=== As a Rubygem
|
363
|
+
|
364
|
+
sudo gem install --remote ago
|
365
|
+
|
366
|
+
Then, add Ago to your script with:
|
367
|
+
|
368
|
+
require 'rubygems'
|
369
|
+
require 'ago'
|
370
|
+
|
371
|
+
=== Directly into your script
|
372
|
+
|
373
|
+
If you want to include Ago directly into your script, you can
|
374
|
+
download Ago as a .tgz or .zip package from the Ago homepage at:
|
375
|
+
|
376
|
+
http://ago.rubygems.org
|
377
|
+
|
378
|
+
Once you have the package, add Ago to your script's directory, add
|
379
|
+
the ago directory to your $LOAD_PATH variable...
|
380
|
+
|
381
|
+
$LOAD_PATH << "./ago"
|
382
|
+
|
383
|
+
.. and require Ago at the top of your script:
|
384
|
+
|
385
|
+
require 'ago'
|
386
|
+
|
387
|
+
== LICENSE:
|
388
|
+
|
389
|
+
(The MIT License)
|
390
|
+
|
391
|
+
Copyright (c) 2009 Mike Zazaian
|
392
|
+
|
393
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
394
|
+
a copy of this software and associated documentation files (the
|
395
|
+
'Software'), to deal in the Software without restriction, including
|
396
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
397
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
398
|
+
permit persons to whom the Software is furnished to do so, subject to
|
399
|
+
the following conditions:
|
400
|
+
|
401
|
+
The above copyright notice and this permission notice shall be
|
402
|
+
included in all copies or substantial portions of the Software.
|
403
|
+
|
404
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
405
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
406
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
407
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
408
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
409
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
410
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'hoe'
|
4
|
+
$:.unshift(File.dirname(__FILE__) + "/lib")
|
5
|
+
require 'ago'
|
6
|
+
|
7
|
+
Hoe.new('ago', Ago::VERSION.print) do |p|
|
8
|
+
p.developer 'Mike Zazaian', 'zazaian@gmail.com'
|
9
|
+
|
10
|
+
d = "Allows easy conversion of Time objects to human-readable format."
|
11
|
+
p.description = d
|
12
|
+
p.summary = d
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Simple test on packaged files to make sure they are all there"
|
16
|
+
task :verify => :package do
|
17
|
+
# An error message will be displayed if files are missing
|
18
|
+
if system %(ruby -e "require 'pkg/ago-#{Ago::VERSION}/lib/ago'")
|
19
|
+
puts "\nThe library files are present"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/bin/ago
ADDED
data/lib/ago.rb
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
|
2
|
+
module Ago
|
3
|
+
module VERSION
|
4
|
+
MAJOR = 0
|
5
|
+
MINOR = 1
|
6
|
+
TINY = 5
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def pretty
|
10
|
+
"#{MAJOR}.#{MINOR}.#{TINY}"
|
11
|
+
end
|
12
|
+
alias_method :print, :pretty
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Ago::Order = [:year, :month, :week, :day, :hour, :minute, :second]
|
17
|
+
Ago::Units = {
|
18
|
+
:year => {
|
19
|
+
:basic => 60 * 60 * 24 * 365,
|
20
|
+
:gregorian => 86400 * 365.2425,
|
21
|
+
},
|
22
|
+
:month => {
|
23
|
+
:basic => 60 * 60 * 24 * 30,
|
24
|
+
:gregorian => 86400 * 30.436875,
|
25
|
+
},
|
26
|
+
:week => {
|
27
|
+
:basic => 60 * 60 * 24 * 7,
|
28
|
+
:gregorian => 86400 * 7.02389423076923,
|
29
|
+
},
|
30
|
+
:day => {
|
31
|
+
:basic => 60 * 60 * 24
|
32
|
+
},
|
33
|
+
:hour => {
|
34
|
+
:basic => 60 * 60
|
35
|
+
},
|
36
|
+
:minute => {
|
37
|
+
:basic => 60
|
38
|
+
},
|
39
|
+
:second => {
|
40
|
+
:basic => 1
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
def Ago.calendar_check(calendar)
|
45
|
+
error = ":calendar => value must be either :basic or :gregorian."
|
46
|
+
unless calendar == :basic || calendar == :gregorian
|
47
|
+
raise ArgumentError, error
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
module Ago::TimeAgo
|
53
|
+
# Generate List of valid unit :symbols
|
54
|
+
valids = ""
|
55
|
+
Ago::Order.each do |u|
|
56
|
+
unless u == :second
|
57
|
+
valids += ":#{u.to_s}, "
|
58
|
+
else
|
59
|
+
valids += "and :#{u.to_s}."
|
60
|
+
end
|
61
|
+
end
|
62
|
+
Valids = valids
|
63
|
+
|
64
|
+
def ago(opts={})
|
65
|
+
# Process options {hash}
|
66
|
+
focus = opts[:focus] ? opts[:focus] : 0
|
67
|
+
start_at = opts[:start_at] ? opts[:start_at] : :year
|
68
|
+
now = opts[:now] ? opts[:now] : Time.now
|
69
|
+
in_time = opts[:in_time] ? opts[:in_time] : :past
|
70
|
+
calendar = opts[:calendar] ? opts[:calendar] : :basic
|
71
|
+
|
72
|
+
# Filter out invalid arguments for :in_time
|
73
|
+
in_time_error = ":in_time => value must be either :past or :future, " \
|
74
|
+
+ "depending on whether the Time object is before or after Time.now."
|
75
|
+
unless in_time == :past || in_time == :future
|
76
|
+
raise ArgumentError, in_time_error
|
77
|
+
end
|
78
|
+
|
79
|
+
# Filter out invalid arguments for :calendar
|
80
|
+
Ago.calendar_check(calendar)
|
81
|
+
|
82
|
+
# Filter out invalid arguments for :start_at and :focus
|
83
|
+
base_error = " => value must either be a number " +
|
84
|
+
"between 0 and 6 (inclusive),\nor one of the following " +
|
85
|
+
"symbols: " + Valids
|
86
|
+
{:focus => focus, :start_at => start_at}.each do |key, opt|
|
87
|
+
opt_error = ":" + key.to_s + base_error
|
88
|
+
if opt.class == Fixnum
|
89
|
+
raise ArgumentError, opt_error unless opt >= 0 && opt <= 6
|
90
|
+
elsif opt.class == Symbol
|
91
|
+
raise ArgumentError, opt_error unless Ago::Units[opt]
|
92
|
+
else
|
93
|
+
raise ArgumentError, opt_error
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Create Variables necessary for processing.
|
98
|
+
frags = []
|
99
|
+
output = ""
|
100
|
+
count = 0
|
101
|
+
|
102
|
+
now = calendar == :basic ? now.to_i : now.to_f
|
103
|
+
my_time = calendar == :basic ? self.to_i : self.to_f
|
104
|
+
if now > my_time
|
105
|
+
diff = now - my_time
|
106
|
+
tail = " ago"
|
107
|
+
elsif my_time > now
|
108
|
+
diff = my_time - now
|
109
|
+
tail = " from now"
|
110
|
+
else
|
111
|
+
diff = 0
|
112
|
+
tail = "Right now, this very moment."
|
113
|
+
end
|
114
|
+
|
115
|
+
# Begin Ago.ago processing
|
116
|
+
Ago::Order.each do |u|
|
117
|
+
if calendar == :gregorian && Ago::Units[u][:gregorian]
|
118
|
+
value = Ago::Units[u][:gregorian]
|
119
|
+
else
|
120
|
+
value = Ago::Units[u][:basic]
|
121
|
+
end
|
122
|
+
count += 1
|
123
|
+
|
124
|
+
# Move further ahead in the Ago::Units array if start_at is farther back than
|
125
|
+
# the current point in the array.
|
126
|
+
if start_at.class == Fixnum
|
127
|
+
next if count <= start_at
|
128
|
+
elsif start_at.class == Symbol
|
129
|
+
next if Ago::Order.index(u) < Ago::Order.index(start_at)
|
130
|
+
end
|
131
|
+
|
132
|
+
n = (diff/value).floor
|
133
|
+
if n > 0
|
134
|
+
plural = n > 1 ? "s" : ""
|
135
|
+
frags << "#{n} #{u.to_s + plural}"
|
136
|
+
|
137
|
+
# If the argument passed into ago() is a symbol, focus the ago statement
|
138
|
+
# down to the level specified in the symbol
|
139
|
+
if focus.class == Symbol
|
140
|
+
break if u == focus || u == :second
|
141
|
+
elsif focus.class == Fixnum
|
142
|
+
if focus == 0 || u == :second
|
143
|
+
break
|
144
|
+
else
|
145
|
+
focus -= 1
|
146
|
+
end
|
147
|
+
end
|
148
|
+
diff -= n * value
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Der Kommissar
|
153
|
+
frags.size.times do |n|
|
154
|
+
output += frags[n]
|
155
|
+
output += ", " unless n == frags.size - 1
|
156
|
+
end
|
157
|
+
|
158
|
+
return output + "#{tail}"
|
159
|
+
end
|
160
|
+
|
161
|
+
def from_now(opts={})
|
162
|
+
ago(opts)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
class Time
|
169
|
+
include Ago::TimeAgo
|
170
|
+
end
|
171
|
+
|
172
|
+
# Require the Ago::Numbers module
|
173
|
+
require 'numbers'
|
174
|
+
|
175
|
+
class Fixnum
|
176
|
+
include Ago::Numbers
|
177
|
+
end
|
178
|
+
|
179
|
+
class Bignum
|
180
|
+
include Ago::Numbers
|
181
|
+
end
|
182
|
+
|
183
|
+
class Float
|
184
|
+
include Ago::Numbers
|
185
|
+
end
|
data/lib/numbers.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
|
2
|
+
module Ago
|
3
|
+
module Ago::Numbers
|
4
|
+
|
5
|
+
def ago
|
6
|
+
return Time.now - self
|
7
|
+
end
|
8
|
+
|
9
|
+
def from_now
|
10
|
+
return Time.now + self
|
11
|
+
end
|
12
|
+
|
13
|
+
def years(opts={})
|
14
|
+
calendar = opts[:calendar] ? opts[:calendar] : :basic
|
15
|
+
Ago.calendar_check(calendar)
|
16
|
+
|
17
|
+
self * Ago::Units[:year][calendar]
|
18
|
+
end
|
19
|
+
|
20
|
+
def year(opts={})
|
21
|
+
years(opts)
|
22
|
+
end
|
23
|
+
|
24
|
+
def months(opts={})
|
25
|
+
calendar = opts[:calendar] ? opts[:calendar] : :basic
|
26
|
+
Ago.calendar_check(calendar)
|
27
|
+
|
28
|
+
self * Ago::Units[:month][calendar]
|
29
|
+
end
|
30
|
+
|
31
|
+
def month(opts={})
|
32
|
+
months(opts)
|
33
|
+
end
|
34
|
+
|
35
|
+
def weeks(opts={})
|
36
|
+
calendar = opts[:calendar] ? opts[:calendar] : :basic
|
37
|
+
Ago.calendar_check(calendar)
|
38
|
+
|
39
|
+
self * Ago::Units[:week][calendar]
|
40
|
+
end
|
41
|
+
|
42
|
+
def week(opts={})
|
43
|
+
weeks(opts)
|
44
|
+
end
|
45
|
+
|
46
|
+
def days
|
47
|
+
self * Ago::Units[:day][:basic]
|
48
|
+
end
|
49
|
+
|
50
|
+
def day
|
51
|
+
days
|
52
|
+
end
|
53
|
+
|
54
|
+
def hours
|
55
|
+
self * Ago::Units[:hour][:basic]
|
56
|
+
end
|
57
|
+
|
58
|
+
def hour
|
59
|
+
hours
|
60
|
+
end
|
61
|
+
|
62
|
+
def minutes
|
63
|
+
self * Ago::Units[:minute][:basic]
|
64
|
+
end
|
65
|
+
|
66
|
+
def minute
|
67
|
+
minutes
|
68
|
+
end
|
69
|
+
|
70
|
+
def seconds
|
71
|
+
self * Ago::Units[:second][:basic]
|
72
|
+
end
|
73
|
+
|
74
|
+
def second
|
75
|
+
seconds
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
data/test/test_ago.rb
ADDED
metadata
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ago
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike Zazaian
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-06-20 00:00:00 +10:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hoe
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.12.2
|
24
|
+
version:
|
25
|
+
description: Allows easy conversion of Time objects to human-readable format.
|
26
|
+
email:
|
27
|
+
- zazaian@gmail.com
|
28
|
+
executables:
|
29
|
+
- ago
|
30
|
+
extensions: []
|
31
|
+
|
32
|
+
extra_rdoc_files:
|
33
|
+
- History.txt
|
34
|
+
- Manifest.txt
|
35
|
+
- README.txt
|
36
|
+
files:
|
37
|
+
- .autotest
|
38
|
+
- History.txt
|
39
|
+
- Manifest.txt
|
40
|
+
- README.txt
|
41
|
+
- Rakefile
|
42
|
+
- bin/ago
|
43
|
+
- lib/ago.rb
|
44
|
+
- lib/numbers.rb
|
45
|
+
- test/test_ago.rb
|
46
|
+
has_rdoc: true
|
47
|
+
homepage: Easy conversion of Time objects to human-readable format.
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options:
|
50
|
+
- --main
|
51
|
+
- README.txt
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project: ago
|
69
|
+
rubygems_version: 1.2.0
|
70
|
+
signing_key:
|
71
|
+
specification_version: 2
|
72
|
+
summary: Allows easy conversion of Time objects to human-readable format.
|
73
|
+
test_files:
|
74
|
+
- test/test_ago.rb
|