标准 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
了解有关现代 date-time API 的更多信息
如果您正在为您的 Android 项目执行此操作,并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring and .
我的数据库中有 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.
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
了解有关现代 date-time API 的更多信息
如果您正在为您的 Android 项目执行此操作,并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring and