chronic-mmlac 0.6.4.2 → 0.10.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -3
- data/.travis.yml +8 -0
- data/HISTORY.md +69 -0
- data/README.md +47 -42
- data/Rakefile +28 -8
- data/chronic.gemspec +9 -3
- data/lib/chronic.rb +113 -74
- data/lib/chronic/date.rb +82 -0
- data/lib/chronic/grabber.rb +9 -7
- data/lib/chronic/handler.rb +47 -40
- data/lib/chronic/handlers.rb +210 -28
- data/lib/chronic/numerizer.rb +11 -2
- data/lib/chronic/ordinal.rb +28 -23
- data/lib/chronic/parser.rb +268 -0
- data/lib/chronic/pointer.rb +9 -7
- data/lib/chronic/repeater.rb +58 -48
- data/lib/chronic/repeaters/repeater_day.rb +4 -3
- data/lib/chronic/repeaters/repeater_day_name.rb +5 -4
- data/lib/chronic/repeaters/repeater_day_portion.rb +29 -14
- data/lib/chronic/repeaters/repeater_fortnight.rb +4 -3
- data/lib/chronic/repeaters/repeater_hour.rb +4 -3
- data/lib/chronic/repeaters/repeater_minute.rb +4 -3
- data/lib/chronic/repeaters/repeater_month.rb +5 -4
- data/lib/chronic/repeaters/repeater_month_name.rb +4 -3
- data/lib/chronic/repeaters/repeater_season.rb +5 -3
- data/lib/chronic/repeaters/repeater_second.rb +4 -3
- data/lib/chronic/repeaters/repeater_time.rb +35 -25
- data/lib/chronic/repeaters/repeater_week.rb +4 -3
- data/lib/chronic/repeaters/repeater_weekday.rb +4 -3
- data/lib/chronic/repeaters/repeater_weekend.rb +4 -3
- data/lib/chronic/repeaters/repeater_year.rb +5 -4
- data/lib/chronic/scalar.rb +40 -68
- data/lib/chronic/season.rb +1 -12
- data/lib/chronic/separator.rb +142 -23
- data/lib/chronic/sign.rb +49 -0
- data/lib/chronic/span.rb +2 -2
- data/lib/chronic/tag.rb +10 -15
- data/lib/chronic/time.rb +40 -0
- data/lib/chronic/time_zone.rb +9 -7
- data/lib/chronic/token.rb +16 -10
- data/test/helper.rb +7 -1
- data/test/{test_Chronic.rb → test_chronic.rb} +69 -34
- data/test/{test_DaylightSavings.rb → test_daylight_savings.rb} +1 -1
- data/test/{test_Handler.rb → test_handler.rb} +38 -14
- data/test/{test_MiniDate.rb → test_mini_date.rb} +9 -9
- data/test/{test_Numerizer.rb → test_numerizer.rb} +16 -2
- data/test/test_parsing.rb +367 -18
- data/test/{test_RepeaterDayName.rb → test_repeater_day_name.rb} +1 -1
- data/test/test_repeater_day_portion.rb +254 -0
- data/test/{test_RepeaterFortnight.rb → test_repeater_fortnight.rb} +1 -1
- data/test/{test_RepeaterHour.rb → test_repeater_hour.rb} +1 -1
- data/test/{test_RepeaterMinute.rb → test_repeater_minute.rb} +1 -1
- data/test/{test_RepeaterMonth.rb → test_repeater_month.rb} +1 -1
- data/test/{test_RepeaterMonthName.rb → test_repeater_month_name.rb} +1 -1
- data/test/{test_RepeaterSeason.rb → test_repeater_season.rb} +1 -1
- data/test/{test_RepeaterTime.rb → test_repeater_time.rb} +19 -1
- data/test/{test_RepeaterWeek.rb → test_repeater_week.rb} +1 -1
- data/test/{test_RepeaterWeekday.rb → test_repeater_weekday.rb} +1 -1
- data/test/{test_RepeaterWeekend.rb → test_repeater_weekend.rb} +1 -1
- data/test/{test_RepeaterYear.rb → test_repeater_year.rb} +1 -1
- data/test/{test_Span.rb → test_span.rb} +2 -2
- data/test/{test_Token.rb → test_token.rb} +1 -1
- metadata +107 -46
- data/.gemtest +0 -0
- data/.yardopts +0 -3
- data/lib/chronic/chronic.rb +0 -325
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64794a6186c6495e6c7e10a36f6a144314e989c4
|
4
|
+
data.tar.gz: dea5dd4fa693f047fe6be705ec6d42371d4231e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3134feb1bee6ff0a14244742e39a30c309755e54b871c5ec11c8405fbded5f3c086f005f2f16707e82050ecfa6090fd3300a6565e2e0d5fb198a47cbd48d8c7c
|
7
|
+
data.tar.gz: b4c753fe1c44c66dd7d56f4f943cdb71e7ba19f410db75f1bd035f5e383a4499d633fc6fc562f22921b8e297dbc2234509a6122db0388adeef077b1ce1d05178
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/HISTORY.md
CHANGED
@@ -1,3 +1,72 @@
|
|
1
|
+
# 0.10.2 / 2013-09-09
|
2
|
+
|
3
|
+
* Fix 1.8.7 support (due to be dropped in 0.11.0)
|
4
|
+
* Bugfix for times with negative zones
|
5
|
+
|
6
|
+
# 0.10.1 / 2013-08-27
|
7
|
+
|
8
|
+
* Support `ActiveSupport::TimeZone` (#209, #208)
|
9
|
+
|
10
|
+
# 0.10.0 / 2013-08-25
|
11
|
+
|
12
|
+
* Chronic will parse subseconds correctly
|
13
|
+
for all supported date/time formats (#195, #198 and #200)
|
14
|
+
* Support for date format: dd.mm.yyyy (#197)
|
15
|
+
* Option `:hours24` to parse as 24 hour clock (#201 and #202)
|
16
|
+
* `:guess` option allows to specify which part of Span to return.
|
17
|
+
(accepted values `false`,`true`,`:begin`, `:middle`, `:end`)
|
18
|
+
* Replace `rcov` with `SimpleCov` for coverage generation
|
19
|
+
* Add more tests
|
20
|
+
* Various changes in codebase (#202 and #206)
|
21
|
+
|
22
|
+
# 0.9.1 / 2013-02-25
|
23
|
+
|
24
|
+
* Ensure Chronic strips periods from day portions (#173)
|
25
|
+
* Properly numerize "twelfth", "twentieth" etc. (#172, James McKinney)
|
26
|
+
* Ensure Chronic is compatible with Ruby 2.0.0 (#165, Ravil Bayramgalin)
|
27
|
+
|
28
|
+
# 0.9.0 / 2012-12-21
|
29
|
+
|
30
|
+
* Implement Chronic::Parser class and create an instance of this class
|
31
|
+
instead of leaving all data in the class level of Chronic
|
32
|
+
* Various bug fixes
|
33
|
+
* Add support for excel date formats (#149, @jmondo)
|
34
|
+
* Added support for time expressions such as '10 till' or 'half
|
35
|
+
past two' (#146, @chicagogrooves)
|
36
|
+
* Add support for RepeaterDayName, RepeaterMonthName,
|
37
|
+
Ordinal/ScalarDay and Time (#153, @kareemk)
|
38
|
+
|
39
|
+
# 0.8.0 / 2012-09-16
|
40
|
+
|
41
|
+
* Support parsing "<ordinal> of this month" (#109)
|
42
|
+
* Support parsing ISO 8601 format (#115)
|
43
|
+
* Support parsing "on <day>" without a timestamp (#117)
|
44
|
+
* Fix time parsing regexp (#125)
|
45
|
+
* Support time when parsing dd-mm-yyy <time> (#126)
|
46
|
+
* Allow anchor handler to accept any separators (at, on) (#128)
|
47
|
+
* Support parsing EXIF date format (#112)
|
48
|
+
* Start using minitest for testing
|
49
|
+
* Ensure periods are interpreted as colons (#81).
|
50
|
+
* Support month/day and day/month parsing (#59).
|
51
|
+
* Support day(scalar)-month(name)-year(scalar) (#99).
|
52
|
+
* Handle text starting with 'a' or 'an' (#101, @steveburkett).
|
53
|
+
* Ensure post medium timestamps are correctly formatted (#89)
|
54
|
+
|
55
|
+
# 0.6.7 / 2012-01-31
|
56
|
+
|
57
|
+
* Handle day, month names with scalar day and year (Joe Fiorini)
|
58
|
+
* Ensure 31st parses correctly with day names (Joe Fiorini)
|
59
|
+
|
60
|
+
# 0.6.6 / 2011-11-23
|
61
|
+
|
62
|
+
* `Chronic.parse('thur')` no longer returns `nil` (@harold)
|
63
|
+
|
64
|
+
# 0.6.5 / 2011-11-04
|
65
|
+
|
66
|
+
* Fix bug when parsing ordinal repeaters (#73)
|
67
|
+
* Added handler support for day_name month_name (@imme5150)
|
68
|
+
* Fix bug when parsing strings prefixed with PM
|
69
|
+
|
1
70
|
# 0.6.4 / 2011-08-08
|
2
71
|
|
3
72
|
* Fixed bug where 'noon' was parsed as 00:00 rather than 12:00
|
data/README.md
CHANGED
@@ -1,56 +1,54 @@
|
|
1
1
|
Chronic
|
2
2
|
=======
|
3
3
|
|
4
|
-
## DESCRIPTION
|
5
|
-
|
6
4
|
Chronic is a natural language date/time parser written in pure Ruby. See below
|
7
5
|
for the wide variety of formats Chronic will parse.
|
8
6
|
|
7
|
+
## Installation
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
$ [sudo] gem install chronic
|
9
|
+
```
|
10
|
+
$ gem install chronic
|
11
|
+
```
|
15
12
|
|
16
|
-
|
13
|
+
## Usage
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
$ gem install chronic-<version>.gem
|
15
|
+
```ruby
|
16
|
+
require 'chronic'
|
21
17
|
|
18
|
+
Time.now #=> Sun Aug 27 23:18:25 PDT 2006
|
22
19
|
|
23
|
-
|
20
|
+
Chronic.parse('tomorrow')
|
21
|
+
#=> Mon Aug 28 12:00:00 PDT 2006
|
24
22
|
|
25
|
-
|
26
|
-
|
23
|
+
Chronic.parse('monday', :context => :past)
|
24
|
+
#=> Mon Aug 21 12:00:00 PDT 2006
|
27
25
|
|
28
|
-
|
26
|
+
Chronic.parse('this tuesday 5:00')
|
27
|
+
#=> Tue Aug 29 17:00:00 PDT 2006
|
29
28
|
|
30
|
-
|
29
|
+
Chronic.parse('this tuesday 5:00', :ambiguous_time_range => :none)
|
30
|
+
#=> Tue Aug 29 05:00:00 PDT 2006
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
Chronic.parse('may 27th', :now => Time.local(2000, 1, 1))
|
33
|
+
#=> Sat May 27 12:00:00 PDT 2000
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
Chronic.parse('may 27th', :guess => false)
|
36
|
+
#=> Sun May 27 00:00:00 PDT 2007..Mon May 28 00:00:00 PDT 2007
|
37
37
|
|
38
|
-
|
39
|
-
|
38
|
+
Chronic.parse('6/4/2012', :endian_precedence => :little)
|
39
|
+
#=> Fri Apr 06 00:00:00 PDT 2012
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
Chronic.parse('INVALID DATE')
|
42
|
+
#=> nil
|
43
|
+
```
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
Chronic.parse('may 27th', :guess => false)
|
48
|
-
#=> Sun May 27 00:00:00 PDT 2007..Mon May 28 00:00:00 PDT 2007
|
45
|
+
If the parser can find a date or time, either a Time or Chronic::Span
|
46
|
+
will be returned (depending on the value of `:guess`). If no
|
47
|
+
date or time can be found, `nil` will be returned.
|
49
48
|
|
50
49
|
See `Chronic.parse` for detailed usage instructions.
|
51
50
|
|
52
|
-
|
53
|
-
## EXAMPLES
|
51
|
+
## Examples
|
54
52
|
|
55
53
|
Chronic can parse a huge variety of date and time formats. Following is a
|
56
54
|
small sample of strings that will be properly parsed. Parsing is case
|
@@ -64,12 +62,17 @@ Simple
|
|
64
62
|
* friday 13:00
|
65
63
|
* mon 2:35
|
66
64
|
* 4pm
|
65
|
+
* 10 to 8
|
66
|
+
* 10 past 2
|
67
|
+
* half past 2
|
67
68
|
* 6 in the morning
|
68
69
|
* friday 1pm
|
69
70
|
* sat 7 in the evening
|
70
71
|
* yesterday
|
71
72
|
* today
|
72
73
|
* tomorrow
|
74
|
+
* last week
|
75
|
+
* next week
|
73
76
|
* this tuesday
|
74
77
|
* next month
|
75
78
|
* last winter
|
@@ -86,6 +89,7 @@ Simple
|
|
86
89
|
Complex
|
87
90
|
|
88
91
|
* 3 years ago
|
92
|
+
* a year ago
|
89
93
|
* 5 months before now
|
90
94
|
* 7 hours ago
|
91
95
|
* 7 days from now
|
@@ -131,10 +135,11 @@ Specific Times (many of the above with an added time)
|
|
131
135
|
* January 5 at 7pm
|
132
136
|
* 22nd of june at 8am
|
133
137
|
* 1979-05-27 05:00:00
|
138
|
+
* 03/01/2012 07:25:09.234567
|
134
139
|
* etc
|
135
140
|
|
136
141
|
|
137
|
-
##
|
142
|
+
## Time Zones
|
138
143
|
|
139
144
|
Chronic allows you to set which Time class to use when constructing times. By
|
140
145
|
default, the built in Ruby time class creates times in your system's local
|
@@ -142,13 +147,14 @@ time zone. You can set this to something like ActiveSupport's
|
|
142
147
|
[TimeZone](http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html)
|
143
148
|
class to get full time zone support.
|
144
149
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
+
```
|
151
|
+
>> Time.zone = "UTC"
|
152
|
+
>> Chronic.time_class = Time.zone
|
153
|
+
>> Chronic.parse("June 15 2006 at 5:45 AM")
|
154
|
+
=> Thu, 15 Jun 2006 05:45:00 UTC +00:00
|
155
|
+
```
|
150
156
|
|
151
|
-
##
|
157
|
+
## Limitations
|
152
158
|
|
153
159
|
Chronic uses Ruby's built in Time class for all time storage and computation.
|
154
160
|
Because of this, only times that the Time class can handle will be properly
|
@@ -156,20 +162,19 @@ parsed. Parsing for times outside of this range will simply return nil.
|
|
156
162
|
Support for a wider range of times is planned for a future release.
|
157
163
|
|
158
164
|
|
159
|
-
##
|
165
|
+
## Contribute
|
160
166
|
|
161
167
|
If you'd like to hack on Chronic, start by forking the repo on GitHub:
|
162
168
|
|
163
169
|
https://github.com/mojombo/chronic
|
164
170
|
|
165
|
-
|
166
|
-
your changes merged back into core is as follows:
|
171
|
+
The best way to get your changes merged back into core is as follows:
|
167
172
|
|
168
173
|
1. Clone down your fork
|
169
174
|
1. Create a thoughtfully named topic branch to contain your change
|
170
175
|
1. Hack away
|
171
176
|
1. Add tests and make sure everything still passes by running `rake`
|
172
|
-
1. Ensure your tests pass in multiple timezones
|
177
|
+
1. Ensure your tests pass in multiple timezones. ie `TZ=utc rake` `TZ=BST rake`
|
173
178
|
1. If you are adding new functionality, document it in the README
|
174
179
|
1. Do not change the version number, we will do that on our end
|
175
180
|
1. If necessary, rebase your commits into logical chunks, without errors
|
data/Rakefile
CHANGED
@@ -5,17 +5,37 @@ def version
|
|
5
5
|
contents[/VERSION = "([^"]+)"/, 1]
|
6
6
|
end
|
7
7
|
|
8
|
-
|
8
|
+
def do_test
|
9
9
|
$:.unshift './test'
|
10
10
|
Dir.glob('test/test_*.rb').each { |t| require File.basename(t) }
|
11
11
|
end
|
12
12
|
|
13
|
-
|
13
|
+
def open_command
|
14
|
+
case RUBY_PLATFORM
|
15
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
16
|
+
'start'
|
17
|
+
when /darwin|mac os/
|
18
|
+
'open'
|
19
|
+
else
|
20
|
+
'xdg-open'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
task :test do
|
25
|
+
do_test
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Generate SimpleCov test coverage and open in your browser"
|
14
29
|
task :coverage do
|
15
|
-
require '
|
16
|
-
|
17
|
-
|
18
|
-
|
30
|
+
require 'simplecov'
|
31
|
+
FileUtils.rm_rf("./coverage")
|
32
|
+
SimpleCov.command_name 'Unit Tests'
|
33
|
+
SimpleCov.at_exit do
|
34
|
+
SimpleCov.result.format!
|
35
|
+
sh "#{open_command} #{SimpleCov.coverage_path}/index.html"
|
36
|
+
end
|
37
|
+
SimpleCov.start
|
38
|
+
do_test
|
19
39
|
end
|
20
40
|
|
21
41
|
desc "Open an irb session preloaded with this library"
|
@@ -38,9 +58,9 @@ end
|
|
38
58
|
|
39
59
|
desc "Build a gem from the gemspec"
|
40
60
|
task :build do
|
41
|
-
|
61
|
+
FileUtils.mkdir_p "pkg"
|
42
62
|
sh "gem build chronic.gemspec"
|
43
|
-
|
63
|
+
FileUtils.mv("./chronic-#{version}.gem", "pkg")
|
44
64
|
end
|
45
65
|
|
46
66
|
task :default => :test
|
data/chronic.gemspec
CHANGED
@@ -8,10 +8,16 @@ Gem::Specification.new do |s|
|
|
8
8
|
s.summary = 'Natural language date/time parsing.'
|
9
9
|
s.description = 'Chronic is a natural language date/time parser written in pure Ruby.'
|
10
10
|
s.authors = ['Tom Preston-Werner', 'Lee Jarvis']
|
11
|
-
s.email = ['tom@mojombo.com', '
|
11
|
+
s.email = ['tom@mojombo.com', 'ljjarvis@gmail.com']
|
12
12
|
s.homepage = 'http://github.com/mojombo/chronic'
|
13
|
+
s.license = 'MIT'
|
13
14
|
s.rdoc_options = ['--charset=UTF-8']
|
14
15
|
s.extra_rdoc_files = %w[README.md HISTORY.md LICENSE]
|
15
|
-
s.files = `git ls-files`.split(
|
16
|
-
s.test_files = `git ls-files -- test`.split(
|
16
|
+
s.files = `git ls-files`.split($/)
|
17
|
+
s.test_files = `git ls-files -- test`.split($/)
|
18
|
+
|
19
|
+
s.add_development_dependency 'rake'
|
20
|
+
s.add_development_dependency 'simplecov'
|
21
|
+
s.add_development_dependency 'minitest', '~> 5.0'
|
22
|
+
s.add_development_dependency 'activesupport'
|
17
23
|
end
|
data/lib/chronic.rb
CHANGED
@@ -1,9 +1,48 @@
|
|
1
1
|
require 'time'
|
2
2
|
require 'date'
|
3
3
|
|
4
|
-
|
4
|
+
require 'chronic/parser'
|
5
|
+
require 'chronic/date'
|
6
|
+
require 'chronic/time'
|
7
|
+
|
8
|
+
require 'chronic/handler'
|
9
|
+
require 'chronic/handlers'
|
10
|
+
require 'chronic/mini_date'
|
11
|
+
require 'chronic/tag'
|
12
|
+
require 'chronic/span'
|
13
|
+
require 'chronic/token'
|
14
|
+
require 'chronic/grabber'
|
15
|
+
require 'chronic/pointer'
|
16
|
+
require 'chronic/scalar'
|
17
|
+
require 'chronic/ordinal'
|
18
|
+
require 'chronic/separator'
|
19
|
+
require 'chronic/sign'
|
20
|
+
require 'chronic/time_zone'
|
21
|
+
require 'chronic/numerizer'
|
22
|
+
require 'chronic/season'
|
23
|
+
|
24
|
+
require 'chronic/repeater'
|
25
|
+
require 'chronic/repeaters/repeater_year'
|
26
|
+
require 'chronic/repeaters/repeater_season'
|
27
|
+
require 'chronic/repeaters/repeater_season_name'
|
28
|
+
require 'chronic/repeaters/repeater_month'
|
29
|
+
require 'chronic/repeaters/repeater_month_name'
|
30
|
+
require 'chronic/repeaters/repeater_fortnight'
|
31
|
+
require 'chronic/repeaters/repeater_week'
|
32
|
+
require 'chronic/repeaters/repeater_weekend'
|
33
|
+
require 'chronic/repeaters/repeater_weekday'
|
34
|
+
require 'chronic/repeaters/repeater_day'
|
35
|
+
require 'chronic/repeaters/repeater_day_name'
|
36
|
+
require 'chronic/repeaters/repeater_day_portion'
|
37
|
+
require 'chronic/repeaters/repeater_hour'
|
38
|
+
require 'chronic/repeaters/repeater_minute'
|
39
|
+
require 'chronic/repeaters/repeater_second'
|
40
|
+
require 'chronic/repeaters/repeater_time'
|
41
|
+
|
42
|
+
# Parse natural language dates and times into Time or Chronic::Span objects.
|
43
|
+
#
|
44
|
+
# Examples:
|
5
45
|
#
|
6
|
-
# @example
|
7
46
|
# require 'chronic'
|
8
47
|
#
|
9
48
|
# Time.now #=> Sun Aug 27 23:18:25 PDT 2006
|
@@ -13,29 +52,16 @@ require 'date'
|
|
13
52
|
#
|
14
53
|
# Chronic.parse('monday', :context => :past)
|
15
54
|
# #=> Mon Aug 21 12:00:00 PDT 2006
|
16
|
-
#
|
17
|
-
# Chronic.parse('this tuesday 5:00')
|
18
|
-
# #=> Tue Aug 29 17:00:00 PDT 2006
|
19
|
-
#
|
20
|
-
# Chronic.parse('this tuesday 5:00', :ambiguous_time_range => :none)
|
21
|
-
# #=> Tue Aug 29 05:00:00 PDT 2006
|
22
|
-
#
|
23
|
-
# Chronic.parse('may 27th', :now => Time.local(2000, 1, 1))
|
24
|
-
# #=> Sat May 27 12:00:00 PDT 2000
|
25
|
-
#
|
26
|
-
# Chronic.parse('may 27th', :guess => false)
|
27
|
-
# #=> Sun May 27 00:00:00 PDT 2007..Mon May 28 00:00:00 PDT 2007
|
28
|
-
#
|
29
|
-
# @author Tom Preston-Werner, Lee Jarvis
|
30
55
|
module Chronic
|
31
|
-
VERSION = "0.
|
56
|
+
VERSION = "0.10.2.1"
|
32
57
|
|
33
58
|
class << self
|
34
59
|
|
35
|
-
#
|
60
|
+
# Returns true when debug mode is enabled.
|
36
61
|
attr_accessor :debug
|
37
62
|
|
38
|
-
#
|
63
|
+
# Examples:
|
64
|
+
#
|
39
65
|
# require 'chronic'
|
40
66
|
# require 'active_support/time'
|
41
67
|
#
|
@@ -44,20 +70,7 @@ module Chronic
|
|
44
70
|
# Chronic.parse('June 15 2006 at 5:54 AM')
|
45
71
|
# # => Thu, 15 Jun 2006 05:45:00 UTC +00:00
|
46
72
|
#
|
47
|
-
#
|
48
|
-
attr_accessor :time_class
|
49
|
-
|
50
|
-
# The current Time Chronic is using to base from
|
51
|
-
#
|
52
|
-
# @example
|
53
|
-
# Time.now #=> 2011-06-06 14:13:43 +0100
|
54
|
-
# Chronic.parse('yesterday') #=> 2011-06-05 12:00:00 +0100
|
55
|
-
#
|
56
|
-
# now = Time.local(2025, 12, 24)
|
57
|
-
# Chronic.parse('tomorrow', :now => now) #=> 2025-12-25 12:00:00 +0000
|
58
|
-
#
|
59
|
-
# @return [Time, nil]
|
60
|
-
attr_accessor :now
|
73
|
+
# Returns The Time class Chronic uses internally.
|
61
74
|
|
62
75
|
# To ensure thread safety, this value is thread-local.
|
63
76
|
def time_class
|
@@ -69,50 +82,76 @@ module Chronic
|
|
69
82
|
end
|
70
83
|
|
71
84
|
self.debug = false
|
72
|
-
|
73
|
-
|
74
|
-
require 'chronic/chronic'
|
75
|
-
require 'chronic/handler'
|
76
|
-
require 'chronic/handlers'
|
77
|
-
require 'chronic/mini_date'
|
78
|
-
require 'chronic/tag'
|
79
|
-
require 'chronic/span'
|
80
|
-
require 'chronic/token'
|
81
|
-
require 'chronic/grabber'
|
82
|
-
require 'chronic/pointer'
|
83
|
-
require 'chronic/scalar'
|
84
|
-
require 'chronic/ordinal'
|
85
|
-
require 'chronic/separator'
|
86
|
-
require 'chronic/time_zone'
|
87
|
-
require 'chronic/numerizer'
|
88
|
-
require 'chronic/season'
|
85
|
+
self.time_class = ::Time
|
89
86
|
|
90
|
-
require 'chronic/repeater'
|
91
|
-
require 'chronic/repeaters/repeater_year'
|
92
|
-
require 'chronic/repeaters/repeater_season'
|
93
|
-
require 'chronic/repeaters/repeater_season_name'
|
94
|
-
require 'chronic/repeaters/repeater_month'
|
95
|
-
require 'chronic/repeaters/repeater_month_name'
|
96
|
-
require 'chronic/repeaters/repeater_fortnight'
|
97
|
-
require 'chronic/repeaters/repeater_week'
|
98
|
-
require 'chronic/repeaters/repeater_weekend'
|
99
|
-
require 'chronic/repeaters/repeater_weekday'
|
100
|
-
require 'chronic/repeaters/repeater_day'
|
101
|
-
require 'chronic/repeaters/repeater_day_name'
|
102
|
-
require 'chronic/repeaters/repeater_day_portion'
|
103
|
-
require 'chronic/repeaters/repeater_hour'
|
104
|
-
require 'chronic/repeaters/repeater_minute'
|
105
|
-
require 'chronic/repeaters/repeater_second'
|
106
|
-
require 'chronic/repeaters/repeater_time'
|
107
87
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
88
|
+
# Parses a string containing a natural language date or time.
|
89
|
+
#
|
90
|
+
# If the parser can find a date or time, either a Time or Chronic::Span
|
91
|
+
# will be returned (depending on the value of `:guess`). If no
|
92
|
+
# date or time can be found, `nil` will be returned.
|
93
|
+
#
|
94
|
+
# text - The String text to parse.
|
95
|
+
# opts - An optional Hash of configuration options passed to Parser::new.
|
96
|
+
def self.parse(text, options = {})
|
97
|
+
Parser.new(options).parse(text)
|
112
98
|
end
|
113
99
|
|
114
|
-
|
115
|
-
|
116
|
-
|
100
|
+
# Construct a new time object determining possible month overflows
|
101
|
+
# and leap years.
|
102
|
+
#
|
103
|
+
# year - Integer year.
|
104
|
+
# month - Integer month.
|
105
|
+
# day - Integer day.
|
106
|
+
# hour - Integer hour.
|
107
|
+
# minute - Integer minute.
|
108
|
+
# second - Integer second.
|
109
|
+
#
|
110
|
+
# Returns a new Time object constructed from these params.
|
111
|
+
def self.construct(year, month = 1, day = 1, hour = 0, minute = 0, second = 0, offset = nil)
|
112
|
+
if second >= 60
|
113
|
+
minute += second / 60
|
114
|
+
second = second % 60
|
115
|
+
end
|
116
|
+
|
117
|
+
if minute >= 60
|
118
|
+
hour += minute / 60
|
119
|
+
minute = minute % 60
|
120
|
+
end
|
121
|
+
|
122
|
+
if hour >= 24
|
123
|
+
day += hour / 24
|
124
|
+
hour = hour % 24
|
125
|
+
end
|
126
|
+
|
127
|
+
# determine if there is a day overflow. this is complicated by our crappy calendar
|
128
|
+
# system (non-constant number of days per month)
|
129
|
+
day <= 56 || raise("day must be no more than 56 (makes month resolution easier)")
|
130
|
+
if day > 28 # no month ever has fewer than 28 days, so only do this if necessary
|
131
|
+
days_this_month = ::Date.leap?(year) ? Date::MONTH_DAYS_LEAP[month] : Date::MONTH_DAYS[month]
|
132
|
+
if day > days_this_month
|
133
|
+
month += day / days_this_month
|
134
|
+
day = day % days_this_month
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
if month > 12
|
139
|
+
if month % 12 == 0
|
140
|
+
year += (month - 12) / 12
|
141
|
+
month = 12
|
142
|
+
else
|
143
|
+
year += month / 12
|
144
|
+
month = month % 12
|
145
|
+
end
|
146
|
+
end
|
147
|
+
if Chronic.time_class.name == "Date"
|
148
|
+
Chronic.time_class.new(year, month, day)
|
149
|
+
elsif not Chronic.time_class.respond_to?(:new) or (RUBY_VERSION.to_f < 1.9 and Chronic.time_class.name == "Time")
|
150
|
+
Chronic.time_class.local(year, month, day, hour, minute, second)
|
151
|
+
else
|
152
|
+
offset = Time::normalize_offset(offset) if Chronic.time_class.name == "DateTime"
|
153
|
+
Chronic.time_class.new(year, month, day, hour, minute, second, offset)
|
154
|
+
end
|
117
155
|
end
|
156
|
+
|
118
157
|
end
|