Add TimeZone and SimpleTimeZone to com.ibm.util.

X-SVN-Rev: 1360
This commit is contained in:
Alan Liu 2000-05-12 23:21:32 +00:00
parent 4a4bbe2373
commit 88e3406421
55 changed files with 11948 additions and 207 deletions

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/demo/calendar/Attic/CalendarApp.java,v $
* $Date: 2000/03/10 03:47:42 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:21:23 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -21,9 +21,6 @@ import java.awt.event.*;
import java.net.*;
import java.io.*;
import java.text.DateFormat;
import java.util.SimpleTimeZone;
import com.ibm.util.*;
import com.ibm.text.*;

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/demo/calendar/Attic/CalendarCalc.java,v $
* $Date: 2000/04/26 18:40:15 $
* $Revision: 1.6 $
* $Date: 2000/05/12 23:21:23 $
* $Revision: 1.7 $
*
*****************************************************************************************
*/
@ -28,7 +28,8 @@ import java.text.ParsePosition;
import com.ibm.util.Calendar;
//import java.util.GregorianCalendar;
import com.ibm.util.GregorianCalendar;
import java.util.TimeZone;
//import java.util.TimeZone;
import com.ibm.util.TimeZone;
import java.util.Locale;
import com.ibm.util.*;
@ -568,4 +569,4 @@ class RollAddField {
}
int field;
String name;
};
};

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/demo/calendar/Attic/CalendarFrame.java,v $
* $Date: 2000/04/26 18:40:15 $
* $Revision: 1.6 $
* $Date: 2000/05/12 23:21:23 $
* $Revision: 1.7 $
*
*****************************************************************************************
*/
@ -20,7 +20,8 @@ import com.ibm.util.BuddhistCalendar;
import com.ibm.util.JapaneseCalendar;
import com.ibm.util.IslamicCalendar;
import com.ibm.text.SimpleDateFormat;
import java.util.SimpleTimeZone;
//import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
@ -37,7 +38,8 @@ import com.ibm.util.GregorianCalendar;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.TimeZone;
//import java.util.TimeZone;
import com.ibm.util.TimeZone;
/**
* A Frame is a top-level window with a title. The default layout for a frame

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/demo/calendar/Attic/CalendarPanel.java,v $
* $Date: 2000/03/31 18:49:02 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:21:23 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -24,7 +24,8 @@ import java.io.*;
//import java.text.DateFormat;
import com.ibm.text.DateFormat;
import java.util.SimpleTimeZone;
//import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
//import java.util.*;
import java.util.Date;
import java.util.Locale;

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/demo/holiday/Attic/HolidayCalendarDemo.java,v $
* $Date: 2000/04/26 19:13:48 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:21:32 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -23,7 +23,8 @@ import java.io.*;
//import java.text.SimpleDateFormat;
import com.ibm.text.SimpleDateFormat;
import java.text.DateFormatSymbols;
import java.util.SimpleTimeZone;
//import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
import java.util.Locale;
import java.util.Vector;
import java.util.Date;

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/demo/calendar/CalendarApp.java,v $
* $Date: 2000/03/10 03:47:42 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:21:23 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -21,9 +21,6 @@ import java.awt.event.*;
import java.net.*;
import java.io.*;
import java.text.DateFormat;
import java.util.SimpleTimeZone;
import com.ibm.util.*;
import com.ibm.text.*;

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/demo/calendar/CalendarCalc.java,v $
* $Date: 2000/04/26 18:40:15 $
* $Revision: 1.6 $
* $Date: 2000/05/12 23:21:23 $
* $Revision: 1.7 $
*
*****************************************************************************************
*/
@ -28,7 +28,8 @@ import java.text.ParsePosition;
import com.ibm.util.Calendar;
//import java.util.GregorianCalendar;
import com.ibm.util.GregorianCalendar;
import java.util.TimeZone;
//import java.util.TimeZone;
import com.ibm.util.TimeZone;
import java.util.Locale;
import com.ibm.util.*;
@ -568,4 +569,4 @@ class RollAddField {
}
int field;
String name;
};
};

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/demo/calendar/CalendarFrame.java,v $
* $Date: 2000/04/26 18:40:15 $
* $Revision: 1.6 $
* $Date: 2000/05/12 23:21:23 $
* $Revision: 1.7 $
*
*****************************************************************************************
*/
@ -20,7 +20,8 @@ import com.ibm.util.BuddhistCalendar;
import com.ibm.util.JapaneseCalendar;
import com.ibm.util.IslamicCalendar;
import com.ibm.text.SimpleDateFormat;
import java.util.SimpleTimeZone;
//import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
@ -37,7 +38,8 @@ import com.ibm.util.GregorianCalendar;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.TimeZone;
//import java.util.TimeZone;
import com.ibm.util.TimeZone;
/**
* A Frame is a top-level window with a title. The default layout for a frame

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/demo/calendar/CalendarPanel.java,v $
* $Date: 2000/03/31 18:49:02 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:21:23 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -24,7 +24,8 @@ import java.io.*;
//import java.text.DateFormat;
import com.ibm.text.DateFormat;
import java.util.SimpleTimeZone;
//import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
//import java.util.*;
import java.util.Date;
import java.util.Locale;

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/demo/holiday/HolidayCalendarDemo.java,v $
* $Date: 2000/04/26 19:13:48 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:21:32 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -23,7 +23,8 @@ import java.io.*;
//import java.text.SimpleDateFormat;
import com.ibm.text.SimpleDateFormat;
import java.text.DateFormatSymbols;
import java.util.SimpleTimeZone;
//import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
import java.util.Locale;
import java.util.Vector;
import java.util.Date;

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/calendar/AstroTest.java,v $
* $Date: 2000/03/21 02:20:08 $
* $Revision: 1.3 $
* $Date: 2000/05/12 23:19:12 $
* $Revision: 1.4 $
*
*****************************************************************************************
*/
@ -15,7 +15,6 @@ package com.ibm.test.calendar;
// AstroTest
import com.ibm.test.*;
import java.util.SimpleTimeZone;
import com.ibm.util.*;
import com.ibm.util.CalendarAstronomer.*;

View File

@ -1,8 +1,6 @@
package com.ibm.test.calendar;
import com.ibm.util.*;
import java.util.Date;
import java.util.TimeZone;
import java.util.SimpleTimeZone;
import java.util.Locale;
import com.ibm.text.*;
@ -771,23 +769,25 @@ public class CalendarRegression extends com.ibm.test.TestFmwk {
// I am disabling this test -- it is currently failing because of a bug
// in Sun's latest change to STZ.getOffset(). I have filed a Sun bug
// against this problem.
//! /**
//! * Prove that GregorianCalendar is proleptic (it used to cut off
//! * at 45 BC, and not have leap years before then).
//! */
//! public void Test4125892() {
//! GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();
//! DateFormat fmt = new SimpleDateFormat("MMMM d, yyyy G");
//! cal.clear();
//! cal.set(Calendar.ERA, GregorianCalendar.BC);
//! cal.set(Calendar.YEAR, 81); // 81 BC is a leap year (proleptically)
//! cal.set(Calendar.MONTH, Calendar.FEBRUARY);
//! cal.set(Calendar.DATE, 28);
//! cal.add(Calendar.DATE, 1);
//! if (cal.get(Calendar.DATE) != 29 ||
//! !cal.isLeapYear(-80)) // -80 == 81 BC
//! errln("Calendar not proleptic");
//! }
// Re-enabled after 'porting' TZ and STZ from java.util to com.ibm.util.
/**
* Prove that GregorianCalendar is proleptic (it used to cut off
* at 45 BC, and not have leap years before then).
*/
public void Test4125892() {
GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();
DateFormat fmt = new SimpleDateFormat("MMMM d, yyyy G");
cal.clear();
cal.set(Calendar.ERA, GregorianCalendar.BC);
cal.set(Calendar.YEAR, 81); // 81 BC is a leap year (proleptically)
cal.set(Calendar.MONTH, Calendar.FEBRUARY);
cal.set(Calendar.DATE, 28);
cal.add(Calendar.DATE, 1);
if (cal.get(Calendar.DATE) != 29 ||
!cal.isLeapYear(-80)) // -80 == 81 BC
errln("Calendar not proleptic");
}
/**
* Calendar and GregorianCalendar hashCode() methods need improvement.

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/calendar/CalendarTest.java,v $
* $Date: 2000/03/21 02:20:08 $
* $Revision: 1.3 $
* $Date: 2000/05/12 23:19:12 $
* $Revision: 1.4 $
*
*****************************************************************************************
*/
@ -18,7 +18,6 @@ import com.ibm.text.DateFormat;
import com.ibm.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone;
import com.ibm.util.*;
/**

View File

@ -7,8 +7,6 @@
package com.ibm.test.calendar;
import com.ibm.util.*;
import java.util.Date;
import java.util.TimeZone;
import java.util.SimpleTimeZone;
import java.util.Locale;
import java.text.*;
import java.io.*;

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/test/calendar/TestCase.java,v $
* $Date: 2000/03/21 02:20:08 $
* $Revision: 1.3 $
* $Date: 2000/05/12 23:19:12 $
* $Revision: 1.4 $
*
*****************************************************************************************
*/
@ -16,7 +16,7 @@ import com.ibm.test.*;
import com.ibm.util.Calendar;
import com.ibm.util.GregorianCalendar;
import java.util.Date;
import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
import java.util.Locale;
/**

View File

@ -0,0 +1,674 @@
/*
@test 1.9 99/06/15
@summary test Time Zone Boundary
*/
package com.ibm.test.timezone;
import com.ibm.text.*;
import com.ibm.util.*;
import com.ibm.test.*;
import java.util.Date;
/**
* A test which discovers the boundaries of DST programmatically and verifies
* that they are correct.
*/
public class TimeZoneBoundaryTest extends TestFmwk
{
static final int ONE_SECOND = 1000;
static final int ONE_MINUTE = 60*ONE_SECOND;
static final int ONE_HOUR = 60*ONE_MINUTE;
static final long ONE_DAY = 24*ONE_HOUR;
static final long ONE_YEAR = (long)(365.25 * ONE_DAY);
static final long SIX_MONTHS = ONE_YEAR / 2;
static final int MONTH_LENGTH[] = {31,29,31,30,31,30,31,31,30,31,30,31};
// These values are empirically determined to be correct
static final long PST_1997_BEG = 860320800000L;
static final long PST_1997_END = 877856400000L;
// Minimum interval for binary searches in ms; should be no larger
// than 1000.
static final long INTERVAL = 10; // Milliseconds
// When long zone names are supported again, switch this to the
// long zone name.
static final String AUSTRALIA = "AET"; // Australia/Adelaide
static final long AUSTRALIA_1997_BEG = 872524800000L; // 877797000000L
static final long AUSTRALIA_1997_END = 859651200000L; // 859653000000L
public static void main(String[] args) throws Exception {
new TimeZoneBoundaryTest().run(args);
}
/**
* Date.toString().substring() Boundary Test
* Look for a DST changeover to occur within 6 months of the given Date.
* The initial Date.toString() should yield a string containing the
* startMode as a SUBSTRING. The boundary will be tested to be
* at the expectedBoundary value.
*/
void findDaylightBoundaryUsingDate(Date d, String startMode, long expectedBoundary)
{
// Given a date with a year start, find the Daylight onset
// and end. The given date should be 1/1/xx in some year.
if (d.toString().indexOf(startMode) == -1)
{
logln("Error: " + startMode + " not present in " + d);
}
// Use a binary search, assuming that we have a Standard
// time at the midpoint.
long min = d.getTime();
long max = min + SIX_MONTHS;
while ((max - min) > INTERVAL)
{
long mid = (min + max) >> 1;
String s = new Date(mid).toString();
// logln(s);
if (s.indexOf(startMode) != -1)
{
min = mid;
}
else
{
max = mid;
}
}
logln("Date Before: " + showDate(min));
logln("Date After: " + showDate(max));
long mindelta = expectedBoundary - min;
long maxdelta = max - expectedBoundary;
if (mindelta >= 0 && mindelta <= INTERVAL &&
mindelta >= 0 && mindelta <= INTERVAL)
logln("PASS: Expected boundary at " + expectedBoundary);
else
errln("FAIL: Expected boundary at " + expectedBoundary);
}
// This test cannot be compiled until the inDaylightTime() method of GregorianCalendar
// becomes public.
// static void findDaylightBoundaryUsingCalendar(Date d, boolean startsInDST)
// {
// // Given a date with a year start, find the Daylight onset
// // and end. The given date should be 1/1/xx in some year.
//
// GregorianCalendar cal = new GregorianCalendar();
// cal.setTime(d);
// if (cal.inDaylightTime() != startsInDST)
// {
// logln("Error: inDaylightTime(" + d + ") != " + startsInDST);
// }
//
// // Use a binary search, assuming that we have a Standard
// // time at the midpoint.
// long min = d.getTime();
// long max = min + (long)(365.25 / 2 * 24*60*60*1000);
//
// while ((max - min) > INTERVAL)
// {
// long mid = (min + max) >> 1;
// cal.setTime(new Date(mid));
// if (cal.inDaylightTime() == startsInDST)
// {
// min = mid;
// }
// else
// {
// max = mid;
// }
// }
//
// logln("Calendar Before: " + showDate(min));
// logln("Calendar After: " + showDate(max));
// }
void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST, long expectedBoundary)
{
findDaylightBoundaryUsingTimeZone(d, startsInDST, expectedBoundary,
TimeZone.getDefault());
}
void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST,
long expectedBoundary, TimeZone tz)
{
// Given a date with a year start, find the Daylight onset
// and end. The given date should be 1/1/xx in some year.
// Use a binary search, assuming that we have a Standard
// time at the midpoint.
long min = d.getTime();
long max = min + SIX_MONTHS;
if (tz.inDaylightTime(d) != startsInDST)
{
errln("FAIL: " + tz.getID() + " inDaylightTime(" +
d + ") != " + startsInDST);
startsInDST = !startsInDST; // Flip over; find the apparent value
}
if (tz.inDaylightTime(new Date(max)) == startsInDST)
{
errln("FAIL: " + tz.getID() + " inDaylightTime(" +
(new Date(max)) + ") != " + (!startsInDST));
return;
}
while ((max - min) > INTERVAL)
{
long mid = (min + max) >> 1;
boolean isIn = tz.inDaylightTime(new Date(mid));
if (isIn == startsInDST)
{
min = mid;
}
else
{
max = mid;
}
}
logln(tz.getID() + " Before: " + showDate(min, tz));
logln(tz.getID() + " After: " + showDate(max, tz));
long mindelta = expectedBoundary - min;
long maxdelta = max - expectedBoundary;
if (mindelta >= 0 && mindelta <= INTERVAL &&
mindelta >= 0 && mindelta <= INTERVAL)
logln("PASS: Expected boundary at " + expectedBoundary);
else
errln("FAIL: Expected boundary at " + expectedBoundary);
}
private static String showDate(long l)
{
return showDate(new Date(l));
}
private static String showDate(Date d)
{
return "" + d.getYear() + "/" + showNN(d.getMonth()+1) + "/" + showNN(d.getDate()) +
" " + showNN(d.getHours()) + ":" + showNN(d.getMinutes()) +
" \"" + d + "\" = " +
d.getTime();
}
private static String showDate(long l, TimeZone z)
{
return showDate(new Date(l), z);
}
private static String showDate(Date d, TimeZone zone)
{
DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
fmt.setTimeZone(zone);
return "" + d.getYear() + "/" + showNN(d.getMonth()+1) + "/" + showNN(d.getDate()) +
" " + showNN(d.getHours()) + ":" + showNN(d.getMinutes()) +
" \"" + d + "\" = " +
fmt.format(d);
}
private static String showNN(int n)
{
return ((n < 10) ? "0" : "") + n;
}
/**
* Given a date, a TimeZone, and expected values for inDaylightTime,
* useDaylightTime, zone and DST offset, verify that this is the case.
*/
void verifyDST(Date d, TimeZone time_zone,
boolean expUseDaylightTime, boolean expInDaylightTime,
int expZoneOffset, int expDSTOffset)
{
logln("-- Verifying time " + d +
" in zone " + time_zone.getID());
if (time_zone.inDaylightTime(d) == expInDaylightTime)
logln("PASS: inDaylightTime = " + time_zone.inDaylightTime(d));
else
errln("FAIL: inDaylightTime = " + time_zone.inDaylightTime(d));
if (time_zone.useDaylightTime() == expUseDaylightTime)
logln("PASS: useDaylightTime = " + time_zone.useDaylightTime());
else
errln("FAIL: useDaylightTime = " + time_zone.useDaylightTime());
if (time_zone.getRawOffset() == expZoneOffset)
logln("PASS: getRawOffset() = " + expZoneOffset/(double)ONE_HOUR);
else
errln("FAIL: getRawOffset() = " + time_zone.getRawOffset()/(double)ONE_HOUR +
"; expected " + expZoneOffset/(double)ONE_HOUR);
GregorianCalendar gc = new GregorianCalendar(time_zone);
gc.setTime(d);
int offset = time_zone.getOffset(gc.get(gc.ERA), gc.get(gc.YEAR), gc.get(gc.MONTH),
gc.get(gc.DAY_OF_MONTH), gc.get(gc.DAY_OF_WEEK),
((gc.get(gc.HOUR_OF_DAY) * 60 +
gc.get(gc.MINUTE)) * 60 +
gc.get(gc.SECOND)) * 1000 +
gc.get(gc.MILLISECOND));
if (offset == expDSTOffset)
logln("PASS: getOffset() = " + offset/(double)ONE_HOUR);
else
errln("FAIL: getOffset() = " + offset/(double)ONE_HOUR +
"; expected " + expDSTOffset/(double)ONE_HOUR);
}
public void TestBoundaries()
{
TimeZone pst = TimeZone.getTimeZone("PST");
TimeZone save = TimeZone.getDefault();
try {
TimeZone.setDefault(pst);
// DST changeover for PST is 4/6/1997 at 2 hours past midnight
Date d = new Date(97,Calendar.APRIL,6);
// i is minutes past midnight standard time
for (int i=60; i<=180; i+=15)
{
boolean inDST = (i >= 120);
Date e = new Date(d.getTime() + i*60*1000);
verifyDST(e, pst, true, inDST, -8*ONE_HOUR,
inDST ? -7*ONE_HOUR : -8*ONE_HOUR);
}
} finally {
TimeZone.setDefault(save);
}
if (true)
{
// This only works in PST/PDT
TimeZone.setDefault(TimeZone.getTimeZone("PST"));
logln("========================================");
findDaylightBoundaryUsingDate(new Date(97,0,1), "PST", PST_1997_BEG);
logln("========================================");
findDaylightBoundaryUsingDate(new Date(97,6,1), "PDT", PST_1997_END);
}
// if (true)
// {
// logln("========================================");
// findDaylightBoundaryUsingCalendar(new Date(97,0,1), false);
// logln("========================================");
// findDaylightBoundaryUsingCalendar(new Date(97,6,1), true);
// }
if (true)
{
// Southern hemisphere test
logln("========================================");
TimeZone z = TimeZone.getTimeZone(AUSTRALIA);
findDaylightBoundaryUsingTimeZone(new Date(97,0,1), true, AUSTRALIA_1997_END, z);
logln("========================================");
findDaylightBoundaryUsingTimeZone(new Date(97,6,1), false, AUSTRALIA_1997_BEG, z);
}
if (true)
{
logln("========================================");
findDaylightBoundaryUsingTimeZone(new Date(97,0,1), false, PST_1997_BEG);
logln("========================================");
findDaylightBoundaryUsingTimeZone(new Date(97,6,1), true, PST_1997_END);
}
// This just shows the offset for April 4-7 in 1997. This is redundant
// with a test above, so we disable it.
if (false)
{
TimeZone z = TimeZone.getDefault();
logln(z.getOffset(1, 97, 3, 4, 6, 0) + " " + new Date(97, 3, 4));
logln(z.getOffset(1, 97, 3, 5, 7, 0) + " " + new Date(97, 3, 5));
logln(z.getOffset(1, 97, 3, 6, 1, 0) + " " + new Date(97, 3, 6));
logln(z.getOffset(1, 97, 3, 7, 2, 0) + " " + new Date(97, 3, 7));
}
}
//----------------------------------------------------------------------
// Can't do any of these without a public inDaylightTime in GC
//----------------------------------------------------------------------
// static GregorianCalendar cal = new GregorianCalendar();
//
// static void _testUsingBinarySearch(Date d, boolean startsInDST)
// {
// // Given a date with a year start, find the Daylight onset
// // and end. The given date should be 1/1/xx in some year.
//
// // Use a binary search, assuming that we have a Standard
// // time at the midpoint.
// long min = d.getTime();
// long max = min + (long)(365.25 / 2 * ONE_DAY);
//
// // First check the max
// cal.setTime(new Date(max));
// if (cal.inDaylightTime() == startsInDST)
// {
// logln("Error: inDaylightTime(" + (new Date(max)) + ") != " + (!startsInDST));
// }
//
// cal.setTime(d);
// if (cal.inDaylightTime() != startsInDST)
// {
// logln("Error: inDaylightTime(" + d + ") != " + startsInDST);
// }
//
// while ((max - min) > INTERVAL)
// {
// long mid = (min + max) >> 1;
// cal.setTime(new Date(mid));
// if (cal.inDaylightTime() == startsInDST)
// {
// min = mid;
// }
// else
// {
// max = mid;
// }
// }
//
// logln("Binary Search Before: " + showDate(min));
// logln("Binary Search After: " + showDate(max));
// }
//
// static void _testUsingMillis(Date d, boolean startsInDST)
// {
// long millis = d.getTime();
// long max = millis + (long)(370 * ONE_DAY); // A year plus extra
//
// boolean lastDST = startsInDST;
// while (millis < max)
// {
// cal.setTime(new Date(millis));
// boolean inDaylight = cal.inDaylightTime();
//
// if (inDaylight != lastDST)
// {
// logln("Switch " + (inDaylight ? "into" : "out of")
// + " DST at " + (new Date(millis)));
// lastDST = inDaylight;
// }
//
// millis += 15*ONE_MINUTE;
// }
// }
//
// static void _testUsingFields(int y, boolean startsInDST)
// {
// boolean lastDST = startsInDST;
// for (int m = 0; m < 12; ++m)
// {
// for (int d = 1; d <= MONTH_LENGTH[m]; ++d)
// {
// for (int h = 0; h < 24; ++h)
// {
// for (int min = 0; min < 60; min += 15)
// {
// cal.clear();
// cal.set(y, m, d, h, min);
// boolean inDaylight = cal.inDaylightTime();
// if (inDaylight != lastDST)
// {
// lastDST = inDaylight;
// log("Switch " + (lastDST ? "into" : "out of")
// + " DST at " + y + "/" + (m+1) + "/" + d
// + " " + showNN(h) + ":" + showNN(min));
// logln(" " + cal.getTime());
//
// cal.set(y, m, d, h-1, 45);
// log("Before = "
//+ y + "/" + (m+1) + "/" + d
//+ " " + showNN(h-1) + ":" + showNN(45));
// logln(" " + cal.getTime());
// }
// }
// }
// }
// }
// }
//
// public void Test1()
// {
// logln(Locale.getDefault().getDisplayName());
// logln(TimeZone.getDefault().getID());
// logln(new Date(0));
//
// if (true)
// {
// logln("========================================");
// _testUsingBinarySearch(new Date(97,0,1), false);
// logln("========================================");
// _testUsingBinarySearch(new Date(97,6,1), true);
// }
//
// if (true)
// {
// logln("========================================");
// logln("Stepping using millis");
// _testUsingMillis(new Date(97,0,1), false);
// }
//
// if (true)
// {
// logln("========================================");
// logln("Stepping using fields");
// _testUsingFields(1997, false);
// }
//
// if (false)
// {
// cal.clear();
// cal.set(1997, 3, 5, 10, 0);
// // cal.inDaylightTime();
// logln("Date = " + cal.getTime());
// logln("Millis = " + cal.getTime().getTime()/3600000);
// }
// }
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//----------------------------------------------------------------------
void _testUsingBinarySearch(SimpleTimeZone tz, Date d, long expectedBoundary)
{
// Given a date with a year start, find the Daylight onset
// and end. The given date should be 1/1/xx in some year.
// Use a binary search, assuming that we have a Standard
// time at the midpoint.
long min = d.getTime();
long max = min + (long)(365.25 / 2 * ONE_DAY);
// First check the boundaries
boolean startsInDST = tz.inDaylightTime(d);
if (tz.inDaylightTime(new Date(max)) == startsInDST)
{
logln("Error: inDaylightTime(" + (new Date(max)) + ") != " + (!startsInDST));
}
while ((max - min) > INTERVAL)
{
long mid = (min + max) >> 1;
if (tz.inDaylightTime(new Date(mid)) == startsInDST)
{
min = mid;
}
else
{
max = mid;
}
}
logln("Binary Search Before: " + showDate(min));
logln("Binary Search After: " + showDate(max));
long mindelta = expectedBoundary - min;
long maxdelta = max - expectedBoundary;
if (mindelta >= 0 && mindelta <= INTERVAL &&
mindelta >= 0 && mindelta <= INTERVAL)
logln("PASS: Expected boundary at " + expectedBoundary);
else
errln("FAIL: Expected boundary at " + expectedBoundary);
}
/*
static void _testUsingMillis(Date d, boolean startsInDST)
{
long millis = d.getTime();
long max = millis + (long)(370 * ONE_DAY); // A year plus extra
boolean lastDST = startsInDST;
while (millis < max)
{
cal.setTime(new Date(millis));
boolean inDaylight = cal.inDaylightTime();
if (inDaylight != lastDST)
{
logln("Switch " + (inDaylight ? "into" : "out of")
+ " DST at " + (new Date(millis)));
lastDST = inDaylight;
}
millis += 15*ONE_MINUTE;
}
}
*/
/**
* Test new rule formats.
*/
public void TestNewRules()
{
//logln(Locale.getDefault().getDisplayName());
//logln(TimeZone.getDefault().getID());
//logln(new Date(0));
if (true)
{
// Doesn't matter what the default TimeZone is here, since we
// are creating our own TimeZone objects.
SimpleTimeZone tz;
logln("-----------------------------------------------------------------");
logln("Aug 2ndTues .. Mar 15");
tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_1",
Calendar.AUGUST, 2, Calendar.TUESDAY, 2*ONE_HOUR,
Calendar.MARCH, 15, 0, 2*ONE_HOUR);
//logln(tz.toString());
logln("========================================");
_testUsingBinarySearch(tz, new Date(97,0,1), 858416400000L);
logln("========================================");
_testUsingBinarySearch(tz, new Date(97,6,1), 871380000000L);
logln("-----------------------------------------------------------------");
logln("Apr Wed>=14 .. Sep Sun<=20");
tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_2",
Calendar.APRIL, 14, -Calendar.WEDNESDAY, 2*ONE_HOUR,
Calendar.SEPTEMBER, -20, -Calendar.SUNDAY, 2*ONE_HOUR);
//logln(tz.toString());
logln("========================================");
_testUsingBinarySearch(tz, new Date(97,0,1), 861184800000L);
logln("========================================");
_testUsingBinarySearch(tz, new Date(97,6,1), 874227600000L);
}
/*
if (true)
{
logln("========================================");
logln("Stepping using millis");
_testUsingMillis(new Date(97,0,1), false);
}
if (true)
{
logln("========================================");
logln("Stepping using fields");
_testUsingFields(1997, false);
}
if (false)
{
cal.clear();
cal.set(1997, 3, 5, 10, 0);
// cal.inDaylightTime();
logln("Date = " + cal.getTime());
logln("Millis = " + cal.getTime().getTime()/3600000);
}
*/
}
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Long Bug
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//public void Test3()
//{
// findDaylightBoundaryUsingTimeZone(new Date(97,6,1), true);
//}
/**
* Find boundaries by stepping.
*/
void findBoundariesStepwise(int year, long interval, TimeZone z, int expectedChanges)
{
Date d = new Date(year - 1900, Calendar.JANUARY, 1);
long time = d.getTime(); // ms
long limit = time + ONE_YEAR + ONE_DAY;
boolean lastState = z.inDaylightTime(d);
int changes = 0;
logln("-- Zone " + z.getID() + " starts in " + year + " with DST = " + lastState);
logln("useDaylightTime = " + z.useDaylightTime());
while (time < limit)
{
d.setTime(time);
boolean state = z.inDaylightTime(d);
if (state != lastState)
{
logln((state ? "Entry " : "Exit ") +
"at " + d);
lastState = state;
++changes;
}
time += interval;
}
if (changes == 0)
{
if (!lastState && !z.useDaylightTime()) logln("No DST");
else errln("FAIL: DST all year, or no DST with true useDaylightTime");
}
else if (changes != 2)
{
errln("FAIL: " + changes + " changes seen; should see 0 or 2");
}
else if (!z.useDaylightTime())
{
errln("FAIL: useDaylightTime false but 2 changes seen");
}
if (changes != expectedChanges)
{
errln("FAIL: " + changes + " changes seen; expected " + expectedChanges);
}
}
public void TestStepwise()
{
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("EST"), 2);
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("ACT"), 0);
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone(AUSTRALIA), 2);
}
}

