简体   繁体   English

如何在 java 13 或更高版本中格式化 OffsetDateTime?

[英]How to format OffsetDateTime in java 13 or above?

In Java 11, clock system uses millisecond precision, but apparently in Java 13 and above, it uses microsecond precision and this causes my tests to fail.在 Java 11 中,时钟系统使用毫秒精度,但显然在 Java 13 及更高版本中,它使用微秒精度,这导致我的测试失败。 As an example, OffsetDateTime.now() gives me this date "2021-12-10T10:58:05.309594500+01:00" while when I read this date from database "2021-12-10T10:58:05.309595+01:00".例如,当我从数据库“2021-12-10T10:58:05.309595+01:00”中读取该日期时, OffsetDateTime.now()给了我这个日期“2021-12-10T10:58:05.309594500+01:00” ”。 I am searching for a way that I can format the first date that I can drop two 00 at the end.我正在寻找一种可以格式化第一个日期的方法,我可以在最后删除两个 00。 I do want having it in OffsetDateTime type not string.我确实希望它在 OffsetDateTime 类型而不是字符串中。

Could you please help me?请你帮助我好吗?

An OffsetDateTime always has got nanosecond precision. OffsetDateTime始终具有纳秒精度。 It's now method may not have depending on platform and Java version. now的方法可能没有,具体取决于平台和 Java 版本。 Internally the object has. object 内部有。 So there is no way that you can have an OffsetDateTime with fewer than 9 decimals on the seconds.因此,您不可能在秒上拥有少于 9 位小数的OffsetDateTime

How many decimals are printed is a different question.打印多少个小数是一个不同的问题。 What is really printed when you print an OffsetDateTime is a String .打印OffsetDateTime时真正打印的是String If you just print the object, its toString method is implicitly called to produce the string that we see in print.如果你只打印 object,它的toString方法会被隐式调用以生成我们在打印中看到的字符串。 OffsetDateTime.toString() always gives us as many groups of 3 decimals as are necessary for rendering the full precision. OffsetDateTime.toString()总是为我们提供尽可能多的 3 位小数组,这是渲染完整精度所必需的。 So if the decimals were .100000000 , then .100 is printed.因此,如果小数为.100000000 ,则打印.100 If they were .309594500 , as you have seen already, all 9 decimals are present in the string.如果它们是.309594500 ,正如您已经看到的,所有 9 位小数都存在于字符串中。 There is no way that you can change this behaviour.您无法更改此行为。

If you want a different string printed, you can use a DateTimeFormatter with the number of decimals you like.如果要打印不同的字符串,可以使用DateTimeFormatter和您喜欢的小数位数。

So what you can do:所以你可以做什么:

  1. You can modify the OffsetDateTime , or really, you can create a new one like the old one only with more decimals being zero, which in turn may cause fewer decimals to be printed by toString() .您可以修改OffsetDateTime ,或者实际上,您可以像旧的一样创建一个新的,只有更多的小数为零,这反过来可能会导致toString()打印更少的小数。
  2. You can format the OffsetDateTime into a string of your liking.您可以将OffsetDateTime格式化为您喜欢的字符串。

The following code snippets combines both options.以下代码片段结合了这两个选项。 For formatting only the decimals up to the last non-zero decimal I am using the following formatter:对于仅格式化到最后一个非零小数的小数,我使用以下格式化程序:

private static final DateTimeFormatter ODT_FORMATTER = new DateTimeFormatterBuilder()
        .appendPattern("uuuu-MM-dd'T'HH:mm.ss")
        .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
        .appendOffsetId()
        .toFormatter(Locale.ROOT);

Demonstration:示范:

    OffsetDateTime dateTime = OffsetDateTime.parse("2021-12-10T10:58:05.309594500+01:00");

    int nanos = dateTime.getNano();
    OffsetDateTime with7Decimals = dateTime.withNano(nanos / 100 * 100);
    System.out.println("toString(): " + with7Decimals);
    System.out.println("Formatted:  " + with7Decimals.format(ODT_FORMATTER));
    OffsetDateTime with5Decimals = dateTime.withNano(nanos / 10000 * 10000);
    System.out.println("toString(): " + with5Decimals);
    System.out.println("Formatted:  " + with5Decimals.format(ODT_FORMATTER));

Output: Output:

 toString(): 2021-12-10T10:58:05.309594500+01:00 Formatted: 2021-12-10T10:58.05.3095945+01:00 toString(): 2021-12-10T10:58:05.309590+01:00 Formatted: 2021-12-10T10:58.05.30959+01:00

For you tests I see no reason to use strings for comparison.对于您的测试,我认为没有理由使用字符串进行比较。 Just compare the OffsetDateTime objects after setting those decimals to zero that will be lost in your database anyway.只需在将这些小数设置为零之后比较OffsetDateTime对象,无论如何这将在您的数据库中丢失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM