natural_lang_date_parser 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/natural_lang_date_parser.rb +160 -0
- metadata +87 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1c44662a10c410ad6f040fd563fc834d8f138c10
|
4
|
+
data.tar.gz: 9d1fbfb35fbc2d0b2c9351025ee1de11c4266893
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4587d1a7c87734d45138f6458bba12a6adce70a16deb7e0abe4e94851a6d3b1e47b535d1ac9865e332729d43f5bad97faa3cded917b710600fb277b2153c8aad
|
7
|
+
data.tar.gz: 73aae2dd89c1d9e6272350cac351c49014c82442e4fade9d39dbe5d731e5fbacfda62a335bf04b6a0da56f25f262efacbc42e4a11b536aeee06f0aeb54cccf47
|
@@ -0,0 +1,160 @@
|
|
1
|
+
#require "natural_lang_date_parser/version"
|
2
|
+
|
3
|
+
module NaturalLangDateParser
|
4
|
+
require "date"
|
5
|
+
require 'active_support/all'
|
6
|
+
|
7
|
+
EXISTING_PATTERNS = {
|
8
|
+
months: ['january','february','march','may','june','july','august','september', 'october','november','december'],
|
9
|
+
days: ['sunday','monday','tuesday', 'wednesday','thursday','friday','saturday'],
|
10
|
+
past: ["before","ago", 'yesterday', 'last','previous'],
|
11
|
+
future: ['after','later','tomorrow','next', 'in']
|
12
|
+
}
|
13
|
+
class NaturalDateParser
|
14
|
+
|
15
|
+
def initialize(datetime)
|
16
|
+
@current_datetime = DateTime.now
|
17
|
+
@input_params = datetime
|
18
|
+
@formatted_params = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def format_input
|
22
|
+
# removing white spaces at the beginning and the end
|
23
|
+
@input_params.strip()
|
24
|
+
@formatted_params = @input_params.split(" ").map {|x| x.downcase.singularize}
|
25
|
+
# p @formatted_params
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_input
|
29
|
+
# sanitise the input before processing.
|
30
|
+
format_input
|
31
|
+
|
32
|
+
# check if its today
|
33
|
+
if @input_params == 'today'
|
34
|
+
DateTime.now
|
35
|
+
# check if its past
|
36
|
+
elsif !(@formatted_params & EXISTING_PATTERNS[:past]).empty?
|
37
|
+
calculate_past_date
|
38
|
+
# check if its future
|
39
|
+
elsif !(@formatted_params & EXISTING_PATTERNS[:future]).empty?
|
40
|
+
calculate_future_date
|
41
|
+
# Fallback to Ruby Date parser
|
42
|
+
else
|
43
|
+
# replacing noon with 12pm. Further scenarios can be added and moved to a new method in future
|
44
|
+
@input_params.gsub!(/noon/,'12pm')
|
45
|
+
DateTime.parse(@input_params)
|
46
|
+
end
|
47
|
+
rescue
|
48
|
+
puts "Sorry!! Something went wrong while interpreting your input. Pls. check and try again."
|
49
|
+
end
|
50
|
+
|
51
|
+
def calculate_past_date
|
52
|
+
# storing the various parameters
|
53
|
+
past_params = {
|
54
|
+
past_type: nil,
|
55
|
+
past_value: nil,
|
56
|
+
date_type: nil,
|
57
|
+
date_quantity: nil,
|
58
|
+
past_index: nil
|
59
|
+
}
|
60
|
+
|
61
|
+
past_params[:past_value] = @formatted_params & EXISTING_PATTERNS[:past]
|
62
|
+
|
63
|
+
# case for yesterday
|
64
|
+
if past_params[:past_value] && @formatted_params.length == 1
|
65
|
+
calculate_time('days',1,"ago")
|
66
|
+
|
67
|
+
# case for string containing last or previous ( Immediate Past)
|
68
|
+
elsif is_immediate_past?(past_params[:past_value])
|
69
|
+
# Removing preposition like on, at
|
70
|
+
temp_formatted_params = @formatted_params.reject{|item| item == /on|at/i }
|
71
|
+
|
72
|
+
# check if the user is inputing a weekeday
|
73
|
+
if is_weekday? temp_formatted_params[1]
|
74
|
+
Date.today.beginning_of_week(:temp_formatted_params[1])
|
75
|
+
# if its one among year, day, month
|
76
|
+
else
|
77
|
+
calculate_time(temp_formatted_params[1],1,"ago")
|
78
|
+
end
|
79
|
+
|
80
|
+
# case for string containing ago or before etc (non-immediate past)
|
81
|
+
elsif !(past_params[:past_value] & ['ago','before']).empty?
|
82
|
+
temp_formatted_params = @formatted_params.reject{|item| item == /on|at|ago|before/i }
|
83
|
+
|
84
|
+
# Extracting Values
|
85
|
+
past_params[:date_quantity] = temp_formatted_params[0]
|
86
|
+
past_params[:date_type] = temp_formatted_params[1]
|
87
|
+
|
88
|
+
# Calcuate Datetime
|
89
|
+
calculate_time(past_params[:date_type],past_params[:date_quantity].to_i,"ago")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def calculate_future_date
|
94
|
+
# storing the various parameters
|
95
|
+
future_params = {
|
96
|
+
future_type: nil,
|
97
|
+
future_value: nil,
|
98
|
+
date_type: nil,
|
99
|
+
date_quantity: nil,
|
100
|
+
future_index: nil
|
101
|
+
}
|
102
|
+
future_params[:future_value] = @formatted_params & EXISTING_PATTERNS[:future]
|
103
|
+
|
104
|
+
# case for tomorrow
|
105
|
+
if future_params[:future_value] == ["tomorrow"] && @formatted_params.length == 1
|
106
|
+
calculate_time('days',1,"from_now")
|
107
|
+
|
108
|
+
# Case for immediate future
|
109
|
+
elsif is_immediate_future? @formatted_params
|
110
|
+
future_params[:future_type] ='immediate'
|
111
|
+
future_params[:date_type] = @formatted_params[1]
|
112
|
+
|
113
|
+
# check if the user is inputing a weekeday
|
114
|
+
# can be exteneded with options like next full moon, next christmas etc
|
115
|
+
if is_weekday? @formatted_params[1]
|
116
|
+
date_of_next @formatted_params[1]
|
117
|
+
# it its one among year, day, month
|
118
|
+
else
|
119
|
+
calculate_time(@formatted_params[1],1,"from_now")
|
120
|
+
end
|
121
|
+
|
122
|
+
# case for string non-immediate future like 'later','in
|
123
|
+
elsif !(future_params[:future_value] & ['later','in']).empty?
|
124
|
+
future_params[:future_type] = 'future'
|
125
|
+
temp_formatted_params = @formatted_params.reject{|item| item =~ /later|in/i }
|
126
|
+
|
127
|
+
# Extracting Values
|
128
|
+
future_params[:date_quantity] = temp_formatted_params[0]
|
129
|
+
future_params[:date_type] = temp_formatted_params[1]
|
130
|
+
calculate_time(future_params[:date_type],future_params[:date_quantity].to_i,"from_now")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# reutrns if its a valid day of the week
|
135
|
+
def is_weekday?(day)
|
136
|
+
day && (EXISTING_PATTERNS[:days].include? day)
|
137
|
+
end
|
138
|
+
|
139
|
+
# Return the next specific weekeday. Example: next tuesday
|
140
|
+
def date_of_next(day)
|
141
|
+
date = Date.parse(day)
|
142
|
+
delta = date > Date.today ? 0 : 7
|
143
|
+
date + delta
|
144
|
+
end
|
145
|
+
|
146
|
+
def is_immediate_future?(data)
|
147
|
+
data.include? "next"
|
148
|
+
end
|
149
|
+
|
150
|
+
def is_immediate_past?(data)
|
151
|
+
!(data & ['last', 'previous']).empty?
|
152
|
+
end
|
153
|
+
|
154
|
+
def calculate_time(type, quantity, tense)
|
155
|
+
type = type.pluralize
|
156
|
+
quantity.send(type).send(tense)
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: natural_lang_date_parser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sriram R
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.13'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
description: Natural Lang Date Parser for Ruby
|
56
|
+
email:
|
57
|
+
- sriram15690@mail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- lib/natural_lang_date_parser.rb
|
63
|
+
homepage: https://github.com/sriram15690?tab=repositories
|
64
|
+
licenses:
|
65
|
+
- MIT
|
66
|
+
metadata: {}
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
requirements: []
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 2.4.8
|
84
|
+
signing_key:
|
85
|
+
specification_version: 4
|
86
|
+
summary: Natural Lang Date Parser
|
87
|
+
test_files: []
|