首页 > 解决方案 > Criteria api 错误时间

问题描述

我的数据库中有 timestamp(6) 列。示例:“2020-10-01 00:00:00”通过标准 API 我做了两个谓词

private static Predicate withInstantGe(CriteriaBuilder cb, Root<Object> root, Instant date) {
return Optional.ofNullable(date).map(d -> cb.greaterThanOrEqualTo(root.<Instant>get("date"), d)).orElse(cb.and());
}

private static Predicate withInstantLe(CriteriaBuilder cb, Root<Object> root, Instant date) {
return Optional.ofNullable(date).map(d -> cb.lessThanOrEqualTo(root.<Instant>get("date"), d)).orElse(cb.and());
}

但它不会返回日期从“2020-10-01 00:00:00”到“2020-10-01 05:00:00”的列,差异是 5 小时......而我的 ZoneInfo[id="Asia /叶卡捷琳堡”,但我并不低估它对标准回报的影响。

Calendar startCalendar = getCalendarFrom(); (method returns Calendar where i setted yead day month etc)
TimeZone sdvsd = startCalendar.getTimeZone();
Instant start = getInstant(startCalendar);

Calendar endCalendar = getCalendarTo();
Instant end = getInstant(endCalendar);

private Instant getInstant(Calendar calendar) {
ZonedDateTime zdt = ZonedDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId());
return zdt.withZoneSameLocal(ZoneOffset.UTC).toInstant();
}

标签: javahibernate-criteriacriteria-api

解决方案


我建议您不要使用容易出错的旧日期时间 API 污染干净的现代日期java.util时间 API。

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
        ZonedDateTime zdtStart = LocalDateTime.parse("2020-10-01 00:00:00", formatter)
                .atZone(ZoneId.of("Asia/Yekaterinburg"));
        System.out.println(zdtStart);

        // Add 5 hours to start date-time
        ZonedDateTime zdtEnd = zdtStart.plusHours(5);
        System.out.println(zdtEnd);

        // In case you need Instant from ZonedDateTime
        Instant start = zdtStart.toInstant();
        Instant end = zdtEnd.toInstant();
        System.out.println(start);
        System.out.println(end);
    }
}

输出:

2020-10-01T00:00+05:00[Asia/Yekaterinburg]
2020-10-01T05:00+05:00[Asia/Yekaterinburg]
2020-09-30T19:00:00Z
2020-10-01T00:00:00Z

在Trail: Date Time了解有关现代日期时间 API 的更多信息。

如果您正在为您的 Android 项目执行此操作,并且您的 Android API 级别仍然不符合 Java-8,请通过 desugaring和How to use ThreeTenABP in Android Project检查Java 8+ APIs available


推荐阅读