toInstant()方法在Java中返回错误的值

huangapple go评论112阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2020年9月4日 18:24:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/63739319.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定