Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将Excel中表示日期的数字转换为Java日期对象_Java_Excel - Fatal编程技术网

将Excel中表示日期的数字转换为Java日期对象

将Excel中表示日期的数字转换为Java日期对象,java,excel,Java,Excel,我在Excel中有一个日期列,但当我在Java应用程序中读取它时,我得到的值是数字 范例 Excel日期 1/1/2013 我得到的是 41275.00 如何在我的Java应用程序中将数字转换为日期?Apache POI有一些实用程序,尤其是 注:Excel将日期存储为自1900年以来的天数(加上小数天)(在某些情况下,日期可以从1904年开始)。请参阅。以下是一个如何将Excel日期转换为Java日期的简单示例: Date javaDate= DateUtil.getJav

我在Excel中有一个日期列,但当我在Java应用程序中读取它时,我得到的值是数字

范例

Excel日期

1/1/2013
我得到的是

41275.00

如何在我的Java应用程序中将数字转换为日期?

Apache POI有一些实用程序,尤其是


注:Excel将日期存储为自1900年以来的天数(加上小数天)(在某些情况下,日期可以从1904年开始)。请参阅。

以下是一个如何将Excel日期转换为Java日期的简单示例:

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

01/01/2013
您还需要导入以下软件包:

java.text.SimpleDateFormat
java.util.Date

Excel的序列化日期是自1900年1月1日起的天数。为了再次计算出日期,我们必须添加相当于天的序列号

对于Java 8,没有任何依赖关系

```

```

tl;博士 使用现代java.time类

2013-01-01

java.time 现代解决方案使用java.time类取代了与最早版本的java捆绑在一起的糟糕的遗留日期时间类

纪元参考日期:1899-12-30 根据,该值from是自1900-01-01年开始的天数。内部,实际参考日期为1899年12月30日,如上所述

注意,Excel的某些版本(macOS的旧版本?)

在代码中的某个地方建立epoch引用

final static public LocalDate EXCEL_EPOCH_REFERENCE = 
    LocalDate.of( 1899 , Month.DECEMBER , 30 )
; // Beware: Some versions of Excel use a 1904 epoch reference.
算算 将输入字符串解析为
BigDecimal
,以获得准确度(与牺牲准确度以加快执行速度的浮点类型相比)

将整个天数添加到历元参考日期

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


关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,&

要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是

该项目现已启动,建议迁移到类

您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
类。Hibernate5和JPA2.2支持java.time