View File

@ -0,0 +1,851 @@
/**
* @test 1.18 99/09/21
* @bug 4052967 4073209 4073215 4084933 4096952 4109314 4126678 4151406 4151429
* @bug 4154525 4154537 4154542 4154650 4159922 4162593 4173604 4176686 4184229 4208960
*/
package com.ibm.test.timezone;
import com.ibm.util.*;
import java.io.*;
import com.ibm.text.*;
import com.ibm.test.*;
import java.util.Date;
import java.util.Locale;
public class TimeZoneRegression extends TestFmwk {
public static void main(String[] args) throws Exception {
new TimeZoneRegression().run(args);
}
public void Test4052967() {
logln("*** CHECK TIMEZONE AGAINST HOST OS SETTING ***");
String id = TimeZone.getDefault().getID();
logln("user.timezone: " + System.getProperty("user.timezone", "<not set>"));
logln("TimeZone.getDefault().getID(): " + id);
logln(new Date().toString());
logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");
}
public void Test4073209() {
TimeZone z1 = TimeZone.getTimeZone("PST");
TimeZone z2 = TimeZone.getTimeZone("PST");
if (z1 == z2) errln("Fail: TimeZone should return clones");
}
public void Test4073215() {
SimpleTimeZone z = (SimpleTimeZone) TimeZone.getTimeZone("GMT");
if (z.useDaylightTime())
errln("Fail: Fix test to start with non-DST zone");
z.setStartRule(Calendar.FEBRUARY, 1, Calendar.SUNDAY, 0);
z.setEndRule(Calendar.MARCH, -1, Calendar.SUNDAY, 0);
if (!z.useDaylightTime())
errln("Fail: DST not active");
if (z.inDaylightTime(new Date(97, Calendar.JANUARY, 31)) ||
!z.inDaylightTime(new Date(97, Calendar.MARCH, 1)) ||
z.inDaylightTime(new Date(97, Calendar.MARCH, 31))) {
errln("Fail: DST not working as expected");
}
}
/**
* The expected behavior of TimeZone around the boundaries is:
* (Assume transition time of 2:00 AM)
* day of onset 1:59 AM STD = display name 1:59 AM ST
* 2:00 AM STD = display name 3:00 AM DT
* day of end 0:59 AM STD = display name 1:59 AM DT
* 1:00 AM STD = display name 1:00 AM ST
*/
public void Test4084933() {
TimeZone tz = TimeZone.getTimeZone("PST");
long offset1 = tz.getOffset(1,
1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (2*60*60*1000));
long offset2 = tz.getOffset(1,
1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (2*60*60*1000)-1);
long offset3 = tz.getOffset(1,
1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (1*60*60*1000));
long offset4 = tz.getOffset(1,
1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (1*60*60*1000)-1);
/*
* The following was added just for consistency. It shows that going *to* Daylight
* Savings Time (PDT) does work at 2am.
*/
long offset5 = tz.getOffset(1,
1997, Calendar.APRIL, 6, Calendar.SUNDAY, (2*60*60*1000));
long offset6 = tz.getOffset(1,
1997, Calendar.APRIL, 6, Calendar.SUNDAY, (2*60*60*1000)-1);
long offset7 = tz.getOffset(1,
1997, Calendar.APRIL, 6, Calendar.SUNDAY, (1*60*60*1000));
long offset8 = tz.getOffset(1,
1997, Calendar.APRIL, 6, Calendar.SUNDAY, (1*60*60*1000)-1);
long SToffset = -8 * 60*60*1000L;
long DToffset = -7 * 60*60*1000L;
if (offset1 != SToffset || offset2 != SToffset ||
offset3 != SToffset || offset4 != DToffset ||
offset5 != DToffset || offset6 != SToffset ||
offset7 != SToffset || offset8 != SToffset)
errln("Fail: TimeZone misbehaving");
}
public void Test4096952() {
String[] ZONES = { "GMT", "MET", "IST" };
boolean pass = true;
try {
for (int i=0; i<ZONES.length; ++i) {
TimeZone zone = TimeZone.getTimeZone(ZONES[i]);
if (!zone.getID().equals(ZONES[i]))
errln("Fail: Test broken; zones not instantiating");
ByteArrayOutputStream baos;
ObjectOutputStream ostream =
new ObjectOutputStream(baos = new
ByteArrayOutputStream());
ostream.writeObject(zone);
ostream.close();
baos.close();
ObjectInputStream istream =
new ObjectInputStream(new
ByteArrayInputStream(baos.toByteArray()));
TimeZone frankenZone = (TimeZone) istream.readObject();
//logln("Zone: " + zone);
//logln("FrankenZone: " + frankenZone);
if (!zone.equals(frankenZone)) {
logln("TimeZone " + zone.getID() +
" not equal to serialized/deserialized one");
pass = false;
}
}
if (!pass) errln("Fail: TimeZone serialization/equality bug");
}
catch (IOException e) {
errln("Fail: " + e);
e.printStackTrace();
}
catch (ClassNotFoundException e) {
errln("Fail: " + e);
e.printStackTrace();
}
}
public void Test4109314() {
GregorianCalendar testCal = (GregorianCalendar)Calendar.getInstance();
TimeZone PST = TimeZone.getTimeZone("PST");
Object[] testData = {
PST, new Date(98,Calendar.APRIL,4,22,0), new Date(98, Calendar.APRIL, 5,6,0),
PST, new Date(98,Calendar.OCTOBER,24,22,0), new Date(98,Calendar.OCTOBER,25,6,0),
};
boolean pass=true;
for (int i=0; i<testData.length; i+=3) {
testCal.setTimeZone((TimeZone) testData[i]);
long t = ((Date)testData[i+1]).getTime();
Date end = (Date) testData[i+2];
while (t < end.getTime()) {
testCal.setTime(new Date(t));
if (!checkCalendar314(testCal, (TimeZone) testData[i]))
pass = false;
t += 60*60*1000L;
}
}
if (!pass) errln("Fail: TZ API inconsistent");
}
boolean checkCalendar314(GregorianCalendar testCal, TimeZone testTZ) {
// GregorianCalendar testCal = (GregorianCalendar)aCal.clone();
final int ONE_DAY = 24*60*60*1000;
int tzOffset, tzRawOffset;
Float tzOffsetFloat,tzRawOffsetFloat;
// Here is where the user made an error. They were passing in the value of
// the MILLSECOND field; you need to pass in the millis in the day in STANDARD
// time.
int millis = testCal.get(Calendar.MILLISECOND) +
1000 * (testCal.get(Calendar.SECOND) +
60 * (testCal.get(Calendar.MINUTE) +
60 * (testCal.get(Calendar.HOUR_OF_DAY)))) -
testCal.get(Calendar.DST_OFFSET);
/* Fix up millis to be in range. ASSUME THAT WE ARE NOT AT THE
* BEGINNING OR END OF A MONTH. We must add this code because
* getOffset() has been changed to be more strict about the parameters
* it receives -- it turns out that this test was passing in illegal
* values. */
int date = testCal.get(Calendar.DATE);
int dow = testCal.get(Calendar.DAY_OF_WEEK);
while (millis < 0) {
millis += ONE_DAY;
--date;
dow = Calendar.SUNDAY + ((dow - Calendar.SUNDAY + 6) % 7);
}
while (millis >= ONE_DAY) {
millis -= ONE_DAY;
++date;
dow = Calendar.SUNDAY + ((dow - Calendar.SUNDAY + 1) % 7);
}
tzOffset = testTZ.getOffset(testCal.get(Calendar.ERA),
testCal.get(Calendar.YEAR),
testCal.get(Calendar.MONTH),
date,
dow,
millis);
tzRawOffset = testTZ.getRawOffset();
tzOffsetFloat = new Float((float)tzOffset/(float)3600000);
tzRawOffsetFloat = new Float((float)tzRawOffset/(float)3600000);
Date testDate = testCal.getTime();
boolean inDaylightTime = testTZ.inDaylightTime(testDate);
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm");
sdf.setCalendar(testCal);
String inDaylightTimeString;
boolean passed;
if (inDaylightTime)
{
inDaylightTimeString = " DST ";
passed = (tzOffset == (tzRawOffset + 3600000));
}
else
{
inDaylightTimeString = " ";
passed = (tzOffset == tzRawOffset);
}
String output = testTZ.getID() + " " + sdf.format(testDate) +
" Offset(" + tzOffsetFloat + ")" +
" RawOffset(" + tzRawOffsetFloat + ")" +
" " + millis/(float)3600000 + " " +
inDaylightTimeString;
if (passed)
output += " ";
else
output += "ERROR";
if (passed) logln(output); else errln(output);
return passed;
}
/**
* CANNOT REPRODUDE
*
* Yet another _alleged_ bug in TimeZone.getOffset(), a method that never
* should have been made public. It's simply too hard to use correctly.
*
* The original test code failed to do the following:
* (1) Call Calendar.setTime() before getting the fields!
* (2) Use the right millis (as usual) for getOffset(); they were passing
* in the MILLIS field, instead of the STANDARD MILLIS IN DAY.
* When you fix these two problems, the test passes, as expected.
*/
public void Test4126678() {
// Note: this test depends on the PST time zone.
TimeZone initialZone = TimeZone.getDefault();
Calendar cal = Calendar.getInstance();
TimeZone tz = TimeZone.getTimeZone("PST");
TimeZone.setDefault(tz);
cal.setTimeZone(tz);
Date dt = new Date(1998-1900, Calendar.APRIL, 5, 10, 0);
// the dt value is local time in PST.
if (!tz.inDaylightTime(dt))
errln("We're not in Daylight Savings Time and we should be.\n");
cal.setTime(dt);
int era = cal.get(Calendar.ERA);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DATE);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
int millis = cal.get(Calendar.MILLISECOND) +
(cal.get(Calendar.SECOND) +
(cal.get(Calendar.MINUTE) +
(cal.get(Calendar.HOUR) * 60) * 60) * 1000) -
cal.get(Calendar.DST_OFFSET);
long offset = tz.getOffset(era, year, month, day, dayOfWeek, millis);
long raw_offset = tz.getRawOffset();
if (offset == raw_offset)
errln("Offsets should not match when in DST");
// restore the initial time zone so that this test case
// doesn't affect the others.
TimeZone.setDefault(initialZone);
}
/**
* TimeZone.getAvailableIDs(int) throws exception for certain values,
* due to a faulty constant in TimeZone.java.
*/
public void Test4151406() {
int max = 0;
for (int h=-28; h<=30; ++h) {
// h is in half-hours from GMT; rawoffset is in millis
int rawoffset = h * 1800000;
int hh = (h<0) ? -h : h;
String hname = ((h<0) ? "GMT-" : "GMT+") +
((hh/2 < 10) ? "0" : "") +
(hh/2) + ':' +
((hh%2==0) ? "00" : "30");
try {
String[] ids = TimeZone.getAvailableIDs(rawoffset);
if (ids.length > max) max = ids.length;
logln(hname + ' ' + ids.length +
((ids.length > 0) ? (" e.g. " + ids[0]) : ""));
} catch (Exception e) {
errln(hname + ' ' + "Fail: " + e);
}
}
logln("Maximum zones per offset = " + max);
}
public void Test4151429() {
try {
TimeZone tz = TimeZone.getTimeZone("GMT");
String name = tz.getDisplayName(true, Integer.MAX_VALUE,
Locale.getDefault());
errln("IllegalArgumentException not thrown by TimeZone.getDisplayName()");
} catch(IllegalArgumentException e) {}
}
/**
* SimpleTimeZone accepts illegal DST savings values. These values
* must be non-zero. There is no upper limit at this time.
*/
public void Test4154525() {
final int GOOD = 1, BAD = 0;
int[] DATA = {
1, GOOD,
0, BAD,
-1, BAD,
60*60*1000, GOOD,
Integer.MIN_VALUE, BAD,
// Integer.MAX_VALUE, ?, // no upper limit on DST savings at this time
};
for (int i=0; i<DATA.length; i+=2) {
int savings = DATA[i];
boolean valid = DATA[i+1] == GOOD;
String method = null;
for (int j=0; j<2; ++j) {
try {
switch (j) {
case 0:
method = "constructor";
SimpleTimeZone z = new SimpleTimeZone(0, "id",
Calendar.JANUARY, 1, 0, 0,
Calendar.MARCH, 1, 0, 0,
savings); // <- what we're interested in
break;
case 1:
method = "setDSTSavings()";
z = new SimpleTimeZone(0, "GMT");
z.setDSTSavings(savings);
break;
}
if (valid) {
logln("Pass: DST savings of " + savings + " accepted by " + method);
} else {
errln("Fail: DST savings of " + savings + " accepted by " + method);
}
} catch (IllegalArgumentException e) {
if (valid) {
errln("Fail: DST savings of " + savings + " to " + method + " gave " + e);
} else {
logln("Pass: DST savings of " + savings + " to " + method + " gave " + e);
}
}
}
}
}
/**
* SimpleTimeZone.hasSameRules() doesn't work for zones with no DST
* and different DST parameters.
*/
public void Test4154537() {
// tz1 and tz2 have no DST and different rule parameters
SimpleTimeZone tz1 = new SimpleTimeZone(0, "1", 0, 0, 0, 0, 2, 0, 0, 0);
SimpleTimeZone tz2 = new SimpleTimeZone(0, "2", 1, 0, 0, 0, 3, 0, 0, 0);
// tza and tzA have the same rule params
SimpleTimeZone tza = new SimpleTimeZone(0, "a", 0, 1, 0, 0, 3, 2, 0, 0);
SimpleTimeZone tzA = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 3, 2, 0, 0);
// tzb differs from tza
SimpleTimeZone tzb = new SimpleTimeZone(0, "b", 0, 1, 0, 0, 3, 1, 0, 0);
if (tz1.useDaylightTime() || tz2.useDaylightTime() ||
!tza.useDaylightTime() || !tzA.useDaylightTime() ||
!tzb.useDaylightTime()) {
errln("Test is broken -- rewrite it");
}
if (!tza.hasSameRules(tzA) || tza.hasSameRules(tzb)) {
errln("Fail: hasSameRules() broken for zones with rules");
}
if (!tz1.hasSameRules(tz2)) {
errln("Fail: hasSameRules() returns false for zones without rules");
errln("zone 1 = " + tz1);
errln("zone 2 = " + tz2);
}
}
/**
* SimpleTimeZone constructors, setStartRule(), and setEndRule() don't
* check for out-of-range arguments.
*/
public void Test4154542() {
final int GOOD = 1;
final int BAD = 0;
final int GOOD_MONTH = Calendar.JANUARY;
final int GOOD_DAY = 1;
final int GOOD_DAY_OF_WEEK = Calendar.SUNDAY;
final int GOOD_TIME = 0;
int[] DATA = {
GOOD, Integer.MIN_VALUE, 0, Integer.MAX_VALUE, Integer.MIN_VALUE,
GOOD, Calendar.JANUARY, -5, Calendar.SUNDAY, 0,
GOOD, Calendar.DECEMBER, 5, Calendar.SATURDAY, 24*60*60*1000-1,
BAD, Calendar.DECEMBER, 5, Calendar.SATURDAY, 24*60*60*1000,
BAD, Calendar.DECEMBER, 5, Calendar.SATURDAY, -1,
BAD, Calendar.JANUARY, -6, Calendar.SUNDAY, 0,
BAD, Calendar.DECEMBER, 6, Calendar.SATURDAY, 24*60*60*1000,
GOOD, Calendar.DECEMBER, 1, 0, 0,
GOOD, Calendar.DECEMBER, 31, 0, 0,
BAD, Calendar.APRIL, 31, 0, 0,
BAD, Calendar.DECEMBER, 32, 0, 0,
BAD, Calendar.JANUARY-1, 1, Calendar.SUNDAY, 0,
BAD, Calendar.DECEMBER+1, 1, Calendar.SUNDAY, 0,
GOOD, Calendar.DECEMBER, 31, -Calendar.SUNDAY, 0,
GOOD, Calendar.DECEMBER, 31, -Calendar.SATURDAY, 0,
BAD, Calendar.DECEMBER, 32, -Calendar.SATURDAY, 0,
BAD, Calendar.DECEMBER, -32, -Calendar.SATURDAY, 0,
BAD, Calendar.DECEMBER, 31, -Calendar.SATURDAY-1, 0,
};
SimpleTimeZone zone = new SimpleTimeZone(0, "Z");
for (int i=0; i<DATA.length; i+=5) {
boolean shouldBeGood = (DATA[i] == GOOD);
int month = DATA[i+1];
int day = DATA[i+2];
int dayOfWeek = DATA[i+3];
int time = DATA[i+4];
Exception ex = null;
try {
zone.setStartRule(month, day, dayOfWeek, time);
} catch (IllegalArgumentException e) {
ex = e;
}
if ((ex == null) != shouldBeGood) {
errln("setStartRule(month=" + month + ", day=" + day +
", dayOfWeek=" + dayOfWeek + ", time=" + time +
(shouldBeGood ? (") should work but throws " + ex)
: ") should fail but doesn't"));
}
ex = null;
try {
zone.setEndRule(month, day, dayOfWeek, time);
} catch (IllegalArgumentException e) {
ex = e;
}
if ((ex == null) != shouldBeGood) {
errln("setEndRule(month=" + month + ", day=" + day +
", dayOfWeek=" + dayOfWeek + ", time=" + time +
(shouldBeGood ? (") should work but throws " + ex)
: ") should fail but doesn't"));
}
ex = null;
try {
SimpleTimeZone temp = new SimpleTimeZone(0, "Z",
month, day, dayOfWeek, time,
GOOD_MONTH, GOOD_DAY, GOOD_DAY_OF_WEEK, GOOD_TIME);
} catch (IllegalArgumentException e) {
ex = e;
}
if ((ex == null) != shouldBeGood) {
errln("SimpleTimeZone(month=" + month + ", day=" + day +
", dayOfWeek=" + dayOfWeek + ", time=" + time +
(shouldBeGood ? (", <end>) should work but throws " + ex)
: ", <end>) should fail but doesn't"));
}
ex = null;
try {
SimpleTimeZone temp = new SimpleTimeZone(0, "Z",
GOOD_MONTH, GOOD_DAY, GOOD_DAY_OF_WEEK, GOOD_TIME,
month, day, dayOfWeek, time);
} catch (IllegalArgumentException e) {
ex = e;
}
if ((ex == null) != shouldBeGood) {
errln("SimpleTimeZone(<start>, month=" + month + ", day=" + day +
", dayOfWeek=" + dayOfWeek + ", time=" + time +
(shouldBeGood ? (") should work but throws " + ex)
: ") should fail but doesn't"));
}
}
}
/**
* SimpleTimeZone.getOffset accepts illegal arguments.
*/
public void Test4154650() {
final int GOOD=1, BAD=0;
final int GOOD_ERA=GregorianCalendar.AD, GOOD_YEAR=1998, GOOD_MONTH=Calendar.AUGUST;
final int GOOD_DAY=2, GOOD_DOW=Calendar.SUNDAY, GOOD_TIME=16*3600000;
int[] DATA = {
GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
GOOD, GregorianCalendar.BC, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
GOOD, GregorianCalendar.AD, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
BAD, GregorianCalendar.BC-1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
BAD, GregorianCalendar.AD+1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, GOOD_DAY, GOOD_DOW, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, Calendar.DECEMBER, GOOD_DAY, GOOD_DOW, GOOD_TIME,
BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY-1, GOOD_DAY, GOOD_DOW, GOOD_TIME,
BAD, GOOD_ERA, GOOD_YEAR, Calendar.DECEMBER+1, GOOD_DAY, GOOD_DOW, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 1, GOOD_DOW, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 31, GOOD_DOW, GOOD_TIME,
BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 0, GOOD_DOW, GOOD_TIME,
BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 32, GOOD_DOW, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SUNDAY, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SATURDAY, GOOD_TIME,
BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SUNDAY-1, GOOD_TIME,
BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SATURDAY+1, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 0,
GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000-1,
BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, -1,
BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000,
};
TimeZone tz = TimeZone.getDefault();
for (int i=0; i<DATA.length; i+=7) {
boolean good = DATA[i] == GOOD;
IllegalArgumentException e = null;
try {
int offset = tz.getOffset(DATA[i+1], DATA[i+2], DATA[i+3],
DATA[i+4], DATA[i+5], DATA[i+6]);
} catch (IllegalArgumentException ex) {
e = ex;
}
if (good != (e == null)) {
errln("Fail: getOffset(" +
DATA[i+1] + ", " + DATA[i+2] + ", " + DATA[i+3] + ", " +
DATA[i+4] + ", " + DATA[i+5] + ", " + DATA[i+6] +
(good ? (") threw " + e) : ") accepts invalid args"));
}
}
}
/**
* TimeZone constructors allow null IDs.
*/
public void Test4159922() {
TimeZone z = null;
// TimeZone API. Only hasSameRules() and setDefault() should
// allow null.
try {
z = TimeZone.getTimeZone(null);
errln("FAIL: Null allowed in getTimeZone");
} catch (NullPointerException e) {}
z = TimeZone.getTimeZone("GMT");
try {
z.getDisplayName(false, TimeZone.SHORT, null);
errln("FAIL: Null allowed in getDisplayName(3)");
} catch (NullPointerException e) {}
try {
z.getDisplayName(null);
errln("FAIL: Null allowed in getDisplayName(1)");
} catch (NullPointerException e) {}
try {
if (z.hasSameRules(null)) {
errln("FAIL: hasSameRules returned true");
}
} catch (NullPointerException e) {
errln("FAIL: Null NOT allowed in hasSameRules");
}
try {
z.inDaylightTime(null);
errln("FAIL: Null allowed in inDaylightTime");
} catch (NullPointerException e) {}
try {
z.setID(null);
errln("FAIL: Null allowed in setID");
} catch (NullPointerException e) {}
TimeZone save = TimeZone.getDefault();
try {
TimeZone.setDefault(null);
} catch (NullPointerException e) {
errln("FAIL: Null NOT allowed in setDefault");
} finally {
TimeZone.setDefault(save);
}
// SimpleTimeZone API
SimpleTimeZone s = null;
try {
s = new SimpleTimeZone(0, null);
errln("FAIL: Null allowed in SimpleTimeZone(2)");
} catch (NullPointerException e) {}
try {
s = new SimpleTimeZone(0, null, 0, 1, 0, 0, 0, 1, 0, 0);
errln("FAIL: Null allowed in SimpleTimeZone(10)");
} catch (NullPointerException e) {}
try {
s = new SimpleTimeZone(0, null, 0, 1, 0, 0, 0, 1, 0, 0, 1000);
errln("FAIL: Null allowed in SimpleTimeZone(11)");
} catch (NullPointerException e) {}
}
/**
* TimeZone broken at midnight. The TimeZone code fails to handle
* transitions at midnight correctly.
*/
public void Test4162593() {
SimpleDateFormat fmt = new SimpleDateFormat("z", Locale.US);
final int ONE_HOUR = 60*60*1000;
TimeZone initialZone = TimeZone.getDefault();
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy HH:mm z");
SimpleTimeZone asuncion = new SimpleTimeZone(-4*ONE_HOUR, "America/Asuncion" /*PY%sT*/,
Calendar.OCTOBER, 1, 0 /*DOM*/, 0*ONE_HOUR,
Calendar.MARCH, 1, 0 /*DOM*/, 0*ONE_HOUR, 1*ONE_HOUR);
/* Zone
* Starting time
* Transition expected between start+1H and start+2H
*/
Object[] DATA = {
new SimpleTimeZone(2*ONE_HOUR, "Asia/Damascus" /*EE%sT*/,
Calendar.APRIL, 1, 0 /*DOM*/, 0*ONE_HOUR,
Calendar.OCTOBER, 1, 0 /*DOM*/, 0*ONE_HOUR, 1*ONE_HOUR),
new int[] {98, Calendar.SEPTEMBER, 30, 22, 0},
Boolean.TRUE,
asuncion,
new int[] {100, Calendar.FEBRUARY, 28, 22, 0},
Boolean.FALSE,
asuncion,
new int[] {100, Calendar.FEBRUARY, 29, 22, 0},
Boolean.TRUE,
};
String[] zone = new String[4];
for (int j=0; j<DATA.length; j+=3) {
TimeZone tz = (TimeZone)DATA[j];
TimeZone.setDefault(tz);
fmt.setTimeZone(tz);
sdf.setTimeZone(tz);
// Must construct the Date object AFTER setting the default zone
int[] p = (int[])DATA[j+1];
Date d = new Date(p[0], p[1], p[2], p[3], p[4]);
boolean transitionExpected = ((Boolean)DATA[j+2]).booleanValue();
logln(tz.getID() + ":");
for (int i=0; i<4; ++i) {
zone[i] = fmt.format(d);
logln("" + i + ": " + sdf.format(d) + " => " + zone[i]);
d = new Date(d.getTime() + ONE_HOUR);
}
if (zone[0].equals(zone[1]) &&
(zone[1].equals(zone[2]) != transitionExpected) &&
zone[2].equals(zone[3])) {
logln("Ok: transition " + transitionExpected);
} else {
errln("Fail: boundary transition incorrect");
}
}
// restore the initial time zone so that this test case
// doesn't affect the others.
TimeZone.setDefault(initialZone);
}
/**
* TimeZone broken in last hour of year
*/
public void Test4173604() {
SimpleTimeZone pst = (SimpleTimeZone)TimeZone.getTimeZone("PST");
int o22 = pst.getOffset(1, 1998, 11, 31, Calendar.THURSDAY, 22*60*60*1000);
int o23 = pst.getOffset(1, 1998, 11, 31, Calendar.THURSDAY, 23*60*60*1000);
int o00 = pst.getOffset(1, 1999, 0, 1, Calendar.FRIDAY, 0);
if (o22 != o23 || o22 != o00) {
errln("Offsets should be the same (for PST), but got: " +
"12/31 22:00 " + o22 +
", 12/31 23:00 " + o23 +
", 01/01 00:00 " + o00);
}
GregorianCalendar cal = new GregorianCalendar();
cal.setTimeZone(pst);
cal.clear();
cal.set(1998, Calendar.JANUARY, 1);
int lastDST = cal.get(Calendar.DST_OFFSET);
int transitions = 0;
int delta = 5;
while (cal.get(Calendar.YEAR) < 2000) {
cal.add(Calendar.MINUTE, delta);
if (cal.get(Calendar.DST_OFFSET) != lastDST) {
++transitions;
Calendar t = (Calendar)cal.clone();
t.add(Calendar.MINUTE, -delta);
logln(t.getTime() + " " + t.get(Calendar.DST_OFFSET));
logln(cal.getTime() + " " + (lastDST=cal.get(Calendar.DST_OFFSET)));
}
}
if (transitions != 4) {
errln("Saw " + transitions + " transitions; should have seen 4");
}
}
/**
* getDisplayName doesn't work with unusual savings/offsets.
*/
public void Test4176686() {
// Construct a zone that does not observe DST but
// that does have a DST savings (which should be ignored).
int offset = 90 * 60000; // 1:30
SimpleTimeZone z1 = new SimpleTimeZone(offset, "_std_zone_");
z1.setDSTSavings(45 * 60000); // 0:45
// Construct a zone that observes DST for the first 6 months.
SimpleTimeZone z2 = new SimpleTimeZone(offset, "_dst_zone_");
z2.setDSTSavings(45 * 60000); // 0:45
z2.setStartRule(Calendar.JANUARY, 1, 0);
z2.setEndRule(Calendar.JULY, 1, 0);
// Also check DateFormat
DateFormat fmt1 = new SimpleDateFormat("z");
fmt1.setTimeZone(z1); // Format uses standard zone
DateFormat fmt2 = new SimpleDateFormat("z");
fmt2.setTimeZone(z2); // Format uses DST zone
Date dst = new Date(1970-1900, Calendar.FEBRUARY, 1); // Time in DST
Date std = new Date(1970-1900, Calendar.AUGUST, 1); // Time in standard
// Description, Result, Expected Result
String[] DATA = {
"getDisplayName(false, SHORT)/std zone",
z1.getDisplayName(false, TimeZone.SHORT), "GMT+01:30",
"getDisplayName(false, LONG)/std zone",
z1.getDisplayName(false, TimeZone.LONG ), "GMT+01:30",
"getDisplayName(true, SHORT)/std zone",
z1.getDisplayName(true, TimeZone.SHORT), "GMT+01:30",
"getDisplayName(true, LONG)/std zone",
z1.getDisplayName(true, TimeZone.LONG ), "GMT+01:30",
"getDisplayName(false, SHORT)/dst zone",
z2.getDisplayName(false, TimeZone.SHORT), "GMT+01:30",
"getDisplayName(false, LONG)/dst zone",
z2.getDisplayName(false, TimeZone.LONG ), "GMT+01:30",
"getDisplayName(true, SHORT)/dst zone",
z2.getDisplayName(true, TimeZone.SHORT), "GMT+02:15",
"getDisplayName(true, LONG)/dst zone",
z2.getDisplayName(true, TimeZone.LONG ), "GMT+02:15",
"DateFormat.format(std)/std zone", fmt1.format(std), "GMT+01:30",
"DateFormat.format(dst)/std zone", fmt1.format(dst), "GMT+01:30",
"DateFormat.format(std)/dst zone", fmt2.format(std), "GMT+01:30",
"DateFormat.format(dst)/dst zone", fmt2.format(dst), "GMT+02:15",
};
for (int i=0; i<DATA.length; i+=3) {
if (!DATA[i+1].equals(DATA[i+2])) {
errln("FAIL: " + DATA[i] + " -> " + DATA[i+1] + ", exp " + DATA[i+2]);
}
}
}
/**
* SimpleTimeZone allows invalid DOM values.
*/
public void Test4184229() {
SimpleTimeZone zone = null;
try {
zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0);
errln("Failed. No exception has been thrown for DOM -1 startDay");
} catch(IllegalArgumentException e) {
logln("(a) " + e.getMessage());
}
try {
zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0);
errln("Failed. No exception has been thrown for DOM -1 endDay");
} catch(IllegalArgumentException e) {
logln("(b) " + e.getMessage());
}
try {
zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0, 1000);
errln("Failed. No exception has been thrown for DOM -1 startDay +savings");
} catch(IllegalArgumentException e) {
logln("(c) " + e.getMessage());
}
try {
zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0, 1000);
errln("Failed. No exception has been thrown for DOM -1 endDay +savings");
} catch(IllegalArgumentException e) {
logln("(d) " + e.getMessage());
}
// Make a valid constructor call for subsequent tests.
zone = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 0, 1, 0, 0);
try {
zone.setStartRule(0, -1, 0, 0);
errln("Failed. No exception has been thrown for DOM -1 setStartRule +savings");
} catch(IllegalArgumentException e) {
logln("(e) " + e.getMessage());
}
try {
zone.setStartRule(0, -1, 0);
errln("Failed. No exception has been thrown for DOM -1 setStartRule");
} catch(IllegalArgumentException e) {
logln("(f) " + e.getMessage());
}
try {
zone.setEndRule(0, -1, 0, 0);
errln("Failed. No exception has been thrown for DOM -1 setEndRule +savings");
} catch(IllegalArgumentException e) {
logln("(g) " + e.getMessage());
}
try {
zone.setEndRule(0, -1, 0);
errln("Failed. No exception has been thrown for DOM -1 setEndRule");
} catch(IllegalArgumentException e) {
logln("(h) " + e.getMessage());
}
}
/**
* SimpleTimeZone.getOffset() throws IllegalArgumentException when to get
* of 2/29/1996 (leap day).
*/
public void Test4208960 () {
SimpleTimeZone tz = (SimpleTimeZone)TimeZone.getTimeZone("PST");
try {
int offset = tz.getOffset(GregorianCalendar.AD, 1996, Calendar.FEBRUARY, 29,
Calendar.THURSDAY, 0);
} catch (IllegalArgumentException e) {
errln("FAILED: to get TimeZone.getOffset(2/29/96)");
}
try {
int offset = tz.getOffset(GregorianCalendar.AD, 1997, Calendar.FEBRUARY, 29,
Calendar.THURSDAY, 0);
errln("FAILED: TimeZone.getOffset(2/29/97) expected to throw Exception.");
} catch (IllegalArgumentException e) {
logln("got IllegalArgumentException");
}
}
}
//eof

View File

@ -0,0 +1,701 @@
/**
* @test 1.22 99/09/21
* @bug 4028006 4044013 4096694 4107276 4107570 4112869 4130885
* @summary test TimeZone
* @build TimeZoneTest
*/
package com.ibm.test.timezone;
import com.ibm.text.*;
import com.ibm.util.*;
import com.ibm.test.*;
import java.util.Date;
import java.util.Locale;
import java.util.Hashtable;
import java.util.ResourceBundle;
public class TimeZoneTest extends TestFmwk
{
static final int millisPerHour = 3600000;
public static void main(String[] args) throws Exception {
new TimeZoneTest().run(args);
}
/**
* Bug 4130885
* Certain short zone IDs, used since 1.1.x, are incorrect.
*
* The worst of these is:
*
* "CAT" (Central African Time) should be GMT+2:00, but instead returns a
* zone at GMT-1:00. The zone at GMT-1:00 should be called EGT, CVT, EGST,
* or AZOST, depending on which zone is meant, but in no case is it CAT.
*
* Other wrong zone IDs:
*
* ECT (European Central Time) GMT+1:00: ECT is Ecuador Time,
* GMT-5:00. European Central time is abbreviated CEST.
*
* SST (Solomon Island Time) GMT+11:00. SST is actually Samoa Standard Time,
* GMT-11:00. Solomon Island time is SBT.
*
* NST (New Zealand Time) GMT+12:00. NST is the abbreviation for
* Newfoundland Standard Time, GMT-3:30. New Zealanders use NZST.
*
* AST (Alaska Standard Time) GMT-9:00. [This has already been noted in
* another bug.] It should be "AKST". AST is Atlantic Standard Time,
* GMT-4:00.
*
* PNT (Phoenix Time) GMT-7:00. PNT usually means Pitcairn Time,
* GMT-8:30. There is no standard abbreviation for Phoenix time, as distinct
* from MST with daylight savings.
*
* In addition to these problems, a number of zones are FAKE. That is, they
* don't match what people use in the real world.
*
* FAKE zones:
*
* EET (should be EEST)
* ART (should be EEST)
* MET (should be IRST)
* NET (should be AMST)
* PLT (should be PKT)
* BST (should be BDT)
* VST (should be ICT)
* CTT (should be CST) +
* ACT (should be CST) +
* AET (should be EST) +
* MIT (should be WST) +
* IET (should be EST) +
* PRT (should be AST) +
* CNT (should be NST)
* AGT (should be ARST)
* BET (should be EST) +
*
* + A zone with the correct name already exists and means something
* else. E.g., EST usually indicates the US Eastern zone, so it cannot be
* used for Brazil (BET).
*/
public void TestShortZoneIDs() throws Exception {
ZoneDescriptor[] JDK_116_REFERENCE_LIST = {
new ZoneDescriptor("MIT", -660, false),
new ZoneDescriptor("HST", -600, false),
new ZoneDescriptor("AST", -540, true),
new ZoneDescriptor("PST", -480, true),
new ZoneDescriptor("PNT", -420, false),
new ZoneDescriptor("MST", -420, true),
new ZoneDescriptor("CST", -360, true),
new ZoneDescriptor("IET", -300, false),
new ZoneDescriptor("EST", -300, true),
new ZoneDescriptor("PRT", -240, false),
new ZoneDescriptor("CNT", -210, true),
new ZoneDescriptor("AGT", -180, false),
new ZoneDescriptor("BET", -180, true),
// new ZoneDescriptor("CAT", -60, false), // Wrong:
// As of bug 4130885, fix CAT (Central Africa)
new ZoneDescriptor("CAT", 120, false), // Africa/Harare
new ZoneDescriptor("GMT", 0, false),
new ZoneDescriptor("UTC", 0, false),
new ZoneDescriptor("ECT", 60, true),
new ZoneDescriptor("ART", 120, true),
new ZoneDescriptor("EET", 120, true),
new ZoneDescriptor("EAT", 180, false),
new ZoneDescriptor("MET", 210, true),
// new ZoneDescriptor("NET", 240, false);
// As of bug 4191164, fix NET
new ZoneDescriptor("NET", 240, true),
new ZoneDescriptor("PLT", 300, false),
new ZoneDescriptor("IST", 330, false),
new ZoneDescriptor("BST", 360, false),
new ZoneDescriptor("VST", 420, false),
new ZoneDescriptor("CTT", 480, false),
new ZoneDescriptor("JST", 540, false),
new ZoneDescriptor("ACT", 570, false),
new ZoneDescriptor("AET", 600, true),
new ZoneDescriptor("SST", 660, false),
// new ZoneDescriptor("NST", 720, false),
// As of bug 4130885, fix NST (New Zealand)
new ZoneDescriptor("NST", 720, true), // Pacific/Auckland
};
Hashtable hash = new Hashtable();
String[] ids = TimeZone.getAvailableIDs();
for (int i=0; i<ids.length; ++i) {
String id = ids[i];
if (id.length() == 3) {
hash.put(id, new ZoneDescriptor(TimeZone.getTimeZone(id)));
}
}
for (int i=0; i<JDK_116_REFERENCE_LIST.length; ++i) {
ZoneDescriptor referenceZone = JDK_116_REFERENCE_LIST[i];
ZoneDescriptor currentZone = (ZoneDescriptor)hash.get(referenceZone.getID());
if (referenceZone.equals(currentZone)) {
logln("ok " + referenceZone);
}
else {
errln("Fail: Expected " + referenceZone +
"; got " + currentZone);
}
}
}
/**
* A descriptor for a zone; used to regress the short zone IDs.
*/
static class ZoneDescriptor {
String id;
int offset; // In minutes
boolean daylight;
ZoneDescriptor(TimeZone zone) {
this.id = zone.getID();
this.offset = zone.getRawOffset() / 60000;
this.daylight = zone.useDaylightTime();
}
ZoneDescriptor(String id, int offset, boolean daylight) {
this.id = id;
this.offset = offset;
this.daylight = daylight;
}
public String getID() { return id; }
public boolean equals(Object o) {
ZoneDescriptor that = (ZoneDescriptor)o;
return that != null &&
id.equals(that.id) &&
offset == that.offset &&
daylight == that.daylight;
}
public String toString() {
int min = offset;
char sign = '+';
if (min < 0) { sign = '-'; min = -min; }
return "Zone[\"" + id + "\", GMT" + sign + (min/60) + ':' +
(min%60<10?"0":"") + (min%60) + ", " +
(daylight ? "Daylight" : "Standard") + "]";
}
public static int compare(Object o1, Object o2) {
ZoneDescriptor i1 = (ZoneDescriptor)o1;
ZoneDescriptor i2 = (ZoneDescriptor)o2;
if (i1.offset > i2.offset) return 1;
if (i1.offset < i2.offset) return -1;
if (i1.daylight && !i2.daylight) return 1;
if (!i1.daylight && i2.daylight) return -1;
return i1.id.compareTo(i2.id);
}
}
static final String EXPECTED_CUSTOM_ID = "Custom";
static final String formatMinutes(int min) {
char sign = '+';
if (min < 0) { sign = '-'; min = -min; }
int h = min/60;
min = min%60;
return "" + sign + h + ":" + ((min<10) ? "0" : "") + min;
}
/**
* As part of the VM fix (see CCC approved RFE 4028006, bug
* 4044013), TimeZone.getTimeZone() has been modified to recognize
* generic IDs of the form GMT[+-]hh:mm, GMT[+-]hhmm, and
* GMT[+-]hh. Test this behavior here.
*
* Bug 4044013
*/
public void TestCustomParse() throws Exception {
Object[] DATA = {
// ID Expected offset in minutes
"GMT", null,
"GMT0", null,
"GMT+0", new Integer(0),
"GMT+1", new Integer(60),
"GMT-0030", new Integer(-30),
"GMT+15:99", new Integer(15*60+99),
"GMT+", null,
"GMT-", null,
"GMT+0:", null,
"GMT-:", null,
"GMT+0010", new Integer(10), // Interpret this as 00:10
"GMT-10", new Integer(-10*60),
"GMT+30", new Integer(30),
"GMT-3:30", new Integer(-(3*60+30)),
"GMT-230", new Integer(-(2*60+30)),
};
for (int i=0; i<DATA.length; i+=2) {
String id = (String)DATA[i];
Integer exp = (Integer)DATA[i+1];
TimeZone zone = TimeZone.getTimeZone(id);
if (zone.getID().equals("GMT")) {
logln(id + " -> generic GMT");
// When TimeZone.getTimeZone() can't parse the id, it
// returns GMT -- a dubious practice, but required for
// backward compatibility.
if (exp != null) {
throw new Exception("Expected offset of " + formatMinutes(exp.intValue()) +
" for " + id + ", got parse failure");
}
}
else {
int ioffset = zone.getRawOffset()/60000;
String offset = formatMinutes(ioffset);
logln(id + " -> " + zone.getID() + " GMT" + offset);
if (exp == null) {
throw new Exception("Expected parse failure for " + id +
", got offset of " + offset +
", id " + zone.getID());
}
else if (ioffset != exp.intValue() ||
!zone.getID().equals(EXPECTED_CUSTOM_ID)) {
throw new Exception("Expected offset of " + formatMinutes(exp.intValue()) +
", id Custom, for " + id +
", got offset of " + offset +
", id " + zone.getID());
}
}
}
}
/**
* Test the basic functionality of the getDisplayName() API.
*
* Bug 4112869
* Bug 4028006
*
* See also API change request A41.
*
* 4/21/98 - make smarter, so the test works if the ext resources
* are present or not.
*/
public void TestDisplayName() {
TimeZone zone = TimeZone.getTimeZone("PST");
String name = zone.getDisplayName(Locale.ENGLISH);
logln("PST->" + name);
if (!name.equals("Pacific Standard Time"))
errln("Fail: Expected \"Pacific Standard Time\"");
//*****************************************************************
// THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
// THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
// THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
//*****************************************************************
Object[] DATA = {
new Boolean(false), new Integer(TimeZone.SHORT), "PST",
new Boolean(true), new Integer(TimeZone.SHORT), "PDT",
new Boolean(false), new Integer(TimeZone.LONG), "Pacific Standard Time",
new Boolean(true), new Integer(TimeZone.LONG), "Pacific Daylight Time",
};
for (int i=0; i<DATA.length; i+=3) {
name = zone.getDisplayName(((Boolean)DATA[i]).booleanValue(),
((Integer)DATA[i+1]).intValue(),
Locale.ENGLISH);
if (!name.equals(DATA[i+2]))
errln("Fail: Expected " + DATA[i+2] + "; got " + name);
}
// Make sure that we don't display the DST name by constructing a fake
// PST zone that has DST all year long.
SimpleTimeZone zone2 = new SimpleTimeZone(0, "PST");
zone2.setStartRule(Calendar.JANUARY, 1, 0);
zone2.setEndRule(Calendar.DECEMBER, 31, 0);
logln("Modified PST inDaylightTime->" + zone2.inDaylightTime(new Date()));
name = zone2.getDisplayName(Locale.ENGLISH);
logln("Modified PST->" + name);
if (!name.equals("Pacific Standard Time"))
errln("Fail: Expected \"Pacific Standard Time\"");
// Make sure we get the default display format for Locales
// with no display name data.
Locale zh_CN = Locale.SIMPLIFIED_CHINESE;
name = zone.getDisplayName(zh_CN);
//*****************************************************************
// THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
// THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
// THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
//*****************************************************************
logln("PST(zh_CN)->" + name);
// Now be smart -- check to see if zh resource is even present.
// If not, we expect the en fallback behavior.
ResourceBundle enRB = ResourceBundle.getBundle("java.text.resources.DateFormatZoneData",
Locale.ENGLISH);
ResourceBundle zhRB = ResourceBundle.getBundle("java.text.resources.DateFormatZoneData",
zh_CN);
boolean noZH = enRB == zhRB;
if (noZH) {
logln("Warning: Not testing the zh_CN behavior because resource is absent");
if (!name.equals("Pacific Standard Time"))
errln("Fail: Expected Pacific Standard Time");
}
else if (!name.equals("Pacific Standard Time") &&
!name.equals("GMT-08:00") &&
!name.equals("GMT-8:00") &&
!name.equals("GMT-0800") &&
!name.equals("GMT-800")) {
errln("Fail: Expected GMT-08:00 or something similar");
errln("************************************************************");
errln("THE ABOVE FAILURE MAY JUST MEAN THE LOCALE DATA HAS CHANGED");
errln("************************************************************");
}
// Now try a non-existent zone
zone2 = new SimpleTimeZone(90*60*1000, "xyzzy");
name = zone2.getDisplayName(Locale.ENGLISH);
logln("GMT+90min->" + name);
if (!name.equals("GMT+01:30") &&
!name.equals("GMT+1:30") &&
!name.equals("GMT+0130") &&
!name.equals("GMT+130"))
errln("Fail: Expected GMT+01:30 or something similar");
}
public void TestGenericAPI() {
String id = "NewGMT";
int offset = 12345;
SimpleTimeZone zone = new SimpleTimeZone(offset, id);
if (zone.useDaylightTime()) errln("FAIL: useDaylightTime should return false");
TimeZone zoneclone = (TimeZone)zone.clone();
if (!zoneclone.equals(zone)) errln("FAIL: clone or operator== failed");
zoneclone.setID("abc");
if (zoneclone.equals(zone)) errln("FAIL: clone or operator!= failed");
// delete zoneclone;
zoneclone = (TimeZone)zone.clone();
if (!zoneclone.equals(zone)) errln("FAIL: clone or operator== failed");
zoneclone.setRawOffset(45678);
if (zoneclone.equals(zone)) errln("FAIL: clone or operator!= failed");
// C++ only
/*
SimpleTimeZone copy(*zone);
if (!(copy == *zone)) errln("FAIL: copy constructor or operator== failed");
copy = *(SimpleTimeZone*)zoneclone;
if (!(copy == *zoneclone)) errln("FAIL: assignment operator or operator== failed");
*/
TimeZone saveDefault = TimeZone.getDefault();
TimeZone.setDefault(zone);
TimeZone defaultzone = TimeZone.getDefault();
if (defaultzone == zone) errln("FAIL: Default object is identical, not clone");
if (!defaultzone.equals(zone)) errln("FAIL: Default object is not equal");
TimeZone.setDefault(saveDefault);
// delete defaultzone;
// delete zoneclone;
}
public void TestRuleAPI()
{
// ErrorCode status = ZERO_ERROR;
int offset = (int)(60*60*1000*1.75); // Pick a weird offset
SimpleTimeZone zone = new SimpleTimeZone(offset, "TestZone");
if (zone.useDaylightTime()) errln("FAIL: useDaylightTime should return false");
// Establish our expected transition times. Do this with a non-DST
// calendar with the (above) declared local offset.
GregorianCalendar gc = new GregorianCalendar(zone);
gc.clear();
gc.set(1990, Calendar.MARCH, 1);
long marchOneStd = gc.getTime().getTime(); // Local Std time midnight
gc.clear();
gc.set(1990, Calendar.JULY, 1);
long julyOneStd = gc.getTime().getTime(); // Local Std time midnight
// Starting and ending hours, WALL TIME
int startHour = (int)(2.25 * 3600000);
int endHour = (int)(3.5 * 3600000);
zone.setStartRule(Calendar.MARCH, 1, 0, startHour);
zone.setEndRule (Calendar.JULY, 1, 0, endHour);
gc = new GregorianCalendar(zone);
// if (failure(status, "new GregorianCalendar")) return;
long marchOne = marchOneStd + startHour;
long julyOne = julyOneStd + endHour - 3600000; // Adjust from wall to Std time
long expMarchOne = 636251400000L;
if (marchOne != expMarchOne)
{
errln("FAIL: Expected start computed as " + marchOne +
" = " + new Date(marchOne));
logln(" Should be " + expMarchOne +
" = " + new Date(expMarchOne));
}
long expJulyOne = 646793100000L;
if (julyOne != expJulyOne)
{
errln("FAIL: Expected start computed as " + julyOne +
" = " + new Date(julyOne));
logln(" Should be " + expJulyOne +
" = " + new Date(expJulyOne));
}
_testUsingBinarySearch(zone, new Date(90, Calendar.JANUARY, 1).getTime(),
new Date(90, Calendar.JUNE, 15).getTime(), marchOne);
_testUsingBinarySearch(zone, new Date(90, Calendar.JUNE, 1).getTime(),
new Date(90, Calendar.DECEMBER, 31).getTime(), julyOne);
if (zone.inDaylightTime(new Date(marchOne - 1000)) ||
!zone.inDaylightTime(new Date(marchOne)))
errln("FAIL: Start rule broken");
if (!zone.inDaylightTime(new Date(julyOne - 1000)) ||
zone.inDaylightTime(new Date(julyOne)))
errln("FAIL: End rule broken");
zone.setStartYear(1991);
if (zone.inDaylightTime(new Date(marchOne)) ||
zone.inDaylightTime(new Date(julyOne - 1000)))
errln("FAIL: Start year broken");
// failure(status, "TestRuleAPI");
// delete gc;
// delete zone;
}
void _testUsingBinarySearch(SimpleTimeZone tz, long min, long max, long expectedBoundary)
{
// ErrorCode status = ZERO_ERROR;
boolean startsInDST = tz.inDaylightTime(new Date(min));
// if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
if (tz.inDaylightTime(new Date(max)) == startsInDST) {
logln("Error: inDaylightTime(" + new Date(max) + ") != " + (!startsInDST));
return;
}
// if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
while ((max - min) > INTERVAL) {
long mid = (min + max) / 2;
if (tz.inDaylightTime(new Date(mid)) == startsInDST) {
min = mid;
}
else {
max = mid;
}
// if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
}
logln("Binary Search Before: " + min + " = " + new Date(min));
logln("Binary Search After: " + max + " = " + new Date(max));
long mindelta = expectedBoundary - min;
long maxdelta = max - expectedBoundary;
if (mindelta >= 0 &&
mindelta <= INTERVAL &&
mindelta >= 0 &&
mindelta <= INTERVAL)
logln("PASS: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary));
else
errln("FAIL: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary));
}
static final int INTERVAL = 100;
// Bug 006; verify the offset for a specific zone.
public void TestPRTOffset()
{
TimeZone tz = TimeZone.getTimeZone( "PRT" );
if( tz == null ) {
errln( "FAIL: TimeZone(PRT) is null" );
}
else{
if (tz.getRawOffset() != (-4*millisPerHour))
errln("FAIL: Offset for PRT should be -4");
}
}
// Test various calls
public void TestVariousAPI518()
{
TimeZone time_zone = TimeZone.getTimeZone("PST");
Date d = new Date(97, Calendar.APRIL, 30);
logln("The timezone is " + time_zone.getID());
if (time_zone.inDaylightTime(d) != true)
errln("FAIL: inDaylightTime returned false");
if (time_zone.useDaylightTime() != true)
errln("FAIL: useDaylightTime returned false");
if (time_zone.getRawOffset() != -8*millisPerHour)
errln( "FAIL: getRawOffset returned wrong value");
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(d);
if (time_zone.getOffset(gc.AD, gc.get(gc.YEAR), gc.get(gc.MONTH),
gc.get(gc.DAY_OF_MONTH),
gc.get(gc.DAY_OF_WEEK), 0)
!= -7*millisPerHour)
errln("FAIL: getOffset returned wrong value");
}
// Test getAvailableID API
public void TestGetAvailableIDs913()
{
StringBuffer buf = new StringBuffer("TimeZone.getAvailableIDs() = { ");
String[] s = TimeZone.getAvailableIDs();
for (int i=0; i<s.length; ++i)
{
if (i > 0) buf.append(", ");
buf.append(s[i]);
}
buf.append(" };");
logln(buf.toString());
buf.setLength(0);
buf.append("TimeZone.getAvailableIDs(GMT+02:00) = { ");
s = TimeZone.getAvailableIDs(+2 * 60 * 60 * 1000);
for (int i=0; i<s.length; ++i)
{
if (i > 0) buf.append(", ");
buf.append(s[i]);
}
buf.append(" };");
logln(buf.toString());
TimeZone tz = TimeZone.getTimeZone("PST");
if (tz != null)
logln("getTimeZone(PST) = " + tz.getID());
else
errln("FAIL: getTimeZone(PST) = null");
tz = TimeZone.getTimeZone("America/Los_Angeles");
if (tz != null)
logln("getTimeZone(America/Los_Angeles) = " + tz.getID());
else
errln("FAIL: getTimeZone(PST) = null");
// Bug 4096694
tz = TimeZone.getTimeZone("NON_EXISTENT");
if (tz == null)
errln("FAIL: getTimeZone(NON_EXISTENT) = null");
else if (!tz.getID().equals("GMT"))
errln("FAIL: getTimeZone(NON_EXISTENT) = " + tz.getID());
}
/**
* Bug 4107276
*/
public void TestDSTSavings() {
// It might be better to find a way to integrate this test into the main TimeZone
// tests above, but I don't have time to figure out how to do this (or if it's
// even really a good idea). Let's consider that a future. --rtg 1/27/98
SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "dstSavingsTest",
Calendar.MARCH, 1, 0, 0, Calendar.SEPTEMBER, 1, 0, 0,
(int)(0.5 * millisPerHour));
if (tz.getRawOffset() != -5 * millisPerHour)
errln("Got back a raw offset of " + (tz.getRawOffset() / millisPerHour) +
" hours instead of -5 hours.");
if (!tz.useDaylightTime())
errln("Test time zone should use DST but claims it doesn't.");
if (tz.getDSTSavings() != 0.5 * millisPerHour)
errln("Set DST offset to 0.5 hour, but got back " + (tz.getDSTSavings() /
millisPerHour) + " hours instead.");
int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,
Calendar.THURSDAY, 10 * millisPerHour);
if (offset != -5 * millisPerHour)
errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,
10 * millisPerHour);
if (offset != -4.5 * millisPerHour)
errln("The offset for 10 AM, 6/1/98 should have been -4.5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
tz.setDSTSavings(millisPerHour);
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,
Calendar.THURSDAY, 10 * millisPerHour);
if (offset != -5 * millisPerHour)
errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,
10 * millisPerHour);
if (offset != -4 * millisPerHour)
errln("The offset for 10 AM, 6/1/98 (with a 1-hour DST offset) should have been -4 hours, but we got "
+ (offset / millisPerHour) + " hours.");
}
/**
* Bug 4107570
*/
public void TestAlternateRules() {
// Like TestDSTSavings, this test should probably be integrated somehow with the main
// test at the top of this class, but I didn't have time to figure out how to do that.
// --rtg 1/28/98
SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "alternateRuleTest");
// test the day-of-month API
tz.setStartRule(Calendar.MARCH, 10, 12 * millisPerHour);
tz.setEndRule(Calendar.OCTOBER, 20, 12 * millisPerHour);
int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 5,
Calendar.THURSDAY, 10 * millisPerHour);
if (offset != -5 * millisPerHour)
errln("The offset for 10AM, 3/5/98 should have been -5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 15,
Calendar.SUNDAY, 10 * millisPerHour);
if (offset != -4 * millisPerHour)
errln("The offset for 10AM, 3/15/98 should have been -4 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,
Calendar.THURSDAY, 10 * millisPerHour);
if (offset != -4 * millisPerHour)
errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 25,
Calendar.SUNDAY, 10 * millisPerHour);
if (offset != -5 * millisPerHour)
errln("The offset for 10AM, 10/25/98 should have been -5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
// test the day-of-week-after-day-in-month API
tz.setStartRule(Calendar.MARCH, 10, Calendar.FRIDAY, 12 * millisPerHour, true);
tz.setEndRule(Calendar.OCTOBER, 20, Calendar.FRIDAY, 12 * millisPerHour, false);
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 11,
Calendar.WEDNESDAY, 10 * millisPerHour);
if (offset != -5 * millisPerHour)
errln("The offset for 10AM, 3/11/98 should have been -5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 14,
Calendar.SATURDAY, 10 * millisPerHour);
if (offset != -4 * millisPerHour)
errln("The offset for 10AM, 3/14/98 should have been -4 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,
Calendar.THURSDAY, 10 * millisPerHour);
if (offset != -4 * millisPerHour)
errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 17,
Calendar.SATURDAY, 10 * millisPerHour);
if (offset != -5 * millisPerHour)
errln("The offset for 10AM, 10/17/98 should have been -5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
}
}
//eof

View File

@ -37,7 +37,7 @@ import java.text.NumberFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
import java.util.TimeZone;
import com.ibm.util.TimeZone;
import com.ibm.util.Calendar;
import com.ibm.util.GregorianCalendar;
import java.util.Date;
@ -118,9 +118,9 @@ import java.text.resources.*;
* @see Format
* @see NumberFormat
* @see SimpleDateFormat
* @see java.util.Calendar
* @see java.util.GregorianCalendar
* @see java.util.TimeZone
* @see com.ibm.util.Calendar
* @see com.ibm.util.GregorianCalendar
* @see com.ibm.util.TimeZone
* @version 1.37 11/02/99
* @author Mark Davis, Chen-Lieh Huang, Alan Liu
*/
@ -582,7 +582,7 @@ public abstract class DateFormat extends Format {
* do not precisely match this object's format. With strict parsing,
* inputs must match this object's format.
* @param lenient when true, parsing is lenient
* @see java.util.Calendar#setLenient
* @see com.ibm.util.Calendar#setLenient
*/
public void setLenient(boolean lenient)
{

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/DateFormatSymbols.java,v $
* $Date: 2000/04/27 22:41:39 $
* $Revision: 1.3 $
* $Date: 2000/05/12 23:19:35 $
* $Revision: 1.4 $
*
*****************************************************************************************
*/
@ -64,7 +64,7 @@ import com.ibm.util.Utility;
* @see DateFormat
* @see SimpleDateFormat
* @see java.util.SimpleTimeZone
* @see com.ibm.util.SimpleTimeZone
* @version 1.31 09/21/99
* @author Chen-Lieh Huang
*/
@ -169,7 +169,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* are localized names. If a zone does not implement daylight savings
* time, the daylight savings time names are ignored.
* @see java.text.resources.DateFormatZoneData
* @see java.util.TimeZone
* @see com.ibm.util.TimeZone
* @serial
*/
String zoneStrings[][] = null;
@ -505,7 +505,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* @param ID the given time zone ID.
* @return the index of the given time zone ID. Returns -1 if
* the given time zone ID can't be located in the DateFormatSymbols object.
* @see java.util.SimpleTimeZone
* @see com.ibm.util.SimpleTimeZone
*/
final int getZoneIndex (String ID)
{

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/text/SimpleDateFormat.java,v $
* $Date: 2000/04/27 22:41:39 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:19:35 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -20,12 +20,12 @@ import java.text.NumberFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.util.TimeZone;
import com.ibm.util.TimeZone;
import com.ibm.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
import com.ibm.util.GregorianCalendar;
import java.io.ObjectInputStream;
import java.io.IOException;
@ -170,9 +170,9 @@ import java.lang.StringIndexOutOfBoundsException;
* time zone. There is one common decimal format to handle all the numbers;
* the digit count is handled programmatically according to the pattern.
*
* @see java.util.Calendar
* @see java.util.GregorianCalendar
* @see java.util.TimeZone
* @see com.ibm.util.Calendar
* @see com.ibm.util.GregorianCalendar
* @see com.ibm.util.TimeZone
* @see DateFormat
* @see DateFormatSymbols
* @see DecimalFormat

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/util/BuddhistCalendar.java,v $
* $Date: 2000/03/21 02:19:32 $
* $Revision: 1.3 $
* $Date: 2000/05/12 23:20:10 $
* $Revision: 1.4 $
*
*****************************************************************************************
*/
@ -16,7 +16,6 @@ package com.ibm.util;
import java.util.Date;
import com.ibm.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
/**
* <code>BuddhistCalendar</code> is a subclass of <code>GregorianCalendar</code>
@ -33,7 +32,7 @@ import java.util.TimeZone;
* calendar is not in lenient mode (see <code>setLenient</code>), dates before
* 1/1/1 BE are rejected with an <code>IllegalArgumentException</code>.
*
* @see java.util.GregorianCalendar
* @see com.ibm.util.GregorianCalendar
*
* @author Laura Werner
*/
@ -49,7 +48,7 @@ public class BuddhistCalendar extends GregorianCalendar {
* Constant for the Buddhist Era. This is the only allowable <code>ERA</code>
* value for the Buddhist calendar.
*
* @see java.util.Calendar#ERA
* @see com.ibm.util.Calendar#ERA
*/
public static final int BE = 0;

View File

@ -33,7 +33,6 @@ import java.util.Date;
import java.util.Hashtable;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.TimeZone;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/util/EasterHoliday.java,v $
* $Date: 2000/03/21 02:19:32 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:20:10 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -16,7 +16,7 @@ package com.ibm.util;
import java.util.Date;
import com.ibm.util.GregorianCalendar;
import com.ibm.util.Calendar;
import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
/**
* A Holiday subclass which represents holidays that occur

View File

@ -31,7 +31,6 @@
package com.ibm.util;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
/**
* <code>GregorianCalendar</code> is a concrete subclass of
@ -1184,8 +1183,9 @@ public class GregorianCalendar extends Calendar {
// getOffset(..., monthLen). This makes some zones behave incorrectly.
// Fix this later, if desired, by porting TimeZone and STZ to this pkg.
// -Alan
int dstOffset = getTimeZone().getOffset(era,year,month,date,dayOfWeek,millisInDay /*,
monthLength(month), prevMonthLength(month)*/)
// [icu4j fixed after 'port' of tz&stz to com.ibm.util - liu]
int dstOffset = getTimeZone().getOffset(era,year,month,date,dayOfWeek,millisInDay,
monthLength(month), prevMonthLength(month))
- rawOffset;
// Adjust our millisInDay for DST, if necessary.
@ -1525,14 +1525,15 @@ public class GregorianCalendar extends Calendar {
// getOffset(..., millis). This makes some zones behave incorrectly.
// Fix this later, if desired, by porting TimeZone and STZ to this pkg.
// -Alan
// [icu4j fixed after 'port' of tz&stz to com.ibm.util - liu]
dstOffset = zone.getOffset(era,
internalGet(YEAR),
internalGet(MONTH),
internalGet(DATE),
dow,
normalizedMillisInDay[0] /*,
normalizedMillisInDay[0],
monthLength(internalGet(MONTH)),
prevMonthLength(internalGet(MONTH)) */) -
prevMonthLength(internalGet(MONTH))) -
zoneOffset;
// Note: Because we pass in wall millisInDay, rather than
// standard millisInDay, we interpret "1:00 am" on the day

View File

@ -5,17 +5,15 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/util/HebrewCalendar.java,v $
* $Date: 2000/03/10 04:17:58 $
* $Revision: 1.2 $
* $Date: 2000/05/12 23:20:10 $
* $Revision: 1.3 $
*
*****************************************************************************************
*/
package com.ibm.util;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
/**
* <code>HebrewCalendar</code> is a subclass of <code>Calendar</code>
@ -63,7 +61,7 @@ import java.util.TimeZone;
* http://www.pip.dknet.dk/~pip10160/calendar.html</a>
* </ul>
* <p>
* @see java.util.GregorianCalendar
* @see com.ibm.util.GregorianCalendar
*
* @author Laura Werner
*/
@ -352,7 +350,7 @@ public class HebrewCalendar extends IBMCalendar {
*
* @param field The field whose minimum value is desired.
*
* @see java.util.Calendar#getMinimum
* @see com.ibm.util.Calendar#getMinimum
*/
public int getMinimum(int field)
{
@ -570,7 +568,7 @@ public class HebrewCalendar extends IBMCalendar {
//-------------------------------------------------------------------------
// Functions for converting from field values to milliseconds and back...
//
// These are overrides of abstract methods on java.util.Calendar
// These are overrides of abstract methods on com.ibm.util.Calendar
//-------------------------------------------------------------------------
/**
@ -1099,4 +1097,4 @@ public class HebrewCalendar extends IBMCalendar {
System.out.println(str);
}
}
};
};

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/util/IslamicCalendar.java,v $
* $Date: 2000/03/21 02:19:32 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:20:10 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -16,7 +16,6 @@ import com.ibm.util.Calendar;
import java.util.Date;
import com.ibm.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import com.ibm.util.CalendarAstronomer;
/**
@ -69,7 +68,7 @@ import com.ibm.util.CalendarAstronomer;
* fixed-cycle civil calendar is used. However, if <code>setCivil(false)</code>
* is called, an approximation of the true lunar calendar will be used.
*
* @see java.util.GregorianCalendar
* @see com.ibm.util.GregorianCalendar
*
* @author Laura Werner
* @version 1.0
@ -297,7 +296,7 @@ public class IslamicCalendar extends IBMCalendar {
*
* @param field The field whose minimum value is desired.
*
* @see java.util.Calendar#getMinimum
* @see com.ibm.util.Calendar#getMinimum
*/
public int getMinimum(int field)
{

View File

@ -5,18 +5,15 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/util/JapaneseCalendar.java,v $
* $Date: 2000/03/21 02:19:32 $
* $Revision: 1.3 $
* $Date: 2000/05/12 23:20:10 $
* $Revision: 1.4 $
*
*****************************************************************************************
*/
package com.ibm.util;
import java.util.Date;
import com.ibm.util.GregorianCalendar;
import java.util.Locale;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
/**
* <code>JapaneseCalendar</code> is a subclass of <code>GregorianCalendar</code>
@ -43,7 +40,7 @@ import java.util.TimeZone;
* constants rather than using actual, absolute numbers.
* <p>
*
* @see java.util.GregorianCalendar
* @see com.ibm.util.GregorianCalendar
*
* @author Laura Werner
*/

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/util/SimpleDateRule.java,v $
* $Date: 2000/03/21 02:19:32 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:20:11 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -16,7 +16,7 @@ package com.ibm.util;
import java.util.Date;
import com.ibm.util.Calendar;
import com.ibm.util.GregorianCalendar;
import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
public class SimpleDateRule implements DateRule
{

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,157 @@
/* Copyright (c) 2000 International Business Machines Corporation and
* others. All Rights Reserved.
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/util/Attic/SimpleTimeZoneAdapter.java,v $
* $Date: 2000/05/12 23:20:11 $
* $Revision: 1.1 $
*/
package com.ibm.util;
import java.util.Date;
/**
* <code>SimpleTimeZoneAdapter</code> wraps a
* com.ibm.util.SimpleTimeZone and inherits from java.util.TimeZone.
* Without this class, we would need to 'port' java.util.Date to
* com.ibm.util as well, so that Date could interoperate properly with
* the com.ibm.util TimeZone and Calendar classes. With this class,
* we can (mostly) use java.util.Date together with com.ibm.util
* classes.
*
* <p>This solution is imperfect because of the faulty design of
* java.util.TimeZone. Specifically, TZ contains a package private
* method, getOffset(), that should really be public. Because it is
* package private, it cannot be overridden from where we are, and we
* cannot properly delegate its operation to our contained
* com.ibm.util.STZ object.
*
* <p>For the moment we live with this problem. It appear not to
* cause too much trouble since most real computations happen using
* the com.ibm.util classes. However, if this becomes a problem in
* the future, we will have to stop using this adapter, and 'port'
* java.util.Date into com.ibm.util.
*
* @see com.ibm.util.TimeZone#setDefault
* @author Alan Liu
*/
public class SimpleTimeZoneAdapter extends java.util.TimeZone {
/**
* The contained com.ibm.util.SimpleTimeZone object.
* We delegate all methods to this object.
*/
private SimpleTimeZone zone;
public SimpleTimeZoneAdapter(SimpleTimeZone zone) {
this.zone = zone;
}
/**
* Override TimeZone
*/
public String getID() {
return zone.getID();
}
/**
* Override TimeZone
*/
public void setID(String ID) {
zone.setID(ID);
}
/**
* Override TimeZone
*/
public boolean hasSameRules(java.util.TimeZone other) {
return other instanceof SimpleTimeZoneAdapter &&
zone.hasSameRules(((SimpleTimeZoneAdapter)other).zone);
}
/**
* Override TimeZone
*/
public int getOffset(int era, int year, int month, int day, int dayOfWeek,
int millis) {
return zone.getOffset(era, year, month, day, dayOfWeek, millis);
}
// This doesn't work! Because this is a package-private method,
// it cannot override the corresponding method in java.util.TZ.
// This reflects a fundamental bug in the architecture of
// java.util.TZ. If not for this, this adapter class would
// work flawlessly. - liu
//! /**
//! * Override TimeZone
//! */
//! int getOffset(int era, int year, int month, int day, int dayOfWeek,
//! int millis, int monthLength, int prevMonthLength) {
//! return zone.getOffset(era, year, month, day, dayOfWeek,
//! millis, monthLength, prevMonthLength);
//! }
/**
* Overrides TimeZone
* Gets the GMT offset for this time zone.
*/
public int getRawOffset() {
return zone.getRawOffset();
}
/**
* Overrides TimeZone
*/
public void setRawOffset(int offsetMillis) {
zone.setRawOffset(offsetMillis);
}
/**
* Overrides TimeZone
*/
public boolean useDaylightTime() {
return zone.useDaylightTime();
}
/**
* Overrides TimeZone
*/
public boolean inDaylightTime(Date date) {
return zone.inDaylightTime(date);
}
/**
* Overrides Cloneable
*/
public Object clone() {
return new SimpleTimeZoneAdapter((SimpleTimeZone)zone.clone());
}
/**
* Override hashCode.
*/
public synchronized int hashCode() {
return zone.hashCode();
}
/**
* Compares the equality of two SimpleTimeZone objects.
*
* @param obj The SimpleTimeZone object to be compared with.
* @return True if the given obj is the same as this SimpleTimeZone
* object; false otherwise.
*/
public boolean equals(Object obj) {
if (obj instanceof SimpleTimeZoneAdapter) {
obj = ((SimpleTimeZoneAdapter)obj).zone;
}
return zone.equals(obj);
}
/**
* Return a string representation of this time zone.
* @return a string representation of this time zone.
*/
public String toString() {
// Should probably show our class name here...fix later.
return zone.toString();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/test/calendar/Attic/AstroTest.java,v $
* $Date: 2000/03/21 02:20:08 $
* $Revision: 1.3 $
* $Date: 2000/05/12 23:19:12 $
* $Revision: 1.4 $
*
*****************************************************************************************
*/
@ -15,7 +15,6 @@ package com.ibm.test.calendar;
// AstroTest
import com.ibm.test.*;
import java.util.SimpleTimeZone;
import com.ibm.util.*;
import com.ibm.util.CalendarAstronomer.*;

View File

@ -1,8 +1,6 @@
package com.ibm.test.calendar;
import com.ibm.util.*;
import java.util.Date;
import java.util.TimeZone;
import java.util.SimpleTimeZone;
import java.util.Locale;
import com.ibm.text.*;
@ -771,23 +769,25 @@ public class CalendarRegression extends com.ibm.test.TestFmwk {
// I am disabling this test -- it is currently failing because of a bug
// in Sun's latest change to STZ.getOffset(). I have filed a Sun bug
// against this problem.
//! /**
//! * Prove that GregorianCalendar is proleptic (it used to cut off
//! * at 45 BC, and not have leap years before then).
//! */
//! public void Test4125892() {
//! GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();
//! DateFormat fmt = new SimpleDateFormat("MMMM d, yyyy G");
//! cal.clear();
//! cal.set(Calendar.ERA, GregorianCalendar.BC);
//! cal.set(Calendar.YEAR, 81); // 81 BC is a leap year (proleptically)
//! cal.set(Calendar.MONTH, Calendar.FEBRUARY);
//! cal.set(Calendar.DATE, 28);
//! cal.add(Calendar.DATE, 1);
//! if (cal.get(Calendar.DATE) != 29 ||
//! !cal.isLeapYear(-80)) // -80 == 81 BC
//! errln("Calendar not proleptic");
//! }
// Re-enabled after 'porting' TZ and STZ from java.util to com.ibm.util.
/**
* Prove that GregorianCalendar is proleptic (it used to cut off
* at 45 BC, and not have leap years before then).
*/
public void Test4125892() {
GregorianCalendar cal = (GregorianCalendar) Calendar.getInstance();
DateFormat fmt = new SimpleDateFormat("MMMM d, yyyy G");
cal.clear();
cal.set(Calendar.ERA, GregorianCalendar.BC);
cal.set(Calendar.YEAR, 81); // 81 BC is a leap year (proleptically)
cal.set(Calendar.MONTH, Calendar.FEBRUARY);
cal.set(Calendar.DATE, 28);
cal.add(Calendar.DATE, 1);
if (cal.get(Calendar.DATE) != 29 ||
!cal.isLeapYear(-80)) // -80 == 81 BC
errln("Calendar not proleptic");
}
/**
* Calendar and GregorianCalendar hashCode() methods need improvement.

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/test/calendar/Attic/CalendarTest.java,v $
* $Date: 2000/03/21 02:20:08 $
* $Revision: 1.3 $
* $Date: 2000/05/12 23:19:12 $
* $Revision: 1.4 $
*
*****************************************************************************************
*/
@ -18,7 +18,6 @@ import com.ibm.text.DateFormat;
import com.ibm.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone;
import com.ibm.util.*;
/**

View File

@ -7,8 +7,6 @@
package com.ibm.test.calendar;
import com.ibm.util.*;
import java.util.Date;
import java.util.TimeZone;
import java.util.SimpleTimeZone;
import java.util.Locale;
import java.text.*;
import java.io.*;

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/test/calendar/Attic/TestCase.java,v $
* $Date: 2000/03/21 02:20:08 $
* $Revision: 1.3 $
* $Date: 2000/05/12 23:19:12 $
* $Revision: 1.4 $
*
*****************************************************************************************
*/
@ -16,7 +16,7 @@ import com.ibm.test.*;
import com.ibm.util.Calendar;
import com.ibm.util.GregorianCalendar;
import java.util.Date;
import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
import java.util.Locale;
/**

View File

@ -0,0 +1,674 @@
/*
@test 1.9 99/06/15
@summary test Time Zone Boundary
*/
package com.ibm.test.timezone;
import com.ibm.text.*;
import com.ibm.util.*;
import com.ibm.test.*;
import java.util.Date;
/**
* A test which discovers the boundaries of DST programmatically and verifies
* that they are correct.
*/
public class TimeZoneBoundaryTest extends TestFmwk
{
static final int ONE_SECOND = 1000;
static final int ONE_MINUTE = 60*ONE_SECOND;
static final int ONE_HOUR = 60*ONE_MINUTE;
static final long ONE_DAY = 24*ONE_HOUR;
static final long ONE_YEAR = (long)(365.25 * ONE_DAY);
static final long SIX_MONTHS = ONE_YEAR / 2;
static final int MONTH_LENGTH[] = {31,29,31,30,31,30,31,31,30,31,30,31};
// These values are empirically determined to be correct
static final long PST_1997_BEG = 860320800000L;
static final long PST_1997_END = 877856400000L;
// Minimum interval for binary searches in ms; should be no larger
// than 1000.
static final long INTERVAL = 10; // Milliseconds
// When long zone names are supported again, switch this to the
// long zone name.
static final String AUSTRALIA = "AET"; // Australia/Adelaide
static final long AUSTRALIA_1997_BEG = 872524800000L; // 877797000000L
static final long AUSTRALIA_1997_END = 859651200000L; // 859653000000L
public static void main(String[] args) throws Exception {
new TimeZoneBoundaryTest().run(args);
}
/**
* Date.toString().substring() Boundary Test
* Look for a DST changeover to occur within 6 months of the given Date.
* The initial Date.toString() should yield a string containing the
* startMode as a SUBSTRING. The boundary will be tested to be
* at the expectedBoundary value.
*/
void findDaylightBoundaryUsingDate(Date d, String startMode, long expectedBoundary)
{
// Given a date with a year start, find the Daylight onset
// and end. The given date should be 1/1/xx in some year.
if (d.toString().indexOf(startMode) == -1)
{
logln("Error: " + startMode + " not present in " + d);
}
// Use a binary search, assuming that we have a Standard
// time at the midpoint.
long min = d.getTime();
long max = min + SIX_MONTHS;
while ((max - min) > INTERVAL)
{
long mid = (min + max) >> 1;
String s = new Date(mid).toString();
// logln(s);
if (s.indexOf(startMode) != -1)
{
min = mid;
}
else
{
max = mid;
}
}
logln("Date Before: " + showDate(min));
logln("Date After: " + showDate(max));
long mindelta = expectedBoundary - min;
long maxdelta = max - expectedBoundary;
if (mindelta >= 0 && mindelta <= INTERVAL &&
mindelta >= 0 && mindelta <= INTERVAL)
logln("PASS: Expected boundary at " + expectedBoundary);
else
errln("FAIL: Expected boundary at " + expectedBoundary);
}
// This test cannot be compiled until the inDaylightTime() method of GregorianCalendar
// becomes public.
// static void findDaylightBoundaryUsingCalendar(Date d, boolean startsInDST)
// {
// // Given a date with a year start, find the Daylight onset
// // and end. The given date should be 1/1/xx in some year.
//
// GregorianCalendar cal = new GregorianCalendar();
// cal.setTime(d);
// if (cal.inDaylightTime() != startsInDST)
// {
// logln("Error: inDaylightTime(" + d + ") != " + startsInDST);
// }
//
// // Use a binary search, assuming that we have a Standard
// // time at the midpoint.
// long min = d.getTime();
// long max = min + (long)(365.25 / 2 * 24*60*60*1000);
//
// while ((max - min) > INTERVAL)
// {
// long mid = (min + max) >> 1;
// cal.setTime(new Date(mid));
// if (cal.inDaylightTime() == startsInDST)
// {
// min = mid;
// }
// else
// {
// max = mid;
// }
// }
//
// logln("Calendar Before: " + showDate(min));
// logln("Calendar After: " + showDate(max));
// }
void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST, long expectedBoundary)
{
findDaylightBoundaryUsingTimeZone(d, startsInDST, expectedBoundary,
TimeZone.getDefault());
}
void findDaylightBoundaryUsingTimeZone(Date d, boolean startsInDST,
long expectedBoundary, TimeZone tz)
{
// Given a date with a year start, find the Daylight onset
// and end. The given date should be 1/1/xx in some year.
// Use a binary search, assuming that we have a Standard
// time at the midpoint.
long min = d.getTime();
long max = min + SIX_MONTHS;
if (tz.inDaylightTime(d) != startsInDST)
{
errln("FAIL: " + tz.getID() + " inDaylightTime(" +
d + ") != " + startsInDST);
startsInDST = !startsInDST; // Flip over; find the apparent value
}
if (tz.inDaylightTime(new Date(max)) == startsInDST)
{
errln("FAIL: " + tz.getID() + " inDaylightTime(" +
(new Date(max)) + ") != " + (!startsInDST));
return;
}
while ((max - min) > INTERVAL)
{
long mid = (min + max) >> 1;
boolean isIn = tz.inDaylightTime(new Date(mid));
if (isIn == startsInDST)
{
min = mid;
}
else
{
max = mid;
}
}
logln(tz.getID() + " Before: " + showDate(min, tz));
logln(tz.getID() + " After: " + showDate(max, tz));
long mindelta = expectedBoundary - min;
long maxdelta = max - expectedBoundary;
if (mindelta >= 0 && mindelta <= INTERVAL &&
mindelta >= 0 && mindelta <= INTERVAL)
logln("PASS: Expected boundary at " + expectedBoundary);
else
errln("FAIL: Expected boundary at " + expectedBoundary);
}
private static String showDate(long l)
{
return showDate(new Date(l));
}
private static String showDate(Date d)
{
return "" + d.getYear() + "/" + showNN(d.getMonth()+1) + "/" + showNN(d.getDate()) +
" " + showNN(d.getHours()) + ":" + showNN(d.getMinutes()) +
" \"" + d + "\" = " +
d.getTime();
}
private static String showDate(long l, TimeZone z)
{
return showDate(new Date(l), z);
}
private static String showDate(Date d, TimeZone zone)
{
DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
fmt.setTimeZone(zone);
return "" + d.getYear() + "/" + showNN(d.getMonth()+1) + "/" + showNN(d.getDate()) +
" " + showNN(d.getHours()) + ":" + showNN(d.getMinutes()) +
" \"" + d + "\" = " +
fmt.format(d);
}
private static String showNN(int n)
{
return ((n < 10) ? "0" : "") + n;
}
/**
* Given a date, a TimeZone, and expected values for inDaylightTime,
* useDaylightTime, zone and DST offset, verify that this is the case.
*/
void verifyDST(Date d, TimeZone time_zone,
boolean expUseDaylightTime, boolean expInDaylightTime,
int expZoneOffset, int expDSTOffset)
{
logln("-- Verifying time " + d +
" in zone " + time_zone.getID());
if (time_zone.inDaylightTime(d) == expInDaylightTime)
logln("PASS: inDaylightTime = " + time_zone.inDaylightTime(d));
else
errln("FAIL: inDaylightTime = " + time_zone.inDaylightTime(d));
if (time_zone.useDaylightTime() == expUseDaylightTime)
logln("PASS: useDaylightTime = " + time_zone.useDaylightTime());
else
errln("FAIL: useDaylightTime = " + time_zone.useDaylightTime());
if (time_zone.getRawOffset() == expZoneOffset)
logln("PASS: getRawOffset() = " + expZoneOffset/(double)ONE_HOUR);
else
errln("FAIL: getRawOffset() = " + time_zone.getRawOffset()/(double)ONE_HOUR +
"; expected " + expZoneOffset/(double)ONE_HOUR);
GregorianCalendar gc = new GregorianCalendar(time_zone);
gc.setTime(d);
int offset = time_zone.getOffset(gc.get(gc.ERA), gc.get(gc.YEAR), gc.get(gc.MONTH),
gc.get(gc.DAY_OF_MONTH), gc.get(gc.DAY_OF_WEEK),
((gc.get(gc.HOUR_OF_DAY) * 60 +
gc.get(gc.MINUTE)) * 60 +
gc.get(gc.SECOND)) * 1000 +
gc.get(gc.MILLISECOND));
if (offset == expDSTOffset)
logln("PASS: getOffset() = " + offset/(double)ONE_HOUR);
else
errln("FAIL: getOffset() = " + offset/(double)ONE_HOUR +
"; expected " + expDSTOffset/(double)ONE_HOUR);
}
public void TestBoundaries()
{
TimeZone pst = TimeZone.getTimeZone("PST");
TimeZone save = TimeZone.getDefault();
try {
TimeZone.setDefault(pst);
// DST changeover for PST is 4/6/1997 at 2 hours past midnight
Date d = new Date(97,Calendar.APRIL,6);
// i is minutes past midnight standard time
for (int i=60; i<=180; i+=15)
{
boolean inDST = (i >= 120);
Date e = new Date(d.getTime() + i*60*1000);
verifyDST(e, pst, true, inDST, -8*ONE_HOUR,
inDST ? -7*ONE_HOUR : -8*ONE_HOUR);
}
} finally {
TimeZone.setDefault(save);
}
if (true)
{
// This only works in PST/PDT
TimeZone.setDefault(TimeZone.getTimeZone("PST"));
logln("========================================");
findDaylightBoundaryUsingDate(new Date(97,0,1), "PST", PST_1997_BEG);
logln("========================================");
findDaylightBoundaryUsingDate(new Date(97,6,1), "PDT", PST_1997_END);
}
// if (true)
// {
// logln("========================================");
// findDaylightBoundaryUsingCalendar(new Date(97,0,1), false);
// logln("========================================");
// findDaylightBoundaryUsingCalendar(new Date(97,6,1), true);
// }
if (true)
{
// Southern hemisphere test
logln("========================================");
TimeZone z = TimeZone.getTimeZone(AUSTRALIA);
findDaylightBoundaryUsingTimeZone(new Date(97,0,1), true, AUSTRALIA_1997_END, z);
logln("========================================");
findDaylightBoundaryUsingTimeZone(new Date(97,6,1), false, AUSTRALIA_1997_BEG, z);
}
if (true)
{
logln("========================================");
findDaylightBoundaryUsingTimeZone(new Date(97,0,1), false, PST_1997_BEG);
logln("========================================");
findDaylightBoundaryUsingTimeZone(new Date(97,6,1), true, PST_1997_END);
}
// This just shows the offset for April 4-7 in 1997. This is redundant
// with a test above, so we disable it.
if (false)
{
TimeZone z = TimeZone.getDefault();
logln(z.getOffset(1, 97, 3, 4, 6, 0) + " " + new Date(97, 3, 4));
logln(z.getOffset(1, 97, 3, 5, 7, 0) + " " + new Date(97, 3, 5));
logln(z.getOffset(1, 97, 3, 6, 1, 0) + " " + new Date(97, 3, 6));
logln(z.getOffset(1, 97, 3, 7, 2, 0) + " " + new Date(97, 3, 7));
}
}
//----------------------------------------------------------------------
// Can't do any of these without a public inDaylightTime in GC
//----------------------------------------------------------------------
// static GregorianCalendar cal = new GregorianCalendar();
//
// static void _testUsingBinarySearch(Date d, boolean startsInDST)
// {
// // Given a date with a year start, find the Daylight onset
// // and end. The given date should be 1/1/xx in some year.
//
// // Use a binary search, assuming that we have a Standard
// // time at the midpoint.
// long min = d.getTime();
// long max = min + (long)(365.25 / 2 * ONE_DAY);
//
// // First check the max
// cal.setTime(new Date(max));
// if (cal.inDaylightTime() == startsInDST)
// {
// logln("Error: inDaylightTime(" + (new Date(max)) + ") != " + (!startsInDST));
// }
//
// cal.setTime(d);
// if (cal.inDaylightTime() != startsInDST)
// {
// logln("Error: inDaylightTime(" + d + ") != " + startsInDST);
// }
//
// while ((max - min) > INTERVAL)
// {
// long mid = (min + max) >> 1;
// cal.setTime(new Date(mid));
// if (cal.inDaylightTime() == startsInDST)
// {
// min = mid;
// }
// else
// {
// max = mid;
// }
// }
//
// logln("Binary Search Before: " + showDate(min));
// logln("Binary Search After: " + showDate(max));
// }
//
// static void _testUsingMillis(Date d, boolean startsInDST)
// {
// long millis = d.getTime();
// long max = millis + (long)(370 * ONE_DAY); // A year plus extra
//
// boolean lastDST = startsInDST;
// while (millis < max)
// {
// cal.setTime(new Date(millis));
// boolean inDaylight = cal.inDaylightTime();
//
// if (inDaylight != lastDST)
// {
// logln("Switch " + (inDaylight ? "into" : "out of")
// + " DST at " + (new Date(millis)));
// lastDST = inDaylight;
// }
//
// millis += 15*ONE_MINUTE;
// }
// }
//
// static void _testUsingFields(int y, boolean startsInDST)
// {
// boolean lastDST = startsInDST;
// for (int m = 0; m < 12; ++m)
// {
// for (int d = 1; d <= MONTH_LENGTH[m]; ++d)
// {
// for (int h = 0; h < 24; ++h)
// {
// for (int min = 0; min < 60; min += 15)
// {
// cal.clear();
// cal.set(y, m, d, h, min);
// boolean inDaylight = cal.inDaylightTime();
// if (inDaylight != lastDST)
// {
// lastDST = inDaylight;
// log("Switch " + (lastDST ? "into" : "out of")
// + " DST at " + y + "/" + (m+1) + "/" + d
// + " " + showNN(h) + ":" + showNN(min));
// logln(" " + cal.getTime());
//
// cal.set(y, m, d, h-1, 45);
// log("Before = "
//+ y + "/" + (m+1) + "/" + d
//+ " " + showNN(h-1) + ":" + showNN(45));
// logln(" " + cal.getTime());
// }
// }
// }
// }
// }
// }
//
// public void Test1()
// {
// logln(Locale.getDefault().getDisplayName());
// logln(TimeZone.getDefault().getID());
// logln(new Date(0));
//
// if (true)
// {
// logln("========================================");
// _testUsingBinarySearch(new Date(97,0,1), false);
// logln("========================================");
// _testUsingBinarySearch(new Date(97,6,1), true);
// }
//
// if (true)
// {
// logln("========================================");
// logln("Stepping using millis");
// _testUsingMillis(new Date(97,0,1), false);
// }
//
// if (true)
// {
// logln("========================================");
// logln("Stepping using fields");
// _testUsingFields(1997, false);
// }
//
// if (false)
// {
// cal.clear();
// cal.set(1997, 3, 5, 10, 0);
// // cal.inDaylightTime();
// logln("Date = " + cal.getTime());
// logln("Millis = " + cal.getTime().getTime()/3600000);
// }
// }
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//----------------------------------------------------------------------
void _testUsingBinarySearch(SimpleTimeZone tz, Date d, long expectedBoundary)
{
// Given a date with a year start, find the Daylight onset
// and end. The given date should be 1/1/xx in some year.
// Use a binary search, assuming that we have a Standard
// time at the midpoint.
long min = d.getTime();
long max = min + (long)(365.25 / 2 * ONE_DAY);
// First check the boundaries
boolean startsInDST = tz.inDaylightTime(d);
if (tz.inDaylightTime(new Date(max)) == startsInDST)
{
logln("Error: inDaylightTime(" + (new Date(max)) + ") != " + (!startsInDST));
}
while ((max - min) > INTERVAL)
{
long mid = (min + max) >> 1;
if (tz.inDaylightTime(new Date(mid)) == startsInDST)
{
min = mid;
}
else
{
max = mid;
}
}
logln("Binary Search Before: " + showDate(min));
logln("Binary Search After: " + showDate(max));
long mindelta = expectedBoundary - min;
long maxdelta = max - expectedBoundary;
if (mindelta >= 0 && mindelta <= INTERVAL &&
mindelta >= 0 && mindelta <= INTERVAL)
logln("PASS: Expected boundary at " + expectedBoundary);
else
errln("FAIL: Expected boundary at " + expectedBoundary);
}
/*
static void _testUsingMillis(Date d, boolean startsInDST)
{
long millis = d.getTime();
long max = millis + (long)(370 * ONE_DAY); // A year plus extra
boolean lastDST = startsInDST;
while (millis < max)
{
cal.setTime(new Date(millis));
boolean inDaylight = cal.inDaylightTime();
if (inDaylight != lastDST)
{
logln("Switch " + (inDaylight ? "into" : "out of")
+ " DST at " + (new Date(millis)));
lastDST = inDaylight;
}
millis += 15*ONE_MINUTE;
}
}
*/
/**
* Test new rule formats.
*/
public void TestNewRules()
{
//logln(Locale.getDefault().getDisplayName());
//logln(TimeZone.getDefault().getID());
//logln(new Date(0));
if (true)
{
// Doesn't matter what the default TimeZone is here, since we
// are creating our own TimeZone objects.
SimpleTimeZone tz;
logln("-----------------------------------------------------------------");
logln("Aug 2ndTues .. Mar 15");
tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_1",
Calendar.AUGUST, 2, Calendar.TUESDAY, 2*ONE_HOUR,
Calendar.MARCH, 15, 0, 2*ONE_HOUR);
//logln(tz.toString());
logln("========================================");
_testUsingBinarySearch(tz, new Date(97,0,1), 858416400000L);
logln("========================================");
_testUsingBinarySearch(tz, new Date(97,6,1), 871380000000L);
logln("-----------------------------------------------------------------");
logln("Apr Wed>=14 .. Sep Sun<=20");
tz = new SimpleTimeZone(-8*ONE_HOUR, "Test_2",
Calendar.APRIL, 14, -Calendar.WEDNESDAY, 2*ONE_HOUR,
Calendar.SEPTEMBER, -20, -Calendar.SUNDAY, 2*ONE_HOUR);
//logln(tz.toString());
logln("========================================");
_testUsingBinarySearch(tz, new Date(97,0,1), 861184800000L);
logln("========================================");
_testUsingBinarySearch(tz, new Date(97,6,1), 874227600000L);
}
/*
if (true)
{
logln("========================================");
logln("Stepping using millis");
_testUsingMillis(new Date(97,0,1), false);
}
if (true)
{
logln("========================================");
logln("Stepping using fields");
_testUsingFields(1997, false);
}
if (false)
{
cal.clear();
cal.set(1997, 3, 5, 10, 0);
// cal.inDaylightTime();
logln("Date = " + cal.getTime());
logln("Millis = " + cal.getTime().getTime()/3600000);
}
*/
}
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//----------------------------------------------------------------------
// Long Bug
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//----------------------------------------------------------------------
//public void Test3()
//{
// findDaylightBoundaryUsingTimeZone(new Date(97,6,1), true);
//}
/**
* Find boundaries by stepping.
*/
void findBoundariesStepwise(int year, long interval, TimeZone z, int expectedChanges)
{
Date d = new Date(year - 1900, Calendar.JANUARY, 1);
long time = d.getTime(); // ms
long limit = time + ONE_YEAR + ONE_DAY;
boolean lastState = z.inDaylightTime(d);
int changes = 0;
logln("-- Zone " + z.getID() + " starts in " + year + " with DST = " + lastState);
logln("useDaylightTime = " + z.useDaylightTime());
while (time < limit)
{
d.setTime(time);
boolean state = z.inDaylightTime(d);
if (state != lastState)
{
logln((state ? "Entry " : "Exit ") +
"at " + d);
lastState = state;
++changes;
}
time += interval;
}
if (changes == 0)
{
if (!lastState && !z.useDaylightTime()) logln("No DST");
else errln("FAIL: DST all year, or no DST with true useDaylightTime");
}
else if (changes != 2)
{
errln("FAIL: " + changes + " changes seen; should see 0 or 2");
}
else if (!z.useDaylightTime())
{
errln("FAIL: useDaylightTime false but 2 changes seen");
}
if (changes != expectedChanges)
{
errln("FAIL: " + changes + " changes seen; expected " + expectedChanges);
}
}
public void TestStepwise()
{
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("EST"), 2);
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone("ACT"), 0);
findBoundariesStepwise(1997, ONE_DAY, TimeZone.getTimeZone(AUSTRALIA), 2);
}
}

View File

@ -0,0 +1,851 @@
/**
* @test 1.18 99/09/21
* @bug 4052967 4073209 4073215 4084933 4096952 4109314 4126678 4151406 4151429
* @bug 4154525 4154537 4154542 4154650 4159922 4162593 4173604 4176686 4184229 4208960
*/
package com.ibm.test.timezone;
import com.ibm.util.*;
import java.io.*;
import com.ibm.text.*;
import com.ibm.test.*;
import java.util.Date;
import java.util.Locale;
public class TimeZoneRegression extends TestFmwk {
public static void main(String[] args) throws Exception {
new TimeZoneRegression().run(args);
}
public void Test4052967() {
logln("*** CHECK TIMEZONE AGAINST HOST OS SETTING ***");
String id = TimeZone.getDefault().getID();
logln("user.timezone: " + System.getProperty("user.timezone", "<not set>"));
logln("TimeZone.getDefault().getID(): " + id);
logln(new Date().toString());
logln("*** THE RESULTS OF THIS TEST MUST BE VERIFIED MANUALLY ***");
}
public void Test4073209() {
TimeZone z1 = TimeZone.getTimeZone("PST");
TimeZone z2 = TimeZone.getTimeZone("PST");
if (z1 == z2) errln("Fail: TimeZone should return clones");
}
public void Test4073215() {
SimpleTimeZone z = (SimpleTimeZone) TimeZone.getTimeZone("GMT");
if (z.useDaylightTime())
errln("Fail: Fix test to start with non-DST zone");
z.setStartRule(Calendar.FEBRUARY, 1, Calendar.SUNDAY, 0);
z.setEndRule(Calendar.MARCH, -1, Calendar.SUNDAY, 0);
if (!z.useDaylightTime())
errln("Fail: DST not active");
if (z.inDaylightTime(new Date(97, Calendar.JANUARY, 31)) ||
!z.inDaylightTime(new Date(97, Calendar.MARCH, 1)) ||
z.inDaylightTime(new Date(97, Calendar.MARCH, 31))) {
errln("Fail: DST not working as expected");
}
}
/**
* The expected behavior of TimeZone around the boundaries is:
* (Assume transition time of 2:00 AM)
* day of onset 1:59 AM STD = display name 1:59 AM ST
* 2:00 AM STD = display name 3:00 AM DT
* day of end 0:59 AM STD = display name 1:59 AM DT
* 1:00 AM STD = display name 1:00 AM ST
*/
public void Test4084933() {
TimeZone tz = TimeZone.getTimeZone("PST");
long offset1 = tz.getOffset(1,
1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (2*60*60*1000));
long offset2 = tz.getOffset(1,
1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (2*60*60*1000)-1);
long offset3 = tz.getOffset(1,
1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (1*60*60*1000));
long offset4 = tz.getOffset(1,
1997, Calendar.OCTOBER, 26, Calendar.SUNDAY, (1*60*60*1000)-1);
/*
* The following was added just for consistency. It shows that going *to* Daylight
* Savings Time (PDT) does work at 2am.
*/
long offset5 = tz.getOffset(1,
1997, Calendar.APRIL, 6, Calendar.SUNDAY, (2*60*60*1000));
long offset6 = tz.getOffset(1,
1997, Calendar.APRIL, 6, Calendar.SUNDAY, (2*60*60*1000)-1);
long offset7 = tz.getOffset(1,
1997, Calendar.APRIL, 6, Calendar.SUNDAY, (1*60*60*1000));
long offset8 = tz.getOffset(1,
1997, Calendar.APRIL, 6, Calendar.SUNDAY, (1*60*60*1000)-1);
long SToffset = -8 * 60*60*1000L;
long DToffset = -7 * 60*60*1000L;
if (offset1 != SToffset || offset2 != SToffset ||
offset3 != SToffset || offset4 != DToffset ||
offset5 != DToffset || offset6 != SToffset ||
offset7 != SToffset || offset8 != SToffset)
errln("Fail: TimeZone misbehaving");
}
public void Test4096952() {
String[] ZONES = { "GMT", "MET", "IST" };
boolean pass = true;
try {
for (int i=0; i<ZONES.length; ++i) {
TimeZone zone = TimeZone.getTimeZone(ZONES[i]);
if (!zone.getID().equals(ZONES[i]))
errln("Fail: Test broken; zones not instantiating");
ByteArrayOutputStream baos;
ObjectOutputStream ostream =
new ObjectOutputStream(baos = new
ByteArrayOutputStream());
ostream.writeObject(zone);
ostream.close();
baos.close();
ObjectInputStream istream =
new ObjectInputStream(new
ByteArrayInputStream(baos.toByteArray()));
TimeZone frankenZone = (TimeZone) istream.readObject();
//logln("Zone: " + zone);
//logln("FrankenZone: " + frankenZone);
if (!zone.equals(frankenZone)) {
logln("TimeZone " + zone.getID() +
" not equal to serialized/deserialized one");
pass = false;
}
}
if (!pass) errln("Fail: TimeZone serialization/equality bug");
}
catch (IOException e) {
errln("Fail: " + e);
e.printStackTrace();
}
catch (ClassNotFoundException e) {
errln("Fail: " + e);
e.printStackTrace();
}
}
public void Test4109314() {
GregorianCalendar testCal = (GregorianCalendar)Calendar.getInstance();
TimeZone PST = TimeZone.getTimeZone("PST");
Object[] testData = {
PST, new Date(98,Calendar.APRIL,4,22,0), new Date(98, Calendar.APRIL, 5,6,0),
PST, new Date(98,Calendar.OCTOBER,24,22,0), new Date(98,Calendar.OCTOBER,25,6,0),
};
boolean pass=true;
for (int i=0; i<testData.length; i+=3) {
testCal.setTimeZone((TimeZone) testData[i]);
long t = ((Date)testData[i+1]).getTime();
Date end = (Date) testData[i+2];
while (t < end.getTime()) {
testCal.setTime(new Date(t));
if (!checkCalendar314(testCal, (TimeZone) testData[i]))
pass = false;
t += 60*60*1000L;
}
}
if (!pass) errln("Fail: TZ API inconsistent");
}
boolean checkCalendar314(GregorianCalendar testCal, TimeZone testTZ) {
// GregorianCalendar testCal = (GregorianCalendar)aCal.clone();
final int ONE_DAY = 24*60*60*1000;
int tzOffset, tzRawOffset;
Float tzOffsetFloat,tzRawOffsetFloat;
// Here is where the user made an error. They were passing in the value of
// the MILLSECOND field; you need to pass in the millis in the day in STANDARD
// time.
int millis = testCal.get(Calendar.MILLISECOND) +
1000 * (testCal.get(Calendar.SECOND) +
60 * (testCal.get(Calendar.MINUTE) +
60 * (testCal.get(Calendar.HOUR_OF_DAY)))) -
testCal.get(Calendar.DST_OFFSET);
/* Fix up millis to be in range. ASSUME THAT WE ARE NOT AT THE
* BEGINNING OR END OF A MONTH. We must add this code because
* getOffset() has been changed to be more strict about the parameters
* it receives -- it turns out that this test was passing in illegal
* values. */
int date = testCal.get(Calendar.DATE);
int dow = testCal.get(Calendar.DAY_OF_WEEK);
while (millis < 0) {
millis += ONE_DAY;
--date;
dow = Calendar.SUNDAY + ((dow - Calendar.SUNDAY + 6) % 7);
}
while (millis >= ONE_DAY) {
millis -= ONE_DAY;
++date;
dow = Calendar.SUNDAY + ((dow - Calendar.SUNDAY + 1) % 7);
}
tzOffset = testTZ.getOffset(testCal.get(Calendar.ERA),
testCal.get(Calendar.YEAR),
testCal.get(Calendar.MONTH),
date,
dow,
millis);
tzRawOffset = testTZ.getRawOffset();
tzOffsetFloat = new Float((float)tzOffset/(float)3600000);
tzRawOffsetFloat = new Float((float)tzRawOffset/(float)3600000);
Date testDate = testCal.getTime();
boolean inDaylightTime = testTZ.inDaylightTime(testDate);
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm");
sdf.setCalendar(testCal);
String inDaylightTimeString;
boolean passed;
if (inDaylightTime)
{
inDaylightTimeString = " DST ";
passed = (tzOffset == (tzRawOffset + 3600000));
}
else
{
inDaylightTimeString = " ";
passed = (tzOffset == tzRawOffset);
}
String output = testTZ.getID() + " " + sdf.format(testDate) +
" Offset(" + tzOffsetFloat + ")" +
" RawOffset(" + tzRawOffsetFloat + ")" +
" " + millis/(float)3600000 + " " +
inDaylightTimeString;
if (passed)
output += " ";
else
output += "ERROR";
if (passed) logln(output); else errln(output);
return passed;
}
/**
* CANNOT REPRODUDE
*
* Yet another _alleged_ bug in TimeZone.getOffset(), a method that never
* should have been made public. It's simply too hard to use correctly.
*
* The original test code failed to do the following:
* (1) Call Calendar.setTime() before getting the fields!
* (2) Use the right millis (as usual) for getOffset(); they were passing
* in the MILLIS field, instead of the STANDARD MILLIS IN DAY.
* When you fix these two problems, the test passes, as expected.
*/
public void Test4126678() {
// Note: this test depends on the PST time zone.
TimeZone initialZone = TimeZone.getDefault();
Calendar cal = Calendar.getInstance();
TimeZone tz = TimeZone.getTimeZone("PST");
TimeZone.setDefault(tz);
cal.setTimeZone(tz);
Date dt = new Date(1998-1900, Calendar.APRIL, 5, 10, 0);
// the dt value is local time in PST.
if (!tz.inDaylightTime(dt))
errln("We're not in Daylight Savings Time and we should be.\n");
cal.setTime(dt);
int era = cal.get(Calendar.ERA);
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DATE);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
int millis = cal.get(Calendar.MILLISECOND) +
(cal.get(Calendar.SECOND) +
(cal.get(Calendar.MINUTE) +
(cal.get(Calendar.HOUR) * 60) * 60) * 1000) -
cal.get(Calendar.DST_OFFSET);
long offset = tz.getOffset(era, year, month, day, dayOfWeek, millis);
long raw_offset = tz.getRawOffset();
if (offset == raw_offset)
errln("Offsets should not match when in DST");
// restore the initial time zone so that this test case
// doesn't affect the others.
TimeZone.setDefault(initialZone);
}
/**
* TimeZone.getAvailableIDs(int) throws exception for certain values,
* due to a faulty constant in TimeZone.java.
*/
public void Test4151406() {
int max = 0;
for (int h=-28; h<=30; ++h) {
// h is in half-hours from GMT; rawoffset is in millis
int rawoffset = h * 1800000;
int hh = (h<0) ? -h : h;
String hname = ((h<0) ? "GMT-" : "GMT+") +
((hh/2 < 10) ? "0" : "") +
(hh/2) + ':' +
((hh%2==0) ? "00" : "30");
try {
String[] ids = TimeZone.getAvailableIDs(rawoffset);
if (ids.length > max) max = ids.length;
logln(hname + ' ' + ids.length +
((ids.length > 0) ? (" e.g. " + ids[0]) : ""));
} catch (Exception e) {
errln(hname + ' ' + "Fail: " + e);
}
}
logln("Maximum zones per offset = " + max);
}
public void Test4151429() {
try {
TimeZone tz = TimeZone.getTimeZone("GMT");
String name = tz.getDisplayName(true, Integer.MAX_VALUE,
Locale.getDefault());
errln("IllegalArgumentException not thrown by TimeZone.getDisplayName()");
} catch(IllegalArgumentException e) {}
}
/**
* SimpleTimeZone accepts illegal DST savings values. These values
* must be non-zero. There is no upper limit at this time.
*/
public void Test4154525() {
final int GOOD = 1, BAD = 0;
int[] DATA = {
1, GOOD,
0, BAD,
-1, BAD,
60*60*1000, GOOD,
Integer.MIN_VALUE, BAD,
// Integer.MAX_VALUE, ?, // no upper limit on DST savings at this time
};
for (int i=0; i<DATA.length; i+=2) {
int savings = DATA[i];
boolean valid = DATA[i+1] == GOOD;
String method = null;
for (int j=0; j<2; ++j) {
try {
switch (j) {
case 0:
method = "constructor";
SimpleTimeZone z = new SimpleTimeZone(0, "id",
Calendar.JANUARY, 1, 0, 0,
Calendar.MARCH, 1, 0, 0,
savings); // <- what we're interested in
break;
case 1:
method = "setDSTSavings()";
z = new SimpleTimeZone(0, "GMT");
z.setDSTSavings(savings);
break;
}
if (valid) {
logln("Pass: DST savings of " + savings + " accepted by " + method);
} else {
errln("Fail: DST savings of " + savings + " accepted by " + method);
}
} catch (IllegalArgumentException e) {
if (valid) {
errln("Fail: DST savings of " + savings + " to " + method + " gave " + e);
} else {
logln("Pass: DST savings of " + savings + " to " + method + " gave " + e);
}
}
}
}
}
/**
* SimpleTimeZone.hasSameRules() doesn't work for zones with no DST
* and different DST parameters.
*/
public void Test4154537() {
// tz1 and tz2 have no DST and different rule parameters
SimpleTimeZone tz1 = new SimpleTimeZone(0, "1", 0, 0, 0, 0, 2, 0, 0, 0);
SimpleTimeZone tz2 = new SimpleTimeZone(0, "2", 1, 0, 0, 0, 3, 0, 0, 0);
// tza and tzA have the same rule params
SimpleTimeZone tza = new SimpleTimeZone(0, "a", 0, 1, 0, 0, 3, 2, 0, 0);
SimpleTimeZone tzA = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 3, 2, 0, 0);
// tzb differs from tza
SimpleTimeZone tzb = new SimpleTimeZone(0, "b", 0, 1, 0, 0, 3, 1, 0, 0);
if (tz1.useDaylightTime() || tz2.useDaylightTime() ||
!tza.useDaylightTime() || !tzA.useDaylightTime() ||
!tzb.useDaylightTime()) {
errln("Test is broken -- rewrite it");
}
if (!tza.hasSameRules(tzA) || tza.hasSameRules(tzb)) {
errln("Fail: hasSameRules() broken for zones with rules");
}
if (!tz1.hasSameRules(tz2)) {
errln("Fail: hasSameRules() returns false for zones without rules");
errln("zone 1 = " + tz1);
errln("zone 2 = " + tz2);
}
}
/**
* SimpleTimeZone constructors, setStartRule(), and setEndRule() don't
* check for out-of-range arguments.
*/
public void Test4154542() {
final int GOOD = 1;
final int BAD = 0;
final int GOOD_MONTH = Calendar.JANUARY;
final int GOOD_DAY = 1;
final int GOOD_DAY_OF_WEEK = Calendar.SUNDAY;
final int GOOD_TIME = 0;
int[] DATA = {
GOOD, Integer.MIN_VALUE, 0, Integer.MAX_VALUE, Integer.MIN_VALUE,
GOOD, Calendar.JANUARY, -5, Calendar.SUNDAY, 0,
GOOD, Calendar.DECEMBER, 5, Calendar.SATURDAY, 24*60*60*1000-1,
BAD, Calendar.DECEMBER, 5, Calendar.SATURDAY, 24*60*60*1000,
BAD, Calendar.DECEMBER, 5, Calendar.SATURDAY, -1,
BAD, Calendar.JANUARY, -6, Calendar.SUNDAY, 0,
BAD, Calendar.DECEMBER, 6, Calendar.SATURDAY, 24*60*60*1000,
GOOD, Calendar.DECEMBER, 1, 0, 0,
GOOD, Calendar.DECEMBER, 31, 0, 0,
BAD, Calendar.APRIL, 31, 0, 0,
BAD, Calendar.DECEMBER, 32, 0, 0,
BAD, Calendar.JANUARY-1, 1, Calendar.SUNDAY, 0,
BAD, Calendar.DECEMBER+1, 1, Calendar.SUNDAY, 0,
GOOD, Calendar.DECEMBER, 31, -Calendar.SUNDAY, 0,
GOOD, Calendar.DECEMBER, 31, -Calendar.SATURDAY, 0,
BAD, Calendar.DECEMBER, 32, -Calendar.SATURDAY, 0,
BAD, Calendar.DECEMBER, -32, -Calendar.SATURDAY, 0,
BAD, Calendar.DECEMBER, 31, -Calendar.SATURDAY-1, 0,
};
SimpleTimeZone zone = new SimpleTimeZone(0, "Z");
for (int i=0; i<DATA.length; i+=5) {
boolean shouldBeGood = (DATA[i] == GOOD);
int month = DATA[i+1];
int day = DATA[i+2];
int dayOfWeek = DATA[i+3];
int time = DATA[i+4];
Exception ex = null;
try {
zone.setStartRule(month, day, dayOfWeek, time);
} catch (IllegalArgumentException e) {
ex = e;
}
if ((ex == null) != shouldBeGood) {
errln("setStartRule(month=" + month + ", day=" + day +
", dayOfWeek=" + dayOfWeek + ", time=" + time +
(shouldBeGood ? (") should work but throws " + ex)
: ") should fail but doesn't"));
}
ex = null;
try {
zone.setEndRule(month, day, dayOfWeek, time);
} catch (IllegalArgumentException e) {
ex = e;
}
if ((ex == null) != shouldBeGood) {
errln("setEndRule(month=" + month + ", day=" + day +
", dayOfWeek=" + dayOfWeek + ", time=" + time +
(shouldBeGood ? (") should work but throws " + ex)
: ") should fail but doesn't"));
}
ex = null;
try {
SimpleTimeZone temp = new SimpleTimeZone(0, "Z",
month, day, dayOfWeek, time,
GOOD_MONTH, GOOD_DAY, GOOD_DAY_OF_WEEK, GOOD_TIME);
} catch (IllegalArgumentException e) {
ex = e;
}
if ((ex == null) != shouldBeGood) {
errln("SimpleTimeZone(month=" + month + ", day=" + day +
", dayOfWeek=" + dayOfWeek + ", time=" + time +
(shouldBeGood ? (", <end>) should work but throws " + ex)
: ", <end>) should fail but doesn't"));
}
ex = null;
try {
SimpleTimeZone temp = new SimpleTimeZone(0, "Z",
GOOD_MONTH, GOOD_DAY, GOOD_DAY_OF_WEEK, GOOD_TIME,
month, day, dayOfWeek, time);
} catch (IllegalArgumentException e) {
ex = e;
}
if ((ex == null) != shouldBeGood) {
errln("SimpleTimeZone(<start>, month=" + month + ", day=" + day +
", dayOfWeek=" + dayOfWeek + ", time=" + time +
(shouldBeGood ? (") should work but throws " + ex)
: ") should fail but doesn't"));
}
}
}
/**
* SimpleTimeZone.getOffset accepts illegal arguments.
*/
public void Test4154650() {
final int GOOD=1, BAD=0;
final int GOOD_ERA=GregorianCalendar.AD, GOOD_YEAR=1998, GOOD_MONTH=Calendar.AUGUST;
final int GOOD_DAY=2, GOOD_DOW=Calendar.SUNDAY, GOOD_TIME=16*3600000;
int[] DATA = {
GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
GOOD, GregorianCalendar.BC, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
GOOD, GregorianCalendar.AD, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
BAD, GregorianCalendar.BC-1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
BAD, GregorianCalendar.AD+1, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, GOOD_DAY, GOOD_DOW, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, Calendar.DECEMBER, GOOD_DAY, GOOD_DOW, GOOD_TIME,
BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY-1, GOOD_DAY, GOOD_DOW, GOOD_TIME,
BAD, GOOD_ERA, GOOD_YEAR, Calendar.DECEMBER+1, GOOD_DAY, GOOD_DOW, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 1, GOOD_DOW, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 31, GOOD_DOW, GOOD_TIME,
BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 0, GOOD_DOW, GOOD_TIME,
BAD, GOOD_ERA, GOOD_YEAR, Calendar.JANUARY, 32, GOOD_DOW, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SUNDAY, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SATURDAY, GOOD_TIME,
BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SUNDAY-1, GOOD_TIME,
BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, Calendar.SATURDAY+1, GOOD_TIME,
GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 0,
GOOD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000-1,
BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, -1,
BAD, GOOD_ERA, GOOD_YEAR, GOOD_MONTH, GOOD_DAY, GOOD_DOW, 24*3600000,
};
TimeZone tz = TimeZone.getDefault();
for (int i=0; i<DATA.length; i+=7) {
boolean good = DATA[i] == GOOD;
IllegalArgumentException e = null;
try {
int offset = tz.getOffset(DATA[i+1], DATA[i+2], DATA[i+3],
DATA[i+4], DATA[i+5], DATA[i+6]);
} catch (IllegalArgumentException ex) {
e = ex;
}
if (good != (e == null)) {
errln("Fail: getOffset(" +
DATA[i+1] + ", " + DATA[i+2] + ", " + DATA[i+3] + ", " +
DATA[i+4] + ", " + DATA[i+5] + ", " + DATA[i+6] +
(good ? (") threw " + e) : ") accepts invalid args"));
}
}
}
/**
* TimeZone constructors allow null IDs.
*/
public void Test4159922() {
TimeZone z = null;
// TimeZone API. Only hasSameRules() and setDefault() should
// allow null.
try {
z = TimeZone.getTimeZone(null);
errln("FAIL: Null allowed in getTimeZone");
} catch (NullPointerException e) {}
z = TimeZone.getTimeZone("GMT");
try {
z.getDisplayName(false, TimeZone.SHORT, null);
errln("FAIL: Null allowed in getDisplayName(3)");
} catch (NullPointerException e) {}
try {
z.getDisplayName(null);
errln("FAIL: Null allowed in getDisplayName(1)");
} catch (NullPointerException e) {}
try {
if (z.hasSameRules(null)) {
errln("FAIL: hasSameRules returned true");
}
} catch (NullPointerException e) {
errln("FAIL: Null NOT allowed in hasSameRules");
}
try {
z.inDaylightTime(null);
errln("FAIL: Null allowed in inDaylightTime");
} catch (NullPointerException e) {}
try {
z.setID(null);
errln("FAIL: Null allowed in setID");
} catch (NullPointerException e) {}
TimeZone save = TimeZone.getDefault();
try {
TimeZone.setDefault(null);
} catch (NullPointerException e) {
errln("FAIL: Null NOT allowed in setDefault");
} finally {
TimeZone.setDefault(save);
}
// SimpleTimeZone API
SimpleTimeZone s = null;
try {
s = new SimpleTimeZone(0, null);
errln("FAIL: Null allowed in SimpleTimeZone(2)");
} catch (NullPointerException e) {}
try {
s = new SimpleTimeZone(0, null, 0, 1, 0, 0, 0, 1, 0, 0);
errln("FAIL: Null allowed in SimpleTimeZone(10)");
} catch (NullPointerException e) {}
try {
s = new SimpleTimeZone(0, null, 0, 1, 0, 0, 0, 1, 0, 0, 1000);
errln("FAIL: Null allowed in SimpleTimeZone(11)");
} catch (NullPointerException e) {}
}
/**
* TimeZone broken at midnight. The TimeZone code fails to handle
* transitions at midnight correctly.
*/
public void Test4162593() {
SimpleDateFormat fmt = new SimpleDateFormat("z", Locale.US);
final int ONE_HOUR = 60*60*1000;
TimeZone initialZone = TimeZone.getDefault();
SimpleDateFormat sdf = new SimpleDateFormat("MMM dd yyyy HH:mm z");
SimpleTimeZone asuncion = new SimpleTimeZone(-4*ONE_HOUR, "America/Asuncion" /*PY%sT*/,
Calendar.OCTOBER, 1, 0 /*DOM*/, 0*ONE_HOUR,
Calendar.MARCH, 1, 0 /*DOM*/, 0*ONE_HOUR, 1*ONE_HOUR);
/* Zone
* Starting time
* Transition expected between start+1H and start+2H
*/
Object[] DATA = {
new SimpleTimeZone(2*ONE_HOUR, "Asia/Damascus" /*EE%sT*/,
Calendar.APRIL, 1, 0 /*DOM*/, 0*ONE_HOUR,
Calendar.OCTOBER, 1, 0 /*DOM*/, 0*ONE_HOUR, 1*ONE_HOUR),
new int[] {98, Calendar.SEPTEMBER, 30, 22, 0},
Boolean.TRUE,
asuncion,
new int[] {100, Calendar.FEBRUARY, 28, 22, 0},
Boolean.FALSE,
asuncion,
new int[] {100, Calendar.FEBRUARY, 29, 22, 0},
Boolean.TRUE,
};
String[] zone = new String[4];
for (int j=0; j<DATA.length; j+=3) {
TimeZone tz = (TimeZone)DATA[j];
TimeZone.setDefault(tz);
fmt.setTimeZone(tz);
sdf.setTimeZone(tz);
// Must construct the Date object AFTER setting the default zone
int[] p = (int[])DATA[j+1];
Date d = new Date(p[0], p[1], p[2], p[3], p[4]);
boolean transitionExpected = ((Boolean)DATA[j+2]).booleanValue();
logln(tz.getID() + ":");
for (int i=0; i<4; ++i) {
zone[i] = fmt.format(d);
logln("" + i + ": " + sdf.format(d) + " => " + zone[i]);
d = new Date(d.getTime() + ONE_HOUR);
}
if (zone[0].equals(zone[1]) &&
(zone[1].equals(zone[2]) != transitionExpected) &&
zone[2].equals(zone[3])) {
logln("Ok: transition " + transitionExpected);
} else {
errln("Fail: boundary transition incorrect");
}
}
// restore the initial time zone so that this test case
// doesn't affect the others.
TimeZone.setDefault(initialZone);
}
/**
* TimeZone broken in last hour of year
*/
public void Test4173604() {
SimpleTimeZone pst = (SimpleTimeZone)TimeZone.getTimeZone("PST");
int o22 = pst.getOffset(1, 1998, 11, 31, Calendar.THURSDAY, 22*60*60*1000);
int o23 = pst.getOffset(1, 1998, 11, 31, Calendar.THURSDAY, 23*60*60*1000);
int o00 = pst.getOffset(1, 1999, 0, 1, Calendar.FRIDAY, 0);
if (o22 != o23 || o22 != o00) {
errln("Offsets should be the same (for PST), but got: " +
"12/31 22:00 " + o22 +
", 12/31 23:00 " + o23 +
", 01/01 00:00 " + o00);
}
GregorianCalendar cal = new GregorianCalendar();
cal.setTimeZone(pst);
cal.clear();
cal.set(1998, Calendar.JANUARY, 1);
int lastDST = cal.get(Calendar.DST_OFFSET);
int transitions = 0;
int delta = 5;
while (cal.get(Calendar.YEAR) < 2000) {
cal.add(Calendar.MINUTE, delta);
if (cal.get(Calendar.DST_OFFSET) != lastDST) {
++transitions;
Calendar t = (Calendar)cal.clone();
t.add(Calendar.MINUTE, -delta);
logln(t.getTime() + " " + t.get(Calendar.DST_OFFSET));
logln(cal.getTime() + " " + (lastDST=cal.get(Calendar.DST_OFFSET)));
}
}
if (transitions != 4) {
errln("Saw " + transitions + " transitions; should have seen 4");
}
}
/**
* getDisplayName doesn't work with unusual savings/offsets.
*/
public void Test4176686() {
// Construct a zone that does not observe DST but
// that does have a DST savings (which should be ignored).
int offset = 90 * 60000; // 1:30
SimpleTimeZone z1 = new SimpleTimeZone(offset, "_std_zone_");
z1.setDSTSavings(45 * 60000); // 0:45
// Construct a zone that observes DST for the first 6 months.
SimpleTimeZone z2 = new SimpleTimeZone(offset, "_dst_zone_");
z2.setDSTSavings(45 * 60000); // 0:45
z2.setStartRule(Calendar.JANUARY, 1, 0);
z2.setEndRule(Calendar.JULY, 1, 0);
// Also check DateFormat
DateFormat fmt1 = new SimpleDateFormat("z");
fmt1.setTimeZone(z1); // Format uses standard zone
DateFormat fmt2 = new SimpleDateFormat("z");
fmt2.setTimeZone(z2); // Format uses DST zone
Date dst = new Date(1970-1900, Calendar.FEBRUARY, 1); // Time in DST
Date std = new Date(1970-1900, Calendar.AUGUST, 1); // Time in standard
// Description, Result, Expected Result
String[] DATA = {
"getDisplayName(false, SHORT)/std zone",
z1.getDisplayName(false, TimeZone.SHORT), "GMT+01:30",
"getDisplayName(false, LONG)/std zone",
z1.getDisplayName(false, TimeZone.LONG ), "GMT+01:30",
"getDisplayName(true, SHORT)/std zone",
z1.getDisplayName(true, TimeZone.SHORT), "GMT+01:30",
"getDisplayName(true, LONG)/std zone",
z1.getDisplayName(true, TimeZone.LONG ), "GMT+01:30",
"getDisplayName(false, SHORT)/dst zone",
z2.getDisplayName(false, TimeZone.SHORT), "GMT+01:30",
"getDisplayName(false, LONG)/dst zone",
z2.getDisplayName(false, TimeZone.LONG ), "GMT+01:30",
"getDisplayName(true, SHORT)/dst zone",
z2.getDisplayName(true, TimeZone.SHORT), "GMT+02:15",
"getDisplayName(true, LONG)/dst zone",
z2.getDisplayName(true, TimeZone.LONG ), "GMT+02:15",
"DateFormat.format(std)/std zone", fmt1.format(std), "GMT+01:30",
"DateFormat.format(dst)/std zone", fmt1.format(dst), "GMT+01:30",
"DateFormat.format(std)/dst zone", fmt2.format(std), "GMT+01:30",
"DateFormat.format(dst)/dst zone", fmt2.format(dst), "GMT+02:15",
};
for (int i=0; i<DATA.length; i+=3) {
if (!DATA[i+1].equals(DATA[i+2])) {
errln("FAIL: " + DATA[i] + " -> " + DATA[i+1] + ", exp " + DATA[i+2]);
}
}
}
/**
* SimpleTimeZone allows invalid DOM values.
*/
public void Test4184229() {
SimpleTimeZone zone = null;
try {
zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0);
errln("Failed. No exception has been thrown for DOM -1 startDay");
} catch(IllegalArgumentException e) {
logln("(a) " + e.getMessage());
}
try {
zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0);
errln("Failed. No exception has been thrown for DOM -1 endDay");
} catch(IllegalArgumentException e) {
logln("(b) " + e.getMessage());
}
try {
zone = new SimpleTimeZone(0, "A", 0, -1, 0, 0, 0, 0, 0, 0, 1000);
errln("Failed. No exception has been thrown for DOM -1 startDay +savings");
} catch(IllegalArgumentException e) {
logln("(c) " + e.getMessage());
}
try {
zone = new SimpleTimeZone(0, "A", 0, 0, 0, 0, 0, -1, 0, 0, 1000);
errln("Failed. No exception has been thrown for DOM -1 endDay +savings");
} catch(IllegalArgumentException e) {
logln("(d) " + e.getMessage());
}
// Make a valid constructor call for subsequent tests.
zone = new SimpleTimeZone(0, "A", 0, 1, 0, 0, 0, 1, 0, 0);
try {
zone.setStartRule(0, -1, 0, 0);
errln("Failed. No exception has been thrown for DOM -1 setStartRule +savings");
} catch(IllegalArgumentException e) {
logln("(e) " + e.getMessage());
}
try {
zone.setStartRule(0, -1, 0);
errln("Failed. No exception has been thrown for DOM -1 setStartRule");
} catch(IllegalArgumentException e) {
logln("(f) " + e.getMessage());
}
try {
zone.setEndRule(0, -1, 0, 0);
errln("Failed. No exception has been thrown for DOM -1 setEndRule +savings");
} catch(IllegalArgumentException e) {
logln("(g) " + e.getMessage());
}
try {
zone.setEndRule(0, -1, 0);
errln("Failed. No exception has been thrown for DOM -1 setEndRule");
} catch(IllegalArgumentException e) {
logln("(h) " + e.getMessage());
}
}
/**
* SimpleTimeZone.getOffset() throws IllegalArgumentException when to get
* of 2/29/1996 (leap day).
*/
public void Test4208960 () {
SimpleTimeZone tz = (SimpleTimeZone)TimeZone.getTimeZone("PST");
try {
int offset = tz.getOffset(GregorianCalendar.AD, 1996, Calendar.FEBRUARY, 29,
Calendar.THURSDAY, 0);
} catch (IllegalArgumentException e) {
errln("FAILED: to get TimeZone.getOffset(2/29/96)");
}
try {
int offset = tz.getOffset(GregorianCalendar.AD, 1997, Calendar.FEBRUARY, 29,
Calendar.THURSDAY, 0);
errln("FAILED: TimeZone.getOffset(2/29/97) expected to throw Exception.");
} catch (IllegalArgumentException e) {
logln("got IllegalArgumentException");
}
}
}
//eof

View File

@ -0,0 +1,701 @@
/**
* @test 1.22 99/09/21
* @bug 4028006 4044013 4096694 4107276 4107570 4112869 4130885
* @summary test TimeZone
* @build TimeZoneTest
*/
package com.ibm.test.timezone;
import com.ibm.text.*;
import com.ibm.util.*;
import com.ibm.test.*;
import java.util.Date;
import java.util.Locale;
import java.util.Hashtable;
import java.util.ResourceBundle;
public class TimeZoneTest extends TestFmwk
{
static final int millisPerHour = 3600000;
public static void main(String[] args) throws Exception {
new TimeZoneTest().run(args);
}
/**
* Bug 4130885
* Certain short zone IDs, used since 1.1.x, are incorrect.
*
* The worst of these is:
*
* "CAT" (Central African Time) should be GMT+2:00, but instead returns a
* zone at GMT-1:00. The zone at GMT-1:00 should be called EGT, CVT, EGST,
* or AZOST, depending on which zone is meant, but in no case is it CAT.
*
* Other wrong zone IDs:
*
* ECT (European Central Time) GMT+1:00: ECT is Ecuador Time,
* GMT-5:00. European Central time is abbreviated CEST.
*
* SST (Solomon Island Time) GMT+11:00. SST is actually Samoa Standard Time,
* GMT-11:00. Solomon Island time is SBT.
*
* NST (New Zealand Time) GMT+12:00. NST is the abbreviation for
* Newfoundland Standard Time, GMT-3:30. New Zealanders use NZST.
*
* AST (Alaska Standard Time) GMT-9:00. [This has already been noted in
* another bug.] It should be "AKST". AST is Atlantic Standard Time,
* GMT-4:00.
*
* PNT (Phoenix Time) GMT-7:00. PNT usually means Pitcairn Time,
* GMT-8:30. There is no standard abbreviation for Phoenix time, as distinct
* from MST with daylight savings.
*
* In addition to these problems, a number of zones are FAKE. That is, they
* don't match what people use in the real world.
*
* FAKE zones:
*
* EET (should be EEST)
* ART (should be EEST)
* MET (should be IRST)
* NET (should be AMST)
* PLT (should be PKT)
* BST (should be BDT)
* VST (should be ICT)
* CTT (should be CST) +
* ACT (should be CST) +
* AET (should be EST) +
* MIT (should be WST) +
* IET (should be EST) +
* PRT (should be AST) +
* CNT (should be NST)
* AGT (should be ARST)
* BET (should be EST) +
*
* + A zone with the correct name already exists and means something
* else. E.g., EST usually indicates the US Eastern zone, so it cannot be
* used for Brazil (BET).
*/
public void TestShortZoneIDs() throws Exception {
ZoneDescriptor[] JDK_116_REFERENCE_LIST = {
new ZoneDescriptor("MIT", -660, false),
new ZoneDescriptor("HST", -600, false),
new ZoneDescriptor("AST", -540, true),
new ZoneDescriptor("PST", -480, true),
new ZoneDescriptor("PNT", -420, false),
new ZoneDescriptor("MST", -420, true),
new ZoneDescriptor("CST", -360, true),
new ZoneDescriptor("IET", -300, false),
new ZoneDescriptor("EST", -300, true),
new ZoneDescriptor("PRT", -240, false),
new ZoneDescriptor("CNT", -210, true),
new ZoneDescriptor("AGT", -180, false),
new ZoneDescriptor("BET", -180, true),
// new ZoneDescriptor("CAT", -60, false), // Wrong:
// As of bug 4130885, fix CAT (Central Africa)
new ZoneDescriptor("CAT", 120, false), // Africa/Harare
new ZoneDescriptor("GMT", 0, false),
new ZoneDescriptor("UTC", 0, false),
new ZoneDescriptor("ECT", 60, true),
new ZoneDescriptor("ART", 120, true),
new ZoneDescriptor("EET", 120, true),
new ZoneDescriptor("EAT", 180, false),
new ZoneDescriptor("MET", 210, true),
// new ZoneDescriptor("NET", 240, false);
// As of bug 4191164, fix NET
new ZoneDescriptor("NET", 240, true),
new ZoneDescriptor("PLT", 300, false),
new ZoneDescriptor("IST", 330, false),
new ZoneDescriptor("BST", 360, false),
new ZoneDescriptor("VST", 420, false),
new ZoneDescriptor("CTT", 480, false),
new ZoneDescriptor("JST", 540, false),
new ZoneDescriptor("ACT", 570, false),
new ZoneDescriptor("AET", 600, true),
new ZoneDescriptor("SST", 660, false),
// new ZoneDescriptor("NST", 720, false),
// As of bug 4130885, fix NST (New Zealand)
new ZoneDescriptor("NST", 720, true), // Pacific/Auckland
};
Hashtable hash = new Hashtable();
String[] ids = TimeZone.getAvailableIDs();
for (int i=0; i<ids.length; ++i) {
String id = ids[i];
if (id.length() == 3) {
hash.put(id, new ZoneDescriptor(TimeZone.getTimeZone(id)));
}
}
for (int i=0; i<JDK_116_REFERENCE_LIST.length; ++i) {
ZoneDescriptor referenceZone = JDK_116_REFERENCE_LIST[i];
ZoneDescriptor currentZone = (ZoneDescriptor)hash.get(referenceZone.getID());
if (referenceZone.equals(currentZone)) {
logln("ok " + referenceZone);
}
else {
errln("Fail: Expected " + referenceZone +
"; got " + currentZone);
}
}
}
/**
* A descriptor for a zone; used to regress the short zone IDs.
*/
static class ZoneDescriptor {
String id;
int offset; // In minutes
boolean daylight;
ZoneDescriptor(TimeZone zone) {
this.id = zone.getID();
this.offset = zone.getRawOffset() / 60000;
this.daylight = zone.useDaylightTime();
}
ZoneDescriptor(String id, int offset, boolean daylight) {
this.id = id;
this.offset = offset;
this.daylight = daylight;
}
public String getID() { return id; }
public boolean equals(Object o) {
ZoneDescriptor that = (ZoneDescriptor)o;
return that != null &&
id.equals(that.id) &&
offset == that.offset &&
daylight == that.daylight;
}
public String toString() {
int min = offset;
char sign = '+';
if (min < 0) { sign = '-'; min = -min; }
return "Zone[\"" + id + "\", GMT" + sign + (min/60) + ':' +
(min%60<10?"0":"") + (min%60) + ", " +
(daylight ? "Daylight" : "Standard") + "]";
}
public static int compare(Object o1, Object o2) {
ZoneDescriptor i1 = (ZoneDescriptor)o1;
ZoneDescriptor i2 = (ZoneDescriptor)o2;
if (i1.offset > i2.offset) return 1;
if (i1.offset < i2.offset) return -1;
if (i1.daylight && !i2.daylight) return 1;
if (!i1.daylight && i2.daylight) return -1;
return i1.id.compareTo(i2.id);
}
}
static final String EXPECTED_CUSTOM_ID = "Custom";
static final String formatMinutes(int min) {
char sign = '+';
if (min < 0) { sign = '-'; min = -min; }
int h = min/60;
min = min%60;
return "" + sign + h + ":" + ((min<10) ? "0" : "") + min;
}
/**
* As part of the VM fix (see CCC approved RFE 4028006, bug
* 4044013), TimeZone.getTimeZone() has been modified to recognize
* generic IDs of the form GMT[+-]hh:mm, GMT[+-]hhmm, and
* GMT[+-]hh. Test this behavior here.
*
* Bug 4044013
*/
public void TestCustomParse() throws Exception {
Object[] DATA = {
// ID Expected offset in minutes
"GMT", null,
"GMT0", null,
"GMT+0", new Integer(0),
"GMT+1", new Integer(60),
"GMT-0030", new Integer(-30),
"GMT+15:99", new Integer(15*60+99),
"GMT+", null,
"GMT-", null,
"GMT+0:", null,
"GMT-:", null,
"GMT+0010", new Integer(10), // Interpret this as 00:10
"GMT-10", new Integer(-10*60),
"GMT+30", new Integer(30),
"GMT-3:30", new Integer(-(3*60+30)),
"GMT-230", new Integer(-(2*60+30)),
};
for (int i=0; i<DATA.length; i+=2) {
String id = (String)DATA[i];
Integer exp = (Integer)DATA[i+1];
TimeZone zone = TimeZone.getTimeZone(id);
if (zone.getID().equals("GMT")) {
logln(id + " -> generic GMT");
// When TimeZone.getTimeZone() can't parse the id, it
// returns GMT -- a dubious practice, but required for
// backward compatibility.
if (exp != null) {
throw new Exception("Expected offset of " + formatMinutes(exp.intValue()) +
" for " + id + ", got parse failure");
}
}
else {
int ioffset = zone.getRawOffset()/60000;
String offset = formatMinutes(ioffset);
logln(id + " -> " + zone.getID() + " GMT" + offset);
if (exp == null) {
throw new Exception("Expected parse failure for " + id +
", got offset of " + offset +
", id " + zone.getID());
}
else if (ioffset != exp.intValue() ||
!zone.getID().equals(EXPECTED_CUSTOM_ID)) {
throw new Exception("Expected offset of " + formatMinutes(exp.intValue()) +
", id Custom, for " + id +
", got offset of " + offset +
", id " + zone.getID());
}
}
}
}
/**
* Test the basic functionality of the getDisplayName() API.
*
* Bug 4112869
* Bug 4028006
*
* See also API change request A41.
*
* 4/21/98 - make smarter, so the test works if the ext resources
* are present or not.
*/
public void TestDisplayName() {
TimeZone zone = TimeZone.getTimeZone("PST");
String name = zone.getDisplayName(Locale.ENGLISH);
logln("PST->" + name);
if (!name.equals("Pacific Standard Time"))
errln("Fail: Expected \"Pacific Standard Time\"");
//*****************************************************************
// THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
// THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
// THE FOLLOWING LINES MUST BE UPDATED IF THE LOCALE DATA CHANGES
//*****************************************************************
Object[] DATA = {
new Boolean(false), new Integer(TimeZone.SHORT), "PST",
new Boolean(true), new Integer(TimeZone.SHORT), "PDT",
new Boolean(false), new Integer(TimeZone.LONG), "Pacific Standard Time",
new Boolean(true), new Integer(TimeZone.LONG), "Pacific Daylight Time",
};
for (int i=0; i<DATA.length; i+=3) {
name = zone.getDisplayName(((Boolean)DATA[i]).booleanValue(),
((Integer)DATA[i+1]).intValue(),
Locale.ENGLISH);
if (!name.equals(DATA[i+2]))
errln("Fail: Expected " + DATA[i+2] + "; got " + name);
}
// Make sure that we don't display the DST name by constructing a fake
// PST zone that has DST all year long.
SimpleTimeZone zone2 = new SimpleTimeZone(0, "PST");
zone2.setStartRule(Calendar.JANUARY, 1, 0);
zone2.setEndRule(Calendar.DECEMBER, 31, 0);
logln("Modified PST inDaylightTime->" + zone2.inDaylightTime(new Date()));
name = zone2.getDisplayName(Locale.ENGLISH);
logln("Modified PST->" + name);
if (!name.equals("Pacific Standard Time"))
errln("Fail: Expected \"Pacific Standard Time\"");
// Make sure we get the default display format for Locales
// with no display name data.
Locale zh_CN = Locale.SIMPLIFIED_CHINESE;
name = zone.getDisplayName(zh_CN);
//*****************************************************************
// THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
// THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
// THE FOLLOWING LINE MUST BE UPDATED IF THE LOCALE DATA CHANGES
//*****************************************************************
logln("PST(zh_CN)->" + name);
// Now be smart -- check to see if zh resource is even present.
// If not, we expect the en fallback behavior.
ResourceBundle enRB = ResourceBundle.getBundle("java.text.resources.DateFormatZoneData",
Locale.ENGLISH);
ResourceBundle zhRB = ResourceBundle.getBundle("java.text.resources.DateFormatZoneData",
zh_CN);
boolean noZH = enRB == zhRB;
if (noZH) {
logln("Warning: Not testing the zh_CN behavior because resource is absent");
if (!name.equals("Pacific Standard Time"))
errln("Fail: Expected Pacific Standard Time");
}
else if (!name.equals("Pacific Standard Time") &&
!name.equals("GMT-08:00") &&
!name.equals("GMT-8:00") &&
!name.equals("GMT-0800") &&
!name.equals("GMT-800")) {
errln("Fail: Expected GMT-08:00 or something similar");
errln("************************************************************");
errln("THE ABOVE FAILURE MAY JUST MEAN THE LOCALE DATA HAS CHANGED");
errln("************************************************************");
}
// Now try a non-existent zone
zone2 = new SimpleTimeZone(90*60*1000, "xyzzy");
name = zone2.getDisplayName(Locale.ENGLISH);
logln("GMT+90min->" + name);
if (!name.equals("GMT+01:30") &&
!name.equals("GMT+1:30") &&
!name.equals("GMT+0130") &&
!name.equals("GMT+130"))
errln("Fail: Expected GMT+01:30 or something similar");
}
public void TestGenericAPI() {
String id = "NewGMT";
int offset = 12345;
SimpleTimeZone zone = new SimpleTimeZone(offset, id);
if (zone.useDaylightTime()) errln("FAIL: useDaylightTime should return false");
TimeZone zoneclone = (TimeZone)zone.clone();
if (!zoneclone.equals(zone)) errln("FAIL: clone or operator== failed");
zoneclone.setID("abc");
if (zoneclone.equals(zone)) errln("FAIL: clone or operator!= failed");
// delete zoneclone;
zoneclone = (TimeZone)zone.clone();
if (!zoneclone.equals(zone)) errln("FAIL: clone or operator== failed");
zoneclone.setRawOffset(45678);
if (zoneclone.equals(zone)) errln("FAIL: clone or operator!= failed");
// C++ only
/*
SimpleTimeZone copy(*zone);
if (!(copy == *zone)) errln("FAIL: copy constructor or operator== failed");
copy = *(SimpleTimeZone*)zoneclone;
if (!(copy == *zoneclone)) errln("FAIL: assignment operator or operator== failed");
*/
TimeZone saveDefault = TimeZone.getDefault();
TimeZone.setDefault(zone);
TimeZone defaultzone = TimeZone.getDefault();
if (defaultzone == zone) errln("FAIL: Default object is identical, not clone");
if (!defaultzone.equals(zone)) errln("FAIL: Default object is not equal");
TimeZone.setDefault(saveDefault);
// delete defaultzone;
// delete zoneclone;
}
public void TestRuleAPI()
{
// ErrorCode status = ZERO_ERROR;
int offset = (int)(60*60*1000*1.75); // Pick a weird offset
SimpleTimeZone zone = new SimpleTimeZone(offset, "TestZone");
if (zone.useDaylightTime()) errln("FAIL: useDaylightTime should return false");
// Establish our expected transition times. Do this with a non-DST
// calendar with the (above) declared local offset.
GregorianCalendar gc = new GregorianCalendar(zone);
gc.clear();
gc.set(1990, Calendar.MARCH, 1);
long marchOneStd = gc.getTime().getTime(); // Local Std time midnight
gc.clear();
gc.set(1990, Calendar.JULY, 1);
long julyOneStd = gc.getTime().getTime(); // Local Std time midnight
// Starting and ending hours, WALL TIME
int startHour = (int)(2.25 * 3600000);
int endHour = (int)(3.5 * 3600000);
zone.setStartRule(Calendar.MARCH, 1, 0, startHour);
zone.setEndRule (Calendar.JULY, 1, 0, endHour);
gc = new GregorianCalendar(zone);
// if (failure(status, "new GregorianCalendar")) return;
long marchOne = marchOneStd + startHour;
long julyOne = julyOneStd + endHour - 3600000; // Adjust from wall to Std time
long expMarchOne = 636251400000L;
if (marchOne != expMarchOne)
{
errln("FAIL: Expected start computed as " + marchOne +
" = " + new Date(marchOne));
logln(" Should be " + expMarchOne +
" = " + new Date(expMarchOne));
}
long expJulyOne = 646793100000L;
if (julyOne != expJulyOne)
{
errln("FAIL: Expected start computed as " + julyOne +
" = " + new Date(julyOne));
logln(" Should be " + expJulyOne +
" = " + new Date(expJulyOne));
}
_testUsingBinarySearch(zone, new Date(90, Calendar.JANUARY, 1).getTime(),
new Date(90, Calendar.JUNE, 15).getTime(), marchOne);
_testUsingBinarySearch(zone, new Date(90, Calendar.JUNE, 1).getTime(),
new Date(90, Calendar.DECEMBER, 31).getTime(), julyOne);
if (zone.inDaylightTime(new Date(marchOne - 1000)) ||
!zone.inDaylightTime(new Date(marchOne)))
errln("FAIL: Start rule broken");
if (!zone.inDaylightTime(new Date(julyOne - 1000)) ||
zone.inDaylightTime(new Date(julyOne)))
errln("FAIL: End rule broken");
zone.setStartYear(1991);
if (zone.inDaylightTime(new Date(marchOne)) ||
zone.inDaylightTime(new Date(julyOne - 1000)))
errln("FAIL: Start year broken");
// failure(status, "TestRuleAPI");
// delete gc;
// delete zone;
}
void _testUsingBinarySearch(SimpleTimeZone tz, long min, long max, long expectedBoundary)
{
// ErrorCode status = ZERO_ERROR;
boolean startsInDST = tz.inDaylightTime(new Date(min));
// if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
if (tz.inDaylightTime(new Date(max)) == startsInDST) {
logln("Error: inDaylightTime(" + new Date(max) + ") != " + (!startsInDST));
return;
}
// if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
while ((max - min) > INTERVAL) {
long mid = (min + max) / 2;
if (tz.inDaylightTime(new Date(mid)) == startsInDST) {
min = mid;
}
else {
max = mid;
}
// if (failure(status, "SimpleTimeZone::inDaylightTime")) return;
}
logln("Binary Search Before: " + min + " = " + new Date(min));
logln("Binary Search After: " + max + " = " + new Date(max));
long mindelta = expectedBoundary - min;
long maxdelta = max - expectedBoundary;
if (mindelta >= 0 &&
mindelta <= INTERVAL &&
mindelta >= 0 &&
mindelta <= INTERVAL)
logln("PASS: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary));
else
errln("FAIL: Expected bdry: " + expectedBoundary + " = " + new Date(expectedBoundary));
}
static final int INTERVAL = 100;
// Bug 006; verify the offset for a specific zone.
public void TestPRTOffset()
{
TimeZone tz = TimeZone.getTimeZone( "PRT" );
if( tz == null ) {
errln( "FAIL: TimeZone(PRT) is null" );
}
else{
if (tz.getRawOffset() != (-4*millisPerHour))
errln("FAIL: Offset for PRT should be -4");
}
}
// Test various calls
public void TestVariousAPI518()
{
TimeZone time_zone = TimeZone.getTimeZone("PST");
Date d = new Date(97, Calendar.APRIL, 30);
logln("The timezone is " + time_zone.getID());
if (time_zone.inDaylightTime(d) != true)
errln("FAIL: inDaylightTime returned false");
if (time_zone.useDaylightTime() != true)
errln("FAIL: useDaylightTime returned false");
if (time_zone.getRawOffset() != -8*millisPerHour)
errln( "FAIL: getRawOffset returned wrong value");
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(d);
if (time_zone.getOffset(gc.AD, gc.get(gc.YEAR), gc.get(gc.MONTH),
gc.get(gc.DAY_OF_MONTH),
gc.get(gc.DAY_OF_WEEK), 0)
!= -7*millisPerHour)
errln("FAIL: getOffset returned wrong value");
}
// Test getAvailableID API
public void TestGetAvailableIDs913()
{
StringBuffer buf = new StringBuffer("TimeZone.getAvailableIDs() = { ");
String[] s = TimeZone.getAvailableIDs();
for (int i=0; i<s.length; ++i)
{
if (i > 0) buf.append(", ");
buf.append(s[i]);
}
buf.append(" };");
logln(buf.toString());
buf.setLength(0);
buf.append("TimeZone.getAvailableIDs(GMT+02:00) = { ");
s = TimeZone.getAvailableIDs(+2 * 60 * 60 * 1000);
for (int i=0; i<s.length; ++i)
{
if (i > 0) buf.append(", ");
buf.append(s[i]);
}
buf.append(" };");
logln(buf.toString());
TimeZone tz = TimeZone.getTimeZone("PST");
if (tz != null)
logln("getTimeZone(PST) = " + tz.getID());
else
errln("FAIL: getTimeZone(PST) = null");
tz = TimeZone.getTimeZone("America/Los_Angeles");
if (tz != null)
logln("getTimeZone(America/Los_Angeles) = " + tz.getID());
else
errln("FAIL: getTimeZone(PST) = null");
// Bug 4096694
tz = TimeZone.getTimeZone("NON_EXISTENT");
if (tz == null)
errln("FAIL: getTimeZone(NON_EXISTENT) = null");
else if (!tz.getID().equals("GMT"))
errln("FAIL: getTimeZone(NON_EXISTENT) = " + tz.getID());
}
/**
* Bug 4107276
*/
public void TestDSTSavings() {
// It might be better to find a way to integrate this test into the main TimeZone
// tests above, but I don't have time to figure out how to do this (or if it's
// even really a good idea). Let's consider that a future. --rtg 1/27/98
SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "dstSavingsTest",
Calendar.MARCH, 1, 0, 0, Calendar.SEPTEMBER, 1, 0, 0,
(int)(0.5 * millisPerHour));
if (tz.getRawOffset() != -5 * millisPerHour)
errln("Got back a raw offset of " + (tz.getRawOffset() / millisPerHour) +
" hours instead of -5 hours.");
if (!tz.useDaylightTime())
errln("Test time zone should use DST but claims it doesn't.");
if (tz.getDSTSavings() != 0.5 * millisPerHour)
errln("Set DST offset to 0.5 hour, but got back " + (tz.getDSTSavings() /
millisPerHour) + " hours instead.");
int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,
Calendar.THURSDAY, 10 * millisPerHour);
if (offset != -5 * millisPerHour)
errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,
10 * millisPerHour);
if (offset != -4.5 * millisPerHour)
errln("The offset for 10 AM, 6/1/98 should have been -4.5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
tz.setDSTSavings(millisPerHour);
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JANUARY, 1,
Calendar.THURSDAY, 10 * millisPerHour);
if (offset != -5 * millisPerHour)
errln("The offset for 10 AM, 1/1/98 should have been -5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.JUNE, 1, Calendar.MONDAY,
10 * millisPerHour);
if (offset != -4 * millisPerHour)
errln("The offset for 10 AM, 6/1/98 (with a 1-hour DST offset) should have been -4 hours, but we got "
+ (offset / millisPerHour) + " hours.");
}
/**
* Bug 4107570
*/
public void TestAlternateRules() {
// Like TestDSTSavings, this test should probably be integrated somehow with the main
// test at the top of this class, but I didn't have time to figure out how to do that.
// --rtg 1/28/98
SimpleTimeZone tz = new SimpleTimeZone(-5 * millisPerHour, "alternateRuleTest");
// test the day-of-month API
tz.setStartRule(Calendar.MARCH, 10, 12 * millisPerHour);
tz.setEndRule(Calendar.OCTOBER, 20, 12 * millisPerHour);
int offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 5,
Calendar.THURSDAY, 10 * millisPerHour);
if (offset != -5 * millisPerHour)
errln("The offset for 10AM, 3/5/98 should have been -5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 15,
Calendar.SUNDAY, 10 * millisPerHour);
if (offset != -4 * millisPerHour)
errln("The offset for 10AM, 3/15/98 should have been -4 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,
Calendar.THURSDAY, 10 * millisPerHour);
if (offset != -4 * millisPerHour)
errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 25,
Calendar.SUNDAY, 10 * millisPerHour);
if (offset != -5 * millisPerHour)
errln("The offset for 10AM, 10/25/98 should have been -5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
// test the day-of-week-after-day-in-month API
tz.setStartRule(Calendar.MARCH, 10, Calendar.FRIDAY, 12 * millisPerHour, true);
tz.setEndRule(Calendar.OCTOBER, 20, Calendar.FRIDAY, 12 * millisPerHour, false);
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 11,
Calendar.WEDNESDAY, 10 * millisPerHour);
if (offset != -5 * millisPerHour)
errln("The offset for 10AM, 3/11/98 should have been -5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.MARCH, 14,
Calendar.SATURDAY, 10 * millisPerHour);
if (offset != -4 * millisPerHour)
errln("The offset for 10AM, 3/14/98 should have been -4 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 15,
Calendar.THURSDAY, 10 * millisPerHour);
if (offset != -4 * millisPerHour)
errln("The offset for 10AM, 10/15/98 should have been -4 hours, but we got "
+ (offset / millisPerHour) + " hours.");
offset = tz.getOffset(GregorianCalendar.AD, 1998, Calendar.OCTOBER, 17,
Calendar.SATURDAY, 10 * millisPerHour);
if (offset != -5 * millisPerHour)
errln("The offset for 10AM, 10/17/98 should have been -5 hours, but we got "
+ (offset / millisPerHour) + " hours.");
}
}
//eof

