/**
 *******************************************************************************
 * Copyright (C) 2000-2010, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.test.timezone;
import java.util.Date;

import com.ibm.icu.dev.test.TestFmwk;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.SimpleTimeZone;
import com.ibm.icu.util.TimeZone;

/**
 * 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

    // [3Jan01 Liu] Updated for 2000f data
    static final String AUSTRALIA = "Australia/Adelaide";
    static final long AUSTRALIA_1997_BEG = 877797000000L;
    static final long AUSTRALIA_1997_END = 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;
        // not used 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;
        // not used long maxdelta = max - expectedBoundary; 
        DateFormat fmt = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
        fmt.setTimeZone(tz);
        if (mindelta >= 0 && mindelta <= INTERVAL &&
            mindelta >= 0 && mindelta <= INTERVAL)
            logln("PASS: Expected boundary at " + expectedBoundary + " = " + fmt.format(new Date(expectedBoundary)));
        else
            errln("FAIL: Expected boundary at " + expectedBoundary + " = " + fmt.format(new Date(expectedBoundary)));
    }

    private static String showDate(long l)
    {
        return showDate(new Date(l));
    }

    private static String showDate(Date d)
    {
        java.util.Calendar cal = java.util.Calendar.getInstance();
        cal.setTime(d);
        return "" + (cal.get(Calendar.YEAR) - 1900) + "/" + 
               showNN(cal.get(Calendar.MONTH) + 1) + "/" + 
               showNN(cal.get(Calendar.DAY_OF_MONTH)) + " " + 
               showNN(cal.get(Calendar.HOUR_OF_DAY)) + ":" 
               + showNN(cal.get(Calendar.MINUTE)) + " \"" + 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);
        java.util.Calendar cal = java.util.Calendar.getInstance();
        cal.setTime(d);
        return "" + (cal.get(Calendar.YEAR) - 1900) + "/" + 
               showNN(cal.get(Calendar.MONTH) + 1) + "/" + 
               showNN(cal.get(Calendar.DAY_OF_MONTH)) + " " + 
               showNN(cal.get(Calendar.HOUR_OF_DAY)) + ":" + 
               showNN(cal.get(Calendar.MINUTE)) + " \"" + d + "\" = " +
               fmt.format(d) + " = " + d.getTime();
    }

    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(String tag, Calendar cal, TimeZone time_zone,
                   boolean expUseDaylightTime, boolean expInDaylightTime,
                   int expRawOffset, int expOffset)
    {
        Date d = cal.getTime();

        logln("-- " + tag + ": " + d +
              " in zone " + time_zone.getID() + " (" +
              d.getTime()/3600000.0 + ")");

        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() == expRawOffset)
            logln("PASS: getRawOffset() = " + expRawOffset/(double)ONE_HOUR);
        else
            errln("FAIL: getRawOffset() = " + time_zone.getRawOffset()/(double)ONE_HOUR +
                  "; expected " + expRawOffset/(double)ONE_HOUR);

        //GregorianCalendar gc = new GregorianCalendar(time_zone);
        //gc.setTime(d);
        int offset = time_zone.getOffset(cal.get(Calendar.ERA), cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
                                         cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.DAY_OF_WEEK),
                                         ((cal.get(Calendar.HOUR_OF_DAY) * 60 +
                                           cal.get(Calendar.MINUTE)) * 60 +
                                          cal.get(Calendar.SECOND)) * 1000 +
                                         cal.get(Calendar.MILLISECOND));
        if (offset == expOffset)
            logln("PASS: getOffset() = " + offset/(double)ONE_HOUR);
        else {
            logln("era=" + cal.get(Calendar.ERA) +
                  ", year=" + cal.get(Calendar.YEAR) +
                  ", month=" + cal.get(Calendar.MONTH) +
                  ", dom=" + cal.get(Calendar.DAY_OF_MONTH) +
                  ", dow=" + cal.get(Calendar.DAY_OF_WEEK) +
                  ", time-of-day=" + (((cal.get(Calendar.HOUR_OF_DAY) * 60 +
                               cal.get(Calendar.MINUTE)) * 60 +
                              cal.get(Calendar.SECOND)) * 1000 +
                             cal.get(Calendar.MILLISECOND)) / 3600000.0 +
                            " hours");
            errln("FAIL: getOffset() = " + offset/(double)ONE_HOUR +
                  "; expected " + expOffset/(double)ONE_HOUR);
        }
    }

    /**
     * Check that the given year/month/dom/hour maps to and from the
     * given epochHours.  This verifies the functioning of the
     * calendar and time zone in conjunction with one another,
     * including the calendar time->fields and fields->time and
     * the time zone getOffset method.
     *
     * @param epochHours hours after Jan 1 1970 0:00 GMT.
     */
    void verifyMapping(Calendar cal, int year, int month, int dom, int hour,
                       double epochHours) {
        double H = 3600000.0;
        cal.clear();
        cal.set(year, month, dom, hour, 0, 0);
        Date d = cal.getTime();
        double e = d.getTime() / H;
        Date ed = new Date((long)(epochHours * H));
        if (e == epochHours) {
            logln("Ok: " + year + "/" + (month+1) + "/" + dom + " " + hour + ":00 => " +
                  e + " (" + ed + ")");
        } else {
            errln("FAIL: " + year + "/" + (month+1) + "/" + dom + " " + hour + ":00 => " +
                  e + " (" + new Date((long)(e * H)) + ")" +
                  ", expected " + epochHours + " (" + ed + ")");
        }
        cal.setTime(ed);
        if (cal.get(Calendar.YEAR) == year &&
            cal.get(Calendar.MONTH) == month &&
            cal.get(Calendar.DATE) == dom &&
            cal.get(Calendar.MILLISECONDS_IN_DAY) == hour * 3600000) {
            logln("Ok: " + epochHours + " (" + ed + ") => " +
                  cal.get(Calendar.YEAR) + "/" +
                  (cal.get(Calendar.MONTH)+1) + "/" +
                  cal.get(Calendar.DATE) + " " +
                  cal.get(Calendar.MILLISECONDS_IN_DAY)/H);
        } else {
            errln("FAIL: " + epochHours + " (" + ed + ") => " +
                  cal.get(Calendar.YEAR) + "/" +
                  (cal.get(Calendar.MONTH)+1) + "/" +
                  cal.get(Calendar.DATE) + " " +
                  cal.get(Calendar.MILLISECONDS_IN_DAY)/H +
                  ", expected " + year + "/" + (month+1) + "/" + dom +
                  " " + hour);
        }
    }

