You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xmlbeans.apache.org by ce...@apache.org on 2009/06/10 23:05:24 UTC
svn commit: r783519 - in /xmlbeans/trunk:
src/xmlpublic/org/apache/xmlbeans/GDate.java
src/xmlpublic/org/apache/xmlbeans/GDateBuilder.java
test/src/xmlobject/schematypes/checkin/GDateTests.java
Author: cezar
Date: Wed Jun 10 21:05:24 2009
New Revision: 783519
URL: http://svn.apache.org/viewvc?rev=783519&view=rev
Log:
Fix normalization of dates with hour 24.
Extended the year limitations or dates.
Added date tests
Modified:
xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/GDate.java
xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/GDateBuilder.java
xmlbeans/trunk/test/src/xmlobject/schematypes/checkin/GDateTests.java
Modified: xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/GDate.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/GDate.java?rev=783519&r1=783518&r2=783519&view=diff
==============================================================================
--- xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/GDate.java (original)
+++ xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/GDate.java Wed Jun 10 21:05:24 2009
@@ -40,7 +40,12 @@
public final class GDate implements GDateSpecification, java.io.Serializable
{
private static final long serialVersionUID = 1L;
-
+
+ // XMLSchema spec requires support only for years 1 to 9999, but XMLBeans covers more up to the following limitations
+ // to avoid losing precision when transforming to a java.util.Date
+ static final int MAX_YEAR = 292277265; // is Long.MAX_VALUE ms in years - 1 (for the 11month, 31days, 23h, 59m, 59sec case).
+ static final int MIN_YEAR = -292275295; // is Long.MIN_VALUE ms in years + 1970 + 1
+
// for fast equality comparison, hashing, and serialization
private transient String _canonicalString;
private transient String _string;
@@ -143,8 +148,8 @@
start += 1;
}
digits += start;
- if (digits > 6)
- throw new IllegalArgumentException("year too long (up to 6 digits)");
+ if (digits > 9)
+ throw new IllegalArgumentException("year too long (up to 9 digits)");
else if (digits >= 4)
{
_bits |= HAS_YEAR;
@@ -154,6 +159,12 @@
else if (digits > 0)
throw new IllegalArgumentException("year must be four digits (may pad with zeroes, e.g., 0560)");
+ /*if ( _CY > MAX_YEAR )
+ throw new IllegalArgumentException("year must be less than " + MAX_YEAR);
+
+ if ( _CY < MIN_YEAR )
+ throw new IllegalArgumentException("year must be bigger than " + MIN_YEAR);
+ */
// hyphen introduces a month
if (ch != '-')
{
@@ -279,8 +290,7 @@
if ( hasDate() )
{
GDateBuilder gdb = new GDateBuilder(_CY, _M, _D, _h, _m, _s, _fs, _tzsign, _tzh, _tzm);
- gdb.normalize();
- gdb.normalizeToTimeZone(_tzsign, _tzh, _tzm);
+ gdb.normalize24h();
_D = gdb.getDay();
_M = gdb.getMonth();
Modified: xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/GDateBuilder.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/GDateBuilder.java?rev=783519&r1=783518&r2=783519&view=diff
==============================================================================
--- xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/GDateBuilder.java (original)
+++ xmlbeans/trunk/src/xmlpublic/org/apache/xmlbeans/GDateBuilder.java Wed Jun 10 21:05:24 2009
@@ -374,13 +374,15 @@
public final int getTimeZoneMinute()
{ return _tzm; }
+
+
/**
* Sets the year. Should be a four-digit year specification.
* @param year the year
*/
public void setYear(int year)
{
- if (year < -4713 || year > 999999)
+ if (year < GDate.MIN_YEAR || year > GDate.MAX_YEAR)
throw new IllegalArgumentException("year out of range");
if (year == 0)
throw new IllegalArgumentException("year cannot be 0");
@@ -602,37 +604,14 @@
// DateTime or Time, with TimeZone: normalize to UTC.
// In the process all the fields will be normalized.
if (hasDay() == hasMonth() && hasDay() == hasYear() &&
- hasTimeZone() && hasTime() && getHour()!=24 )
+ hasTimeZone() && hasTime() )
{
normalizeToTimeZone(0, 0, 0);
}
else
{
// No timezone, or incomplete date.
- long carry = 0;
-
- if (hasTime())
- carry = _normalizeTime();
-
- if (hasDay())
- _D += carry;
-
- if (hasDate())
- {
- _normalizeDate();
- }
- else if (hasMonth())
- {
- // with incomplete dates, just months can be normalized:
- // days stay denormalized.
- if (_M < 1 || _M > 12)
- {
- int temp = _M;
- _M = _modulo(temp, 1, 13);
- if (hasYear())
- _CY = _CY + (int)_fQuotient(temp, 1, 13);
- }
- }
+ _normalizeTimeAndDate();
}
// remove trailing zeros from fractional seconds
@@ -654,6 +633,46 @@
}
}
+ /**
+ * Normalizes the instance when hour is 24. If day is present, hour 24 is equivalent to hour 00 next day.
+ */
+ void normalize24h()
+ {
+ if ( !hasTime() || getHour()!=24 )
+ return;
+
+ _normalizeTimeAndDate();
+ }
+
+
+ private void _normalizeTimeAndDate()
+ {
+ long carry = 0;
+
+ if (hasTime())
+ carry = _normalizeTime();
+
+ if (hasDay())
+ _D += carry;
+
+ if (hasDate())
+ {
+ _normalizeDate();
+ }
+ else if (hasMonth())
+ {
+ // with incomplete dates, just months can be normalized:
+ // days stay denormalized.
+ if (_M < 1 || _M > 12)
+ {
+ int temp = _M;
+ _M = _modulo(temp, 1, 13);
+ if (hasYear())
+ _CY = _CY + (int)_fQuotient(temp, 1, 13);
+ }
+ }
+ }
+
/**
* If the time and timezone are known, this method changes the timezone to the
* specified UTC offset, altering minutes, hours, day, month, and year as
Modified: xmlbeans/trunk/test/src/xmlobject/schematypes/checkin/GDateTests.java
URL: http://svn.apache.org/viewvc/xmlbeans/trunk/test/src/xmlobject/schematypes/checkin/GDateTests.java?rev=783519&r1=783518&r2=783519&view=diff
==============================================================================
--- xmlbeans/trunk/test/src/xmlobject/schematypes/checkin/GDateTests.java (original)
+++ xmlbeans/trunk/test/src/xmlobject/schematypes/checkin/GDateTests.java Wed Jun 10 21:05:24 2009
@@ -29,6 +29,7 @@
import java.util.GregorianCalendar;
import java.util.Date;
import java.util.Calendar;
+import java.math.BigDecimal;
public class GDateTests extends TestCase
{
@@ -134,8 +135,8 @@
"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
+ "-999999999-02-28T00:00:00Z", // too long ago
+ "999999999-02-28T00:00:00Z", // too long from now
"9999999999999999999999999999999-02-28T00:00:00Z", // overflow?
"0000-01-01", // year zero
"0000-12-31T04:35:22.456", // year zero
@@ -635,4 +636,89 @@
}
}
}
+
+ public void test24hDates()
+ {
+ GDate d1 = new GDate("2004-03-31T24:00:00");
+ Assert.assertEquals("2004-04-01T00:00:00", d1.toString());
+
+
+ GDateBuilder b = new GDateBuilder();
+ b.setTime(24, 0, 0, new BigDecimal("0.00"));
+ System.out.println("hour 24: " + b.getCalendar());
+ Assert.assertEquals("24:00:00.000", b.getCalendar().toString());
+
+ b.setDay(10);
+ b.setMonth(1);
+ System.out.println("hour 24: " + b.getCalendar());
+ Assert.assertEquals("--01-10T24:00:00.000", b.getCalendar().toString());
+
+ b.setYear(2010);
+ System.out.println("hour 24: " + b.getCalendar());
+ Assert.assertEquals("2010-01-10T24:00:00.000", b.getCalendar().toString());
+
+ b.setDay(31);
+ b.setMonth(03);
+ b.setYear(2004);
+
+ System.out.println("hour 24: canonical str: " + b.canonicalString());
+ Assert.assertEquals("2004-04-01T00:00:00", b.canonicalString());
+ System.out.println("hour 24: toString: " + b.toString());
+ Assert.assertEquals("2004-03-31T24:00:00.00", b.toString());
+ System.out.println("hour 24: toGDate: " + b.toGDate());
+ Assert.assertEquals("2004-03-31T24:00:00.00", b.toGDate().toString());
+ System.out.println("hour 24: toGDate().canonicalStr: " + b.toGDate().canonicalString());
+ Assert.assertEquals("2004-04-01T00:00:00", b.toGDate().canonicalString());
+ System.out.println("hour 24: toGDate().getCal: " + b.toGDate().getCalendar());
+ Assert.assertEquals("2004-03-31T24:00:00.000", b.toGDate().getCalendar().toString());
+
+
+ GDateBuilder gdb = new GDateBuilder("24:00:00+01:00");
+ System.out.println("gdb: " + gdb);
+ Assert.assertEquals("24:00:00+01:00", gdb.toString());
+
+ gdb.normalize();
+ System.out.println("gdb.normalize(): " + gdb);
+ Assert.assertEquals("23:00:00Z", gdb.toString());
+ }
+
+ public void testYearStartingWith0()
+ {
+ GDate gdate = new GDate("0004-08-01"); // 00004-08-01 must fail
+ System.out.println("year starting with 0: " + gdate.getCalendar());
+ Assert.assertEquals("0004-08-01", gdate.toString());
+
+ String txt = "-9999-06";
+ GDate d = new GDate(txt);
+ System.out.println(" gdate(" + txt + ") = " + d);
+ Assert.assertEquals("-9999-06", d.toString());
+
+ txt = "-12345-06";
+ d = new GDate(txt);
+ System.out.println(" gdate(" + txt + ") = " + d);
+ Assert.assertEquals(txt, d.toString());
+
+
+ try
+ {
+ txt = "00004-08-01";
+ d = new GDate(txt); // 00004-08-01 must fail
+ Assert.assertTrue("Year starting with 0 of five digits: " + txt, false);
+ }
+ catch(IllegalArgumentException e)
+ {
+ Assert.assertTrue("Year starting with 0 of five digits: " + txt, true);
+ }
+
+ try
+ {
+ txt = "-012340-08-01";
+ d = new GDate(txt);
+ Assert.assertTrue("Year starting with 0 of six digits: " + txt, false);
+ }
+ catch(IllegalArgumentException e)
+ {
+ Assert.assertTrue("Year starting with 0 of six digits: " + txt, true);
+ }
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@xmlbeans.apache.org
For additional commands, e-mail: commits-help@xmlbeans.apache.org