Как найти значения дат более 10 дней
Я использую Java и перебираю столбец БД, который в свою очередь дает мне строку даты и времени, как показано ниже:
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 и InfluxDB, который не предоставляет столбец sysdate при запросах. Поэтому я должен придумать решение с использованием Java.
2 ответа
java.time
Получить значения даты и времени как объекты даты и времени, а не строки.
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
, Это было рассмотрено много раз, поэтому ищите переполнение стека. Подумайте, означает ли "дни" (а) фрагменты 24-часовых или (б) календарных дат для вас.
К вашему сведению, эти строки в стандартном формате ISO 8601. T
отделяет часть даты от части времени. Z
это сокращение от зулу и означает UTC. это Instant
класс использует тот же формат в своем toString
метод.
SQL
Как правило, вы должны выполнять такую работу по сравнению в базе данных как часть SQL-запроса, а не как ваше Java-приложение. База данных хорошо настроена для этой работы; ваше приложение нет.
String sql = "SELECT * FROM tbl_ WHERE when_ < ? " ;
… make your PreparedStatement
myPreparedStatement.setObject( 1 , tenDaysAgo ) ;
… execute
Если предположить, 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());