1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17package org.apache.harmony.tests.java.text;
18
19import java.text.DateFormat;
20import java.text.DateFormatSymbols;
21import java.text.FieldPosition;
22import java.text.ParseException;
23import java.text.ParsePosition;
24import java.text.SimpleDateFormat;
25import java.util.Calendar;
26import java.util.Date;
27import java.util.GregorianCalendar;
28import java.util.Locale;
29import java.util.SimpleTimeZone;
30import java.util.TimeZone;
31
32
33public class SimpleDateFormatTest extends junit.framework.TestCase {
34
35    private TimeZone previousDefaultTimeZone;
36
37    @Override public void setUp() {
38        previousDefaultTimeZone = TimeZone.getDefault();
39        TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
40    }
41
42    @Override public void tearDown() {
43        TimeZone.setDefault(previousDefaultTimeZone);
44    }
45
46    public void test_Constructor() {
47        // Test for method java.text.SimpleDateFormat()
48        SimpleDateFormat f2 = new SimpleDateFormat();
49        assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
50        assertTrue("Wrong default", f2.equals(DateFormat.getDateTimeInstance(
51                DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault())));
52        assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(new DateFormatSymbols()));
53        assertTrue("Doesn't work", f2.format(new Date()).getClass() == String.class);
54    }
55
56    public void test_ConstructorLjava_lang_String() {
57        // Test for method java.text.SimpleDateFormat(java.lang.String)
58        SimpleDateFormat f2 = new SimpleDateFormat("yyyy");
59        assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
60        assertEquals("Wrong pattern", "yyyy", f2.toPattern());
61        assertTrue("Wrong locale", f2.equals(new SimpleDateFormat("yyyy", Locale.getDefault())));
62        assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(new DateFormatSymbols()));
63        assertTrue("Doesn't work", f2.format(new Date()).getClass() == String.class);
64
65        // Invalid constructor value.
66        try {
67            new SimpleDateFormat("this is an invalid simple date format");
68            fail("Expected test_ConstructorLjava_lang_String to throw IAE.");
69        } catch (IllegalArgumentException ex) {
70            // expected
71        }
72
73        // Null string value
74        try {
75            new SimpleDateFormat(null);
76            fail("Expected test_ConstructorLjava_lang_String to throw NPE.");
77        } catch (NullPointerException ex) {
78            // expected
79        }
80    }
81
82    public void test_ConstructorLjava_lang_StringLjava_text_DateFormatSymbols() {
83        // Test for method java.text.SimpleDateFormat(java.lang.String,
84        // java.text.DateFormatSymbols)
85        DateFormatSymbols symbols = new DateFormatSymbols(Locale.ENGLISH);
86        symbols.setEras(new String[] { "Before", "After" });
87        SimpleDateFormat f2 = new SimpleDateFormat("y'y'yy", symbols);
88        assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
89        assertEquals("Wrong pattern", "y'y'yy", f2.toPattern());
90        assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(symbols));
91        assertTrue("Doesn't work", f2.format(new Date()).getClass() == String.class);
92
93        try {
94            new SimpleDateFormat(null, symbols);
95            fail();
96        } catch (NullPointerException expected) {
97        }
98
99        try {
100            new SimpleDateFormat("eee", symbols);
101            fail();
102        } catch (IllegalArgumentException expected) {
103        }
104    }
105
106    public void test_ConstructorLjava_lang_StringLjava_util_Locale() {
107        // Test for method java.text.SimpleDateFormat(java.lang.String,
108        // java.util.Locale)
109        SimpleDateFormat f2 = new SimpleDateFormat("'yyyy' MM yy", Locale.GERMAN);
110        assertTrue("Wrong class", f2.getClass() == SimpleDateFormat.class);
111        assertEquals("Wrong pattern", "'yyyy' MM yy", f2.toPattern());
112        assertTrue("Wrong symbols", f2.getDateFormatSymbols().equals(
113                new DateFormatSymbols(Locale.GERMAN)));
114        assertTrue("Doesn't work", f2.format(new Date()).getClass() == String.class);
115
116        try {
117            new SimpleDateFormat(null, Locale.GERMAN);
118            fail();
119        } catch (NullPointerException expected) {
120        }
121        try {
122            new SimpleDateFormat("eee", Locale.GERMAN);
123            fail();
124        } catch (IllegalArgumentException expected) {
125        }
126    }
127
128    public void test_applyLocalizedPatternLjava_lang_String() {
129        SimpleDateFormat f2 = new SimpleDateFormat("y", new Locale("de", "CH"));
130        String pattern = "GyMdkHmsSEDFwWahKzZLc";
131        f2.applyLocalizedPattern(pattern);
132        assertEquals(pattern, f2.toPattern());
133        assertEquals(pattern, f2.toLocalizedPattern());
134
135        // test invalid patterns
136        try {
137            f2.applyLocalizedPattern("b");
138            fail();
139        } catch (IllegalArgumentException expected) {
140        }
141
142        try {
143            f2.applyLocalizedPattern("a '"); // Unterminated quote.
144            fail();
145        } catch (IllegalArgumentException expected) {
146        }
147
148        try {
149            f2.applyLocalizedPattern(null);
150            fail();
151        } catch (NullPointerException expected) {
152        }
153    }
154
155    public void test_applyPatternLjava_lang_String() {
156        // Test for method void
157        // java.text.SimpleDateFormat.applyPattern(java.lang.String)
158        SimpleDateFormat f2 = new SimpleDateFormat("y", new Locale("de", "CH"));
159        f2.applyPattern("GyMdkHmsSEDFwWahKz");
160        assertEquals("Wrong pattern", "GyMdkHmsSEDFwWahKz", f2.toPattern());
161
162        // test invalid patterns
163        try {
164            f2.applyPattern("b");
165            fail("Expected IllegalArgumentException for pattern with invalid patter letter: b");
166        } catch (IllegalArgumentException e) {
167        }
168
169//        try {
170//            f2.applyPattern("u");
171//            fail("Expected IllegalArgumentException for pattern with invalid patter letter: u");
172//        } catch (IllegalArgumentException e) {
173//        }
174
175        try {
176            f2.applyPattern("a '");
177            fail("Expected IllegalArgumentException for pattern with unterminated quote: a '");
178        } catch (IllegalArgumentException e) {
179        }
180
181        try {
182            f2.applyPattern(null);
183            fail("Expected NullPointerException for null pattern");
184        } catch (NullPointerException e) {
185        }
186    }
187
188    public void test_clone() {
189        // Test for method java.lang.Object java.text.SimpleDateFormat.clone()
190        SimpleDateFormat f2 = new SimpleDateFormat();
191        SimpleDateFormat clone = (SimpleDateFormat) f2.clone();
192        assertTrue("Invalid clone", f2.equals(clone));
193        clone.applyPattern("y");
194        assertTrue("Format modified", !f2.equals(clone));
195        clone = (SimpleDateFormat) f2.clone();
196        // Date date = clone.get2DigitYearStart();
197        // date.setTime(0);
198        // assertTrue("Equal after date change: " +
199        // f2.get2DigitYearStart().getTime() + " " +
200        // clone.get2DigitYearStart().getTime(), !f2.equals(clone));
201    }
202
203    public void test_equalsLjava_lang_Object() {
204        // Test for method boolean
205        // java.text.SimpleDateFormat.equals(java.lang.Object)
206        SimpleDateFormat format = (SimpleDateFormat) DateFormat.getInstance();
207        SimpleDateFormat clone = (SimpleDateFormat) format.clone();
208        assertTrue("clone not equal", format.equals(clone));
209        format.format(new Date());
210        assertTrue("not equal after format", format.equals(clone));
211    }
212
213    public void test_equals_afterFormat() {
214        // Regression test for HARMONY-209
215        SimpleDateFormat df = new SimpleDateFormat();
216        df.format(new Date());
217        assertEquals(df, new SimpleDateFormat());
218      }
219
220    public void test_hashCode() {
221        SimpleDateFormat format = (SimpleDateFormat) DateFormat.getInstance();
222        SimpleDateFormat clone = (SimpleDateFormat) format.clone();
223        assertTrue("clone has not equal hash code", clone.hashCode() == format.hashCode());
224        format.format(new Date());
225        assertTrue("clone has not equal hash code after format",
226                clone.hashCode() == format.hashCode());
227        DateFormatSymbols symbols = new DateFormatSymbols(Locale.ENGLISH);
228        symbols.setEras(new String[] { "Before", "After" });
229        SimpleDateFormat format2 = new SimpleDateFormat("y'y'yy", symbols);
230        assertFalse("objects has equal hash code", format2.hashCode() == format.hashCode());
231    }
232
233    public void test_formatToCharacterIteratorLjava_lang_Object() {
234        try {
235            // Regression for HARMONY-466
236            new SimpleDateFormat().formatToCharacterIterator(null);
237            fail();
238        } catch (NullPointerException expected) {
239        }
240
241        // Test for method formatToCharacterIterator(java.lang.Object)
242        new Support_SimpleDateFormat(
243                "test_formatToCharacterIteratorLjava_lang_Object")
244                .t_formatToCharacterIterator();
245    }
246
247    public void test_formatLjava_util_DateLjava_lang_StringBufferLjava_text_FieldPosition() {
248        // Test for method java.lang.StringBuffer
249        // java.text.SimpleDateFormat.format(java.util.Date,
250        // java.lang.StringBuffer, java.text.FieldPosition)
251
252        new Support_SimpleDateFormat(
253                "test_formatLjava_util_DateLjava_lang_StringBufferLjava_text_FieldPosition")
254                .t_format_with_FieldPosition();
255
256        SimpleDateFormat format = new SimpleDateFormat("", Locale.ENGLISH);
257        Calendar cal = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3, 6);
258        assertFormat(format, " G", cal, " AD", DateFormat.ERA_FIELD);
259        assertFormat(format, " GG", cal, " AD", DateFormat.ERA_FIELD);
260        assertFormat(format, " GGG", cal, " AD", DateFormat.ERA_FIELD);
261        assertFormat(format, " G", new GregorianCalendar(-1999, Calendar.JUNE, 2), " BC",
262                DateFormat.ERA_FIELD);
263
264        // This assumes Unicode behavior where 'y' and 'yyy' don't truncate,
265        // which means that it will fail on the RI.
266        assertFormat(format, " y", cal, " 1999", DateFormat.YEAR_FIELD);
267        assertFormat(format, " yy", cal, " 99", DateFormat.YEAR_FIELD);
268        assertFormat(format, " yy", new GregorianCalendar(2001, Calendar.JUNE, 2), " 01",
269                DateFormat.YEAR_FIELD);
270        assertFormat(format, " yy", new GregorianCalendar(2000, Calendar.JUNE, 2), " 00",
271                DateFormat.YEAR_FIELD);
272        assertFormat(format, " yyy", new GregorianCalendar(2000, Calendar.JUNE, 2), " 2000",
273                DateFormat.YEAR_FIELD);
274        assertFormat(format, " yyy", cal, " 1999", DateFormat.YEAR_FIELD);
275        assertFormat(format, " yyyy", cal, " 1999", DateFormat.YEAR_FIELD);
276        assertFormat(format, " yyyyy", cal, " 01999", DateFormat.YEAR_FIELD);
277
278        assertFormat(format, " M", cal, " 6", DateFormat.MONTH_FIELD);
279        assertFormat(format, " M", new GregorianCalendar(1999, Calendar.NOVEMBER, 2), " 11",
280                DateFormat.MONTH_FIELD);
281        assertFormat(format, " MM", cal, " 06", DateFormat.MONTH_FIELD);
282        assertFormat(format, " MMM", cal, " Jun", DateFormat.MONTH_FIELD);
283        assertFormat(format, " MMMM", cal, " June", DateFormat.MONTH_FIELD);
284        assertFormat(format, " MMMMM", cal, " J", DateFormat.MONTH_FIELD);
285
286        assertFormat(format, " d", cal, " 2", DateFormat.DATE_FIELD);
287        assertFormat(format, " d", new GregorianCalendar(1999, Calendar.NOVEMBER, 12), " 12",
288                DateFormat.DATE_FIELD);
289        assertFormat(format, " dd", cal, " 02", DateFormat.DATE_FIELD);
290        assertFormat(format, " dddd", cal, " 0002", DateFormat.DATE_FIELD);
291
292        assertFormat(format, " h", cal, " 3", DateFormat.HOUR1_FIELD);
293        assertFormat(format, " h", new GregorianCalendar(1999, Calendar.NOVEMBER, 12), " 12",
294                DateFormat.HOUR1_FIELD);
295        assertFormat(format, " hh", cal, " 03", DateFormat.HOUR1_FIELD);
296        assertFormat(format, " hhhh", cal, " 0003", DateFormat.HOUR1_FIELD);
297
298        assertFormat(format, " H", cal, " 15", DateFormat.HOUR_OF_DAY0_FIELD);
299        assertFormat(format, " H", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 4, 0), " 4",
300                DateFormat.HOUR_OF_DAY0_FIELD);
301        assertFormat(format, " H", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 12, 0), " 12",
302                DateFormat.HOUR_OF_DAY0_FIELD);
303        assertFormat(format, " H", new GregorianCalendar(1999, Calendar.NOVEMBER, 12), " 0",
304                DateFormat.HOUR_OF_DAY0_FIELD);
305        assertFormat(format, " HH", cal, " 15", DateFormat.HOUR_OF_DAY0_FIELD);
306        assertFormat(format, " HHHH", cal, " 0015", DateFormat.HOUR_OF_DAY0_FIELD);
307
308        assertFormat(format, " m", cal, " 3", DateFormat.MINUTE_FIELD);
309        assertFormat(format, " m", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 4, 47), " 47",
310                DateFormat.MINUTE_FIELD);
311        assertFormat(format, " mm", cal, " 03", DateFormat.MINUTE_FIELD);
312        assertFormat(format, " mmmm", cal, " 0003", DateFormat.MINUTE_FIELD);
313
314        assertFormat(format, " s", cal, " 6", DateFormat.SECOND_FIELD);
315        assertFormat(format, " s", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 4, 47, 13), " 13",
316                DateFormat.SECOND_FIELD);
317        assertFormat(format, " ss", cal, " 06", DateFormat.SECOND_FIELD);
318        assertFormat(format, " ssss", cal, " 0006", DateFormat.SECOND_FIELD);
319
320        assertFormat(format, " S", cal, " 0", DateFormat.MILLISECOND_FIELD);
321        Calendar temp = new GregorianCalendar();
322        temp.set(Calendar.MILLISECOND, 961);
323
324        assertFormat(format, " SS", temp, " 96", DateFormat.MILLISECOND_FIELD);
325        assertFormat(format, " SSSS", cal, " 0000", DateFormat.MILLISECOND_FIELD);
326
327        assertFormat(format, " SS", cal, " 00", DateFormat.MILLISECOND_FIELD);
328
329        assertFormat(format, " E", cal, " Wed", DateFormat.DAY_OF_WEEK_FIELD);
330        assertFormat(format, " EE", cal, " Wed", DateFormat.DAY_OF_WEEK_FIELD);
331        assertFormat(format, " EEE", cal, " Wed", DateFormat.DAY_OF_WEEK_FIELD);
332        assertFormat(format, " EEEE", cal, " Wednesday", DateFormat.DAY_OF_WEEK_FIELD);
333        assertFormat(format, " EEEEE", cal, " W", DateFormat.DAY_OF_WEEK_FIELD);
334
335        assertFormat(format, " D", cal, " 153", DateFormat.DAY_OF_YEAR_FIELD);
336        assertFormat(format, " DD", cal, " 153", DateFormat.DAY_OF_YEAR_FIELD);
337        assertFormat(format, " DDDD", cal, " 0153", DateFormat.DAY_OF_YEAR_FIELD);
338
339        assertFormat(format, " F", cal, " 1", DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD);
340        assertFormat(format, " F", new GregorianCalendar(1999, Calendar.NOVEMBER, 14), " 2",
341                DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD);
342        assertFormat(format, " FF", cal, " 01", DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD);
343        assertFormat(format, " FFFF", cal, " 0001", DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD);
344
345        cal.setMinimalDaysInFirstWeek(1);
346        cal.setFirstDayOfWeek(1);
347
348        assertFormat(format, " w", cal, " 23", DateFormat.WEEK_OF_YEAR_FIELD);
349        assertFormat(format, " ww", cal, " 23", DateFormat.WEEK_OF_YEAR_FIELD);
350        assertFormat(format, " wwww", cal, " 0023", DateFormat.WEEK_OF_YEAR_FIELD);
351
352        assertFormat(format, " W", cal, " 1", DateFormat.WEEK_OF_MONTH_FIELD);
353        assertFormat(format, " WW", cal, " 01", DateFormat.WEEK_OF_MONTH_FIELD);
354        assertFormat(format, " WWWW", cal, " 0001", DateFormat.WEEK_OF_MONTH_FIELD);
355
356        assertFormat(format, " a", cal, " PM", DateFormat.AM_PM_FIELD);
357        assertFormat(format, " a", new GregorianCalendar(1999, Calendar.NOVEMBER, 14), " AM",
358                DateFormat.AM_PM_FIELD);
359        assertFormat(format, " a", new GregorianCalendar(1999, Calendar.NOVEMBER, 14, 12, 0), " PM",
360                DateFormat.AM_PM_FIELD);
361        assertFormat(format, " aa", cal, " PM", DateFormat.AM_PM_FIELD);
362        assertFormat(format, " aaa", cal, " PM", DateFormat.AM_PM_FIELD);
363        assertFormat(format, " aaaa", cal, " PM", DateFormat.AM_PM_FIELD);
364        assertFormat(format, " aaaaa", cal, " PM", DateFormat.AM_PM_FIELD);
365
366        assertFormat(format, " k", cal, " 15", DateFormat.HOUR_OF_DAY1_FIELD);
367        assertFormat(format, " k", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 4, 0), " 4",
368                DateFormat.HOUR_OF_DAY1_FIELD);
369        assertFormat(format, " k", new GregorianCalendar(1999, Calendar.NOVEMBER, 12, 12, 0), " 12",
370                DateFormat.HOUR_OF_DAY1_FIELD);
371        assertFormat(format, " k", new GregorianCalendar(1999, Calendar.NOVEMBER, 12), " 24",
372                DateFormat.HOUR_OF_DAY1_FIELD);
373        assertFormat(format, " kk", cal, " 15", DateFormat.HOUR_OF_DAY1_FIELD);
374        assertFormat(format, " kkkk", cal, " 0015", DateFormat.HOUR_OF_DAY1_FIELD);
375
376        assertFormat(format, " K", cal, " 3", DateFormat.HOUR0_FIELD);
377        assertFormat(format, " K", new GregorianCalendar(1999, Calendar.NOVEMBER, 12), " 0",
378                DateFormat.HOUR0_FIELD);
379        assertFormat(format, " KK", cal, " 03", DateFormat.HOUR0_FIELD);
380        assertFormat(format, " KKKK", cal, " 0003", DateFormat.HOUR0_FIELD);
381
382        format.applyPattern("'Mkz''':.@5");
383        assertEquals("Wrong output", "Mkz':.@5", format.format(new Date()));
384
385        // Test invalid args to format.
386        SimpleDateFormat dateFormat = new SimpleDateFormat();
387        try {
388            dateFormat.format(null, new StringBuffer(), new FieldPosition(1));
389            fail();
390        } catch (NullPointerException expected) {
391        }
392    }
393
394    private void assertFormat(SimpleDateFormat format, String pattern, Calendar cal,
395            String expected, int field) {
396        StringBuffer buffer = new StringBuffer();
397        FieldPosition position = new FieldPosition(field);
398        format.applyPattern(pattern);
399        format.format(cal.getTime(), buffer, position);
400        String result = buffer.toString();
401        assertTrue("Wrong format: \"" + pattern + "\" expected: " + expected + " result: " + result,
402                result.equals(expected));
403        assertEquals("Wrong begin position: " + pattern + "\n" + "expected: " + expected + "\n" +
404                "field: " + field, 1, position.getBeginIndex());
405        assertTrue("Wrong end position: " + pattern + " expected: " + expected + " field: " + field,
406                position.getEndIndex() == result.length());
407    }
408
409    public void test_format_time_zones() throws Exception {
410        Calendar cal = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3, 6);
411
412        SimpleDateFormat format = new SimpleDateFormat("", Locale.ENGLISH);
413        format.setTimeZone(TimeZone.getTimeZone("EST"));
414        assertFormat(format, " z", cal, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
415        Calendar temp2 = new GregorianCalendar(1999, Calendar.JANUARY, 12);
416        assertFormat(format, " z", temp2, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
417        assertFormat(format, " zz", cal, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
418        assertFormat(format, " zzz", cal, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
419        assertFormat(format, " zzzz", cal, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
420        assertFormat(format, " zzzz", temp2, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
421        assertFormat(format, " zzzzz", cal, " GMT-05:00", DateFormat.TIMEZONE_FIELD);
422
423        format.setTimeZone(TimeZone.getTimeZone("America/New_York"));
424        assertFormat(format, " z", cal, " EDT", DateFormat.TIMEZONE_FIELD);
425        assertFormat(format, " z", temp2, " EST", DateFormat.TIMEZONE_FIELD);
426        assertFormat(format, " zz", cal, " EDT", DateFormat.TIMEZONE_FIELD);
427        assertFormat(format, " zzz", cal, " EDT", DateFormat.TIMEZONE_FIELD);
428        assertFormat(format, " zzzz", cal, " Eastern Daylight Time", DateFormat.TIMEZONE_FIELD);
429        assertFormat(format, " zzzz", temp2, " Eastern Standard Time", DateFormat.TIMEZONE_FIELD);
430        assertFormat(format, " zzzzz", cal, " Eastern Daylight Time", DateFormat.TIMEZONE_FIELD);
431
432        TimeZone tz0001 = new SimpleTimeZone(60000, "ONE MINUTE");
433        TimeZone tz0130 = new SimpleTimeZone(5400000, "ONE HOUR, THIRTY");
434        TimeZone tzMinus0130 = new SimpleTimeZone(-5400000, "NEG ONE HOUR, THIRTY");
435
436        format.setTimeZone(tz0001);
437//        test(" Z", cal, " +0001", DateFormat.TIMEZONE_FIELD);
438//        test(" ZZZZ", cal, " GMT+00:01", DateFormat.TIMEZONE_FIELD);
439//        test(" ZZZZZ", cal, " +00:01", DateFormat.TIMEZONE_FIELD);
440        format.setTimeZone(tz0130);
441//        test(" Z", cal, " +0130", DateFormat.TIMEZONE_FIELD);
442        format.setTimeZone(tzMinus0130);
443//        test(" Z", cal, " -0130", DateFormat.TIMEZONE_FIELD);
444
445        format.setTimeZone(tz0001);
446        assertFormat(format, " z", cal, " GMT+00:01", DateFormat.TIMEZONE_FIELD);
447        assertFormat(format, " zzzz", cal, " GMT+00:01", DateFormat.TIMEZONE_FIELD);
448        format.setTimeZone(tz0130);
449        assertFormat(format, " z", cal, " GMT+01:30", DateFormat.TIMEZONE_FIELD);
450        format.setTimeZone(tzMinus0130);
451        assertFormat(format, " z", cal, " GMT-01:30", DateFormat.TIMEZONE_FIELD);
452    }
453
454    public void test_timeZoneFormatting() {
455        // tests specific to formatting of timezones
456        Date summerDate = new GregorianCalendar(1999, Calendar.JUNE, 2, 15, 3, 6).getTime();
457        Date winterDate = new GregorianCalendar(1999, Calendar.JANUARY, 12).getTime();
458
459        verifyFormatTimezone(
460                "America/Los_Angeles", "PDT, Pacific Daylight Time", "-0700, GMT-07:00",
461                summerDate);
462        verifyFormatTimezone(
463                "America/Los_Angeles", "PST, Pacific Standard Time", "-0800, GMT-08:00",
464                winterDate);
465
466        verifyFormatTimezone("GMT-7", "GMT-07:00, GMT-07:00", "-0700, GMT-07:00", summerDate);
467        verifyFormatTimezone("GMT-7", "GMT-07:00, GMT-07:00", "-0700, GMT-07:00", winterDate);
468
469        verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, GMT+14:00", summerDate);
470        verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, GMT+14:00", winterDate);
471
472        // this fails on the RI!
473        verifyFormatTimezone("America/Detroit", "EDT, Eastern Daylight Time", "-0400, GMT-04:00",
474                summerDate);
475        verifyFormatTimezone("America/Detroit", "EST, Eastern Standard Time", "-0500, GMT-05:00",
476                winterDate);
477
478        // Pacific/Kiritimati is one of the timezones supported only in mJava
479        verifyFormatTimezone(
480                "Pacific/Kiritimati", "GMT+14:00, Line Islands Time", "+1400, GMT+14:00",
481                summerDate);
482        verifyFormatTimezone(
483                "Pacific/Kiritimati", "GMT+14:00, Line Islands Time", "+1400, GMT+14:00",
484                winterDate);
485
486        verifyFormatTimezone("EST", "GMT-05:00, GMT-05:00", "-0500, GMT-05:00", summerDate);
487        verifyFormatTimezone("EST", "GMT-05:00, GMT-05:00", "-0500, GMT-05:00", winterDate);
488
489        verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, GMT+14:00", summerDate);
490        verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, GMT+14:00", winterDate);
491    }
492
493    private void verifyFormatTimezone(String timeZoneId, String expected1, String expected2,
494            Date date) {
495        SimpleDateFormat format = new SimpleDateFormat("", Locale.ENGLISH);
496        format.setTimeZone(SimpleTimeZone.getTimeZone(timeZoneId));
497        format.applyPattern("z, zzzz");
498        assertEquals("Test z for TimeZone : " + timeZoneId, expected1, format.format(date));
499
500        format.applyPattern("Z, ZZZZ");
501        assertEquals("Test Z for TimeZone : " + timeZoneId, expected2, format.format(date));
502    }
503
504    public void test_get2DigitYearStart() {
505        // Test for method java.util.Date
506        // java.text.SimpleDateFormat.get2DigitYearStart()
507        SimpleDateFormat f1 = new SimpleDateFormat("y");
508        Date date = f1.get2DigitYearStart();
509        Calendar cal = new GregorianCalendar();
510        int year = cal.get(Calendar.YEAR);
511        cal.setTime(date);
512        assertTrue("Wrong default year start", cal.get(Calendar.YEAR) == (year - 80));
513    }
514
515    public void test_getDateFormatSymbols() {
516        // Test for method java.text.DateFormatSymbols
517        // java.text.SimpleDateFormat.getDateFormatSymbols()
518        SimpleDateFormat df = (SimpleDateFormat) DateFormat.getInstance();
519        DateFormatSymbols dfs = df.getDateFormatSymbols();
520        assertTrue("Symbols identical", dfs != df.getDateFormatSymbols());
521    }
522
523    public void test_parseLjava_lang_StringLjava_text_ParsePosition() throws Exception {
524        // Test for method java.util.Date
525        // java.text.SimpleDateFormat.parse(java.lang.String,
526        // java.text.ParsePosition)
527        Calendar cal = new GregorianCalendar(1970, Calendar.JANUARY, 1);
528        Date time = cal.getTime();
529        assertParse("h", " 12", time, 1, 3);
530        assertParse("H", " 0", time, 1, 2);
531        assertParse("k", " 24", time, 1, 3);
532        assertParse("K", " 0", time, 1, 2);
533
534        cal = new GregorianCalendar(1970, Calendar.JANUARY, 1, 1, 0);
535        time = cal.getTime();
536        assertParse("h", "1", time, 0, 1);
537        assertParse("H", "1 ", time, 0, 1);
538        assertParse("k", "1", time, 0, 1);
539        assertParse("K", "1", time, 0, 1);
540
541        cal = new GregorianCalendar(1970, Calendar.JANUARY, 1, 11, 0);
542        time = cal.getTime();
543        assertParse("h", "0011 ", time, 0, 4);
544        assertParse("K", "11", time, 0, 2);
545        cal = new GregorianCalendar(1970, Calendar.JANUARY, 1, 23, 0);
546        time = cal.getTime();
547        assertParse("H", "23", time, 0, 2);
548        assertParse("k", "23", time, 0, 2);
549
550        assertParse("h a", " 3 AM", new GregorianCalendar(1970,
551                Calendar.JANUARY, 1, 3, 0).getTime(), 1, 5);
552        assertParse("K a", " 3 pm ", new GregorianCalendar(1970,
553                Calendar.JANUARY, 1, 15, 0).getTime(), 1, 5);
554        assertParse("m:s", "0:59 ", new GregorianCalendar(1970,
555                Calendar.JANUARY, 1, 0, 0, 59).getTime(), 0, 4);
556        assertParse("m:s", "59:0", new GregorianCalendar(1970, Calendar.JANUARY,
557                1, 0, 59, 0).getTime(), 0, 4);
558        assertParse("ms", "059", new GregorianCalendar(1970, Calendar.JANUARY,
559                1, 0, 0, 59).getTime(), 0, 3);
560
561        cal = new GregorianCalendar(1970, Calendar.JANUARY, 1);
562        assertParse("S", "0", cal.getTime(), 0, 1);
563        cal.setTimeZone(TimeZone.getTimeZone("HST"));
564        cal.set(Calendar.MILLISECOND, 999);
565        assertParse("S z", "999 HST", cal.getTime(), 0, 7);
566
567        cal = new GregorianCalendar(1970, Calendar.JANUARY, 1);
568        cal.set(Calendar.ERA, GregorianCalendar.BC);
569        assertParse("G", "Bc ", cal.getTime(), 0, 2);
570    }
571
572    public void test_parse_y() throws Exception {
573        assertParse("y", "00", new GregorianCalendar(2000, Calendar.JANUARY, 1).getTime(), 0, 2);
574        assertParse("y", "99", new GregorianCalendar(1999, Calendar.JANUARY, 1).getTime(), 0, 2);
575        assertParse("y", "1", new GregorianCalendar(1, Calendar.JANUARY, 1).getTime(), 0, 1);
576        assertParse("y", "-1", new GregorianCalendar(-1, Calendar.JANUARY, 1).getTime(), 0, 2);
577        assertParse("y", "001", new GregorianCalendar(1, Calendar.JANUARY, 1).getTime(), 0, 3);
578        assertParse("y", "2005", new GregorianCalendar(2005, Calendar.JANUARY, 1).getTime(), 0, 4);
579    }
580
581    public void test_parse_yy() throws Exception {
582        assertParse("yy", "00", new GregorianCalendar(2000, Calendar.JANUARY, 1).getTime(), 0, 2);
583        assertParse("yy", "99", new GregorianCalendar(1999, Calendar.JANUARY, 1).getTime(), 0, 2);
584        assertParse("yy", "1", new GregorianCalendar(1, Calendar.JANUARY, 1).getTime(), 0, 1);
585        assertParse("yy", "-1", new GregorianCalendar(-1, Calendar.JANUARY, 1).getTime(), 0, 2);
586        assertParse("yy", "001", new GregorianCalendar(1, Calendar.JANUARY, 1).getTime(), 0, 3);
587        assertParse("yy", "2005", new GregorianCalendar(2005, Calendar.JANUARY, 1).getTime(), 0, 4);
588    }
589
590    public void test_parse_yyy() throws Exception {
591        assertParse("yyy", "99", new GregorianCalendar(99, Calendar.JANUARY, 1).getTime(), 0, 2);
592        assertParse("yyy", "1", new GregorianCalendar(1, Calendar.JANUARY, 1).getTime(), 0, 1);
593        assertParse("yyy", "-1", new GregorianCalendar(-1, Calendar.JANUARY, 1).getTime(), 0, 2);
594        assertParse("yyy", "001", new GregorianCalendar(1, Calendar.JANUARY, 1).getTime(), 0, 3);
595        assertParse("yyy", "2005", new GregorianCalendar(2005, Calendar.JANUARY, 1).getTime(),
596                0, 4);
597    }
598
599    public void test_parse_yyyy() throws Exception {
600        assertParse("yyyy", "99", new GregorianCalendar(99, Calendar.JANUARY, 1).getTime(), 0, 2);
601        assertParse("yyyy", "  1999", new GregorianCalendar(1999, Calendar.JANUARY, 1).getTime(),
602                2, 6);
603    }
604
605    public void test_parse_monthPatterns() throws Exception {
606        assertParse("MM'M'", "4M", new GregorianCalendar(1970, Calendar.APRIL, 1).getTime(), 0, 2);
607        assertParse("MMM", "Feb", new GregorianCalendar(1970, Calendar.FEBRUARY, 1).getTime(),
608                0, 3);
609        assertParse("MMMM d", "April 14 ",
610                new GregorianCalendar(1970, Calendar.APRIL, 14).getTime(), 0, 8);
611        assertParse("MMMMd", "April14 ", new GregorianCalendar(1970, Calendar.APRIL, 14).getTime(),
612                0, 7);
613        assertParse("E w", "Mon 12", new GregorianCalendar(1970, Calendar.MARCH, 16).getTime(),
614                0, 6);
615        assertParse("Ew", "Mon12", new GregorianCalendar(1970, Calendar.MARCH, 16).getTime(), 0, 5);
616        assertParse("M EE ''W", "5 Tue '2", new GregorianCalendar(1970, Calendar.MAY, 5).getTime(),
617                0, 8);
618        assertParse("MEE''W", "5Tue'2", new GregorianCalendar(1970, Calendar.MAY, 5).getTime(),
619                0, 6);
620        assertParse("MMM EEE F", " JUL Sunday 3",
621                new GregorianCalendar(1970, Calendar.JULY, 19).getTime(), 1, 13);
622        assertParse("MMMEEEF", " JULSunday3",
623                new GregorianCalendar(1970, Calendar.JULY, 19).getTime(), 1, 11);
624    }
625
626    public void test_parse_dayOfYearPatterns() throws Exception {
627        GregorianCalendar cal = new GregorianCalendar(1970, Calendar.JANUARY, 1);
628        cal.setTimeZone(TimeZone.getTimeZone("GMT+0:1"));
629        cal.set(Calendar.DAY_OF_YEAR, 243);
630        assertParse("D z", "243 GMT+00:00", cal.getTime(), 0, 13);
631    }
632
633    public void test_parse_h_m_z() throws Exception {
634        GregorianCalendar cal = new GregorianCalendar(1970, Calendar.JANUARY, 1);
635        cal.setTimeZone(TimeZone.getTimeZone("EST"));
636        cal.set(1970, Calendar.JANUARY, 1, 4, 30);
637        assertParse("h:m z", "4:30 GMT-5:00", cal.getTime(), 0, 13);
638    }
639
640    public void test_parse_h_z_2DigitOffsetFromGMT_doesNotParse() throws Exception {
641        SimpleDateFormat pFormat = new SimpleDateFormat("h z", Locale.ENGLISH);
642        try {
643            pFormat.parse("14 GMT-23");
644        } catch (ParseException expected) {
645        }
646
647        try {
648            pFormat.parse("14 GMT+23");
649        } catch (ParseException expected) {
650        }
651    }
652
653    public void test_parse_h_z_4DigitOffsetFromGMT() throws Exception {
654        assertParse("h z", "14 GMT-0100 ", new Date(54000000), 0, 11);
655        assertParse("h z", "14 GMT+0100 ", new Date(46800000), 0, 11);
656
657        SimpleDateFormat pFormat = new SimpleDateFormat("h z", Locale.ENGLISH);
658        // Note that OpenJDK only allows zone offsets in the range [-23:59,+23:59]. These offsets
659        // are confined to a narrower range in practice.
660        try {
661            pFormat.parse("14 GMT+24:00");
662            fail();
663        } catch (ParseException expected) {
664        }
665        try {
666            pFormat.parse("14 GMT-24:00");
667            fail();
668        } catch (ParseException expected) {
669        }
670    }
671
672    public void test_parse_h_z_4DigitOffsetNoGMT() throws Exception {
673        assertParse("h z", "14 +0100 ", new Date(46800000), 0, 8);
674        assertParse("h z", "14 -0100 ", new Date(54000000), 0, 8);
675    }
676
677    public void test_parse_yyyyMMddHHmmss() throws Exception {
678        assertParse("yyyyMMddHHmmss", "19990913171901",
679                new GregorianCalendar(1999, Calendar.SEPTEMBER, 13, 17, 19, 1).getTime(), 0, 14);
680    }
681
682    public void test_parse_dd_MMMM_yyyy_EEEE() throws Exception {
683        Date d = new Date(1015822800000L);
684        String pattern = "dd MMMM yyyy EEEE";
685        String dateString = "11 March 2002 Monday";
686        assertFormat(d, pattern, dateString);
687        assertParse(dateString, pattern, d);
688    }
689
690    public void test_parse_dd_MMMM_yyyy_F() throws Exception {
691        Date d = new Date(1015822800000L);
692        String pattern = "dd MMMM yyyy F";
693        String dateString = "11 March 2002 2";
694        assertFormat(d, pattern, dateString);
695        assertParse(dateString, pattern, d);
696    }
697
698    public void test_parse_dd_MMMM_yyyy_w() throws Exception {
699        Date d = new Date(1015822800000L);
700        String pattern = "dd MMMM yyyy w";
701        String dateString = "11 March 2002 11";
702        assertFormat(d, pattern, dateString);
703        assertParse(dateString, pattern, d);
704    }
705
706    public void test_parse_dd_MMMM_yyyy_W() throws Exception {
707        Date d = new Date(1015822800000L);
708        String pattern = "dd MMMM yyyy W";
709        String dateString = "11 March 2002 3";
710        assertFormat(d, pattern, dateString);
711        assertParse(dateString, pattern, d);
712    }
713
714    public void test_parse_dd_MMMM_yyyy_D() throws Exception {
715        // The day of the year overrides the day of the month.
716        Date d = new Date(1015822800000L);
717        String pattern = "dd MMMM yyyy D";
718        assertFormat(d, pattern, "11 March 2002 70");
719        assertParse("5 January 2002 70", pattern, d);
720    }
721
722    public void test_parse_W_w_dd_MMMM_yyyy_EEEE() throws Exception {
723        Date d = new Date(1015822800000L);
724        String pattern = "W w dd MMMM yyyy EEEE";
725        assertFormat(d, pattern, "3 11 11 March 2002 Monday");
726
727        // http://b/27158550 - this behavior changed when Android switched to using OpenJDK code.
728        // The pattern provides the same information in different ways (e.g. W / w / EEEE
729        // all directly affect the day of the week). The result is entirely dependent on how the
730        // Calendar implementation resolves field order.
731        // assertParse("3 12 5 March 2002 Monday", pattern, d);
732    }
733
734    public void test_parse_w_W_dd_MMMM_yyyy_EEEE() throws Exception {
735        Date d = new Date(1015822800000L);
736        String pattern = "w W dd MMMM yyyy EEEE";
737        assertFormat(d, pattern, "11 3 11 March 2002 Monday");
738        assertParse("12 3 5 March 2002 Monday", pattern, d);
739    }
740
741    public void test_parse_F_dd_MMMM_yyyy_EEEE() throws Exception {
742        Date d = new Date(1015822800000L);
743        String pattern = "F dd MMMM yyyy EEEE";
744        assertFormat(d, pattern, "2 11 March 2002 Monday");
745        assertParse("2 5 March 2002 Monday", pattern, d);
746    }
747
748    public void test_parse_w_dd_MMMM_yyyy_EEEE() throws Exception {
749        Date d = new Date(1015822800000L);
750        String pattern = "w dd MMMM yyyy EEEE";
751        assertFormat(d, pattern, "11 11 March 2002 Monday");
752        assertParse("11 5 January 2002 Monday", pattern, d);
753    }
754
755    public void test_parse_w_dd_yyyy_EEEE_MMMM() throws Exception {
756        Date d = new Date(1015822800000L);
757        String pattern = "w dd yyyy EEEE MMMM";
758        assertFormat(d, pattern, "11 11 2002 Monday March");
759        assertParse("11 5 2002 Monday January", pattern, d);
760    }
761
762    public void test_parse_w_yyyy_EEEE_MMMM_dd() throws Exception {
763        Date d = new Date(1015822800000L);
764        String pattern = "w yyyy EEEE MMMM dd";
765        assertFormat(d, pattern, "11 2002 Monday March 11");
766        assertParse("17 2002 Monday March 11", pattern, d);
767    }
768
769    public void test_parse_dd_D_yyyy_MMMM() throws Exception {
770        Date d = new Date(1015822800000L);
771        String pattern = "dd D yyyy MMMM";
772        assertFormat(d, pattern, "11 70 2002 March");
773        assertParse("5 70 2002 January", pattern, d);
774    }
775
776    public void test_parse_D_dd_yyyy_MMMM() throws Exception {
777        Date d = new Date(1015822800000L);
778        String pattern = "D dd yyyy MMMM";
779        assertFormat(d, pattern, "70 11 2002 March");
780        assertParse("240 11 2002 March", pattern, d);
781    }
782
783    private static void assertParse(String input, String pattern, Date expectedDate)
784            throws Exception {
785        SimpleDateFormat df = new SimpleDateFormat(pattern, new Locale("en", "US"));
786        df.setTimeZone(TimeZone.getTimeZone("EST"));
787        Date date = df.parse(input);
788        assertEquals("Invalid result '" + pattern + "'", expectedDate, date);
789    }
790
791    private static void assertFormat(Date date, String pattern, String expectedOutput) {
792        SimpleDateFormat df = new SimpleDateFormat(pattern, new Locale("en", "US"));
793        df.setTimeZone(TimeZone.getTimeZone("EST"));
794        String output = df.format(date);
795        assertEquals("Invalid output '" + pattern + "'", expectedOutput, output);
796    }
797
798    public void test_parse_nullParsePosition() {
799        SimpleDateFormat format = new SimpleDateFormat("", Locale.ENGLISH);
800        try {
801            format.parse("240 11 2002 March", null);
802            fail();
803        } catch (NullPointerException expected) {
804        }
805    }
806
807    public void test_parse_nullInput() {
808        SimpleDateFormat format = new SimpleDateFormat("", Locale.ENGLISH);
809        try {
810            format.parse(null, new ParsePosition(0));
811            fail();
812        } catch (NullPointerException expected) {
813        }
814    }
815
816    private void assertParse(String pattern, String input, Date expected, int start, int end) {
817        SimpleDateFormat pFormat = new SimpleDateFormat(pattern, Locale.ENGLISH);
818        ParsePosition position = new ParsePosition(start);
819        Date result = pFormat.parse(input, position);
820        assertEquals("Wrong result: " + pattern + " input: " + input +
821                " resultTime: " + ((result == null) ? "null" : result.getTime()),
822                expected, result);
823        assertEquals("Wrong end position: " + pattern + " input: " + input,
824                end, position.getIndex());
825    }
826
827    public void test_set2DigitYearStartLjava_util_Date() {
828        // Test for method void
829        // java.text.SimpleDateFormat.set2DigitYearStart(java.util.Date)
830        SimpleDateFormat f1 = new SimpleDateFormat("yy");
831        f1.set2DigitYearStart(new GregorianCalendar(1950, Calendar.JANUARY, 1).getTime());
832        Calendar cal = new GregorianCalendar();
833        try {
834            cal.setTime(f1.parse("49"));
835            assertEquals("Incorrect year 2049", 2049, cal.get(Calendar.YEAR));
836            cal.setTime(f1.parse("50"));
837            int year = cal.get(Calendar.YEAR);
838            assertTrue("Incorrect year 1950: " + year, year == 1950);
839            f1.applyPattern("y");
840            cal.setTime(f1.parse("00"));
841            assertEquals("Incorrect year 2000", 2000, cal.get(Calendar.YEAR));
842            f1.applyPattern("yyy");
843            cal.setTime(f1.parse("50"));
844            assertEquals("Incorrect year 50", 50, cal.get(Calendar.YEAR));
845        } catch (ParseException e) {
846            fail("ParseException");
847        }
848    }
849
850    public void test_setDateFormatSymbolsLjava_text_DateFormatSymbols() {
851        // Test for method void
852        // java.text.SimpleDateFormat.setDateFormatSymbols(java.text.DateFormatSymbols)
853        SimpleDateFormat f1 = new SimpleDateFormat("a");
854        DateFormatSymbols symbols = new DateFormatSymbols();
855        symbols.setAmPmStrings(new String[] { "morning", "night" });
856        f1.setDateFormatSymbols(symbols);
857        DateFormatSymbols newSym = f1.getDateFormatSymbols();
858        assertTrue("Set incorrectly", newSym.equals(symbols));
859        assertTrue("Not a clone", f1.getDateFormatSymbols() != symbols);
860        String result = f1.format(new GregorianCalendar(1999, Calendar.JUNE, 12, 3, 0).getTime());
861        assertEquals("Incorrect symbols used", "morning", result);
862        symbols.setEras(new String[] { "before", "after" });
863        assertTrue("Identical symbols", !f1.getDateFormatSymbols().equals(symbols));
864
865        try {
866            f1.setDateFormatSymbols(null);
867            fail();
868        } catch (NullPointerException expected) {
869        }
870    }
871
872    public void test_toPattern() {
873        String pattern = "yyyy mm dd";
874        SimpleDateFormat f = new SimpleDateFormat(pattern);
875        assertEquals("Wrong pattern: " + pattern, pattern, f.toPattern());
876
877        pattern = "GyMdkHmsSEDFwWahKz";
878        f = new SimpleDateFormat("GyMdkHmsSEDFwWahKz", new Locale("de", "CH"));
879        assertTrue("Wrong pattern: " + pattern, f.toPattern().equals(pattern));
880
881        pattern = "G y M d Z";
882        f = new SimpleDateFormat(pattern, new Locale("de", "CH"));
883        pattern = f.toPattern();
884        assertTrue("Wrong pattern: " + pattern, f.toPattern().equals(pattern));
885    }
886
887    public void test_toLocalizedPattern() {
888        SimpleDateFormat f2 = new SimpleDateFormat("GyMdkHmsSEDFwWahKzZLc", new Locale("de", "CH"));
889        assertEquals(f2.toPattern(), f2.toLocalizedPattern());
890    }
891
892    public void test_parse_with_spaces() {
893        // Regression for HARMONY-502
894        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
895        df.setLenient(false);
896
897        char allowed_chars[] = { 0x9, 0x20 };
898        String allowed_char_names[] = { "tab", "space" };
899        for (int i = 0; i < allowed_chars.length; i++) {
900            Date expected = new GregorianCalendar(1970, Calendar.JANUARY, 1, 9, 7, 6).getTime();
901            ParsePosition pp = new ParsePosition(0);
902            Date d = df.parse(allowed_chars[i] + "9:07:06", pp);
903            assertNotNull("hour may be prefixed by " + allowed_char_names[i], d);
904            assertEquals(expected, d);
905
906            pp = new ParsePosition(0);
907            d = df.parse("09:" + allowed_chars[i] + "7:06", pp);
908            assertNotNull("minute may be prefixed by " + allowed_char_names[i], d);
909            assertEquals(expected, d);
910
911            pp = new ParsePosition(0);
912            d = df.parse("09:07:" + allowed_chars[i] + "6", pp);
913            assertNotNull("second may be prefixed by " + allowed_char_names[i], d);
914            assertEquals(expected, d);
915        }
916
917        char not_allowed_chars[] = {
918                // whitespace
919                0x1c, 0x1d, 0x1e, 0x1f, 0xa, 0xb, 0xc, 0xd, 0x2001, 0x2002,
920                0x2003, 0x2004, 0x2005, 0x2006, 0x2008, 0x2009, 0x200a, 0x200b,
921                0x2028, 0x2029, 0x3000,
922                // non-breaking space
923                0xA0, 0x2007, 0x202F };
924
925        for (int i = 0; i < not_allowed_chars.length; i++) {
926            ParsePosition pp = new ParsePosition(0);
927            Date d = df.parse(not_allowed_chars[i] + "9:07", pp);
928            assertNull(d);
929
930            pp = new ParsePosition(0);
931            d = df.parse("09:" + not_allowed_chars[i] + "7", pp);
932            assertNull(d);
933
934            pp = new ParsePosition(0);
935            d = df.parse("09:07:" + not_allowed_chars[i] + "6", pp);
936            assertNull(d);
937        }
938    }
939}
940