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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -3
  3. data/.travis.yml +8 -0
  4. data/HISTORY.md +69 -0
  5. data/README.md +47 -42
  6. data/Rakefile +28 -8
  7. data/chronic.gemspec +9 -3
  8. data/lib/chronic.rb +113 -74
  9. data/lib/chronic/date.rb +82 -0
  10. data/lib/chronic/grabber.rb +9 -7
  11. data/lib/chronic/handler.rb +47 -40
  12. data/lib/chronic/handlers.rb +210 -28
  13. data/lib/chronic/numerizer.rb +11 -2
  14. data/lib/chronic/ordinal.rb +28 -23
  15. data/lib/chronic/parser.rb +268 -0
  16. data/lib/chronic/pointer.rb +9 -7
  17. data/lib/chronic/repeater.rb +58 -48
  18. data/lib/chronic/repeaters/repeater_day.rb +4 -3
  19. data/lib/chronic/repeaters/repeater_day_name.rb +5 -4
  20. data/lib/chronic/repeaters/repeater_day_portion.rb +29 -14
  21. data/lib/chronic/repeaters/repeater_fortnight.rb +4 -3
  22. data/lib/chronic/repeaters/repeater_hour.rb +4 -3
  23. data/lib/chronic/repeaters/repeater_minute.rb +4 -3
  24. data/lib/chronic/repeaters/repeater_month.rb +5 -4
  25. data/lib/chronic/repeaters/repeater_month_name.rb +4 -3
  26. data/lib/chronic/repeaters/repeater_season.rb +5 -3
  27. data/lib/chronic/repeaters/repeater_second.rb +4 -3
  28. data/lib/chronic/repeaters/repeater_time.rb +35 -25
  29. data/lib/chronic/repeaters/repeater_week.rb +4 -3
  30. data/lib/chronic/repeaters/repeater_weekday.rb +4 -3
  31. data/lib/chronic/repeaters/repeater_weekend.rb +4 -3
  32. data/lib/chronic/repeaters/repeater_year.rb +5 -4
  33. data/lib/chronic/scalar.rb +40 -68
  34. data/lib/chronic/season.rb +1 -12
  35. data/lib/chronic/separator.rb +142 -23
  36. data/lib/chronic/sign.rb +49 -0
  37. data/lib/chronic/span.rb +2 -2
  38. data/lib/chronic/tag.rb +10 -15
  39. data/lib/chronic/time.rb +40 -0
  40. data/lib/chronic/time_zone.rb +9 -7
  41. data/lib/chronic/token.rb +16 -10
  42. data/test/helper.rb +7 -1
  43. data/test/{test_Chronic.rb → test_chronic.rb} +69 -34
  44. data/test/{test_DaylightSavings.rb → test_daylight_savings.rb} +1 -1
  45. data/test/{test_Handler.rb → test_handler.rb} +38 -14
  46. data/test/{test_MiniDate.rb → test_mini_date.rb} +9 -9
  47. data/test/{test_Numerizer.rb → test_numerizer.rb} +16 -2
  48. data/test/test_parsing.rb +367 -18
  49. data/test/{test_RepeaterDayName.rb → test_repeater_day_name.rb} +1 -1
  50. data/test/test_repeater_day_portion.rb +254 -0
  51. data/test/{test_RepeaterFortnight.rb → test_repeater_fortnight.rb} +1 -1
  52. data/test/{test_RepeaterHour.rb → test_repeater_hour.rb} +1 -1
  53. data/test/{test_RepeaterMinute.rb → test_repeater_minute.rb} +1 -1
  54. data/test/{test_RepeaterMonth.rb → test_repeater_month.rb} +1 -1
  55. data/test/{test_RepeaterMonthName.rb → test_repeater_month_name.rb} +1 -1
  56. data/test/{test_RepeaterSeason.rb → test_repeater_season.rb} +1 -1
  57. data/test/{test_RepeaterTime.rb → test_repeater_time.rb} +19 -1
  58. data/test/{test_RepeaterWeek.rb → test_repeater_week.rb} +1 -1
  59. data/test/{test_RepeaterWeekday.rb → test_repeater_weekday.rb} +1 -1
  60. data/test/{test_RepeaterWeekend.rb → test_repeater_weekend.rb} +1 -1
  61. data/test/{test_RepeaterYear.rb → test_repeater_year.rb} +1 -1
  62. data/test/{test_Span.rb → test_span.rb} +2 -2
  63. data/test/{test_Token.rb → test_token.rb} +1 -1
  64. metadata +107 -46
  65. data/.gemtest +0 -0
  66. data/.yardopts +0 -3
  67. data/lib/chronic/chronic.rb +0 -325
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9e20903b5e5e074b8d546e3bf1b61c8f8d0c0544
4
- data.tar.gz: ed722dfbd01535a516d80b8e97e9afb353f12b11
3
+ metadata.gz: 64794a6186c6495e6c7e10a36f6a144314e989c4
4
+ data.tar.gz: dea5dd4fa693f047fe6be705ec6d42371d4231e1
5
5
  SHA512:
6
- metadata.gz: 6c88b96d1239245f3162ad1dfe5b618e206b331300a69cb0457200be0ef84669cc8d0c199c189bee6e4b74c1f6fd5ae2a11618149de4a0d7d210f02be1570308
7
- data.tar.gz: 81105ef5ab26321e3e4350fb9f8342eea33c172462c4610d1d3d49959761cb12aabba471b12b903a1d3538bb4f97957636c61073f73382d0928640368c9a215a
6
+ metadata.gz: 3134feb1bee6ff0a14244742e39a30c309755e54b871c5ec11c8405fbded5f3c086f005f2f16707e82050ecfa6090fd3300a6565e2e0d5fb198a47cbd48d8c7c
7
+ data.tar.gz: b4c753fe1c44c66dd7d56f4f943cdb71e7ba19f410db75f1bd035f5e383a4499d633fc6fc562f22921b8e297dbc2234509a6122db0388adeef077b1ce1d05178
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
- pkg
2
1
  *.rbc
3
- rdoc
4
2
  .yardoc
5
- doc
3
+ /pkg/
4
+ /coverage/
5
+ /doc/
6
+ /tags/
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.9.2
5
+ - 1.8.7
6
+ - jruby-19mode
7
+ - jruby-18mode
8
+ - rbx-19mode
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
- ## INSTALLATION
11
-
12
- ### RubyGems
13
-
14
- $ [sudo] gem install chronic
9
+ ```
10
+ $ gem install chronic
11
+ ```
15
12
 
16
- ### GitHub
13
+ ## Usage
17
14
 
18
- $ git clone git://github.com/mojombo/chronic.git
19
- $ cd chronic && gem build chronic.gemspec
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
- ## USAGE
20
+ Chronic.parse('tomorrow')
21
+ #=> Mon Aug 28 12:00:00 PDT 2006
24
22
 
25
- You can parse strings containing a natural language date using the
26
- `Chronic.parse` method.
23
+ Chronic.parse('monday', :context => :past)
24
+ #=> Mon Aug 21 12:00:00 PDT 2006
27
25
 
28
- require 'chronic'
26
+ Chronic.parse('this tuesday 5:00')
27
+ #=> Tue Aug 29 17:00:00 PDT 2006
29
28
 
30
- Time.now #=> Sun Aug 27 23:18:25 PDT 2006
29
+ Chronic.parse('this tuesday 5:00', :ambiguous_time_range => :none)
30
+ #=> Tue Aug 29 05:00:00 PDT 2006
31
31
 
32
- Chronic.parse('tomorrow')
33
- #=> Mon Aug 28 12:00:00 PDT 2006
32
+ Chronic.parse('may 27th', :now => Time.local(2000, 1, 1))
33
+ #=> Sat May 27 12:00:00 PDT 2000
34
34
 
35
- Chronic.parse('monday', :context => :past)
36
- #=> Mon Aug 21 12:00:00 PDT 2006
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
- Chronic.parse('this tuesday 5:00')
39
- #=> Tue Aug 29 17:00:00 PDT 2006
38
+ Chronic.parse('6/4/2012', :endian_precedence => :little)
39
+ #=> Fri Apr 06 00:00:00 PDT 2012
40
40
 
41
- Chronic.parse('this tuesday 5:00', :ambiguous_time_range => :none)
42
- #=> Tue Aug 29 05:00:00 PDT 2006
41
+ Chronic.parse('INVALID DATE')
42
+ #=> nil
43
+ ```
43
44
 
44
- Chronic.parse('may 27th', :now => Time.local(2000, 1, 1))
45
- #=> Sat May 27 12:00:00 PDT 2000
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
- ## TIME ZONES
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
- >> Time.zone = "UTC"
146
- >> Chronic.time_class = Time.zone
147
- >> Chronic.parse("June 15 2006 at 5:45 AM")
148
- => Thu, 15 Jun 2006 05:45:00 UTC +00:00
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
- ## LIMITATIONS
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
- ## CONTRIBUTE
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
- To get all of the dependencies, install the gem first. The best way to get
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
- task :test do
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
- desc "Generate RCov test coverage and open in your browser"
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 'rcov'
16
- sh "rm -fr coverage"
17
- sh "rcov test/test_*.rb"
18
- sh "open coverage/index.html"
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
- sh "mkdir -p pkg"
61
+ FileUtils.mkdir_p "pkg"
42
62
  sh "gem build chronic.gemspec"
43
- sh "mv chronic-#{version}.gem pkg"
63
+ FileUtils.mv("./chronic-#{version}.gem", "pkg")
44
64
  end
45
65
 
46
66
  task :default => :test
@@ -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', 'lee@jarvis.co']
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("\n")
16
- s.test_files = `git ls-files -- test`.split("\n")
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
@@ -1,9 +1,48 @@
1
1
  require 'time'
2
2
  require 'date'
3
3
 
4
- # Parse natural language dates and times into Time or {Chronic::Span} objects
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.6.4.2"
56
+ VERSION = "0.10.2.1"
32
57
 
33
58
  class << self
34
59
 
35
- # @return [Boolean] true when debug mode is enabled
60
+ # Returns true when debug mode is enabled.
36
61
  attr_accessor :debug
37
62
 
38
- # @example
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
- # @return [Time] The time class Chronic uses internally
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
- end
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
- class Time
109
- def self.construct(year, month = 1, day = 1, hour = 0, minute = 0, second = 0)
110
- warn "Chronic.construct will be deprecated in version 0.7.0. Please use Chronic.construct instead"
111
- Chronic.construct(year, month, day, hour, minute, second)
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
- def to_minidate
115
- warn "Time.to_minidate will be deprecated in version 0.7.0. Please use Chronic::MiniDate.from_time(time) instead"
116
- Chronic::MiniDate.from_time(self)
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