poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From n...@apache.org
Subject svn commit: r579194 - in /poi/trunk/src: java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java
Date Tue, 25 Sep 2007 10:52:31 GMT
Author: nick
Date: Tue Sep 25 03:52:30 2007
New Revision: 579194

URL: http://svn.apache.org/viewvc?rev=579194&view=rev
Log:
Fix from Pavel Krupets for Excel Bug Date (1900/2/29)

Modified:
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java
    poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java?rev=579194&r1=579193&r2=579194&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFDateUtil.java Tue Sep 25 03:52:30
2007
@@ -43,13 +43,10 @@
     {
     }
 
-    private static final int    BAD_DATE          =
+    private static final int    BAD_DATE         =
         -1;   // used to specify that date is invalid
-    private static final long   DAY_MILLISECONDS  = 24 * 60 * 60 * 1000;
-    private static final double CAL_1900_ABSOLUTE =
-        ( double ) absoluteDay(new GregorianCalendar(1900, Calendar
-        .JANUARY, 1)) - 2.0;
-
+    private static final long   DAY_MILLISECONDS = 24 * 60 * 60 * 1000;
+    
     /**
      * Given a Date, converts it into a double representing its internal Excel representation,
      *   which is the number of days since 1/1/1900. Fractional days represent hours, minutes,
and seconds.
@@ -84,8 +81,13 @@
                               ) / ( double ) DAY_MILLISECONDS;
             calStart = dayStart(calStart);
 
-            return fraction + ( double ) absoluteDay(calStart)
-                   - CAL_1900_ABSOLUTE;
+            double value = fraction + absoluteDay(calStart);
+            
+            if (value >= 60) {
+                value += 1;
+            }
+            
+            return value;
         }
     }
 
@@ -287,9 +289,9 @@
     }
 
     /**
-     * Given a Calendar, return the number of days since 1600/12/31.
+     * Given a Calendar, return the number of days since 1900/12/31.
      *
-     * @return days number of days since 1600/12/31
+     * @return days number of days since 1900/12/31
      * @param  cal the Calendar
      * @exception IllegalArgumentException if date is invalid
      */
@@ -301,29 +303,29 @@
     }
 
     /**
-     * Return the number of days in prior years since 1601
+     * Return the number of days in prior years since 1900
      *
      * @return    days  number of days in years prior to yr.
-     * @param     yr    a year (1600 < yr < 4000)
+     * @param     yr    a year (1900 < yr < 4000)
      * @exception IllegalArgumentException if year is outside of range.
      */
 
     private static int daysInPriorYears(int yr)
     {
-        if (yr < 1601)
-        {
+        if (yr < 1900) {
             throw new IllegalArgumentException(
-                "'year' must be 1601 or greater");
+                "'year' must be 1900 or greater");
         }
-        int y    = yr - 1601;
-        int days = 365 * y      // days in prior years
-                   + y / 4      // plus julian leap days in prior years
-                   - y / 100    // minus prior century years
-                   + y / 400;   // plus years divisible by 400
-
-        return days;
+        
+        int yr1  = yr - 1;
+        int leapDays =   yr1 / 4   // plus julian leap days in prior years
+                       - yr1 / 100 // minus prior century years
+                       + yr1 / 400 // plus years divisible by 400 
+                       - 460;      // leap days in previous 1900 years
+        
+        return 365 * (yr - 1900) + leapDays;
     }
-
+    
     // set HH:MM:SS fields of cal to 00:00:00:000
     private static Calendar dayStart(final Calendar cal)
     {

Modified: poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java?rev=579194&r1=579193&r2=579194&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFDateUtil.java Tue Sep 25
03:52:30 2007
@@ -42,6 +42,12 @@
 public class TestHSSFDateUtil
         extends TestCase
 {
+
+	public static final int CALENDAR_JANUARY = 0;
+	public static final int CALENDAR_FEBRUARY = 0;
+	public static final int CALENDAR_MARCH = 0;
+	public static final int CALENDAR_APRIL = 0;
+
     public TestHSSFDateUtil(String s)
     {
         super(s);
@@ -308,9 +314,37 @@
         assertTrue(HSSFDateUtil.isCellDateFormatted(cell));
     }
     
+    public void testDateBug_2Excel() {
+        assertEquals(59.0, HSSFDateUtil.getExcelDate(createDate(1900, CALENDAR_FEBRUARY,
28)), 0.00001);
+        assertEquals(61.0, HSSFDateUtil.getExcelDate(createDate(1900, CALENDAR_MARCH, 1)),
0.00001);
+        
+        assertEquals(37315.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_FEBRUARY,
28)), 0.00001);
+        assertEquals(37316.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_MARCH,
1)), 0.00001);
+        assertEquals(37257.00, HSSFDateUtil.getExcelDate(createDate(2002, CALENDAR_JANUARY,
1)), 0.00001);
+        assertEquals(38074.00, HSSFDateUtil.getExcelDate(createDate(2004, CALENDAR_MARCH,
28)), 0.00001);
+    }
+    
+    public void testDateBug_2Java() {
+        assertEquals(createDate(1900, Calendar.FEBRUARY, 28), HSSFDateUtil.getJavaDate(59.0));
+        assertEquals(createDate(1900, Calendar.MARCH, 1), HSSFDateUtil.getJavaDate(61.0));
+        
+        assertEquals(createDate(2002, Calendar.FEBRUARY, 28), HSSFDateUtil.getJavaDate(37315.00));
+        assertEquals(createDate(2002, Calendar.MARCH, 1), HSSFDateUtil.getJavaDate(37316.00));
+        assertEquals(createDate(2002, Calendar.JANUARY, 1), HSSFDateUtil.getJavaDate(37257.00));
+        assertEquals(createDate(2004, Calendar.MARCH, 28), HSSFDateUtil.getJavaDate(38074.00));
+    }
+
+    private Date createDate(int year, int month, int day) {
+        Calendar c = new GregorianCalendar();
+        c.set(year, month, day, 0, 0, 0);
+        c.set(Calendar.MILLISECOND, 0);
+        return c.getTime();
+    }
+    
     public static void main(String [] args) {
         System.out
                 .println("Testing org.apache.poi.hssf.usermodel.TestHSSFDateUtil");
         junit.textui.TestRunner.run(TestHSSFDateUtil.class);
     }
 }
+



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org


Mime
View raw message