// NOTE: Enable this code to check the behavior of the underlying JDK,
// using a JDK Calendar object.
//
//    int millisInDay(java.util.Calendar cal) {
//        return ((cal.get(Calendar.HOUR_OF_DAY) * 60 +
//                 cal.get(Calendar.MINUTE)) * 60 +
//                cal.get(Calendar.SECOND)) * 1000 +
//            cal.get(Calendar.MILLISECOND);
//    }
//
//    void verifyMapping(java.util.Calendar cal, int year, int month, int dom, int hour,
//                       double epochHours) {
//        cal.clear();
//        cal.set(year, month, dom, hour, 0, 0);
//        Date d = cal.getTime();
//        double e = d.getTime() / 3600000.0;
//        Date ed = new Date((long)(epochHours * 3600000));
//        if (e == epochHours) {
//            logln("Ok: " + year + "/" + (month+1) + "/" + dom + " " + hour + ":00 => " +
//                  e + " (" + ed + ")");
//        } else {
//            errln("FAIL: " + year + "/" + (month+1) + "/" + dom + " " + hour + ":00 => " +
//                  e + " (" + new Date((long)(e * 3600000)) + ")" +
//                  ", expected " + epochHours + " (" + ed + ")");
//        }
//        cal.setTime(ed);
//        if (cal.get(Calendar.YEAR) == year &&
//            cal.get(Calendar.MONTH) == month &&
//            cal.get(Calendar.DATE) == dom &&
//            millisInDay(cal) == hour * 3600000) {
//            logln("Ok: " + epochHours + " (" + ed + ") => " +
//                  cal.get(Calendar.YEAR) + "/" +
//                  (cal.get(Calendar.MONTH)+1) + "/" +
//                  cal.get(Calendar.DATE) + " " +
//                  millisInDay(cal)/3600000.0);
//        } else {
//            errln("FAIL: " + epochHours + " (" + ed + ") => " +
//                  cal.get(Calendar.YEAR) + "/" +
//                  (cal.get(Calendar.MONTH)+1) + "/" +
//                  cal.get(Calendar.DATE) + " " +
//                  millisInDay(cal)/3600000.0 +
//                  ", expected " + year + "/" + (month+1) + "/" + dom +
//                  " " + hour);
//        }
//    }

    public void TestBoundaries()
    {
        TimeZone save = TimeZone.getDefault();

        // Check basic mappings.  We had a problem with this for ICU
        // 2.8 after migrating to using pass-through time zones.  The
        // problem appeared only on JDK 1.3.
        TimeZone pst = safeGetTimeZone("PST");
        Calendar tempcal = Calendar.getInstance(pst);
        verifyMapping(tempcal, 1997, Calendar.APRIL, 3,  0, 238904.0);
        verifyMapping(tempcal, 1997, Calendar.APRIL, 4,  0, 238928.0);
        verifyMapping(tempcal, 1997, Calendar.APRIL, 5,  0, 238952.0);
        verifyMapping(tempcal, 1997, Calendar.APRIL, 5, 23, 238975.0);
        verifyMapping(tempcal, 1997, Calendar.APRIL, 6,  0, 238976.0);
        verifyMapping(tempcal, 1997, Calendar.APRIL, 6,  1, 238977.0);
        verifyMapping(tempcal, 1997, Calendar.APRIL, 6,  3, 238978.0);
        
        TimeZone utc = safeGetTimeZone("UTC");
        Calendar utccal = Calendar.getInstance(utc);
        verifyMapping(utccal, 1997, Calendar.APRIL, 6, 0, 238968.0);

// NOTE: Enable this code to check the behavior of the underlying JDK,
// using a JDK Calendar object.
//
//        java.util.TimeZone jdkpst = java.util.TimeZone.getTimeZone("PST");
//        java.util.Calendar jdkcal = java.util.Calendar.getInstance(jdkpst);
//        verifyMapping(jdkcal, 1997, Calendar.APRIL, 5,  0, 238952.0);
//        verifyMapping(jdkcal, 1997, Calendar.APRIL, 5, 23, 238975.0);
//        verifyMapping(jdkcal, 1997, Calendar.APRIL, 6,  0, 238976.0);
//        verifyMapping(jdkcal, 1997, Calendar.APRIL, 6,  1, 238977.0);
//        verifyMapping(jdkcal, 1997, Calendar.APRIL, 6,  3, 238978.0);

        tempcal.clear();
        tempcal.set(1997, Calendar.APRIL, 6);
        Date d = tempcal.getTime();

        try {
            TimeZone.setDefault(pst);

            // DST changeover for PST is 4/6/1997 at 2 hours past midnight
            // at 238978.0 epoch hours.

            // i is minutes past midnight standard time
            for (int i=-120; i<=180; i+=60)
            {
                boolean inDST = (i >= 120);
                tempcal.setTimeInMillis(d.getTime() + i*60*1000);
                verifyDST("hour=" + i/60,
                          tempcal, pst, true, inDST, -8*ONE_HOUR,
                          inDST ? -7*ONE_HOUR : -8*ONE_HOUR);
            }
        } finally {
            TimeZone.setDefault(save);
        }

        // We no longer use ICU TimeZone implementation for Java
        // default TimeZone.  Java 1.3 or older version do not
        // support historic transitions, therefore, the test below
        // will fail on such environment (with the latest TimeZone
        // patch for US 2007+ rule).
        String javaver = System.getProperty("java.version", "1.3");
        if (!javaver.startsWith("1.3"))
        {
            // This only works in PST/PDT
            TimeZone.setDefault(safeGetTimeZone("PST"));
            logln("========================================");
            tempcal.set(1997, 0, 1);
            findDaylightBoundaryUsingDate(tempcal.getTime(), "PST", PST_1997_BEG);
            logln("========================================");
            tempcal.set(1997, 6, 1);
            findDaylightBoundaryUsingDate(tempcal.getTime(), "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 = safeGetTimeZone(AUSTRALIA);
            tempcal.set(1997, 0, 1);
            findDaylightBoundaryUsingTimeZone(tempcal.getTime(), true, AUSTRALIA_1997_END, z);
            logln("========================================");
            tempcal.set(1997, 6, 1);
            findDaylightBoundaryUsingTimeZone(tempcal.getTime(), false, AUSTRALIA_1997_BEG, z);
        }

        if (true)
        {
            logln("========================================");
            tempcal.set(1997, 0, 1);
            findDaylightBoundaryUsingTimeZone(tempcal.getTime(), false, PST_1997_BEG);
            logln("========================================");
            tempcal.set(1997, 6, 1);
            findDaylightBoundaryUsingTimeZone(tempcal.getTime(), 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();
            tempcal.set(1997, 3, 4);
            logln(z.getOffset(1, 97, 3, 4, 6, 0) + " " + tempcal.getTime());
            tempcal.set(1997, 3, 5);
            logln(z.getOffset(1, 97, 3, 5, 7, 0) + " " + tempcal.getTime());
            tempcal.set(1997, 3, 6);
            logln(z.getOffset(1, 97, 3, 6, 1, 0) + " " + tempcal.getTime());
            tempcal.set(1997, 3, 7);
            logln(z.getOffset(1, 97, 3, 7, 2, 0) + " " + tempcal.getTime());
        }
    }


    //----------------------------------------------------------------------
    // 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)
        {
            errln("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;
        // not used 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;
            java.util.Calendar tempcal = java.util.Calendar.getInstance();
            tempcal.clear();

            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("========================================");
            tempcal.set(1997, 0, 1);
            _testUsingBinarySearch(tz, tempcal.getTime(), 858416400000L);
            logln("========================================");
            tempcal.set(1997, 6, 1);
            _testUsingBinarySearch(tz, tempcal.getTime(), 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("========================================");
            tempcal.set(1997, 0, 1);
            _testUsingBinarySearch(tz, tempcal.getTime(), 861184800000L);
            logln("========================================");
            tempcal.set(1997, 6, 1);
            _testUsingBinarySearch(tz, tempcal.getTime(), 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)
    {
        java.util.Calendar tempcal = java.util.Calendar.getInstance();
        tempcal.clear();
        tempcal.set(year, Calendar.JANUARY, 1);
        Date d = tempcal.getTime();
        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, safeGetTimeZone("America/New_York"), 2);
        // disabled Oct 2003 aliu; ACT could mean anything, depending on the underlying JDK, as of 2.8
        // findBoundariesStepwise(1997, ONE_DAY, safeGetTimeZone("ACT"), 2);
        findBoundariesStepwise(1997, ONE_DAY, safeGetTimeZone("America/Phoenix"), 0); // Added 3Jan01
        findBoundariesStepwise(1997, ONE_DAY, safeGetTimeZone(AUSTRALIA), 2);
    }
}
