将Excel中表示日期的数字转换为Java日期对象
我在Excel中有一个日期列,但当我在Java应用程序中读取它时,我得到的值是数字 范例 Excel日期将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
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天 好吧,我要检查一下这个声明:
1900年1月1日之后的39447天确实是……2008年1月2日 这是为什么? Excel中的日期由一个纪元(1899年12月30日或1900年1月1日或1904年1月1日…)开始的天数表示,这只是故事的一部分 我在这里找到了一个最终的答案:(某个上帝或任何可能保佑这些家伙的人) 在Excel中实现日期例程的开发人员故意引入了一个bug,以便与来自的同一已知问题兼容 他们将1900年视为闰年,但不是, 因此,任何超过1900年1月28日的日期都比实际日期多一天。LocalDate testDate = LocalDate.of(1900, Month.JANUARY, 1).plusDays(39447); System.out.println(testDate);// prints 2008-01-02
这就是为什么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 8和更高版本中内置的类所取代。请参阅。java.text.simpleDataFormat
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