blob: ac1276ee3b5eab275ec74b760cde5f99f9df7864 [file] [log] [blame]
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package drtcases;
import junit.framework.TestCase;
import junit.framework.Test;
import junit.framework.TestSuite;
import junit.framework.Assert;
import org.apache.xmlbeans.GDate;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.GDateBuilder;
import org.apache.xmlbeans.GDuration;
import org.apache.xmlbeans.GDurationBuilder;
import org.apache.xmlbeans.XmlCalendar;
import java.util.GregorianCalendar;
import java.util.Date;
import java.util.Calendar;
public class GDateTests extends TestCase
{
public GDateTests(String name) { super(name); }
public static Test suite() { return new TestSuite(GDateTests.class); }
static String[] validDurations =
{
"PT0S",
"P1Y",
"P1M",
"P1D",
"P2Y",
"P2M",
"P2D",
"PT1H",
"PT1M",
"PT1S",
"PT3600S",
"P1Y1M1DT1H1M1S",
"P1Y1M1DT1H1M1.1S",
"P1Y365D",
"P1Y366D",
"PT0.1S",
"P1Y-364D",
"P1Y-365D",
"P1Y-366D",
"P1Y-367D",
"P1Y-12M",
"P1M29D",
"P1M-27D",
"P1M-28D",
"P1M-29D",
"P1M-31D",
"P1M-32D",
"P1MT-660H",
"P1MT-670H",
"P1MT-680H",
"P1MT-690H",
"P1MT-700H",
"P1MT-710H",
"P1MT-720H",
"P1MT-730H",
"P1MT-740H",
"PT0.1415926S",
"PT5233132S",
"PT142332M",
"PT98023H",
"-PT0S",
"-P1Y",
"-P1M",
"-P1D",
"-PT1H",
"-PT1M",
"-PT1S",
"-P1Y1M1DT1H1M1S",
"-P1Y1M1DT1H1M1.1S",
"-P27D",
"-P28D",
"-P29D",
"-P30D",
"-P31D",
"-P364D",
"-P365D",
"-P366D",
"-PT0.1S",
"-PT0.1415926S",
"-PT5233132S",
"-PT142332M",
"-PT98023H",
};
static String[] invalidDates =
{
"+14:01", // tz
"-14:01", // tz
"+15:00", // tz
"-15:00", // tz
"X",
",",
"T",
"+",
"-",
":",
"0",
"March 2",
"T00:00:00Z", // T not allowed
"-00:00:00Z", // - not allowed
"96-02-28T00:00:00Z", // year width
"100-02-28T00:00:00Z", // year width
"1900-2-28T00:00:00Z", // month width
"1900-02-8T00:00:00Z", // day width
"1900-02-08T0:00:00Z", // hour width
"1900-02-08T00:0:00Z", // hour width
"1900-02-08T00:00:0Z", // hour width
"1900-02-08T00:00Z", // time incomplete
"1900-02-08 T00:00:00Z", // space
"1900-02-08T 00:00:00Z", // space
"1900-02-08T00:00:00 Z", // space
"1900-02-29T00Z", // time incomplete
"00:00", // time incomplete
"00", // incomplete
"2100-02-29", // not leap
"-9999999-02-28T00:00:00Z", // too long ago
"9999999-02-28T00:00:00Z", // too long from now
"9999999999999999999999999999999-02-28T00:00:00Z", // overflow?
"1996-00-28T00:00:00Z", // month
"1996-13-28T00:00:00Z", // month
"1996-02-00T00:00:00Z", // day
"2000-02-30T00:00:00Z", // day
"1996-02-29T24:00:00Z", // hr
"1996-02-29T00:60:00Z", // min
"1996-02-29T00:00:60Z", // sec
"1996-02-29T00:00:00+14:01", // tz
"1996-02-29T00:00:00-14:01", // tz
"1996-02-29T00:00:00+15:00", // tz
"1996-02-29T00:00:00-15:00", // tz
"1996-00-29", // month
"1996-13-29", // month
"1996-02-00", // day
"2000-02-30", // day
"--00", // month
"--13", // month
"--00-01", // month
"--13-01", // month
"--02-00", // day
"--02-30", // day
"--01-32", // day
"--11-31", // day
"---00", // day
"---32", // day
"24:00:00Z", // hr
"00:60:00Z", // min
"00:00:60Z", // sec
"00:00:00+14:01", // tz
"00:00:00-14:01", // tz
"00:00:00+15:00", // tz
"00:00:00-15:00", // tz
};
static String[] validDates =
{
"",
"Z", // timezone only
"-14:00", // timezone only
"999999-12-31T23:59:59.999Z",
"1970-12-31T23:59:59.990+14:00",
"1996-02-29T00:00:00Z", // leap
"2000-02-29T00:00:00Z", // leap
"2004-02-29T00:00:00Z", // leap
"2008-02-29T00:00:00Z", // leap
"2012-02-29T00:00:00Z", // leap
"1900-02-28T00:00:00Z", // not leap
"2100-02-28T00:00:00Z", // not leap
"1900-03-28T00:00:00Z", // not leap
"-4712-01-01T00:00:00Z",
"1999-01-01T00:00:00+01:00",
"2001-12-31T23:59:59.010",
"2001-12-31T23:59:59.999901000",
"1999-12-31T23:59:59.1234567890-14:00",
"1992-12-31T23:59:59.01-14:00",
"1965-12-31T23:59:59.000Z",
"0000-12-31T04:35:22.456",
"1696-09-01T00:00:00Z",
"1697-02-01T00:00:00Z",
"1903-03-01T00:00:00Z",
"1903-07-01T00:00:00Z",
"1696-09-01T00:00:00+00:00",
"1697-02-01T00:00:00-00:00",
"2002",
"-0001",
"--12",
"-0001-11",
"2002-01",
"---31",
"1554--31",
"-0004--31",
"--02-29",
"--12-31",
"2002-04-18",
"-0423-12-31",
"23:59:59",
"00:00:00",
"2010T23:59:59",
"-0001T00:00:00",
"--12T23:59:59",
"-0001-11T00:00:00",
"2011-01T23:59:59",
"---31T00:00:00",
"2002--31T23:59:59",
"-0004--31T00:00:00",
"2002-02-18T23:59:59",
"-0423-12-31T00:00:00",
"2002Z",
"-0001+01:30",
"--12-14:00",
"-0001-11Z",
"1970-12-01:00",
"---31+01:30",
"2002--31Z",
"--03-31-03:00",
"--04-30+05:00",
"-0004--31-01:00",
"2002-04-18-14:00",
"-0423-12-31Z",
"23:59:59-01:00",
"00:00:00Z",
"00:00:00+01:30",
"1776T23:59:59-14:00",
"-0001T00:00:00Z",
"--12T23:59:59+01:30",
"-0001-11T00:00:00-01:00",
"2002-02T23:59:59Z",
"---31T00:00:00-14:00",
"2002--31T23:59:59-01:00",
"-0004--31T00:00:00+01:30",
"2002-04-18T23:59:59Z",
"-0423-12-31T00:00:00-05:00",
};
private static boolean hasTime(GDuration gd)
{
return gd.getHour() != 0 || gd.getMinute() != 0 || gd.getSecond() != 0 || gd.getFraction().signum() != 0;
}
public static void testGregorianCalendar()
{
// this is a check of DST offsets
Date date = new GDate("2002-04-18T23:59:59Z").getDate();
GregorianCalendar gcal = new XmlCalendar(date);
Assert.assertEquals(date, gcal.getTime());
// now check out some things
GDate gd = new GDate("2001-12-31T07:00:59.010");
GregorianCalendar gc = gd.getCalendar();
Date gdd = gd.getDate();
Date gcd = gc.getTime();
Assert.assertEquals(gdd, gcd);
// set up 2/29, and read out Feb 29 in the year 1 BC.
Calendar gregcal = new GDate("--02-29").getCalendar();
Assert.assertEquals(29, gregcal.get(Calendar.DAY_OF_MONTH));
Assert.assertEquals(2 - 1, gregcal.get(Calendar.MONTH));
Assert.assertEquals(1, gregcal.get(Calendar.YEAR));
Assert.assertEquals(0, gregcal.get(Calendar.ERA));
// repeat some tests to make sure it's stable.
Assert.assertEquals(29, gregcal.get(Calendar.DAY_OF_MONTH));
Assert.assertEquals(2 - 1, gregcal.get(Calendar.MONTH));
// now try some setters
gregcal = new GDate("--02-29").getCalendar();
gregcal.set(Calendar.MONTH, 10);
Assert.assertEquals("--11-29", gregcal.toString());
// repeat to ensure it's stable.
Assert.assertEquals("--11-29", gregcal.toString());
}
public static void testValidDuration()
{
for (int i = 0; i < validDurations.length; i++)
{
GDuration gd = null;
String str = validDurations[i];
try
{
gd = new GDuration(str);
}
catch (IllegalArgumentException e)
{
Assert.assertTrue("Problem with " + str + ": " + e.getMessage(), false);
}
Assert.assertEquals(str, gd.toString());
for (int j = 0; j < validDurations.length; j++)
{
GDuration gd2 = null;
String str2 = validDurations[j];
try
{
gd2 = new GDuration(str2);
}
catch (IllegalArgumentException e)
{
Assert.assertTrue("Problem with " + str2 + ": " + e.getMessage(), false);
}
// subtracting two ways works
GDuration diff = gd.subtract(gd2);
GDurationBuilder gdb = new GDurationBuilder(gd2);
gdb.setSign(-gdb.getSign());
gdb.addGDuration(gd);
GDuration sum2 = gdb.toGDuration();
Assert.assertEquals(0, diff.compareToGDuration(sum2));
gdb.normalize();
GDurationBuilder gdb1 = new GDurationBuilder(diff);
gdb1.normalize();
Assert.assertEquals("Problem: " + gd + " and " + gd2, gdb.toString(), gdb1.toString());
// comparing is reversible
int comp1 = gd.compareToGDuration(gd2);
int comp2 = gd2.compareToGDuration(gd);
if (comp1 == 2)
Assert.assertEquals(2, comp2);
else
Assert.assertEquals(-comp1, comp2);
// comparing translates to addition to dates
boolean[] seen = new boolean[3];
for (int k = 0; k < validDates.length; k++)
{
GDate date = new GDate(validDates[k]);
if (!date.hasDate() || date.getYear() > 99999 || date.getYear() < -4000)
continue;
if ((hasTime(gd) || hasTime(gd2)) && !date.hasTime())
continue;
// System.out.println("Adding " + gd + " and " + gd2 + " to " + date + ", expecting " + comp1);
GDate date1 = date.add(gd);
GDate date2 = date.add(gd2);
comp2 = date1.compareToGDate(date2);
if (comp1 != 2)
{
Assert.assertEquals("Adding " + date + " + " + gd + " -> " + date1 + ", " + gd2 + " -> " + date2 + ", expecting " + comp1, comp1, comp2);
}
else
{
Assert.assertTrue(comp2 != 2);
seen[comp2 + 1] = true;
}
// subtraction should yeild the same result
if (comp1 != 2)
{
GDate date3 = date.add(diff);
Assert.assertEquals(comp1, date3.compareToGDate(date));
}
}
if (comp1 == 2)
{
int seencount = 0;
for (int k = 0; k < seen.length; k++)
if (seen[k])
seencount += 1;
Assert.assertTrue("Not ambiguous as advertised" /* + gd + ", " + gd2 + " d: " + diff */, seencount > 1);
}
}
}
}
public static void testOrder()
{
Assert.assertEquals(-1, new GDate("1998-08-26").compareToGDate(new GDate("2001-08-06")));
Assert.assertEquals(-1, new GDate("1970-12-20T04:14:22Z").compareToGDate(new GDate("1971-04-18T12:51:41Z")));
Assert.assertEquals(2, new GDate("2001-08-06").compareToGDate(new GDate("2001-08-06Z")));
Assert.assertEquals(2, new GDate("2001-08-06").compareToGDate(new GDate("2001-08-07+10:00")));
Assert.assertEquals(2, new GDate("2001-08-06").compareToGDate(new GDate("2001-08-05-10:00")));
Assert.assertEquals(2, new GDate("2001-02-28").compareToGDate(new GDate("2001-03-01+10:00")));
Assert.assertEquals(2, new GDate("2001-03-01").compareToGDate(new GDate("2001-02-28-10:00")));
Assert.assertEquals(-1, new GDate("2000-02-28").compareToGDate(new GDate("2000-03-01+10:00")));
Assert.assertEquals(1, new GDate("2000-03-01").compareToGDate(new GDate("2000-02-28-10:00")));
Assert.assertEquals(-1, new GDate("2001-08-06Z").compareToGDate(new GDate("2001-08-06-00:01")));
Assert.assertEquals(0, new GDate("00:00:00Z").compareToGDate(new GDate("00:01:00+00:01")));
Assert.assertEquals(0, new GDate("12:00:00-05:00").compareToGDate(new GDate("09:00:00-08:00")));
Assert.assertEquals(-1, new GDate("09:00:00-05:00").compareToGDate(new GDate("09:00:00-08:00"))); // the east coast rises before the west
Assert.assertEquals(-1, new GDate("2003-05-05T09:00:00-05:00").compareToGDate(new GDate("2003-05-05T09:00:00-08:00"))); // the east coast rises before the west
Assert.assertEquals(-1, new GDate("---01").compareToGDate(new GDate("---31")));
Assert.assertEquals(-1, new GDate("---01").compareToGDate(new GDate("---31+14:00")));
Assert.assertEquals(-1, new GDate("---01").compareToGDate(new GDate("---31-14:00")));
Assert.assertEquals(1, new GDate("---31").compareToGDate(new GDate("---01")));
Assert.assertEquals(1, new GDate("---31").compareToGDate(new GDate("---01+14:00")));
Assert.assertEquals(1, new GDate("---31").compareToGDate(new GDate("---01-14:00")));
Assert.assertEquals(-1, new GDate("---01").compareToGDate(new GDate("---02")));
Assert.assertEquals(1, new GDate("---02").compareToGDate(new GDate("---01")));
Assert.assertEquals(-1, new GDate("---01").compareToGDate(new GDate("---02Z")));
Assert.assertEquals(1, new GDate("---02").compareToGDate(new GDate("---01Z")));
Assert.assertEquals(2, new GDate("---02").compareToGDate(new GDate("---01-10:00")));
Assert.assertEquals(2, new GDate("---01").compareToGDate(new GDate("---02+10:00")));
Assert.assertEquals(1, new GDate("---02").compareToGDate(new GDate("---01-09:00")));
Assert.assertEquals(-1, new GDate("---01").compareToGDate(new GDate("---02+09:00")));
Assert.assertEquals(0, new GDate("---01").compareToGDate(new GDate("---01")));
Assert.assertEquals(-1, new GDate("2003").compareToGDate(new GDate("2004")));
Assert.assertEquals(-1, new GDate("--11").compareToGDate(new GDate("--12")));
Assert.assertEquals(-1, new GDate("2003-12").compareToGDate(new GDate("2004-01")));
Assert.assertEquals(-1, new GDate("--11-30").compareToGDate(new GDate("--12-01")));
Assert.assertEquals(-1, new GDate("--02-28").compareToGDate(new GDate("--02-29")));
Assert.assertEquals(-1, new GDate("--02-29").compareToGDate(new GDate("--03-01")));
Assert.assertEquals(2, new GDate("--02-29").compareToGDate(new GDate("--03-01+10:00")));
Assert.assertEquals(2, new GDate("--02-28").compareToGDate(new GDate("--03-01+10:00")));
Assert.assertEquals(2, new GDate("--03-01").compareToGDate(new GDate("--02-28-10:00")));
Assert.assertEquals(2, new GDate("--03-01").compareToGDate(new GDate("--02-29-10:00")));
Assert.assertEquals(-1, new GDate("--02-29").compareToGDate(new GDate("--03-01+09:00")));
Assert.assertEquals(-1, new GDate("--02-28").compareToGDate(new GDate("--03-01+09:00")));
Assert.assertEquals(1, new GDate("--03-01").compareToGDate(new GDate("--02-28-09:00")));
Assert.assertEquals(1, new GDate("--03-01").compareToGDate(new GDate("--02-29-09:00")));
Assert.assertEquals(-1, new GDate("00:00:00").compareToGDate(new GDate("23:59:59")));
Assert.assertEquals(-1, new GDate("00:00:00").compareToGDate(new GDate("23:59:59+09:59")));
Assert.assertEquals(-1, new GDate("00:00:00").compareToGDate(new GDate("23:59:01+09:59")));
Assert.assertEquals(2, new GDate("00:00:00").compareToGDate(new GDate("23:59:00+09:59")));
Assert.assertEquals(2, new GDate("00:00:00").compareToGDate(new GDate("23:59:59+10:00")));
Assert.assertEquals(-1, new GDate("00:00:00").compareToGDate(new GDate("23:59:59-14:00")));
Assert.assertEquals(1, new GDate("23:59:59").compareToGDate(new GDate("00:00:00-09:59")));
Assert.assertEquals(1, new GDate("23:59:59").compareToGDate(new GDate("00:00:58-09:59")));
Assert.assertEquals(2, new GDate("23:59:59").compareToGDate(new GDate("00:00:59-09:59")));
Assert.assertEquals(2, new GDate("23:59:59").compareToGDate(new GDate("00:00:00-10:00")));
Assert.assertEquals(1, new GDate("23:59:59").compareToGDate(new GDate("00:00:00+14:00")));
}
public static void testAPI() throws Exception
{
GDateBuilder builder = new GDateBuilder("1970-12-20T04:14:22Z");
builder.normalizeToTimeZone(1, 0, 0);
Assert.assertEquals("1970-12-20T04:14:22+00:00", builder.toString());
builder.setTimeZone(615);
Assert.assertEquals("1970-12-20T04:14:22+10:15", builder.toString());
builder.setTimeZone(-345);
Assert.assertEquals("1970-12-20T04:14:22-05:45", builder.toString());
builder.normalizeToTimeZone(-300);
Assert.assertEquals("1970-12-20T04:59:22-05:00", builder.toString());
}
public static void testFailure() throws Exception
{
for (int i = 0; i < invalidDates.length; i++)
{
String str = invalidDates[i];
try
{
new GDate(str);
}
catch (IllegalArgumentException e)
{
continue;
}
Assert.assertTrue("Missing exception for GDate " + str, false);
}
}
public static void testSuccess() throws Exception
{
for (int i = 0; i < validDates.length; i++)
{
String str = validDates[i];
GDate gdate = null;
try
{
gdate = new GDate(str);
}
catch (IllegalArgumentException e)
{
Assert.assertTrue("Problem with " + str + ": " + e.getMessage(), false);
}
// must round-trip to string
Assert.assertEquals(str, gdate.toString());
// must round-trip to GregorianCalendar if fractions-of-seconds <=3 digits
if (gdate.getFraction() == null || gdate.getFraction().scale() <= 3)
if (!gdate.toString().equals("--02-29")) // bug in gcal -> 03-01
{
GregorianCalendar gcal = gdate.getCalendar();
GDate gdate2 = new GDate(gcal);
Assert.assertEquals(gdate, gdate2);
// and if fractions-of-seconds is 3 digits, stringrep must round-trip
if (gdate.getFraction() == null || gdate.getFraction().scale() == 3 || gdate.getFraction().scale() == 0)
Assert.assertEquals(gdate.toString(), gdate2.toString());
}
// must round-trip to Date if absolute time+timezone + fractions-of-seconds <= 3
if (gdate.hasTimeZone() && gdate.getYear() > -4000 && gdate.getYear() < 99999 && gdate.getBuiltinTypeCode() == SchemaType.BTC_DATE_TIME && gdate.getFraction().scale() <= 3)
{
Date date = gdate.getDate();
GDate gdate2 = new GDate(date);
Assert.assertEquals(gdate, gdate2);
// normalize to UTC fractions-of-seconds is 0 or 3 digits [not 000], stringrep must round-trip
if (gdate.getTimeZoneSign() == 0 && ((gdate.getFraction().scale() == 3 && gdate.getFraction().signum() != 0) || gdate.getFraction().scale() == 0))
{
GDateBuilder gdb = new GDateBuilder(gdate2);
gdb.normalizeToTimeZone(0, 0, 0);
Assert.assertEquals(gdate.toString(), gdb.toString());
}
// verify that going through gcal gives us the same thing
GregorianCalendar gcal = gdate.getCalendar();
Assert.assertEquals(date, gcal.getTime());
// double-check XmlCalendar constructor
gcal = new XmlCalendar(date);
Assert.assertEquals("Doing " + gdate, date, gcal.getTime());
}
else if (gdate.hasDate() && (gdate.getFraction() == null || gdate.getFraction().scale() <= 3))
{
// must be able to get a date if time+timezone is unset (midnight, ltz are assumed)
Date date = gdate.getDate();
GDateBuilder gdate1 = new GDateBuilder(gdate);
if (!gdate1.hasTime())
gdate1.setTime(0, 0, 0, null);
Assert.assertEquals(gdate1.getDate(), date);
// verify that going through gcal gives us the same thing
GregorianCalendar gcal = gdate.getCalendar();
Assert.assertEquals("Comparing " + gdate + " and " + gcal, date, gcal.getTime());
}
}
}
}