标准 api 错误的时间

Criteria api wrong time

我的数据库中有 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());
}

但它没有 return 日期从“2020-10-01 00:00:00”到“2020-10-01 05:00:00”的列 相差 5 小时...和我的 ZoneInfo[id="Asia/Yekaterinburg",但我不会低估它对标准 return.

的影响
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();
}

我会尝试通过以下方式实现它,以便能够从时区中抽象出来,这只会使复杂化:

Calendar start = Calendar.getInstance();
start.set(Calendar.YEAR,2020);
start.set(Calendar.MONTH,9);
start.set(Calendar.DAY_OF_MONTH,1);
start.set(Calendar.HOUR,0);
start.set(Calendar.MINUTE,0);
start.set(Calendar.SECOND,0);

Calendar end = Calendar.getInstance();
start.set(Calendar.YEAR,2020);
start.set(Calendar.MONTH,9);
start.set(Calendar.DAY_OF_MONTH,1);
start.set(Calendar.HOUR,5);
start.set(Calendar.MINUTE,0);
start.set(Calendar.SECOND,0);

你的谓词:

cb.and(
    cb.greaterThanOrEqualTo(root.get("date"),start.getTime()),
    cb.lessThanOrEqualTo(root.get("date"),end.getTime())
)

我建议您不要用 error-prone 旧版 java.util date-time API.

污染干净的 modern date-time 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.

了解有关现代 date-time API 的更多信息

如果您正在为您的 Android 项目执行此操作,并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring and .