Converting Number representation of Date in excel to Date in java

前端 未结 4 494
暖寄归人
暖寄归人 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: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….

提交回复
热议问题