tl;博士
row // Starting with a Poi `Row` object.
.getCell(6) // Extract a Poi `Cell` object.
.getDateCellValue() // Extract value from spreadsheet as a `java.util.Date` object. This terrible class is now legacy. Immediately convert to java.time.Instant as seen on next line.
.toInstant() // Convert from legacy `java.util.Date` class to modern `java.time.Instant`. Both represent a moment in UTC.
.atZone( // Adjusting from UTC to a time zone.
ZoneId.of( "Asia/Tokyo" ) // Specify a time zone to adjust from UTC (an offset of zero hours-minutes-seconds).
) // Returns a `ZonedDateTime` object. Same moment, different wall-clock time.
.toLocalDate() // Extract the date-only portion. Or call `toLocalTime` for the time-of-day portion.
详情
其他答案正确显示了如何获取 java.util.Date 对象。但是这个类 (a) 很糟糕,并且 (b) 现在是遗留的,几年前被现代的 java.time 类所取代。您需要更进一步才能找到合适的解决方案。
得到你的java.util.Date 对象后:
java.util.Date javaUtilDate = row.getCell(6).getDateCellValue() ;
...您在 UTC 中有一段时间。不幸的是,按照建议致电Date::toString:
row.getCell(6).getDateCellValue().toString()
…造成令人困惑的结果。该方法应用 JVM 当前的默认时区,从 UTC 调整到某个时区。这造成了这个时区是java.util.Date 的一部分的错觉,但事实并非如此。这种行为意味着您的结果在运行时会有所不同,具体取决于当前的默认时区。请注意,不仅用户可以更改默认时区,该 JVM 中运行的任何应用程序的任何线程中的任何代码也可以更改。
为了获得可预测的结果,您应该指定所需/预期的时区。
为此,请立即将您的 java.util.Date 转换为它的替代品 Instant 类。两者都代表 UTC 中的一个时刻。请注意添加到旧遗留类中的新转换方法。
Instant instant = javaUtilDate.toInstant() ;
以Continent/Region 的格式指定proper time zone name,例如America/Montreal、Africa/Casablanca 或Pacific/Auckland。切勿使用 2-4 个字母的缩写,例如 EST 或 IST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。
ZoneId zoneId = ZoneId.of( "Africa/Tunis" ) ;
如果您想使用 JVM 当前的默认时区,请显式请求它,并作为参数传递。如果省略,代码会变得模糊,因为我们不确定您是否打算使用默认值,或者您是否像许多程序员一样没有意识到这个问题。
ZoneId zoneId = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
将该时区应用于您在 UTC 中的时刻。
ZonedDateTime zdt = instant.atZone( zoneId ) ;
生成的ZonedDateTime 对象代表同一时刻,时间轴上与Instant 相同的同时点。但它的挂钟时间已调整为特定地区(时区)人们使用的时间。
你问:
如何读取时间?
如何正确读取日期?
您可以使用DateTimeFormatter 以您想要的任何格式打印其中一个或两个,甚至可以自动本地化为Locale 对象中定义的人类语言和文化规范。
或者您可以将日期和时间值提取为单独的对象。
LocalDate localDate = zdt.toLocalDate() ;
LocalTime localTime = zdt.toLocalTime() ;
关于java.time
java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.Date、Calendar 和 SimpleDateFormat。
要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310。
Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。
您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。
从哪里获得 java.time 类?
ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如Interval、YearWeek、YearQuarter 和more。