我正在使用Java并迭代D.B.作为回报的列给出了我的日期和时间字符串,如下所示:
String dateTime = resultSet.getSeries().get(0).getValues().get(0).get(0);
如果我迭代这个结果集,我将获得格式的dateTime值,如下所示。
2017-07-20T19:21:37.987792408Z
2017-04-24T22:04:26.808753375Z
2017-08-14T22:22:40.340772396Z
2017-06-24T22:24:32.422544491Z
2017-07-31T22:27:05.893368615Z
在这些记录中,如何将日期字符串与“当前”日期对象进行比较,并丢弃那些超过10天的值?
我试过
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").parse(s);
那不起作用。还有其他想法吗?
编辑: 我正在使用Java7并使用在查询时不提供sysdate列的InfluxDB。所以我必须使用Java来提出解决方案。
答案 0 :(得分:3)
将日期时间值检索为日期时间对象,而不是字符串。
Instant
类表示UTC时间轴上的一个时刻,分辨率为纳秒。
Instant instant = myResultSet.getObject( … , Instant.class ) ;
与当前时刻前十天比较。
Instant now = Instant.now() ;
Instant tenDaysAgo = now.minus( 10 , ChronoUnit.DAYS ) ;
Boolean prior = instant.isBefore( tenDaysAgo ) ;
您可能不希望将“十天前”作为UTC的基础。如果没有,请应用时区来获取ZonedDateTime
和LocalDate
。这已被多次覆盖,因此搜索Stack Overflow。想想“天”是否意味着(a)24小时或(b)日历日期给你。
仅供参考,这些字符串恰好采用标准ISO 8601格式。 T
将日期部分与时间部分分开。 Z
是Zulu的缩写,意思是UTC。此Instant
类在其toString
方法中使用相同的格式。
通常,您应该在数据库中进行此类比较工作,作为SQL查询的一部分,而不是在Java应用程序中。该数据库高度适应这项工作;你的应用不是。
String sql = "SELECT * FROM tbl_ WHERE when_ < ? " ;
… make your PreparedStatement
myPreparedStatement.setObject( 1 , tenDaysAgo ) ;
… execute
答案 1 :(得分:3)
假设dates
是表示日期的字符串列表,例如在您的示例中,使用Java 8 ZonedDateTime
和DateTimeFormatter
API,您可以执行以下操作:
dates = dates.stream()
.map(ZonedDateTime::parse)
.filter(z -> z.isAfter(ZonedDateTime.now().minusDays(10L)))
.map(ZonedDateTime::toString)
.collect(Collectors.toList());
System.out.println(dates); // [2017-08-14T22:22:40.340772396Z]
<强>更新强>
@Basil和@shmosel在下面的评论中提出了一个有效点,检查,现在实施的方式,针对每个字符串检查now()
(对于任何此类比较,此now()
是不同的)
如果我们要检查相同的特定时间点,针对所有字符串,我们应该“冻结”now()
,一个很好的方法(感谢@shmosel的建议)将是创建一个now()
的实例并使用其方法参考:
ZonedDateTime.now().minusDays(10)::isAfter
或:
ZonedDateTime tenDaysAgo = ZonedDateTime.now().minusDays(10L);
dates = dates.stream()
.map(ZonedDateTime::parse)
.filter(z -> z.isAfter(tenDaysAgo))
.map(ZonedDateTime::toString)
.collect(Collectors.toList());