View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.dateformat;
20  
21  import java.text.SimpleDateFormat;
22  import java.util.Date;
23  import java.util.Locale;
24  
25  import junit.framework.TestCase;
26  
27  import org.joda.time.DateTime;
28  
29  public class TestSimpleDateFormatter extends TestCase
30  {
31      // test just the very basics of date formatting
32      public void testFormatSimple()
33      {
34          SimpleDateFormatter sdf = new SimpleDateFormatter("yyyy-MM-dd'T'hh:mm:ss", null);
35          Date d = new Date();
36          d.setYear(1987 - 1900);
37          d.setMonth(2);
38          d.setDate(12);
39          d.setHours(13);
40          d.setMinutes(23);
41          d.setSeconds(59);
42          
43          String s = sdf.format(d);
44          assertEquals("1987-03-12T01:23:59", s);
45      }
46  
47      // test just the very basics of date parsing
48      public void testParseSimple()
49      {
50          SimpleDateFormatter sdf = new SimpleDateFormatter("yyyy-MM-dd'T'HH:mm:ss", null);
51          Date d = sdf.parse("1987-03-12T04:23:59");
52  
53          assertNotNull(d);
54          assertEquals(1987, d.getYear() + 1900);
55          assertEquals(2, d.getMonth());
56          assertEquals(12, d.getDate());
57          assertEquals(4, d.getHours());
58          assertEquals(23, d.getMinutes());
59          assertEquals(59, d.getSeconds());
60      }
61  
62      /**
63       * Check the parsing of dates with months that use names.
64       */
65      public void testParseNamedMonth()
66      {
67          Locale locale = Locale.ENGLISH;
68          org.apache.myfaces.dateformat.DateFormatSymbols symbols = 
69              new org.apache.myfaces.dateformat.DateFormatSymbols(locale);
70          int firstDayOfWeek = 0;
71          SimpleDateFormatter sdf = new SimpleDateFormatter(
72                  "dd-MMM-yyyy", symbols, firstDayOfWeek);
73          
74          Date d = sdf.parse("12-Mar-2008");
75          assertNotNull(d);
76          assertEquals(2008, d.getYear() + 1900);
77          assertEquals(2, d.getMonth());
78          assertEquals(12, d.getDate());
79          assertEquals(0, d.getHours());
80          assertEquals(0, d.getMinutes());
81          assertEquals(0, d.getSeconds());
82      }
83  
84      // test every possible formatter in date formatting
85      public void testFormatAll()
86      {
87          Date d = new Date();
88          d.setYear(1987 - 1900);
89          d.setMonth(2);
90          d.setDate(12);
91          d.setHours(4);
92          d.setMinutes(23);
93          d.setSeconds(59);
94          
95          String[] data =
96          {
97              "yyyy", "1987",
98              "yyy", "87",
99              "yy", "87",
100             "y", "87",
101             "MMMM", "March",
102             "MMM", "Mar",
103             "MM", "03",
104             "M", "3",
105             "dd", "12",
106             "EEEE", "Thursday",
107             "EE", "Thu",
108             "HH", "04",
109             "H", "4",
110             "hh", "04",
111             "h", "4",
112             "mm", "23",
113             "m", "23",
114             "ss", "59",
115             "s", "59",
116             "a", "AM"
117         };
118 
119         Locale locale = Locale.ENGLISH;
120         for(int i=0; i<data.length; i+=2)
121         {
122             String pattern = data[i];
123             String expected = data[i+1];
124 
125             SimpleDateFormatter sdf = new SimpleDateFormatter(pattern, null);
126             String s = sdf.format(d);
127             assertEquals("custom:" + pattern, expected, s);
128             
129             SimpleDateFormat sf = new SimpleDateFormat(pattern, locale);
130             String s2 = sf.format(d);
131             assertEquals("std:" + pattern, expected, s2);
132         }
133     }
134     
135     // test every possible formatter in date parsing
136     public void testParseAll()
137     {
138         Date d = new Date();
139         d.setYear(1987 - 1900);
140         d.setMonth(2);
141         d.setDate(12);
142         d.setHours(4);
143         d.setMinutes(23);
144         d.setSeconds(59);
145         
146         String[] data =
147         {
148             "yyyy", "1987",
149             "yyy", "87",
150             "yy", "87",
151             "y", "87",
152             "MMMM", "March",
153             "MMM", "Mar",
154             "MM", "03",
155             "M", "3",
156             "dd", "12",
157 
158             // These are difficult to test in this way; disable them
159             //"EEEE", "Monday",
160             //"EE", "Mon",
161 
162             "HH", "04",
163             "H", "4",
164 
165             "hh", "04",
166             "h", "4",
167             "mm", "23",
168             "m", "23",
169             "ss", "59",
170             "s", "59",
171             "a", "AM"
172         };
173 
174         Locale locale = Locale.ENGLISH;
175         for(int i=0; i<data.length; i+=2)
176         {
177             String pattern = data[i];
178             String expected = data[i+1];
179 
180             // parse it with our code, then format it with the std code and
181             // see if we get the same value back.
182             SimpleDateFormatter sdf = new SimpleDateFormatter(pattern, null);
183         
184             Date d2 = sdf.parse(expected);
185             SimpleDateFormat sf = new SimpleDateFormat(pattern, locale);
186             String s2 = sf.format(d2);
187             assertEquals(pattern, expected, s2);
188         }
189     }
190 
191     // try to parse various combinations, and see what we get
192     public void testParseAssorted() throws Exception {
193         Object[] data =
194         {
195             // test standard, with literals
196             "yyyy-MM-dd", "1987-01-08", new Date(1987-1900, 0, 8),
197             
198             // test standard, with multichar literal sequences: any non-alpha
199             // char must exactly match the input.
200             "yyyy--MM-:()dd", "1987--01-:()08", new Date(1987-1900, 0, 8),
201             
202             // test standard, with quoted chars.
203             "yyyy'T'MM'T'dd", "1987T01T08", new Date(1987-1900, 0, 8),
204             
205             // test standard, with non-pattern chars.
206             // An alpha non-pattern char --> error
207             "yyyyRMMRdd", "1987-01-08", null,
208             
209             // test quoted text
210             "yyyy'year'MM'month'dd", "2003year04month06", new Date(2003-1900, 03, 06),
211             
212             // test mismatched quoted text
213             "yyyy'year'MM'month'dd", "2003yexr04month06", null,
214             
215             // test short year format with no century wraparound
216             "yy-MM-dd", "99-04-06", new Date(1999-1900, 03, 06),
217             
218             // test short year format with century wraparound
219             "yy-MM-dd", "03-04-06", new Date(2003-1900, 03, 06),
220             
221             // test short year format with no century wraparound
222             "yy-MM-dd", "33-04-06", new Date(1933-1900, 03, 06),
223         };
224 
225         Locale locale = Locale.ENGLISH;
226         for(int i=0; i<data.length; i+=3)
227         {
228             String pattern = (String) data[i];
229             String input = (String) data[i+1];
230             Date expected = (Date) data[i+2];
231 
232             // parse it with our code, and see if we get the expected result
233             SimpleDateFormatter sdf = new SimpleDateFormatter(pattern, null);
234             Date d = sdf.parse(input);
235             assertEquals("custom:" + pattern, expected, d);
236             
237             // try with the standard parser too
238             try
239             {
240                 SimpleDateFormat sf = new SimpleDateFormat(pattern, locale);
241                 Date d2 = sf.parse(input);
242                 assertEquals("std:" + pattern, expected, d2);
243             }
244             catch(java.text.ParseException e)
245             {
246                 // thrown when the input does not match the pattern
247                 assertEquals("std:" + pattern, null, expected);
248             }
249             catch(IllegalArgumentException e)
250             {
251                 // thrown when the pattern is not value
252                 assertEquals("std:" + pattern, null, expected);
253             }
254         }
255     }
256     
257     //Try to parse non valid data
258     public void testParseInvalidValue()  throws Exception {
259         Object[] data =
260         {
261                 "yyyy", "x1987",
262                 "yyy", "98someinvalid7",                
263                 "yy", "87x/dksk/-",
264                 "y", "x87x-/\\233",
265                 "MMMM", "Marchx",
266                 "MMMM", "xMarch",
267                 "MMMM", "Marcxh",
268                 "MMM", "xMar",
269                 "MMM", "xMxarx",
270                 "MMM", "Marx",
271                 "MM", "x03",
272                 "MM", "0x3",
273                 "MM", "03x",
274                 "M", "x3",
275                 "M", "3x",
276                 "dd", "x12",
277                 "HH", "0x4",
278                 "H", "4x",
279                 "hh", "04x",
280                 "h", "4x",
281                 "mm", "x23",
282                 "m", "23x",
283                 "ss", "x59",
284                 "s", "59x",
285                 "a", "AMx",                
286                 "yyyy-MM-dd", "1987-0x1-08",
287                 "yyyy-MM-dd", "1987-01-08x",
288                 "yyyy-MM-dd", "x1987-0x1-08",
289                 "yyyy--MM-:()dd", "x1987--01-:()08",
290                 "yyyy--MM-:()dd", "1987--01-:()0x8",
291                 "yyyy--MM-:()dd", "1987--01-:()08x",
292                 "yyyy'T'MM'T'dd", "1987T01'T'08",
293                 "yyyy'T'MM'T'dd", "T1987T01T08",
294                 "yyyy'T'MM'T'dd", "19T87T01T08",
295                 "yyyy'T'MM'T'dd", "1987T01T08T",
296                 "yyyyRMMRdd", "1987-01-08",
297                 "yyyyRMMRdd", "1987/01/08",
298                 "yyyyRMMRdd", "1987'R'01-08",
299                 "yyyy'year'MM'month'dd", "2003year0x4month06",
300                 "yyyy'year'MM'month'dd", "2003'year'04month06",
301                 "yyyy'year'MM'month'dd", "2003'year'04monxth06",
302                 "yyyy'year'MM'month'dd", "2003YEAR04month06",
303                 "yyyy'year'MM'month'dd", "2003yexr04month06",
304                 "yy-MM-dd", "x99-04-06", 
305                 "yy-MM-dd", "9x9-04-06",
306                 "yy-MM-dd", "99-04-0x6",
307                 "yy-MM-dd", "99-x04-06",
308                 "yy-MM-dd", "99-x04-06",
309                 "yy-MM-dd", "99-04-06y",
310         };
311         Locale locale = Locale.ENGLISH;
312         for(int i=0; i<data.length; i+=2)
313         {
314             String pattern = (String) data[i];
315             String input = (String) data[i+1];
316 
317             SimpleDateFormatter sdf = new SimpleDateFormatter(pattern, null);
318             Date d = sdf.parse(input);
319             assertNull("Parsing should fail when using this pattern "+
320                     pattern+" and this input "+input,d);
321         }
322     }
323 
324     // try to format with various combinations, and see what we get
325     public void testFormatAssorted() throws Exception
326     {
327         Date d = new Date();
328         d.setYear(1987 - 1900);
329         d.setMonth(2);
330         d.setDate(12);
331         d.setHours(4);
332         d.setMinutes(23);
333         d.setSeconds(59);
334         
335         String[] data =
336         {
337             // test standard, with literals
338             "yyyy-MM-dd", "1987-03-12",
339             
340             // test standard, with multichar literal sequences: any non-alpha
341             "yyyy--MM-:()dd", "1987--03-:()12",
342             
343             // test standard, with non-pattern chars.--> error
344             "yyyyTMMTdd", null,
345             
346             // test standard, with non-pattern chars.
347             "yyyy'T'MM'T'dd", "1987T03T12",
348             
349             // test quoted text
350             "yyyy'year'MM'month'dd", "1987year03month12",
351         };
352 
353         Locale locale = Locale.ENGLISH;
354         for(int i=0; i<data.length; i+=2)
355         {
356             String pattern = data[i];
357             String expected = data[i+1];
358 
359             // format it with our code, and check against expected.
360             SimpleDateFormatter sdf = new SimpleDateFormatter(pattern, null);
361             String s = sdf.format(d);
362             assertEquals("custom:" + pattern, expected, s);
363 
364             // try with the standard parser too
365             try
366             {
367                 SimpleDateFormat sf = new SimpleDateFormat(pattern, locale);
368                 String s2 = sf.format(d);
369                 assertEquals("std:" + pattern, expected, s2);
370             }
371             catch(IllegalArgumentException e)
372             {
373                 // thrown when the pattern is not value
374                 assertEquals("std:" + pattern, null, expected);
375             }
376         }
377     }
378 
379     // test just the very basics of date parsing
380     public void testWeekParseSimple()
381     {
382         SimpleDateFormatter sdf = new SimpleDateFormatter("xxxx-ww", null);
383         Date d = sdf.parse("2009-06");
384 
385         assertNotNull(d);
386         assertEquals(2009, d.getYear() + 1900);
387         assertEquals(2, d.getMonth() + 1);
388         assertEquals(2, d.getDate());
389         assertEquals(0, d.getHours());
390         assertEquals(0, d.getMinutes());
391         assertEquals(0, d.getSeconds());
392     }
393     
394 /* test fails on linux, but code is ok
395     public void testWeekFormatAgainstJoda() throws Exception
396     {
397         // for every year from 2000-2010, test:
398         //   1-8 jan jan
399         //   29,30 may,
400         //   1-8 june
401         //   23-31 dec
402          for(int year = 2000; year < 2020; ++year)
403          {
404              checkWeekFormatAgainstJoda(year, 0, 1);
405              checkWeekFormatAgainstJoda(year, 0, 2);
406              checkWeekFormatAgainstJoda(year, 0, 3);
407              checkWeekFormatAgainstJoda(year, 0, 4);
408              checkWeekFormatAgainstJoda(year, 0, 5);
409              checkWeekFormatAgainstJoda(year, 0, 6);
410              checkWeekFormatAgainstJoda(year, 0, 7);
411              checkWeekFormatAgainstJoda(year, 0, 8);
412 
413              checkWeekFormatAgainstJoda(year, 4, 29);
414              checkWeekFormatAgainstJoda(year, 4, 30);
415              checkWeekFormatAgainstJoda(year, 5, 1);
416              checkWeekFormatAgainstJoda(year, 5, 2);
417              checkWeekFormatAgainstJoda(year, 5, 3);
418              checkWeekFormatAgainstJoda(year, 5, 4);
419              checkWeekFormatAgainstJoda(year, 5, 5);
420              checkWeekFormatAgainstJoda(year, 5, 6);
421              checkWeekFormatAgainstJoda(year, 5, 7);
422              checkWeekFormatAgainstJoda(year, 5, 8);
423 
424              checkWeekFormatAgainstJoda(year, 11, 23);
425              checkWeekFormatAgainstJoda(year, 11, 24);
426              checkWeekFormatAgainstJoda(year, 11, 25);
427              checkWeekFormatAgainstJoda(year, 11, 26);
428              checkWeekFormatAgainstJoda(year, 11, 27);
429              checkWeekFormatAgainstJoda(year, 11, 28);
430              checkWeekFormatAgainstJoda(year, 11, 29);
431              checkWeekFormatAgainstJoda(year, 11, 30);
432              checkWeekFormatAgainstJoda(year, 11, 31);
433          }
434     }
435 */
436 
437     private void checkWeekFormatAgainstJoda(int year, int month, int day)
438     {
439         Date date = new Date(year-1900, month, day);
440         DateTime jdt = new DateTime(date.getTime());
441         int jodaWeekOfWeekyear = jdt.getWeekOfWeekyear();
442         int jodaWeekyear = jdt.getWeekyear();
443 
444         WeekDate iwd = SimpleDateFormatter.getIsoWeekDate(date);
445 
446         // the java.util.Date convention is that 1 = monday
447         int firstDayOfWeek = 1;
448         WeekDate jwd = SimpleDateFormatter.getWeekDate(date, firstDayOfWeek);
449 
450         /*
451         String ds = new SimpleDateFormat("yyyy-MM-dd").format(date);
452         System.out.println(
453             ds + ":"
454             + "(" + jodaWeekyear + "-" + jodaWeekOfWeekyear + ")"
455             + ",(" + iwd.year + "-" + iwd.week + ")"
456             + ",(" + jwd.year + "-" + jwd.week + ")"
457             );
458             */
459         assertEquals(jodaWeekyear, iwd.getYear());
460         assertEquals(jodaWeekOfWeekyear, iwd.getWeek());
461         assertEquals(jodaWeekyear, jwd.getYear());
462         assertEquals(jodaWeekOfWeekyear, jwd.getWeek());
463     }
464 }