【问题标题】:Databse DateTime milli & nano seconds are truncated by default if its 0s while using it in java-11 using ZonedDateTime默认情况下,如果在 java-11 中使用 ZonedDateTime 使用数据库 DateTime 毫秒和纳秒,则其为 0 时会被截断
【发布时间】:2021-01-03 23:14:45
【问题描述】:

我正在从 oracle db 中获取日期时间并使用 ZonedDateTime 在 java-11 中进行解析,如下所示:

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

    java ZonedDateTime 0/p --> 2020-01-19T18:09:46.038631Z[UTC]

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

    java ZonedDateTime o/p --> 2011-01-19T04:00Z[UTC] (所以,这里的 0 默认被截断。 但是,我的要求是像 #1 一样具有一致的固定长度 o/p。)

预期的 java ZonedDateTime o/p --> 2011-01-19T04:00:00.000000Z[UTC]

但是,我没有找到任何日期 api 方法来实现上述预期的 o/p。有没有办法以固定长度保留尾随 0,而不是操纵字符串。 我们在应用程序中具有一致的 ZonedDateTime 类型,因此我们不希望更改它。

【问题讨论】:

标签: datetime java-8 zoneddatetime datetimeformatter


【解决方案1】:

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

为什么你认为2011-01-19T04:00Z[UTC] 不一致?日期时间对象应该只保存(并提供操作的方法/函数)日期、时间和时区信息。它不应该存储任何格式信息;否则会违反Single-responsibility principle。格式化应由格式化类处理,例如DateTimeFormatter (for modern date-time API)、DateFormat(用于旧版 java.util 日期时间 API)等。

每个类都应该重写toString() 函数;否则,将在打印其对象时返回Object#toStringZonedDateTime 具有日期、时间和时区信息。下面给出了它的toString() for time-part 是如何实现的:

@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();
}

如您所见,第二部分和 nano 部分仅在大于 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等]

【讨论】:

  • 非常感谢阿文德。我不知道确切的模式。它工作正常。
  • 实际上,“uuuu-MM-dd'T'HH:mm:ss.nnnnnnz”导致长度问题..例如,对于 0,它在 o/ 中为 nanos 提供了完美的 6 位数字p 但对于源日期为 6 位的非零,它通过添加 3 个 0 为 nanos 提供 9 位输出。所以,我几乎没有修改为我的预期输出提供一致结果的模式:“uuuu-MM-dd'T'HH:mm:ss.SSSSSS'Z['z']'”。生成的字符串 o/p : "2020-04-14T15:51:58.109932Z[UTC]"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 2011-05-17
  • 2020-07-26
  • 2017-11-06
  • 2019-12-04
相关资源
最近更新 更多