英文:
toInstant() java return wrong value
问题
我想获得当前月份的开始和结束的 Instant 对象。
为了完整起见,我可以说我需要它们从数据库(Spring 数据)中获取一些对象。
Optional<List<Object» findAllByObjectAndStateChangeDateBetween(Object partner, Instant start, Instant end);
当然,我在 StackOverflow 上找到了这个
https://stackoverflow.com/questions/3083781/start-and-end-date-of-a-current-month
但我写了
begining = calendar.getTime().toInstant();
我得到了 begining = 2020-08-31T19:00:00Z end = 2020-09-30T18:59:59.999Z
但我只想要 begining = 2020-09-01T00:00:01Z end = 2020-09-30T23:59:59.999Z
英文:
I want to get an Instant object of start and end of the current month.
For completeness, I can say that I need them to get some object from the database (Spring data).
Optional<List<Object» findAllByObjectAndStateChangeDateBetween(Object partner, Instant start, Instant end);
Of course, I found this on StackOverflow
https://stackoverflow.com/questions/3083781/start-and-end-date-of-a-current-month
But I wrote
begining = calendar.getTime().toInstant();
And have begining = 2020-08-31T19:00:00Z end = 2020-09-30T18:59:59.999Z
Bui i just want begining = 2020-09-01T00:00:01Z end = 2020-09-30T23:59:59.999Z
答案1
得分: 1
将Calendar
对象转换为Java 8+ Time API对象,保留Calendar
对象的字段值,请使用:
ZonedDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId())
展示如何正确保留所有字段值:
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Yekaterinburg"));
Calendar cal = Calendar.getInstance();
ZonedDateTime zdt = ZonedDateTime.ofInstant(cal.toInstant(), cal.getTimeZone().toZoneId());
System.out.println("java.util.Date: " + new SimpleDateFormat("MMM d, yyyy, h:mm:ss.SSS a XXX").format(cal.getTime()));
System.out.println("ZonedDateTime : " + DateTimeFormatter.ofPattern("MMM d, uuuu, h:mm:ss.SSS a XXX").format(zdt));
System.out.println();
System.out.printf("%-12s%-20s%s%n", "Field" , "Calendar" , "ZonedDateTime");
System.out.printf("%-12s%-20d%d%n", "Year" , cal.get(Calendar.YEAR) , zdt.getYear());
System.out.printf("%-12s%-20d%d%n", "Month" , cal.get(Calendar.MONTH) , zdt.getMonthValue());
System.out.printf("%-12s%-20d%d%n", "Day" , cal.get(Calendar.DAY_OF_MONTH), zdt.getDayOfMonth());
System.out.printf("%-12s%-20d%d%n", "Hour" , cal.get(Calendar.HOUR_OF_DAY) , zdt.getHour());
System.out.printf("%-12s%-20d%d%n", "Minute" , cal.get(Calendar.MINUTE) , zdt.getMinute());
System.out.printf("%-12s%-20d%d%n", "Second" , cal.get(Calendar.SECOND) , zdt.getSecond());
System.out.printf("%-12s%-20d%d%n", "Milli/Nano", cal.get(Calendar.MILLISECOND) , zdt.getNano());
System.out.printf("%-12s%-20s%s%n", "Time Zone" , cal.getTimeZone().getID() , zdt.getZone().getId());
System.out.printf("%-12s%-20s%d%n", " Offset" , cal.getTimeZone().getOffset(cal.getTimeInMillis()), zdt.getOffset().getTotalSeconds());
System.out.println();
System.out.println("Instant (same real time) : " + zdt.toInstant());
System.out.println("Instant (same local time): " + zdt.withZoneSameLocal(ZoneOffset.UTC).toInstant());
输出结果
java.util.Date: Sep 4, 2020, 4:20:32.475 PM +05:00
ZonedDateTime : Sep 4, 2020, 4:20:32.475 PM +05:00
Field Calendar ZonedDateTime
Year 2020 2020
Month 8 9
Day 4 4
Hour 16 16
Minute 20 20
Second 32 32
Milli/Nano 475 475000000
Time Zone Asia/Yekaterinburg Asia/Yekaterinburg
Offset 18000000 18000
Instant (same real time) : 2020-09-04T11:20:32.475Z
Instant (same local time): 2020-09-04T16:20:32.475Z
请注意,Calendar
的月份值是从0开始的。这是我们不再使用它的许多原因之一。
英文:
To convert a Calendar
object to an object of Java 8+ Time API, retaining the field values of the Calendar
object, use:
ZonedDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId())
To show how this correctly keeps all the field values:
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Yekaterinburg"));
Calendar cal = Calendar.getInstance();
ZonedDateTime zdt = ZonedDateTime.ofInstant(cal.toInstant(), cal.getTimeZone().toZoneId());
System.out.println("java.util.Date: " + new SimpleDateFormat("MMM d, yyyy, h:mm:ss.SSS a XXX").format(cal.getTime()));
System.out.println("ZonedDateTime : " + DateTimeFormatter.ofPattern("MMM d, uuuu, h:mm:ss.SSS a XXX").format(zdt));
System.out.println();
System.out.printf("%-12s%-20s%s%n", "Field" , "Calendar" , "ZonedDateTime");
System.out.printf("%-12s%-20d%d%n", "Year" , cal.get(Calendar.YEAR) , zdt.getYear());
System.out.printf("%-12s%-20d%d%n", "Month" , cal.get(Calendar.MONTH) , zdt.getMonthValue());
System.out.printf("%-12s%-20d%d%n", "Day" , cal.get(Calendar.DAY_OF_MONTH), zdt.getDayOfMonth());
System.out.printf("%-12s%-20d%d%n", "Hour" , cal.get(Calendar.HOUR_OF_DAY) , zdt.getHour());
System.out.printf("%-12s%-20d%d%n", "Minute" , cal.get(Calendar.MINUTE) , zdt.getMinute());
System.out.printf("%-12s%-20d%d%n", "Second" , cal.get(Calendar.SECOND) , zdt.getSecond());
System.out.printf("%-12s%-20d%d%n", "Milli/Nano", cal.get(Calendar.MILLISECOND) , zdt.getNano());
System.out.printf("%-12s%-20s%s%n", "Time Zone" , cal.getTimeZone().getID() , zdt.getZone().getId());
System.out.printf("%-12s%-20s%d%n", " Offset" , cal.getTimeZone().getOffset(cal.getTimeInMillis()), zdt.getOffset().getTotalSeconds());
System.out.println();
System.out.println("Instant (same real time) : " + zdt.toInstant());
System.out.println("Instant (same local time): " + zdt.withZoneSameLocal(ZoneOffset.UTC).toInstant());
Output
java.util.Date: Sep 4, 2020, 4:20:32.475 PM +05:00
ZonedDateTime : Sep 4, 2020, 4:20:32.475 PM +05:00
Field Calendar ZonedDateTime
Year 2020 2020
Month 8 9
Day 4 4
Hour 16 16
Minute 20 20
Second 32 32
Milli/Nano 475 475000000
Time Zone Asia/Yekaterinburg Asia/Yekaterinburg
Offset 18000000 18000
Instant (same real time) : 2020-09-04T11:20:32.475Z
Instant (same local time): 2020-09-04T16:20:32.475Z
Note how the Calendar
month value is 0-based. It's one of the many reasons we don't use it any more.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论