从哪里获得java.time类

  • 、和更高版本-标准Java API的一部分,带有捆绑实现。
    • 带来了一些小功能和修复
    • 大多数java.time功能都在中向后移植到Java6和Java7
    • Android(26+)的更高版本捆绑了java.time类的实现

    • 对于早期的Android(正如许多用户已经指出的,Excel将日期和时间存储为一个数字,表示从那时起的天数,加上24小时工作日的小数部分:
      ddddd.tttttttt

      这称为序列日期或序列日期时间

      但这里的答案只代表了故事的一部分——除了指出现有库中的现成方法之外。

      来自Microsoft的链接文档并没有使其更加清晰。

      MS表示:

      Excel将日期存储为连续序列号,以便在计算中使用。 默认情况下,1900年1月1日是序列号1,2008年1月1日是序列号39448,因为它是1900年1月1日之后的39447天

      好吧,我要检查一下这个声明:

      LocalDate testDate = LocalDate.of(1900, Month.JANUARY, 1).plusDays(39447);
      System.out.println(testDate);// prints 2008-01-02
      
      1900年1月1日之后的39447天确实是……2008年1月2日

      这是为什么?

      Excel中的日期由一个纪元(1899年12月30日或1900年1月1日或1904年1月1日…)开始的天数表示,这只是故事的一部分

      我在这里找到了一个最终的答案:(某个上帝或任何可能保佑这些家伙的人)

      在Excel中实现日期例程的开发人员故意引入了一个bug,以便与来自的同一已知问题兼容

      他们将1900年视为闰年,但不是, 因此,任何超过1900年1月28日的日期都比实际日期多一天。

      这就是为什么Excel认为2008年1月1日用数字39448表示:因为1900年1月0日之后是39448个单位(是的,Excel认为零)——即39447天加1900年1月29日

      Excel还可以将序列日期的日期部分视为自1904年1月0日起的天数;此模式称为1904模式或1904系统,用于与Macintosh系统兼容

      因为Excel日期不携带任何时区信息——它只是一个数字——所以最好使用Java类,如/来表示没有时区信息的值

      实际上,对于现在的日期,人们可能认为从1900年12月30日开始是一个新纪元,但事实并非如此


      Excel演示版-日期格式为dd/mm/yyyy


      日期作为左边的数字插入


      适合所需转换的类别:

      public class SerialDate {
      
          //days from 1899-12-31 to Instant.EPOCH (1970-01-01T00:00:00Z)
          public static final long EPOCH = -25568L;
          private long serialDays;
          private double serialTime;
          private long epochDays;
          private long daySeconds;
      
          /**
           * @param date number of Excel-days since <i>January 0, 1899</i>
           */
          public SerialDate(long date) {
              serialDays = date;
              if (date > 59)//Lotus123 bug
                  --date;
              epochDays = EPOCH + date;
          }
                  
          /**
           * @param date number of days since <i>January 0, 1899</i> with a time fraction
           */
          public SerialDate(double date) {
              this((long)date);
              serialTime = date - serialDays;
              daySeconds = Math.round(serialTime * 24 * 60 * 60);
          }
                  
          /**
           * @return days since 1970-01-01
           */
          public long toEpochDays() {
              return epochDays;
          }
                  
          /**
           * @return seconds of the day for this SerialDate
           */
          public long toDaySeconds() {
              return daySeconds;
          }
                  
          /**
           * @return a value suitable for an Excel date
           */
          public double getSerialDate() {
              return serialTime + serialDays;
          }
          
      }
      


      如何阅读它?@SotiriosDelimanolis使用apache.poi.FYI,非常麻烦的旧日期时间类,如和
      java.text.simpleDataFormat
      ,现在被java 8和更高版本中内置的类所取代。请参阅。
      long days = countFromEpoch.longValue();  // Extract the number of whole days, dropping the fraction.
      LocalDate localDate = EXCEL_EPOCH_REFERENCE.plusDays( days );
      
      LocalDate testDate = LocalDate.of(1900, Month.JANUARY, 1).plusDays(39447);
      System.out.println(testDate);// prints 2008-01-02
      
      public class SerialDate {
      
          //days from 1899-12-31 to Instant.EPOCH (1970-01-01T00:00:00Z)
          public static final long EPOCH = -25568L;
          private long serialDays;
          private double serialTime;
          private long epochDays;
          private long daySeconds;
      
          /**
           * @param date number of Excel-days since <i>January 0, 1899</i>
           */
          public SerialDate(long date) {
              serialDays = date;
              if (date > 59)//Lotus123 bug
                  --date;
              epochDays = EPOCH + date;
          }
                  
          /**
           * @param date number of days since <i>January 0, 1899</i> with a time fraction
           */
          public SerialDate(double date) {
              this((long)date);
              serialTime = date - serialDays;
              daySeconds = Math.round(serialTime * 24 * 60 * 60);
          }
                  
          /**
           * @return days since 1970-01-01
           */
          public long toEpochDays() {
              return epochDays;
          }
                  
          /**
           * @return seconds of the day for this SerialDate
           */
          public long toDaySeconds() {
              return daySeconds;
          }
                  
          /**
           * @return a value suitable for an Excel date
           */
          public double getSerialDate() {
              return serialTime + serialDays;
          }
          
      }
      
      LocalDate dt = LocalDate.ofEpochDay(new SerialDate(41275).toEpochDays());
      System.out.println(dt);//prints 2013-01-01
      
      SerialDate sd = new SerialDate(33257.415972222225);
      LocalDateTime dt = LocalDateTime.of(
              LocalDate.ofEpochDay(sd.toEpochDays()),
              LocalTime.ofSecondOfDay(sd.toDaySeconds()));
      System.out.println(dt);//prints 1991-01-19T09:59