我应该使用哪个Java DateTime类?

时间:2019-01-25 14:45:24

标签: java java-time zoneddatetime java.time.instant

我们有一个用于生成报告的库。它从数据文件(SQL,XML,JSON等)中读取数据,然后可以用用户编写的公式修改日期时间,然后按照为报表输出指定的格式对其进行格式化。

方程式中的用法可以加上一个时间跨度,获得部分值,如“ if date.month == 2”,以及几乎all the datetime macros in Excel

因为数据可以是JSON(或无模式的XML),所以日期时间可以是“ 2019-01-25”,“ 2019-01-25T14:32:23”,“ 2019-01-25T14:32:23.12345 ”,“ 2019-01-25T14:32:23Z”或“ 2019-01-25T14:32:23Z-0500”(最后两个也可以有“ .12345”)。

如果没有时区偏移,则我们假设日期时间为UTC。虽然这应该是正确的,但通常不是,而是当地时间,但使用方式并不重要。因此,除非指定了时区偏移量,否则将其设置为UTC(到目前为止,我们已使用Date)。

第一个问题-我应该使用哪个类来保存此值?根据我的阅读,我认为ZonedDateTime,但也许是Instant?

第二个问题-我必须在日期时间增加3天之类的时间使用哪个班级?

第三个问题-是否有一些解析器可以解析上面列出的所有不同字符串?还是我需要调用String.contains()来确定格式,然后基于该格式执行显式模式?如果可以,使用什么类?

2 个答案:

答案 0 :(得分:4)

  

第三个问题-是否有一些解析器可以解析上面列出的所有不同字符串?还是我需要调用String.contains()来确定格式,然后基于该格式执行显式模式?如果可以,使用什么类?

我可能会犯错,但是您可以将DateTimeFormatter与模式的可选部分以及parseBest方法一起使用吗?

List<String> dates = List.of(
    "2019-01-25", 
    "2019-01-25T14:32:23",
    "2019-01-25T14:32:23.12345", 
    "2019-01-25T14:32:23Z", 
    "2019-01-25T14:32:23Z-0500"
);

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
   "yyyy-MM-dd['T'[HH:mm:ss][.SSSSS]][z][x]"
); // all the possible combinations

dates.forEach( date -> {
            TemporalAccessor accessor = formatter.parseBest(date,                       
       OffsetDateTime::from, // going from most specific date
       LocalDateTime::from, 
       LocalDate::from); // to the less specific 

            System.out.println( accessor.getClass() + " " + accessor);
        }

);

// output for this is 
class java.time.LocalDate 2019-01-25
class java.time.LocalDateTime 2019-01-25T14:32:23
class java.time.LocalDateTime 2019-01-25T14:32:23.123450
class java.time.OffsetDateTime 2019-01-25T14:32:23Z
class java.time.OffsetDateTime 2019-01-25T14:32:23-05:00

答案 1 :(得分:3)

关于第二个问题:是的,Java JDK中有一个“ timespan”类。

对于未附加到时间轴的时间跨度:

Period

表示天数/周数/月数/年。可用于日期计算,自动考虑夏令时(DST)。

例如,要从给定日期减去3天,您可以

ZonedDateTime threeDaysAgo = Period.ofDays(-3).addTo(ZonedDateTime.now());

Duration

类似于Period,但以天数(24小时块,而非日历天),小时,分钟,秒和小数秒为单位。

ChronoUnit

如果您需要进行更广泛的计算(例如,包括小时/分钟/秒等),还有ChronoUnit枚举:

ZonedDateTime threeHoursAgo = ChronoUnit.HOURS.addTo(ZonedDateTime.now(), -3);