默认情况下,如果数据库DateTime毫秒和纳秒为0,则会被截断,而在Java 11中使用ZonedDateTime



我从Oracle数据库中获取日期时间,并使用ZonedDateTime在Java 11中进行解析,如下所示:

  1. Oracle-->1/19/2020 06:09:46.038631 PM

    Java分区日期时间输出-->2020-01-19T18:09:46.038631Z[UTC]

  2. Oracle-->1/19/2011 4:00:00.000000 AM

    Java分区日期时间输出-->2011-01-19T04:00Z[UTC](因此,这里的0在默认情况下被截断。然而,我的要求是具有一致的固定长度输出,如#1。(

预期的Java ZonedDateTime输出-->2011-01-19T04:00:00.000000Z[UTC]

然而,我没有找到任何日期API方法来实现高于预期的输出。有没有一种方法可以保留固定长度的尾部0,而不是操纵字符串?

我们在应用程序中有一致的ZonedDateTime类型,所以我们不希望更改它。

我们在应用程序中有一致的ZonedDateTime类型,所以我们没有更愿意改变这一点。

为什么您认为2011-01-19T04:00Z[UTC]不一致?日期-时间对象应该只保存(并提供操作的方法/函数(日期、时间和时区信息。它不应该存储任何格式化信息;否则,将违反单一责任原则。格式化应由格式化类处理,例如DateTimeFormatter(用于现代日期时间API(、DateFormat(用于传统java.util日期时间API(等。

每个类都应该覆盖toString()函数;否则,Object#toString将在打印其对象时返回。ZonedDateTime具有日期、时间和时区信息。以下是其时间部分的toString()是如何实现的:

@Override
public String toString() {
StringBuilder buf = new StringBuilder(18);
int hourValue = hour;
int minuteValue = minute;
int secondValue = second;
int nanoValue = nano;
buf.append(hourValue < 10 ? "0" : "").append(hourValue)
.append(minuteValue < 10 ? ":0" : ":").append(minuteValue);
if (secondValue > 0 || nanoValue > 0) {
buf.append(secondValue < 10 ? ":0" : ":").append(secondValue);
if (nanoValue > 0) {
buf.append('.');
if (nanoValue % 1000_000 == 0) {
buf.append(Integer.toString((nanoValue / 1000_000) + 1000).substring(1));
} else if (nanoValue % 1000 == 0) {
buf.append(Integer.toString((nanoValue / 1000) + 1000_000).substring(1));
} else {
buf.append(Integer.toString((nanoValue) + 1000_000_000).substring(1));
}
}
}
return buf.toString();
}

正如您所看到的,只有当第二部分和纳米部分大于0时,它们才会包含在返回的字符串中。这意味着,如果您希望在输出字符串中使用这些(秒和纳米(零,则需要使用格式化类。下面是一个例子:

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
String input = "1/19/2011 4:00:00.000000 AM";
// Formatter for input string
DateTimeFormatter inputFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("M/d/u H:m:s.n a")
.toFormatter(Locale.ENGLISH);
ZonedDateTime zdt = LocalDateTime.parse(input, inputFormatter).atZone(ZoneOffset.UTC);
// Print `zdt` in default format i.e. the string returned by `zdt.toString()`
System.out.println(zdt);
// Formatter for input string
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.nnnnnnz");
String output = zdt.format(outputFormatter);
System.out.println(output);
}
}

输出:

2011-01-19T04:00Z
2011-01-19T04:00:00.000000Z

思考的食物:

public class Main {
public static void main(String[] args) {
double d = 5.0000;
System.out.println(d);
}
}

您希望从上面给出的代码中得到什么输出?5.0是否表示与5.0000不同的值?您将如何打印5.0000?[提示:检查String#formatNumberFormatBigDecimal等]

在其他答案中添加一件小事:秒的分数(S(和nanos(n(相似,但如果有更多的位置/数字可用,nanos将输出更多的位/数字。医生们似乎没有很好地阐述这一点。如果只有6个纳米数字可用,那么应该没有区别。

import java.time.*;
import java.util.*;
import java.time.format.*;

public class TestFormats {

public static void main(String[] args)
{
LocalDateTime dt = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.SSSSSS'Z'");
System.out.println("Current time: "
+ formatter.format(dt));
System.out.println("New LocalDateTime with 0 nano: "
+ formatter.format(dt.withNano(0)));
System.out.println("New LocalDateTime with specific nano: "
+ formatter.format(dt.withNano(80888)));
System.out.println("New LocalDateTime with specific bigger nano: "
+ formatter.format(dt.withNano(8088888)));

DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.nnnnnn'Z'");
System.out.println("Format2 Current time: "
+ formatter2.format(dt));
System.out.println("Format2 New LocalDateTime with 0 nano: "
+ formatter2.format(dt.withNano(0)));
System.out.println("Format2 New LocalDateTime with specific nano: "
+ formatter2.format(dt.withNano(80888)));
System.out.println("Format2 New LocalDateTime with specific bigger nano: "
+ formatter2.format(dt.withNano(8088888)));

}
}

结果:

Current time: 2023-07-12 15:55:30.321719Z
New LocalDateTime with 0 nano: 2023-07-12 15:55:30.000000Z
New LocalDateTime with specific nano: 2023-07-12 15:55:30.000080Z
New LocalDateTime with specific bigger nano: 2023-07-12 15:55:30.008088Z
Format2 Current time: 2023-07-12T15:55:30.321719992Z
Format2 New LocalDateTime with 0 nano: 2023-07-12T15:55:30.000000Z
Format2 New LocalDateTime with specific nano: 2023-07-12T15:55:30.080888Z
Format2 New LocalDateTime with specific bigger nano: 2023-07-12T15:55:30.8088888Z

相关内容

  • 没有找到相关文章

最新更新