blob: d276aac088b5bd65cf98ed61c18ddb42db0f677b [file] [log] [blame]
/*
* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.text.*;
import java.util.*;
import java.io.*;
/**
* @test
* @bug 4029195 4052408 4056591 4059917 4060212 4061287 4065240 4071441 4073003
* 4089106 4100302 4101483 4103340 4103341 4104136 4104522 4106807 4108407
* 4134203 4138203 4148168 4151631 4151706 4153860 4162071 4182066 4209272 4210209
* 4213086 4250359 4253490 4266432 4406615 4413980 8008577
* @library /java/text/testlib
* @run main/othervm -Djava.locale.providers=COMPAT,SPI DateFormatRegression
*/
public class DateFormatRegression extends IntlTest {
public static void main(String[] args) throws Exception {
new DateFormatRegression().run(args);
}
public void Test4029195() {
Date today = new Date();
logln("today: " + today);
SimpleDateFormat sdf = (SimpleDateFormat)SimpleDateFormat.getDateInstance();
logln("pattern: " + sdf.toPattern());
logln("today: " + sdf.format(today));
sdf.applyPattern("G yyyy DDD");
String todayS = sdf.format(today);
logln("today: " + todayS);
try {
today = sdf.parse(todayS);
logln("today date: " + today);
} catch(Exception e) {
logln("Error reparsing date: " + e.getMessage());
}
try {
String rt = sdf.format(sdf.parse(todayS));
logln("round trip: " + rt);
if (!rt.equals(todayS)) errln("Fail: Want " + todayS + " Got " + rt);
}
catch (ParseException e) {
errln("Fail: " + e);
e.printStackTrace();
}
}
public void Test4052408() {
DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.SHORT, Locale.US);
Date date = new Date(97, Calendar.MAY, 3, 8, 55);
String str;
logln(str = fmt.format(date));
if (!str.equals("5/3/97 8:55 AM"))
errln("Fail: Test broken; Want 5/3/97 8:55 AM Got " + str);
Hashtable expected = new Hashtable();
expected.put(new Integer(DateFormat.MONTH_FIELD), "5");
expected.put(new Integer(DateFormat.DATE_FIELD), "3");
expected.put(new Integer(DateFormat.YEAR_FIELD), "97");
expected.put(new Integer(DateFormat.HOUR1_FIELD), "8");
expected.put(new Integer(DateFormat.MINUTE_FIELD), "55");
expected.put(new Integer(DateFormat.AM_PM_FIELD), "AM");
StringBuffer buf = new StringBuffer();
String fieldNames[] = {
"ERA_FIELD",
"YEAR_FIELD",
"MONTH_FIELD",
"DATE_FIELD",
"HOUR_OF_DAY1_FIELD",
"HOUR_OF_DAY0_FIELD",
"MINUTE_FIELD",
"SECOND_FIELD",
"MILLISECOND_FIELD",
"DAY_OF_WEEK_FIELD",
"DAY_OF_YEAR_FIELD",
"DAY_OF_WEEK_IN_MONTH_FIELD",
"WEEK_OF_YEAR_FIELD",
"WEEK_OF_MONTH_FIELD",
"AM_PM_FIELD",
"HOUR1_FIELD",
"HOUR0_FIELD",
"TIMEZONE_FIELD",
};
boolean pass = true;
for (int i=0; i<=17; ++i) {
FieldPosition pos = new FieldPosition(i);
fmt.format(date, buf, pos);
char[] dst = new char[pos.getEndIndex() - pos.getBeginIndex()];
buf.getChars(pos.getBeginIndex(), pos.getEndIndex(), dst, 0);
str = new String(dst);
log(i + ": " + fieldNames[i] +
", \"" + str + "\", " +
pos.getBeginIndex() + ", " +
pos.getEndIndex());
String exp = (String) expected.get(new Integer(i));
if ((exp == null && str.length() == 0) ||
str.equals(exp))
logln(" ok");
else {
logln(" expected " + exp);
pass = false;
}
}
if (!pass) errln("Fail: FieldPosition not set right by DateFormat");
}
/**
* Verify the function of the [s|g]et2DigitYearStart() API.
*/
public void Test4056591() {
try {
SimpleDateFormat fmt = new SimpleDateFormat("yyMMdd", Locale.US);
Date start = new Date(1809-1900, Calendar.DECEMBER, 25);
fmt.set2DigitYearStart(start);
if (!fmt.get2DigitYearStart().equals(start))
errln("get2DigitYearStart broken");
Object[] DATA = {
"091225", new Date(1809-1900, Calendar.DECEMBER, 25),
"091224", new Date(1909-1900, Calendar.DECEMBER, 24),
"091226", new Date(1809-1900, Calendar.DECEMBER, 26),
"611225", new Date(1861-1900, Calendar.DECEMBER, 25),
};
for (int i=0; i<DATA.length; i+=2) {
String s = (String) DATA[i];
Date exp = (Date) DATA[i+1];
Date got = fmt.parse(s);
logln(s + " -> " + got + "; exp " + exp);
if (!got.equals(exp)) errln("set2DigitYearStart broken");
}
}
catch (ParseException e) {
errln("Fail: " + e);
e.printStackTrace();
}
}
public void Test4059917() {
if (Locale.getDefault().equals(new Locale("hi", "IN"))) {
return;
}
SimpleDateFormat fmt;
String myDate;
fmt = new SimpleDateFormat( "yyyy/MM/dd" );
myDate = "1997/01/01";
aux917( fmt, myDate );
fmt = new SimpleDateFormat( "yyyyMMdd" );
myDate = "19970101";
aux917( fmt, myDate );
}
void aux917( SimpleDateFormat fmt, String str ) {
try {
logln( "==================" );
logln( "testIt: pattern=" + fmt.toPattern() +
" string=" + str );
Object o;
o = fmt.parseObject( str );
logln( "Parsed object: " + o );
String formatted = fmt.format( o );
logln( "Formatted string: " + formatted );
if (!formatted.equals(str)) errln("Fail: Want " + str + " Got " + formatted);
}
catch (ParseException e) {
errln("Fail: " + e);
e.printStackTrace();
}
}
public void Test4060212() {
Locale savedLocale = Locale.getDefault();
Locale.setDefault(Locale.US);
try {
String dateString = "1995-040.05:01:29";
logln( "dateString= " + dateString );
logln("Using yyyy-DDD.hh:mm:ss");
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-DDD.hh:mm:ss");
ParsePosition pos = new ParsePosition(0);
Date myDate = formatter.parse( dateString, pos );
String myString = DateFormat.getDateTimeInstance( DateFormat.FULL,
DateFormat.LONG).format( myDate );
logln( myString );
Calendar cal = new GregorianCalendar();
cal.setTime(myDate);
if (cal.get(Calendar.DAY_OF_YEAR) != 40)
errln("Fail: Got " + cal.get(Calendar.DAY_OF_YEAR) +
" Want 40");
logln("Using yyyy-ddd.hh:mm:ss");
formatter = new SimpleDateFormat("yyyy-ddd.hh:mm:ss");
pos = new ParsePosition(0);
myDate = formatter.parse( dateString, pos );
myString = DateFormat.getDateTimeInstance( DateFormat.FULL,
DateFormat.LONG).format( myDate );
logln( myString );
cal.setTime(myDate);
if (cal.get(Calendar.DAY_OF_YEAR) != 40)
errln("Fail: Got " + cal.get(Calendar.DAY_OF_YEAR) +
" Want 40");
}
finally {
Locale.setDefault(savedLocale);
}
}
public void Test4061287() {
SimpleDateFormat df = new SimpleDateFormat("dd/MM/yyyy");
try {
logln(df.parse("35/01/1971").toString());
}
catch (ParseException e) {
errln("Fail: " + e);
e.printStackTrace();
}
df.setLenient(false);
boolean ok = false;
try {
logln(df.parse("35/01/1971").toString());
} catch (ParseException e) {ok=true;}
if (!ok) errln("Fail: Lenient not working");
}
public void Test4065240() {
Date curDate;
DateFormat shortdate, fulldate;
String strShortDate, strFullDate;
Locale saveLocale = Locale.getDefault();
TimeZone saveZone = TimeZone.getDefault();
try {
Locale curLocale = new Locale("de","DE");
Locale.setDefault(curLocale);
TimeZone.setDefault(TimeZone.getTimeZone("EST"));
curDate = new Date(98, 0, 1);
shortdate = DateFormat.getDateInstance(DateFormat.SHORT);
fulldate = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG
);
strShortDate = new String("The current date (short form) is " + shortdate.
format(curDate));
strFullDate = new String("The current date (long form) is " + fulldate.format(curDate));
logln(strShortDate);
logln(strFullDate);
// UPDATE THIS AS ZONE NAME RESOURCE FOR <EST> in de_DE is updated
if (!strFullDate.endsWith("EST")
&& !strFullDate.endsWith("GMT-05:00")) {
errln("Fail: Want GMT-05:00");
}
}
finally {
Locale.setDefault(saveLocale);
TimeZone.setDefault(saveZone);
}
}
/*
DateFormat.equals is too narrowly defined. As a result, MessageFormat
does not work correctly. DateFormat.equals needs to be written so
that the Calendar sub-object is not compared using Calendar.equals,
but rather compared for equivalency. This may necessitate adding a
(package private) method to Calendar to test for equivalency.
Currently this bug breaks MessageFormat.toPattern
*/
public void Test4071441() {
DateFormat fmtA = DateFormat.getInstance();
DateFormat fmtB = DateFormat.getInstance();
Calendar calA = fmtA.getCalendar();
Calendar calB = fmtB.getCalendar();
Date epoch = new Date(0);
Date xmas = new Date(61, Calendar.DECEMBER, 25);
calA.setTime(epoch);
calB.setTime(epoch);
if (!calA.equals(calB))
errln("Fail: Can't complete test; Calendar instances unequal");
if (!fmtA.equals(fmtB))
errln("Fail: DateFormat unequal when Calendars equal");
calB.setTime(xmas);
if (calA.equals(calB))
errln("Fail: Can't complete test; Calendar instances equal");
if (!fmtA.equals(fmtB))
errln("Fail: DateFormat unequal when Calendars equivalent");
logln("DateFormat.equals ok");
}
/* The java.text.DateFormat.parse(String) method expects for the
US locale a string formatted according to mm/dd/yy and parses it
correctly.
When given a string mm/dd/yyyy it only parses up to the first
two y's, typically resulting in a date in the year 1919.
Please extend the parsing method(s) to handle strings with
four-digit year values (probably also applicable to various
other locales. */
public void Test4073003() {
try {
DateFormat fmt = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
String[] tests = { "12/25/61", "12/25/1961", "4/3/2010", "4/3/10" };
for (int i=0; i<tests.length; i+=2) {
Date d = fmt.parse(tests[i]);
Date dd = fmt.parse(tests[i+1]);
String s = fmt.format(d);
String ss = fmt.format(dd);
if (!d.equals(dd))
errln("Fail: " + d + " != " + dd);
if (!s.equals(ss))
errln("Fail: " + s + " != " + ss);
logln("Ok: " + s + " " + d);
}
}
catch (ParseException e) {
errln("Fail: " + e);
e.printStackTrace();
}
}
public void Test4089106() {
TimeZone def = TimeZone.getDefault();
try {
TimeZone z = new SimpleTimeZone((int)(1.25 * 3600000), "FAKEZONE");
TimeZone.setDefault(z);
SimpleDateFormat f = new SimpleDateFormat();
if (!f.getTimeZone().equals(z))
errln("Fail: SimpleTimeZone should use TimeZone.getDefault()");
}
finally {
TimeZone.setDefault(def);
}
}
public void Test4100302() {
Locale[] locales = new Locale[] {
Locale.CANADA,
Locale.CANADA_FRENCH,
Locale.CHINA,
Locale.CHINESE,
Locale.ENGLISH,
Locale.FRANCE,
Locale.FRENCH,
Locale.GERMAN,
Locale.GERMANY,
Locale.ITALIAN,
Locale.ITALY,
Locale.JAPAN,
Locale.JAPANESE,
Locale.KOREA,
Locale.KOREAN,
Locale.PRC,
Locale.SIMPLIFIED_CHINESE,
Locale.TAIWAN,
Locale.TRADITIONAL_CHINESE,
Locale.UK,
Locale.US
};
try {
boolean pass = true;
for(int i = 0; i < locales.length; i++) {
Format format = DateFormat.getDateTimeInstance(DateFormat.FULL,
DateFormat.FULL, locales[i]);
byte[] bytes;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(format);
oos.flush();
baos.close();
bytes = baos.toByteArray();
ObjectInputStream ois =
new ObjectInputStream(new ByteArrayInputStream(bytes));
if (!format.equals(ois.readObject())) {
pass = false;
logln("DateFormat instance for locale " +
locales[i] + " is incorrectly serialized/deserialized.");
} else {
logln("DateFormat instance for locale " +
locales[i] + " is OKAY.");
}
}
if (!pass) errln("Fail: DateFormat serialization/equality bug");
}
catch (IOException e) {
errln("Fail: " + e);
e.printStackTrace();
}
catch (ClassNotFoundException e) {
errln("Fail: " + e);
e.printStackTrace();
}
}
/**
* Test whether DataFormat can be serialized/deserialized correctly
* even if invalid/customized TimeZone is used.
*/
public void Test4413980() {
TimeZone savedTimeZone = TimeZone.getDefault();
try {
boolean pass = true;
String[] IDs = new String[] {"Undefined", "PST", "US/Pacific",
"GMT+3:00", "GMT-01:30"};
for (int i = 0; i < IDs.length; i++) {
TimeZone tz = TimeZone.getTimeZone(IDs[i]);
TimeZone.setDefault(tz);
Format format = DateFormat.getDateTimeInstance(DateFormat.FULL,
DateFormat.FULL);
byte[] bytes;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(format);
oos.flush();
baos.close();
bytes = baos.toByteArray();
ObjectInputStream ois =
new ObjectInputStream(new ByteArrayInputStream(bytes));
if (!format.equals(ois.readObject())) {
pass = false;
logln("DateFormat instance which uses TimeZone <" +
IDs[i] + "> is incorrectly serialized/deserialized.");
} else {
logln("DateFormat instance which uses TimeZone <" +
IDs[i] + "> is correctly serialized/deserialized.");
}
}
if (!pass) {
errln("Fail: DateFormat serialization/equality bug");
}
}
catch (IOException e) {
errln("Fail: " + e);
e.printStackTrace();
}
catch (ClassNotFoundException e) {
errln("Fail: " + e);
e.printStackTrace();
}
finally {
TimeZone.setDefault(savedTimeZone);
}
}
public void Test4101483() {
SimpleDateFormat sdf = new SimpleDateFormat("z", Locale.US);
FieldPosition fp = new FieldPosition(DateFormat.TIMEZONE_FIELD);
Date d= new Date(9234567890L);
StringBuffer buf = new StringBuffer("");
logln(sdf.format(d, buf, fp).toString());
logln(d + " => " + buf);
logln("beginIndex = " + fp.getBeginIndex());
logln("endIndex = " + fp.getEndIndex());
if (fp.getBeginIndex() == fp.getEndIndex()) errln("Fail: Empty field");
}
/**
* Bug 4103340
* Bug 4138203
* This bug really only works in Locale.US, since that's what the locale
* used for Date.toString() is. Bug 4138203 reports that it fails on Korean
* NT; it would actually have failed on any non-US locale. Now it should
* work on all locales.
*/
public void Test4103340() {
// choose a date that is the FIRST of some month
// and some arbitrary time
Date d=new Date(97, 3, 1, 1, 1, 1);
SimpleDateFormat df=new SimpleDateFormat("MMMM", Locale.US);
String s = d.toString();
String s2 = df.format(d);
logln("Date="+s);
logln("DF="+s2);
if (s.indexOf(s2.substring(0,2)) == -1)
errln("Months should match");
}
public void Test4103341() {
TimeZone saveZone =TimeZone.getDefault();
try {
TimeZone.setDefault(TimeZone.getTimeZone("CST"));
SimpleDateFormat simple = new SimpleDateFormat("MM/dd/yyyy HH:mm");
if (!simple.getTimeZone().equals(TimeZone.getDefault()))
errln("Fail: SimpleDateFormat not using default zone");
}
finally {
TimeZone.setDefault(saveZone);
}
}
public void Test4104136() {
SimpleDateFormat sdf = new SimpleDateFormat();
String pattern = "'time' hh:mm";
sdf.applyPattern(pattern);
logln("pattern: \"" + pattern + "\"");
Object[] DATA = {
"time 10:30", new ParsePosition(10), new Date(70, Calendar.JANUARY, 1, 10, 30),
"time 10:x", new ParsePosition(0), null,
"time 10x", new ParsePosition(0), null,
};
for (int i=0; i<DATA.length; i+=3) {
String text = (String) DATA[i];
ParsePosition finish = (ParsePosition) DATA[i+1];
Date exp = (Date) DATA[i+2];
ParsePosition pos = new ParsePosition(0);
Date d = sdf.parse(text, pos);
logln(" text: \"" + text + "\"");
logln(" index: " + pos.getIndex());
logln(" result: " + d);
if (pos.getIndex() != finish.getIndex())
errln("Fail: Expected pos " + finish.getIndex());
if (!((d == null && exp == null) ||
d.equals(exp)))
errln("Fail: Expected result " + exp);
}
}
/**
* CANNOT REPRODUCE
* According to the bug report, this test should throw a
* StringIndexOutOfBoundsException during the second parse. However,
* this is not seen.
*/
public void Test4104522() {
SimpleDateFormat sdf = new SimpleDateFormat();
String pattern = "'time' hh:mm";
sdf.applyPattern(pattern);
logln("pattern: \"" + pattern + "\"");
// works correctly
ParsePosition pp = new ParsePosition(0);
String text = "time ";
Date date = sdf.parse(text, pp);
logln(" text: \"" + text + "\"" +
" date: " + date);
// works wrong
pp = new ParsePosition(0);
text = "time";
date = sdf.parse(text, pp);
logln(" text: \"" + text + "\"" +
" date: " + date);
}
public void Test4106807() {
Date date;
DateFormat df = DateFormat.getDateTimeInstance();
Object[] data = {
new SimpleDateFormat("yyyyMMddHHmmss"), "19980211140000",
new SimpleDateFormat("yyyyMMddHHmmss'Z'"), "19980211140000",
new SimpleDateFormat("yyyyMMddHHmmss''"), "19980211140000",
new SimpleDateFormat("yyyyMMddHHmmss'a''a'"), "19980211140000a",
new SimpleDateFormat("yyyyMMddHHmmss %"), "19980211140000 ",
};
GregorianCalendar gc = new GregorianCalendar();
TimeZone timeZone = TimeZone.getDefault();
TimeZone gmt = (TimeZone)timeZone.clone();
gmt.setRawOffset(0);
for (int i=0; i<data.length; i+=2) {
SimpleDateFormat format = (SimpleDateFormat) data[i];
String dateString = (String) data[i+1];
try {
format.setTimeZone(gmt);
date = format.parse(dateString);
logln(df.format(date));
gc.setTime(date);
logln("" + gc.get(Calendar.ZONE_OFFSET));
logln(format.format(date));
}
catch (ParseException e) {
logln("No way Jose");
}
}
}
/*
Synopsis: Chinese time zone CTT is not recogonized correctly.
Description: Platform Chinese Windows 95 - ** Time zone set to CST **
*/
public void Test4108407() {
long l = System.currentTimeMillis();
logln("user.timezone = " + System.getProperty("user.timezone", "?"));
logln("Time Zone :" +
DateFormat.getDateInstance().getTimeZone().getID());
logln("Default format :" +
DateFormat.getDateInstance().format(new Date(l)));
logln("Full format :" +
DateFormat.getDateInstance(DateFormat.FULL).format(new
Date(l)));
logln("*** Set host TZ to CST ***");
logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");
}
/**
* SimpleDateFormat won't parse "GMT"
*/
public void Test4134203() {
String dateFormat = "MM/dd/yy HH:mm:ss zzz";
SimpleDateFormat fmt = new SimpleDateFormat(dateFormat);
ParsePosition p0 = new ParsePosition(0);
Date d = fmt.parse("01/22/92 04:52:00 GMT", p0);
logln(d.toString());
// In the failure case an exception is thrown by parse();
// if no exception is thrown, the test passes.
}
/**
* Another format for GMT string parse
*/
public void Test4266432() {
String dateFormat = "MM/dd HH:mm:ss zzz yyyy";
SimpleDateFormat fmt = new SimpleDateFormat(dateFormat);
ParsePosition p0 = new ParsePosition(0);
Date d = fmt.parse("01/22 04:52:00 GMT 1992", p0);
logln(d.toString());
// In the failure case an exception is thrown by parse();
// if no exception is thrown, the test passes.
}
/**
* Millisecond field is limited to 3 digits; also test general millisecond
* handling.
*
* NOTE: Updated for fixed semantics as of Kestrel. See
* 4253490
*/
public void Test4148168() throws ParseException {
SimpleDateFormat fmt = new SimpleDateFormat("", Locale.US);
int ms = 456;
String[] PAT = { "S", "SS", "SSS", "SSSS", "SSSSS",
"SSSSSSSSSSSSSSSSSSSS" };
String[] OUT = { "456", "456", "456", "0456", "00456",
"00000000000000000456" };
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(Calendar.MILLISECOND, ms);
Date d = cal.getTime();
for (int i=0; i<OUT.length; ++i) {
fmt.applyPattern(PAT[i]);
String str = fmt.format(d);
if (!str.equals(OUT[i])) {
errln("FAIL: " + ms + " ms x \"" + PAT[i] + "\" -> \"" +
str + "\", exp \"" + OUT[i] + '"');
}
}
// Test parsing
fmt.applyPattern("s.S");
String[] IN = { "1.4", "1.04", "1.004", "1.45", "1.456",
"1.4567", "1.45678" };
int[] MS = { 4, 4, 4, 45, 456, 567, 678 };
for (int i=0; i<IN.length; ++i) {
d = fmt.parse(IN[i]);
cal.setTime(d);
ms = cal.get(Calendar.MILLISECOND);
if (ms != MS[i]) {
errln("FAIL: parse(\"" + IN[i] + "\" x \"s.S\") -> " +
ms + " ms, exp " + MS[i] + " ms");
}
}
}
/**
* SimpleDateFormat incorrect handling of 2 single quotes in format()
*/
public void Test4151631() {
String pattern = "'TO_DATE('''dd'-'MM'-'yyyy HH:mm:ss''' , ''DD-MM-YYYY HH:MI:SS'')'";
logln("pattern=" + pattern);
SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.US);
String result = format.format(new Date(1998-1900, Calendar.JUNE, 30, 13, 30, 0));
if (!result.equals("TO_DATE('30-06-1998 13:30:00' , 'DD-MM-YYYY HH:MI:SS')")) {
errln("Fail: result=" + result);
}
else {
logln("Pass: result=" + result);
}
}
/**
* 'z' at end of date format throws index exception in SimpleDateFormat
* CANNOT REPRODUCE THIS BUG ON 1.2FCS
*/
public void Test4151706() {
SimpleDateFormat fmt =
new SimpleDateFormat("EEEE, dd-MMM-yy HH:mm:ss z", Locale.US);
try {
Date d = fmt.parse("Thursday, 31-Dec-98 23:00:00 GMT");
if (d.getTime() != Date.UTC(1998-1900, Calendar.DECEMBER, 31, 23, 0, 0))
errln("Incorrect value: " + d);
} catch (Exception e) {
errln("Fail: " + e);
}
}
/**
* SimpleDateFormat fails to parse redundant data.
* This is actually a bug down in GregorianCalendar, but it was reported
* as follows...
*/
public void Test4153860() throws ParseException {
Locale savedLocale = Locale.getDefault();
Locale.setDefault(Locale.US);
try {
SimpleDateFormat sf = (SimpleDateFormat)DateFormat.getDateTimeInstance();
// Set the pattern
sf.applyPattern("yyyy.MM-dd");
// Try to create a Date for February 4th
Date d1 = sf.parse("1998.02-04");
// Set the pattern, this time to use the W value
sf.applyPattern("yyyy.MM-dd W");
// Try to create a Date for February 4th
Date d2 = sf.parse("1998.02-04 1");
if (!d1.equals(d2)) {
errln("Parse failed, got " + d2 +
", expected " + d1);
}
}
finally {
Locale.setDefault(savedLocale);
}
}
/**
* Confirm that "EST"(GMT-5:00) and "CST"(GMT-6:00) are used in US
* as "EST" or "CST", not Australian "EST" and "CST".
*/
public void Test4406615() {
Locale savedLocale = Locale.getDefault();
TimeZone savedTimeZone = TimeZone.getDefault();
Locale.setDefault(Locale.US);
TimeZone.setDefault(TimeZone.getTimeZone("PST"));
Date d1, d2;
String dt = "Mon, 1 Jan 2001 00:00:00";
SimpleDateFormat sdf =
new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
try {
d1 = sdf.parse(dt+" EST");
d2 = sdf.parse(dt+" CST");
if (d1.getYear() != (2000-1900) || d1.getMonth() != 11 ||
d1.getDate() != 31 || d1.getHours() != 21 || d1.getMinutes() != 0 ||
d2.getYear() != (2000-1900) || d2.getMonth() != 11 ||
d2.getDate() != 31 || d2.getHours() != 22 || d2.getMinutes() != 0) {
errln("Parse failed, d1 = " + d1 + ", d2 = " + d2);
} else {
logln("Parse passed");
}
}
catch (Exception e) {
errln("Parse failed, got Exception " + e);
}
finally {
Locale.setDefault(savedLocale);
TimeZone.setDefault(savedTimeZone);
}
}
/**
* Cannot reproduce this bug under 1.2 FCS -- it may be a convoluted duplicate
* of some other bug that has been fixed.
*/
public void Test4162071() {
String dateString = "Thu, 30-Jul-1999 11:51:14 GMT";
String format = "EEE', 'dd-MMM-yyyy HH:mm:ss z"; // RFC 822/1123
SimpleDateFormat df = new
SimpleDateFormat(format, Locale.US);
try {
Date x = df.parse(dateString);
logln("Parse format \"" + format + "\" ok");
logln(dateString + " -> " + df.format(x));
} catch (Exception e) {
errln("Parse format \"" + format + "\" failed.");
}
}
/**
* DateFormat shouldn't parse year "-1" as a two-digit year (e.g., "-1" -> 1999).
*/
public void Test4182066() {
Locale savedLocale = Locale.getDefault();
Locale.setDefault(Locale.US);
try {
SimpleDateFormat fmt = new SimpleDateFormat("MM/dd/yy",
DateFormatSymbols.getInstance(Locale.US));
SimpleDateFormat dispFmt = new SimpleDateFormat("MMM dd yyyy GG",
DateFormatSymbols.getInstance(Locale.US));
/* We expect 2-digit year formats to put 2-digit years in the right
* window. Out of range years, that is, anything less than "00" or
* greater than "99", are treated as literal years. So "1/2/3456"
* becomes 3456 AD. Likewise, "1/2/-3" becomes -3 AD == 2 BC.
*/
Object[] DATA = {
"02/29/00", new Date(2000-1900, Calendar.FEBRUARY, 29),
"01/23/01", new Date(2001-1900, Calendar.JANUARY, 23),
"04/05/-1", new Date( -1-1900, Calendar.APRIL, 5),
"01/23/-9", new Date( -9-1900, Calendar.JANUARY, 23),
"11/12/1314", new Date(1314-1900, Calendar.NOVEMBER, 12),
"10/31/1", new Date( 1-1900, Calendar.OCTOBER, 31),
"09/12/+1", null, // "+1" isn't recognized by US NumberFormat
"09/12/001", new Date( 1-1900, Calendar.SEPTEMBER,12),
};
StringBuffer out = new StringBuffer();
boolean pass = true;
for (int i=0; i<DATA.length; i+=2) {
String str = (String) DATA[i];
Date expected = (Date) DATA[i+1];
Date actual;
try {
actual = fmt.parse(str);
} catch (ParseException e) {
actual = null;
}
String actStr = actual != null
? dispFmt.format(actual) : String.valueOf(actual);
if (expected == actual
|| (expected != null && expected.equals(actual))) {
out.append(str + " => " + actStr + "\n");
} else {
String expStr = expected != null
? dispFmt.format(expected) : String.valueOf(expected);
out.append("FAIL: " + str + " => " + actStr
+ ", expected " + expStr + "\n");
pass = false;
}
}
if (pass) {
log(out.toString());
} else {
err(out.toString());
}
}
finally {
Locale.setDefault(savedLocale);
}
}
/**
* Bug 4210209
* Bug 4209272
* DateFormat cannot parse Feb 29 2000 when setLenient(false)
*/
public void Test4210209() {
String pattern = "MMM d, yyyy";
DateFormat fmt = new SimpleDateFormat(pattern,
DateFormatSymbols.getInstance(Locale.US));
fmt.getCalendar().setLenient(false);
Date d = new Date(2000-1900, Calendar.FEBRUARY, 29);
String s = fmt.format(d);
logln(d + " x " + pattern + " => " + s);
ParsePosition pos = new ParsePosition(0);
d = fmt.parse(s, pos);
logln(d + " <= " + pattern + " x " + s);
logln("Parse pos = " + pos);
if (pos.getErrorIndex() != -1) {
errln("FAIL");
}
// The underlying bug is in GregorianCalendar. If the following lines
// succeed, the bug is fixed. If the bug isn't fixed, they will throw
// an exception.
GregorianCalendar cal = new GregorianCalendar();
cal.clear();
cal.setLenient(false);
cal.set(2000, Calendar.FEBRUARY, 29); // This should work!
logln(cal.getTime().toString());
}
/**
* DateFormat.getDateTimeInstance() allows illegal parameters.
*/
public void Test4213086() {
int[] DATA = {
// Style value, 0/1 for illegal/legal
-99, 0,
-1, 0,
0, 1,
1, 1,
2, 1,
3, 1,
4, 0,
99, 0,
};
String[] DESC = {
"getDateTimeInstance(date)",
"getDateTimeInstance(time)",
"getDateInstance",
"getTimeInstance",
};
String[] GOT = {
"disallowed", "allowed", "<invalid>"
};
for (int i=0; i<DATA.length; i+=2) {
int got = 2;
for (int j=0; j<4; ++j) {
Exception e = null;
try {
DateFormat df;
switch (j) {
case 0:
df = DateFormat.getDateTimeInstance(DATA[i], 0);
break;
case 1:
df = DateFormat.getDateTimeInstance(0, DATA[i]);
break;
case 2:
df = DateFormat.getDateInstance(DATA[i]);
break;
case 3:
df = DateFormat.getTimeInstance(DATA[i]);
break;
}
got = 1;
} catch (IllegalArgumentException iae) {
got = 0;
} catch (Exception ex) {
e = ex;
}
if (got != DATA[i+1] || e != null) {
errln("FAIL: DateFormat." + DESC[j] + " style " + DATA[i] + " " +
(e != null ? e.toString() : GOT[got]));
}
}
}
}
public void Test4253490() throws ParseException {
SimpleDateFormat fmt = new SimpleDateFormat("S", Locale.US);
GregorianCalendar cal = new GregorianCalendar();
int FORMAT_MS = 12;
String[] FORMAT_PAT = { "S", "SS", "SSS", "SSSS" };
String[] FORMAT_TO = { "12", "12", "012", "0012" };
String PARSE_PAT = "S";
String[] PARSE_STR = { "1", "12", "125", "1250" };
int[] PARSE_TO = { 1, 12, 125, 250 };
String PARSE_LPAT = "SSSSS";
// Test formatting. We want to make sure all digits are output
// and that they are zero-padded on the left if necessary.
cal.setTime(new Date(0L));
cal.set(Calendar.MILLISECOND, FORMAT_MS);
Date d = cal.getTime();
for (int i=0; i<FORMAT_PAT.length; ++i) {
fmt.applyPattern(FORMAT_PAT[i]);
String s = fmt.format(d);
if (s.equals(FORMAT_TO[i])) {
logln(String.valueOf(FORMAT_MS) + " ms f* \"" +
FORMAT_PAT[i] + "\" -> \"" + s + '"');
} else {
errln("FAIL: " + FORMAT_MS + " ms f* \"" +
FORMAT_PAT[i] + "\" -> \"" + s + "\", expect \"" +
FORMAT_TO[i] + '"');
}
}
// Test parsing. We want to make sure all digits are read.
fmt.applyPattern(PARSE_PAT);
for (int i=0; i<PARSE_STR.length; ++i) {
cal.setTime(fmt.parse(PARSE_STR[i]));
int ms = cal.get(Calendar.MILLISECOND);
if (ms == PARSE_TO[i]) {
logln("\"" + PARSE_STR[i] + "\" p* \"" +
PARSE_PAT + "\" -> " + ms + " ms");
} else {
errln("FAIL: \"" + PARSE_STR[i] + "\" p* \"" +
PARSE_PAT + "\" -> " + ms + " ms, expect " +
PARSE_TO[i] + " ms");
}
}
// Test LONG parsing. We want to make sure all digits are read.
fmt.applyPattern(PARSE_LPAT);
for (int i=0; i<PARSE_STR.length; ++i) {
cal.setTime(fmt.parse(PARSE_STR[i]));
int ms = cal.get(Calendar.MILLISECOND);
if (ms == PARSE_TO[i]) {
logln("\"" + PARSE_STR[i] + "\" p* \"" +
PARSE_LPAT + "\" -> " + ms + " ms");
} else {
errln("FAIL: \"" + PARSE_STR[i] + "\" p* \"" +
PARSE_LPAT + "\" -> " + ms + " ms, expect " +
PARSE_TO[i] + " ms");
}
}
}
/**
* Bug in handling of time instance; introduces in fix for 4213086.
*/
public void Test4250359() {
DateFormat df = DateFormat.getTimeInstance(DateFormat.SHORT,
Locale.US);
Date d = new Date(1999-1900, Calendar.DECEMBER, 25,
1, 2, 3);
String s = df.format(d);
// If the bug is present, we see "1:02 AM 1:02 AM".
// Look for more than one instance of "AM".
int i = s.indexOf("AM");
int j = s.indexOf("AM", i+1);
if (i < 0 || j >= 0) {
errln("FAIL: getTimeInstance().format(d) => \"" +
s + "\"");
}
}
/**
* Test whether SimpleDataFormat (DateFormatSymbols) can format/parse
* non-localized time zones.
*/
public void Test4261506() {
Locale savedLocale = Locale.getDefault();
TimeZone savedTimeZone = TimeZone.getDefault();
Locale.setDefault(Locale.JAPAN);
// XXX: Test assumes "PST" is not TimeZoneNames_ja. Need to
// pick up another time zone when L10N is done to that file.
TimeZone.setDefault(TimeZone.getTimeZone("PST"));
SimpleDateFormat fmt = new SimpleDateFormat("yy/MM/dd hh:ss zzz", Locale.JAPAN);
String result = fmt.format(new Date(1999, 0, 1));
logln("format()=>" + result);
if (!result.endsWith("PST")) {
errln("FAIL: SimpleDataFormat.format() did not retrun PST");
}
Date d = null;
try {
d = fmt.parse("99/1/1 10:10 PST");
} catch (ParseException e) {
errln("FAIL: SimpleDataFormat.parse() could not parse PST");
}
result = fmt.format(d);
logln("roundtrip:" + result);
if (!result.equals("99/01/01 10:10 PST")) {
errln("FAIL: SimpleDataFomat timezone roundtrip failed");
}
Locale.setDefault(savedLocale);
TimeZone.setDefault(savedTimeZone);
}
}
//eof