1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.jrobin.core.timespec;
26
27 class TimeScanner {
28 private String dateString;
29
30 private int pos, pos_save;
31 private TimeToken token, token_save;
32
33 static final TimeToken[] WORDS = {
34 new TimeToken("midnight", TimeToken.MIDNIGHT),
35 new TimeToken("noon", TimeToken.NOON),
36 new TimeToken("teatime", TimeToken.TEATIME),
37 new TimeToken("am", TimeToken.AM),
38 new TimeToken("pm", TimeToken.PM),
39 new TimeToken("tomorrow", TimeToken.TOMORROW),
40 new TimeToken("yesterday", TimeToken.YESTERDAY),
41 new TimeToken("today", TimeToken.TODAY),
42 new TimeToken("now", TimeToken.NOW),
43 new TimeToken("n", TimeToken.NOW),
44 new TimeToken("start", TimeToken.START),
45 new TimeToken("s", TimeToken.START),
46 new TimeToken("end", TimeToken.END),
47 new TimeToken("e", TimeToken.END),
48 new TimeToken("jan", TimeToken.JAN),
49 new TimeToken("feb", TimeToken.FEB),
50 new TimeToken("mar", TimeToken.MAR),
51 new TimeToken("apr", TimeToken.APR),
52 new TimeToken("may", TimeToken.MAY),
53 new TimeToken("jun", TimeToken.JUN),
54 new TimeToken("jul", TimeToken.JUL),
55 new TimeToken("aug", TimeToken.AUG),
56 new TimeToken("sep", TimeToken.SEP),
57 new TimeToken("oct", TimeToken.OCT),
58 new TimeToken("nov", TimeToken.NOV),
59 new TimeToken("dec", TimeToken.DEC),
60 new TimeToken("january", TimeToken.JAN),
61 new TimeToken("february", TimeToken.FEB),
62 new TimeToken("march", TimeToken.MAR),
63 new TimeToken("april", TimeToken.APR),
64 new TimeToken("may", TimeToken.MAY),
65 new TimeToken("june", TimeToken.JUN),
66 new TimeToken("july", TimeToken.JUL),
67 new TimeToken("august", TimeToken.AUG),
68 new TimeToken("september", TimeToken.SEP),
69 new TimeToken("october", TimeToken.OCT),
70 new TimeToken("november", TimeToken.NOV),
71 new TimeToken("december", TimeToken.DEC),
72 new TimeToken("sunday", TimeToken.SUN),
73 new TimeToken("sun", TimeToken.SUN),
74 new TimeToken("monday", TimeToken.MON),
75 new TimeToken("mon", TimeToken.MON),
76 new TimeToken("tuesday", TimeToken.TUE),
77 new TimeToken("tue", TimeToken.TUE),
78 new TimeToken("wednesday", TimeToken.WED),
79 new TimeToken("wed", TimeToken.WED),
80 new TimeToken("thursday", TimeToken.THU),
81 new TimeToken("thu", TimeToken.THU),
82 new TimeToken("friday", TimeToken.FRI),
83 new TimeToken("fri", TimeToken.FRI),
84 new TimeToken("saturday", TimeToken.SAT),
85 new TimeToken("sat", TimeToken.SAT),
86 new TimeToken(null, 0)
87 };
88
89 static TimeToken[] MULTIPLIERS = {
90 new TimeToken("second", TimeToken.SECONDS),
91 new TimeToken("seconds", TimeToken.SECONDS),
92 new TimeToken("sec", TimeToken.SECONDS),
93 new TimeToken("s", TimeToken.SECONDS),
94 new TimeToken("minute", TimeToken.MINUTES),
95 new TimeToken("minutes", TimeToken.MINUTES),
96 new TimeToken("min", TimeToken.MINUTES),
97 new TimeToken("m", TimeToken.MONTHS_MINUTES),
98 new TimeToken("hour", TimeToken.HOURS),
99 new TimeToken("hours", TimeToken.HOURS),
100 new TimeToken("hr", TimeToken.HOURS),
101 new TimeToken("h", TimeToken.HOURS),
102 new TimeToken("day", TimeToken.DAYS),
103 new TimeToken("days", TimeToken.DAYS),
104 new TimeToken("d", TimeToken.DAYS),
105 new TimeToken("week", TimeToken.WEEKS),
106 new TimeToken("weeks", TimeToken.WEEKS),
107 new TimeToken("wk", TimeToken.WEEKS),
108 new TimeToken("w", TimeToken.WEEKS),
109 new TimeToken("month", TimeToken.MONTHS),
110 new TimeToken("months", TimeToken.MONTHS),
111 new TimeToken("mon", TimeToken.MONTHS),
112 new TimeToken("year", TimeToken.YEARS),
113 new TimeToken("years", TimeToken.YEARS),
114 new TimeToken("yr", TimeToken.YEARS),
115 new TimeToken("y", TimeToken.YEARS),
116 new TimeToken(null, 0)
117 };
118
119 TimeToken[] specials = WORDS;
120
121 public TimeScanner(String dateString) {
122 this.dateString = dateString;
123 }
124
125 void setContext(boolean parsingWords) {
126 specials = parsingWords ? WORDS : MULTIPLIERS;
127 }
128
129 TimeToken nextToken() {
130 StringBuffer buffer = new StringBuffer("");
131 while (pos < dateString.length()) {
132 char c = dateString.charAt(pos++);
133 if (Character.isWhitespace(c) || c == '_' || c == ',') {
134 continue;
135 }
136 buffer.append(c);
137 if (Character.isDigit(c)) {
138
139 while (pos < dateString.length()) {
140 char next = dateString.charAt(pos);
141 if (Character.isDigit(next)) {
142 buffer.append(next);
143 pos++;
144 }
145 else {
146 break;
147 }
148 }
149 String value = buffer.toString();
150 return token = new TimeToken(value, TimeToken.NUMBER);
151 }
152 if (Character.isLetter(c)) {
153
154 while (pos < dateString.length()) {
155 char next = dateString.charAt(pos);
156 if (Character.isLetter(next)) {
157 buffer.append(next);
158 pos++;
159 }
160 else {
161 break;
162 }
163 }
164 String value = buffer.toString();
165 return token = new TimeToken(value, parseToken(value));
166 }
167 switch (c) {
168 case ':':
169 return token = new TimeToken(":", TimeToken.COLON);
170 case '.':
171 return token = new TimeToken(".", TimeToken.DOT);
172 case '+':
173 return token = new TimeToken("+", TimeToken.PLUS);
174 case '-':
175 return token = new TimeToken("-", TimeToken.MINUS);
176 case '/':
177 return token = new TimeToken("/", TimeToken.SLASH);
178 default:
179 pos--;
180 return token = new TimeToken(null, TimeToken.EOF);
181 }
182 }
183 return token = new TimeToken(null, TimeToken.EOF);
184 }
185
186 TimeToken resolveMonthsMinutes(int newId) {
187 assert token.id == TimeToken.MONTHS_MINUTES;
188 assert newId == TimeToken.MONTHS || newId == TimeToken.MINUTES;
189 return token = new TimeToken(token.value, newId);
190 }
191
192 void saveState() {
193 token_save = token;
194 pos_save = pos;
195 }
196
197 TimeToken restoreState() {
198 pos = pos_save;
199 return token = token_save;
200 }
201
202 private int parseToken(String arg) {
203 for (int i = 0; specials[i].value != null; i++) {
204 if (specials[i].value.equalsIgnoreCase(arg)) {
205 return specials[i].id;
206 }
207 }
208 return TimeToken.ID;
209 }
210 }