View File

@ -37,7 +37,7 @@ import java.text.NumberFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.MissingResourceException;
import java.util.TimeZone;
import com.ibm.util.TimeZone;
import com.ibm.util.Calendar;
import com.ibm.util.GregorianCalendar;
import java.util.Date;
@ -118,9 +118,9 @@ import java.text.resources.*;
* @see Format
* @see NumberFormat
* @see SimpleDateFormat
* @see java.util.Calendar
* @see java.util.GregorianCalendar
* @see java.util.TimeZone
* @see com.ibm.util.Calendar
* @see com.ibm.util.GregorianCalendar
* @see com.ibm.util.TimeZone
* @version 1.37 11/02/99
* @author Mark Davis, Chen-Lieh Huang, Alan Liu
*/
@ -582,7 +582,7 @@ public abstract class DateFormat extends Format {
* do not precisely match this object's format. With strict parsing,
* inputs must match this object's format.
* @param lenient when true, parsing is lenient
* @see java.util.Calendar#setLenient
* @see com.ibm.util.Calendar#setLenient
*/
public void setLenient(boolean lenient)
{

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/text/Attic/DateFormatSymbols.java,v $
* $Date: 2000/04/27 22:41:39 $
* $Revision: 1.3 $
* $Date: 2000/05/12 23:19:35 $
* $Revision: 1.4 $
*
*****************************************************************************************
*/
@ -64,7 +64,7 @@ import com.ibm.util.Utility;
* @see DateFormat
* @see SimpleDateFormat
* @see java.util.SimpleTimeZone
* @see com.ibm.util.SimpleTimeZone
* @version 1.31 09/21/99
* @author Chen-Lieh Huang
*/
@ -169,7 +169,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* are localized names. If a zone does not implement daylight savings
* time, the daylight savings time names are ignored.
* @see java.text.resources.DateFormatZoneData
* @see java.util.TimeZone
* @see com.ibm.util.TimeZone
* @serial
*/
String zoneStrings[][] = null;
@ -505,7 +505,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* @param ID the given time zone ID.
* @return the index of the given time zone ID. Returns -1 if
* the given time zone ID can't be located in the DateFormatSymbols object.
* @see java.util.SimpleTimeZone
* @see com.ibm.util.SimpleTimeZone
*/
final int getZoneIndex (String ID)
{

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/text/Attic/SimpleDateFormat.java,v $
* $Date: 2000/04/27 22:41:39 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:19:35 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -20,12 +20,12 @@ import java.text.NumberFormat;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.util.TimeZone;
import com.ibm.util.TimeZone;
import com.ibm.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
import com.ibm.util.GregorianCalendar;
import java.io.ObjectInputStream;
import java.io.IOException;
@ -170,9 +170,9 @@ import java.lang.StringIndexOutOfBoundsException;
* time zone. There is one common decimal format to handle all the numbers;
* the digit count is handled programmatically according to the pattern.
*
* @see java.util.Calendar
* @see java.util.GregorianCalendar
* @see java.util.TimeZone
* @see com.ibm.util.Calendar
* @see com.ibm.util.GregorianCalendar
* @see com.ibm.util.TimeZone
* @see DateFormat
* @see DateFormatSymbols
* @see DecimalFormat

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/util/Attic/BuddhistCalendar.java,v $
* $Date: 2000/03/21 02:19:32 $
* $Revision: 1.3 $
* $Date: 2000/05/12 23:20:10 $
* $Revision: 1.4 $
*
*****************************************************************************************
*/
@ -16,7 +16,6 @@ package com.ibm.util;
import java.util.Date;
import com.ibm.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
/**
* <code>BuddhistCalendar</code> is a subclass of <code>GregorianCalendar</code>
@ -33,7 +32,7 @@ import java.util.TimeZone;
* calendar is not in lenient mode (see <code>setLenient</code>), dates before
* 1/1/1 BE are rejected with an <code>IllegalArgumentException</code>.
*
* @see java.util.GregorianCalendar
* @see com.ibm.util.GregorianCalendar
*
* @author Laura Werner
*/
@ -49,7 +48,7 @@ public class BuddhistCalendar extends GregorianCalendar {
* Constant for the Buddhist Era. This is the only allowable <code>ERA</code>
* value for the Buddhist calendar.
*
* @see java.util.Calendar#ERA
* @see com.ibm.util.Calendar#ERA
*/
public static final int BE = 0;

View File

@ -33,7 +33,6 @@ import java.util.Date;
import java.util.Hashtable;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.TimeZone;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/util/Attic/EasterHoliday.java,v $
* $Date: 2000/03/21 02:19:32 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:20:10 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -16,7 +16,7 @@ package com.ibm.util;
import java.util.Date;
import com.ibm.util.GregorianCalendar;
import com.ibm.util.Calendar;
import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
/**
* A Holiday subclass which represents holidays that occur

View File

@ -31,7 +31,6 @@
package com.ibm.util;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
/**
* <code>GregorianCalendar</code> is a concrete subclass of
@ -1184,8 +1183,9 @@ public class GregorianCalendar extends Calendar {
// getOffset(..., monthLen). This makes some zones behave incorrectly.
// Fix this later, if desired, by porting TimeZone and STZ to this pkg.
// -Alan
int dstOffset = getTimeZone().getOffset(era,year,month,date,dayOfWeek,millisInDay /*,
monthLength(month), prevMonthLength(month)*/)
// [icu4j fixed after 'port' of tz&stz to com.ibm.util - liu]
int dstOffset = getTimeZone().getOffset(era,year,month,date,dayOfWeek,millisInDay,
monthLength(month), prevMonthLength(month))
- rawOffset;
// Adjust our millisInDay for DST, if necessary.
@ -1525,14 +1525,15 @@ public class GregorianCalendar extends Calendar {
// getOffset(..., millis). This makes some zones behave incorrectly.
// Fix this later, if desired, by porting TimeZone and STZ to this pkg.
// -Alan
// [icu4j fixed after 'port' of tz&stz to com.ibm.util - liu]
dstOffset = zone.getOffset(era,
internalGet(YEAR),
internalGet(MONTH),
internalGet(DATE),
dow,
normalizedMillisInDay[0] /*,
normalizedMillisInDay[0],
monthLength(internalGet(MONTH)),
prevMonthLength(internalGet(MONTH)) */) -
prevMonthLength(internalGet(MONTH))) -
zoneOffset;
// Note: Because we pass in wall millisInDay, rather than
// standard millisInDay, we interpret "1:00 am" on the day

View File

@ -5,17 +5,15 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/util/Attic/HebrewCalendar.java,v $
* $Date: 2000/03/10 04:17:58 $
* $Revision: 1.2 $
* $Date: 2000/05/12 23:20:10 $
* $Revision: 1.3 $
*
*****************************************************************************************
*/
package com.ibm.util;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
/**
* <code>HebrewCalendar</code> is a subclass of <code>Calendar</code>
@ -63,7 +61,7 @@ import java.util.TimeZone;
* http://www.pip.dknet.dk/~pip10160/calendar.html</a>
* </ul>
* <p>
* @see java.util.GregorianCalendar
* @see com.ibm.util.GregorianCalendar
*
* @author Laura Werner
*/
@ -352,7 +350,7 @@ public class HebrewCalendar extends IBMCalendar {
*
* @param field The field whose minimum value is desired.
*
* @see java.util.Calendar#getMinimum
* @see com.ibm.util.Calendar#getMinimum
*/
public int getMinimum(int field)
{
@ -570,7 +568,7 @@ public class HebrewCalendar extends IBMCalendar {
//-------------------------------------------------------------------------
// Functions for converting from field values to milliseconds and back...
//
// These are overrides of abstract methods on java.util.Calendar
// These are overrides of abstract methods on com.ibm.util.Calendar
//-------------------------------------------------------------------------
/**
@ -1099,4 +1097,4 @@ public class HebrewCalendar extends IBMCalendar {
System.out.println(str);
}
}
};
};

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/util/Attic/IBMCalendar.java,v $
* $Date: 2000/04/27 22:34:40 $
* $Revision: 1.9 $
* $Date: 2000/05/12 23:20:10 $
* $Revision: 1.10 $
*
*****************************************************************************************
*/
@ -18,7 +18,6 @@ import com.ibm.util.GregorianCalendar;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.TimeZone;
import java.text.MessageFormat;
import com.ibm.text.DateFormat;
import com.ibm.text.DateFormatSymbols;

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/util/Attic/IslamicCalendar.java,v $
* $Date: 2000/03/21 02:19:32 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:20:10 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -16,7 +16,6 @@ import com.ibm.util.Calendar;
import java.util.Date;
import com.ibm.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;
import com.ibm.util.CalendarAstronomer;
/**
@ -69,7 +68,7 @@ import com.ibm.util.CalendarAstronomer;
* fixed-cycle civil calendar is used. However, if <code>setCivil(false)</code>
* is called, an approximation of the true lunar calendar will be used.
*
* @see java.util.GregorianCalendar
* @see com.ibm.util.GregorianCalendar
*
* @author Laura Werner
* @version 1.0
@ -297,7 +296,7 @@ public class IslamicCalendar extends IBMCalendar {
*
* @param field The field whose minimum value is desired.
*
* @see java.util.Calendar#getMinimum
* @see com.ibm.util.Calendar#getMinimum
*/
public int getMinimum(int field)
{

View File

@ -5,18 +5,15 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/util/Attic/JapaneseCalendar.java,v $
* $Date: 2000/03/21 02:19:32 $
* $Revision: 1.3 $
* $Date: 2000/05/12 23:20:10 $
* $Revision: 1.4 $
*
*****************************************************************************************
*/
package com.ibm.util;
import java.util.Date;
import com.ibm.util.GregorianCalendar;
import java.util.Locale;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
/**
* <code>JapaneseCalendar</code> is a subclass of <code>GregorianCalendar</code>
@ -43,7 +40,7 @@ import java.util.TimeZone;
* constants rather than using actual, absolute numbers.
* <p>
*
* @see java.util.GregorianCalendar
* @see com.ibm.util.GregorianCalendar
*
* @author Laura Werner
*/

View File

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/util/Attic/SimpleDateRule.java,v $
* $Date: 2000/03/21 02:19:32 $
* $Revision: 1.4 $
* $Date: 2000/05/12 23:20:11 $
* $Revision: 1.5 $
*
*****************************************************************************************
*/
@ -16,7 +16,7 @@ package com.ibm.util;
import java.util.Date;
import com.ibm.util.Calendar;
import com.ibm.util.GregorianCalendar;
import java.util.SimpleTimeZone;
import com.ibm.util.SimpleTimeZone;
public class SimpleDateRule implements DateRule
{

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,157 @@
/* Copyright (c) 2000 International Business Machines Corporation and
* others. All Rights Reserved.
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/util/Attic/SimpleTimeZoneAdapter.java,v $
* $Date: 2000/05/12 23:20:11 $
* $Revision: 1.1 $
*/
package com.ibm.util;
import java.util.Date;
/**
* <code>SimpleTimeZoneAdapter</code> wraps a
* com.ibm.util.SimpleTimeZone and inherits from java.util.TimeZone.
* Without this class, we would need to 'port' java.util.Date to
* com.ibm.util as well, so that Date could interoperate properly with
* the com.ibm.util TimeZone and Calendar classes. With this class,
* we can (mostly) use java.util.Date together with com.ibm.util
* classes.
*
* <p>This solution is imperfect because of the faulty design of
* java.util.TimeZone. Specifically, TZ contains a package private
* method, getOffset(), that should really be public. Because it is
* package private, it cannot be overridden from where we are, and we
* cannot properly delegate its operation to our contained
* com.ibm.util.STZ object.
*
* <p>For the moment we live with this problem. It appear not to
* cause too much trouble since most real computations happen using
* the com.ibm.util classes. However, if this becomes a problem in
* the future, we will have to stop using this adapter, and 'port'
* java.util.Date into com.ibm.util.
*
* @see com.ibm.util.TimeZone#setDefault
* @author Alan Liu
*/
public class SimpleTimeZoneAdapter extends java.util.TimeZone {
/**
* The contained com.ibm.util.SimpleTimeZone object.
* We delegate all methods to this object.
*/
private SimpleTimeZone zone;
public SimpleTimeZoneAdapter(SimpleTimeZone zone) {
this.zone = zone;
}
/**
* Override TimeZone
*/
public String getID() {
return zone.getID();
}
/**
* Override TimeZone
*/
public void setID(String ID) {
zone.setID(ID);
}
/**
* Override TimeZone
*/
public boolean hasSameRules(java.util.TimeZone other) {
return other instanceof SimpleTimeZoneAdapter &&
zone.hasSameRules(((SimpleTimeZoneAdapter)other).zone);
}
/**
* Override TimeZone
*/
public int getOffset(int era, int year, int month, int day, int dayOfWeek,
int millis) {
return zone.getOffset(era, year, month, day, dayOfWeek, millis);
}
// This doesn't work! Because this is a package-private method,
// it cannot override the corresponding method in java.util.TZ.
// This reflects a fundamental bug in the architecture of
// java.util.TZ. If not for this, this adapter class would
// work flawlessly. - liu
//! /**
//! * Override TimeZone
//! */
//! int getOffset(int era, int year, int month, int day, int dayOfWeek,
//! int millis, int monthLength, int prevMonthLength) {
//! return zone.getOffset(era, year, month, day, dayOfWeek,
//! millis, monthLength, prevMonthLength);
//! }
/**
* Overrides TimeZone
* Gets the GMT offset for this time zone.
*/
public int getRawOffset() {
return zone.getRawOffset();
}
/**
* Overrides TimeZone
*/
public void setRawOffset(int offsetMillis) {
zone.setRawOffset(offsetMillis);
}
/**
* Overrides TimeZone
*/
public boolean useDaylightTime() {
return zone.useDaylightTime();
}
/**
* Overrides TimeZone
*/
public boolean inDaylightTime(Date date) {
return zone.inDaylightTime(date);
}
/**
* Overrides Cloneable
*/
public Object clone() {
return new SimpleTimeZoneAdapter((SimpleTimeZone)zone.clone());
}
/**
* Override hashCode.
*/
public synchronized int hashCode() {
return zone.hashCode();
}
/**
* Compares the equality of two SimpleTimeZone objects.
*
* @param obj The SimpleTimeZone object to be compared with.
* @return True if the given obj is the same as this SimpleTimeZone
* object; false otherwise.
*/
public boolean equals(Object obj) {
if (obj instanceof SimpleTimeZoneAdapter) {
obj = ((SimpleTimeZoneAdapter)obj).zone;
}
return zone.equals(obj);
}
/**
* Return a string representation of this time zone.
* @return a string representation of this time zone.
*/
public String toString() {
// Should probably show our class name here...fix later.
return zone.toString();
}
}

File diff suppressed because it is too large Load Diff