Converting Number representation of Date in excel to Date in java

前端 未结 4 492
暖寄归人
暖寄归人 2020-11-30 10:05

I have date column in excel, but when I\'m reading in my java application I\'m getting value as number

Example

Excel Date

1/1/2013

相关标签:
4条回答
  • 2020-11-30 10:39

    Apache POI has some utilities for that http://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/DateUtil.html, notably http://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/DateUtil.html#getJavaDate(double)

    Note Excel stores dates as the number of days (plus fractional days) since 1900 (and in some cases it can be from 1904). See http://support.microsoft.com/kb/180162.

    0 讨论(0)
  • 2020-11-30 10:40

    tl;dr

    Use modern java.time classes.

    LocalDate                                    // Represent a date-only vaule, without time-of-day and without time zone.
    .of( 1899 , Month.DECEMBER , 30 )            // Specify epoch reference date used by *some* versions of Excel. Beware: Some versions use a 1904 epoch reference. Returns a `LocalDate` object.
    .plusDays(                                   // Add a number of days. 
        (long) Double.parseDouble( "41275.00" )  // Get a number of whole days from your input string.
    )                                            // Returns another instance of a `LocalDate`, per Immutable Objects pattern, rather than altering the original.        
    .toString()                                  // Generate text representing the value of this `LocalDate` in standard ISO 8601 format.
    

    2013-01-01

    java.time

    The modern solution uses the java.time classes that supplanted the terrible legacy date-time classes bundled with the earliest versions of Java.

    Epoch reference date: 1899-12-30

    According to this documentation, that value from Microsoft Excel is the number of days since the epoch reference of 1900-01-01 in UTC. Internally, the actual reference date is December 30, 1899 as documented on this Wikipedia page.

    Beware, some versions (old versions for macOS?) of Excel use a different epoch in 1904.

    Establish the epoch reference somewhere in your code.

    final static public LocalDate EXCEL_EPOCH_REFERENCE = 
        LocalDate.of( 1899 , Month.DECEMBER , 30 )
    ; // Beware: Some versions of Excel use a 1904 epoch reference.
    

    Do the math

    Parse your input string as a BigDecimal for accuracy (versus floating-point types that trade away accuracy for faster execution).

    BigDecimal countFromEpoch = new BigDecimal( "41275.00" );
    

    Add the number of whole days to the epoch reference date.

    long days = countFromEpoch.longValue();  // Extract the number of whole days, dropping the fraction.
    LocalDate localDate = EXCEL_EPOCH_REFERENCE.plusDays( days );
    

    localDate.toString(): 2013-01-01


    About java.time

    The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

    To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

    The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

    You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes. Hibernate 5 & JPA 2.2 support java.time.

    Where to obtain the java.time classes?

    • Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
      • Java 9 brought some minor features and fixes.
    • Java SE 6 and Java SE 7
      • Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
    • Android
      • Later versions of Android (26+) bundle implementations of the java.time classes.
      • For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
        • If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
    0 讨论(0)
  • 2020-11-30 10:45

    Excel’s serialized dates are the number of days since 1/1/1900. In order to figure out the date again, we have to add the serial number worth of days.

    for Java 8 without any dependency

    ```

      /*
    
        1900-1-0            0
        1900-1-1            1
        1900-1-2            2
        1900-1-3            3
    
    
         */
    
    
        int days = 43323;
        LocalDate start = LocalDate.of(1900, 1, 1);
        LocalDate today = LocalDate.of(2018, 8, 11);
    
    
        // days to date
        LocalDate date = start.plusDays(days).minusDays(2);
    
        System.out.println(date);
    
        // date to days
        long days1 = ChronoUnit.DAYS.between(start, today) + 2;
        System.out.println(days1);
    

    ```

    0 讨论(0)
  • 2020-11-30 10:51

    Here is a minimal working example how to convert an Excel date to a Java date:

            Date javaDate= DateUtil.getJavaDate((double) 41275.00);
            System.out.println(new SimpleDateFormat("MM/dd/yyyy").format(javaDate));
    

    which returns

    01/01/2013
    

    You also need to import the following packages:

    java.text.SimpleDateFormat
    java.util.Date
    
    0 讨论(0)
提交回复
热议问题