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