1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.net.ftp.parser;
18
19 import java.text.Format;
20 import java.text.ParseException;
21 import java.text.SimpleDateFormat;
22 import java.util.Calendar;
23 import java.util.Date;
24 import java.util.GregorianCalendar;
25 import java.util.Locale;
26 import java.util.TimeZone;
27
28 import org.apache.commons.net.ftp.FTPClientConfig;
29
30 import junit.framework.AssertionFailedError;
31 import junit.framework.TestCase;
32
33
34
35
36
37
38
39 public class FTPTimestampParserImplTest extends TestCase {
40
41 private static final int TWO_HOURS_OF_MILLISECONDS = 2 * 60 * 60 * 1000;
42
43 public void testParseTimestamp() {
44 Calendar cal = Calendar.getInstance();
45 cal.add(Calendar.HOUR_OF_DAY, 1);
46 cal.set(Calendar.SECOND,0);
47 cal.set(Calendar.MILLISECOND,0);
48 Date anHourFromNow = cal.getTime();
49 FTPTimestampParserImpl parser = new FTPTimestampParserImpl();
50 SimpleDateFormat sdf =
51 new SimpleDateFormat(parser.getRecentDateFormatString());
52 String fmtTime = sdf.format(anHourFromNow);
53 try {
54 Calendar parsed = parser.parseTimestamp(fmtTime);
55
56
57 assertEquals("test.roll.back.year", 1, cal.get(Calendar.YEAR) - parsed.get(Calendar.YEAR));
58 } catch (ParseException e) {
59 fail("Unable to parse");
60 }
61 }
62
63 public void testParseTimestampWithSlop() {
64 Calendar cal = Calendar.getInstance();
65 cal.set(Calendar.SECOND,0);
66 cal.set(Calendar.MILLISECOND,0);
67
68 Calendar caltemp = (Calendar) cal.clone();
69 caltemp.add(Calendar.HOUR_OF_DAY, 1);
70 Date anHourFromNow = caltemp.getTime();
71 caltemp.add(Calendar.DATE, 1);
72 Date anHourFromNowTomorrow = caltemp.getTime();
73
74 FTPTimestampParserImpl parser = new FTPTimestampParserImpl();
75
76
77 parser.setLenientFutureDates(true);
78
79 SimpleDateFormat sdf =
80 new SimpleDateFormat(parser.getRecentDateFormatString());
81 try {
82 String fmtTime = sdf.format(anHourFromNow);
83 Calendar parsed = parser.parseTimestamp(fmtTime);
84
85
86
87 assertEquals("test.slop.no.roll.back.year", 0, cal.get(Calendar.YEAR) - parsed.get(Calendar.YEAR));
88
89
90
91 fmtTime = sdf.format(anHourFromNowTomorrow);
92 parsed = parser.parseTimestamp(fmtTime);
93 assertEquals("test.slop.roll.back.year", 1, cal.get(Calendar.YEAR) - parsed.get(Calendar.YEAR));
94
95 } catch (ParseException e) {
96 fail("Unable to parse");
97 }
98 }
99
100 public void testNET444() throws Exception {
101 FTPTimestampParserImpl parser = new FTPTimestampParserImpl();
102 parser.setLenientFutureDates(true);
103 SimpleDateFormat sdf = new SimpleDateFormat(parser.getRecentDateFormatString());
104 GregorianCalendar now = new GregorianCalendar(2012, Calendar.FEBRUARY, 28, 12, 0);
105
106 GregorianCalendar nowplus1 = new GregorianCalendar(2012, Calendar.FEBRUARY, 28, 13, 0);
107
108 String future1 = sdf.format(nowplus1.getTime());
109 Calendar parsed1 = parser.parseTimestamp(future1, now);
110 assertEquals(nowplus1.get(Calendar.YEAR), parsed1.get(Calendar.YEAR));
111
112 GregorianCalendar nowplus25 = new GregorianCalendar(2012, Calendar.FEBRUARY, 29, 13, 0);
113
114 String future25 = sdf.format(nowplus25.getTime());
115 Calendar parsed25 = parser.parseTimestamp(future25, now);
116 assertEquals(nowplus25.get(Calendar.YEAR) - 1, parsed25.get(Calendar.YEAR));
117 }
118
119 public void testParseTimestampAcrossTimeZones() {
120
121
122 Calendar cal = Calendar.getInstance();
123 cal.set(Calendar.SECOND,0);
124 cal.set(Calendar.MILLISECOND,0);
125
126 cal.add(Calendar.HOUR_OF_DAY, 1);
127 Date anHourFromNow = cal.getTime();
128
129 cal.add(Calendar.HOUR_OF_DAY, 2);
130 Date threeHoursFromNow = cal.getTime();
131 cal.add(Calendar.HOUR_OF_DAY, -2);
132
133 FTPTimestampParserImpl parser = new FTPTimestampParserImpl();
134
135
136
137 FTPClientConfig config =
138 new FTPClientConfig(FTPClientConfig.SYST_UNIX);
139 config.setDefaultDateFormatStr(FTPTimestampParser.DEFAULT_SDF);
140 config.setRecentDateFormatStr(FTPTimestampParser.DEFAULT_RECENT_SDF);
141
142 config.setServerTimeZoneId("America/Chicago");
143 config.setLenientFutureDates(false);
144 parser.configure(config);
145
146 SimpleDateFormat sdf = (SimpleDateFormat)
147 parser.getRecentDateFormat().clone();
148
149
150 TimeZone tzla = TimeZone.getTimeZone("America/Los_Angeles");
151 sdf.setTimeZone(tzla);
152
153
154 String fmtTimePlusOneHour = sdf.format(anHourFromNow);
155 String fmtTimePlusThreeHours = sdf.format(threeHoursFromNow);
156
157
158 try {
159 Calendar parsed = parser.parseTimestamp(fmtTimePlusOneHour);
160
161
162 assertEquals("no.rollback.because.of.time.zones",
163 TWO_HOURS_OF_MILLISECONDS,
164 cal.getTime().getTime() - parsed.getTime().getTime());
165 } catch (ParseException e){
166 fail("Unable to parse " + fmtTimePlusOneHour);
167 }
168
169
170
171
172
173 try {
174 Calendar parsed = parser.parseTimestamp(fmtTimePlusThreeHours);
175
176 assertEquals("rollback.even.with.time.zones",
177 1, cal.get(Calendar.YEAR) - parsed.get(Calendar.YEAR));
178 } catch (ParseException e){
179 fail("Unable to parse" + fmtTimePlusThreeHours);
180 }
181 }
182
183
184 public void testParser() {
185
186 Locale locale = Locale.getDefault();
187 try {
188 Locale.setDefault(Locale.ENGLISH);
189 FTPTimestampParserImpl parser = new FTPTimestampParserImpl();
190 try {
191 parser.parseTimestamp("feb 22 2002");
192 } catch (ParseException e) {
193 fail("failed.to.parse.default");
194 }
195 try {
196 Calendar c = parser.parseTimestamp("f\u00e9v 22 2002");
197 fail("should.have.failed.to.parse.default, but was: "+c.getTime().toString());
198 } catch (ParseException e) {
199
200 }
201
202 FTPClientConfig config = new FTPClientConfig();
203 config.setDefaultDateFormatStr("d MMM yyyy");
204 config.setRecentDateFormatStr("d MMM HH:mm");
205 config.setServerLanguageCode("fr");
206 parser.configure(config);
207 try {
208 parser.parseTimestamp("d\u00e9c 22 2002");
209 fail("incorrect.field.order");
210 } catch (ParseException e) {
211
212 }
213 try {
214 parser.parseTimestamp("22 d\u00e9c 2002");
215 } catch (ParseException e) {
216 fail("failed.to.parse.french");
217 }
218
219 try {
220 parser.parseTimestamp("22 dec 2002");
221 fail("incorrect.language");
222 } catch (ParseException e) {
223
224 }
225 try {
226 parser.parseTimestamp("29 f\u00e9v 2002");
227 fail("nonexistent.date");
228 } catch (ParseException e) {
229
230 }
231
232 try {
233 parser.parseTimestamp("22 ao\u00fb 30:02");
234 fail("bad.hour");
235 } catch (ParseException e) {
236
237 }
238
239 try {
240 parser.parseTimestamp("22 ao\u00fb 20:74");
241 fail("bad.minute");
242 } catch (ParseException e) {
243
244 }
245 try {
246 parser.parseTimestamp("28 ao\u00fb 20:02");
247 } catch (ParseException e) {
248 fail("failed.to.parse.french.recent");
249 }
250 } finally {
251 Locale.setDefault(locale);
252 }
253 }
254
255
256
257
258
259 private void checkShortParse(String msg, Calendar serverTime, Calendar input) throws ParseException {
260 checkShortParse(msg, serverTime, input, false);
261 checkShortParse(msg, serverTime, input, true);
262 }
263
264
265
266
267
268 private void checkShortParse(String msg, Calendar serverTime, Calendar input, Calendar expected) throws ParseException {
269 checkShortParse(msg, serverTime, input, expected, false);
270 checkShortParse(msg, serverTime, input, expected, true);
271 }
272
273
274
275
276
277
278
279
280
281 private void checkShortParse(String msg, Calendar servertime, Calendar input, boolean lenient) throws ParseException {
282 checkShortParse(msg, servertime, input, input, lenient);
283 }
284
285
286
287
288
289
290
291
292
293
294 private void checkShortParse(String msg, Calendar servertime, Calendar input, Calendar expected, boolean lenient) throws ParseException {
295 FTPTimestampParserImpl parser = new FTPTimestampParserImpl();
296 parser.setLenientFutureDates(lenient);
297 Format shortFormat = parser.getRecentDateFormat();
298
299 final String shortDate = shortFormat.format(input.getTime());
300 Calendar output=parser.parseTimestamp(shortDate, servertime);
301 int outyear = output.get(Calendar.YEAR);
302 int outdom = output.get(Calendar.DAY_OF_MONTH);
303 int outmon = output.get(Calendar.MONTH);
304 int inyear = expected.get(Calendar.YEAR);
305 int indom = expected.get(Calendar.DAY_OF_MONTH);
306 int inmon = expected.get(Calendar.MONTH);
307 if (indom != outdom || inmon != outmon || inyear != outyear){
308 Format longFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
309 fail("Test: '"+msg+"' Server="+longFormat.format(servertime.getTime())
310 +". Failed to parse "+shortDate
311 +". Actual "+longFormat.format(output.getTime())
312 +". Expected "+longFormat.format(expected.getTime()));
313 }
314 }
315
316 public void testParseShortPastDates1() throws Exception {
317 GregorianCalendar now = new GregorianCalendar(2001, Calendar.MAY, 30, 12, 0);
318 checkShortParse("2001-5-30",now,now);
319 GregorianCalendar target = (GregorianCalendar) now.clone();
320 target.add(Calendar.WEEK_OF_YEAR, -1);
321 checkShortParse("2001-5-30 -1 week",now,target);
322 target.add(Calendar.WEEK_OF_YEAR, -12);
323 checkShortParse("2001-5-30 -13 weeks",now,target);
324 target.add(Calendar.WEEK_OF_YEAR, -13);
325 checkShortParse("2001-5-30 -26 weeks",now,target);
326 }
327
328 public void testParseShortPastDates2() throws Exception {
329 GregorianCalendar now = new GregorianCalendar(2004, Calendar.AUGUST, 1, 12, 0);
330 checkShortParse("2004-8-1",now,now);
331 GregorianCalendar target = (GregorianCalendar) now.clone();
332 target.add(Calendar.WEEK_OF_YEAR, -1);
333 checkShortParse("2004-8-1 -1 week",now,target);
334 target.add(Calendar.WEEK_OF_YEAR, -12);
335 checkShortParse("2004-8-1 -13 weeks",now,target);
336 target.add(Calendar.WEEK_OF_YEAR, -13);
337 checkShortParse("2004-8-1 -26 weeks",now,target);
338 }
339
340
341
342 public void testParseShortFutureDates1() throws Exception {
343 GregorianCalendar now = new GregorianCalendar(2001, Calendar.MAY, 30, 12, 0);
344 checkShortParse("2001-5-30",now,now);
345 GregorianCalendar target = (GregorianCalendar) now.clone();
346 target.add(Calendar.DAY_OF_MONTH, 1);
347 checkShortParse("2001-5-30 +1 day",now,target,true);
348 try {
349 checkShortParse("2001-5-30 +1 day",now,target,false);
350 fail("Expected AssertionFailedError");
351 } catch (AssertionFailedError pe) {
352 if (pe.getMessage().startsWith("Expected AssertionFailedError")) {
353 throw pe;
354 }
355 }
356 target.add(Calendar.WEEK_OF_YEAR, 1);
357
358
359
360
361
362 }
363
364 public void testParseShortFutureDates2() throws Exception {
365 GregorianCalendar now = new GregorianCalendar(2004, Calendar.AUGUST, 1, 12, 0);
366 checkShortParse("2004-8-1",now,now);
367 GregorianCalendar target = (GregorianCalendar) now.clone();
368 target.add(Calendar.DAY_OF_MONTH, 1);
369 checkShortParse("2004-8-1 +1 day",now,target,true);
370 try {
371 checkShortParse("2004-8-1 +1 day",now,target,false);
372 fail("Expected AssertionFailedError");
373 } catch (AssertionFailedError pe) {
374 if (pe.getMessage().startsWith("Expected AssertionFailedError")) {
375 throw pe;
376 }
377 }
378
379
380
381
382
383
384 }
385
386
387 public void testFeb29IfLeapYear() throws Exception{
388 GregorianCalendar now = new GregorianCalendar();
389 final int thisYear = now.get(Calendar.YEAR);
390 if (now.isLeapYear(thisYear) && now.before(new GregorianCalendar(thisYear,Calendar.AUGUST,29))){
391 GregorianCalendar target = new GregorianCalendar(thisYear,Calendar.FEBRUARY,29);
392 checkShortParse("Feb 29th",now,target);
393 } else {
394 System.out.println("Skipping Feb 29 test");
395 }
396 }
397
398
399 public void testFeb29LeapYear() throws Exception{
400 int year = 2000;
401 GregorianCalendar now = new GregorianCalendar(year, Calendar.APRIL, 1, 12, 0);
402 checkShortParse("Feb 29th 2000",now,new GregorianCalendar(year, Calendar.FEBRUARY,29));
403 }
404
405
406 public void testFeb29NonLeapYear(){
407 GregorianCalendar server = new GregorianCalendar(1999, Calendar.APRIL, 1, 12, 0);
408
409 GregorianCalendar input = new GregorianCalendar(2000, Calendar.FEBRUARY,29);
410 GregorianCalendar expected = new GregorianCalendar(1999, Calendar.FEBRUARY,29);
411 try {
412 checkShortParse("Feb 29th 1999", server, input, expected, true);
413 fail("Should have failed to parse Feb 29th 1999");
414 } catch (ParseException pe) {
415 }
416 try {
417 checkShortParse("Feb 29th 1999", server, input, expected, false);
418 fail("Should have failed to parse Feb 29th 1999");
419 } catch (ParseException pe) {
420 }
421 }
422
423
424 public void DISABLEDtestNET446() throws Exception {
425 GregorianCalendar server = new GregorianCalendar(2001, Calendar.JANUARY, 1, 12, 0);
426
427 GregorianCalendar input = new GregorianCalendar(2000, Calendar.FEBRUARY,29);
428 GregorianCalendar expected = new GregorianCalendar(2000, Calendar.FEBRUARY,29);
429 checkShortParse("Feb 29th 2000", server, input, expected);
430 }
431
432 public void testParseDec31Lenient() throws Exception {
433 GregorianCalendar now = new GregorianCalendar(2007, Calendar.DECEMBER, 30, 12, 0);
434 checkShortParse("2007-12-30",now,now);
435 GregorianCalendar target = (GregorianCalendar) now.clone();
436 target.add(Calendar.DAY_OF_YEAR, +1);
437 checkShortParse("2007-12-31",now,target, true);
438 }
439
440 public void testParseJan01Lenient() throws Exception {
441 GregorianCalendar now = new GregorianCalendar(2007, Calendar.DECEMBER, 31, 12, 0);
442 checkShortParse("2007-12-31",now,now);
443 GregorianCalendar target = (GregorianCalendar) now.clone();
444 target.add(Calendar.DAY_OF_YEAR, +1);
445 checkShortParse("2008-1-1",now,target, true);
446 }
447
448 public void testParseJan01() throws Exception {
449 GregorianCalendar now = new GregorianCalendar(2007, Calendar.JANUARY, 1, 12, 0);
450 checkShortParse("2007-01-01",now,now);
451 GregorianCalendar target = new GregorianCalendar(2006, Calendar.DECEMBER, 31, 12, 0);
452 checkShortParse("2006-12-31",now,target, true);
453 checkShortParse("2006-12-31",now,target, false);
454 }
455
456 }