Java 日期对象格式

Java 日期对象格式,java,date-formatting,date,Java,Date Formatting,Date,我试图用Java格式化一个输入日期,在调试器中如下所示 result = {Date@13861} "2019-09-29" fastTime = 1569729600000 cdate = {Gregorian$Date@13873} "2019-09-29T00:00:00.000-0400" 我需要将其转换为:2019-09-28 20:00:00.0 我的代码: DateTimeFormatter dateTimeformatter_Test = DateTimeFormatter

我试图用Java格式化一个输入日期,在调试器中如下所示

result = {Date@13861} "2019-09-29"
 fastTime = 1569729600000
 cdate = {Gregorian$Date@13873} "2019-09-29T00:00:00.000-0400"
我需要将其转换为:
2019-09-28 20:00:00.0

我的代码:

DateTimeFormatter dateTimeformatter_Test = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

LocalDate tempDate = LocalDate.parse(date.toString(), DateTimeFormatter.ofPattern( "yyyy-MM-dd" , Locale.US ));
但是下面的一行抛出了一个运行时错误:Unsupported field:HourOfDay

String result= tempDate.format(dateTimeformatter_Test);
请问我这里缺什么


谢谢。

您的问题缺少时区信息,但这里有一种方法可以将
2019-09-29
转换为
2019-09-28 20:00:00.0

System.out.println(
        LocalDate.parse("2019-09-29")
        .atStartOfDay(ZoneOffset.UTC)
        .withZoneSameInstant(ZoneId.of("America/New_York"))
        .format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.S")));
输出


以下是一种完全不同的方式,显示您在调试器中看到的值:

TimeZone.setDefault(TimeZone.getTimeZone("America/New_York"));

java.sql.Date result = java.sql.Date.valueOf("2019-09-29");
System.out.println("result = " + result);

long fastTime = result.getTime();
System.out.println("fastTime = " + fastTime);

System.out.println("cdate = " + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(result));

ZonedDateTime zdt = Instant.ofEpochMilli(fastTime).atZone(ZoneId.of("America/Anchorage"));
System.out.println("zdt = " + zdt.format(DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.S")));
输出


如果这是SQL数据库的时间戳:不要将时间戳作为字符串提供给数据库。给它一个合适的日期时间对象。由于JDBC 4.2,这意味着:

  • 对于带有时区的SQL
    时间戳(建议用于绝大多数目的),请提供
    OffsetDateTime
    ;许多司机也接受即时的
  • 对于不带时区的SQL
    时间戳
    ,请提供
    LocalDateTime
例如:

    java.sql.Date inputDate = getFromSomewhere();
    OffsetDateTime dateTimeForDatabase = inputDate.toLocalDate()
            .atStartOfDay(ZoneOffset.UTC)
            .toOffsetDateTime();
    System.out.println(dateTimeForDatabase);

    PreparedStatement stmt = yourDatabaseConnection.prepareStatement(
            "insert into your_table(your_timestamp_col) values (?)");
    stmt.setObject(1, dateTimeForDatabase);
    int rowsInserted = stmt.executeUpdate();
中间的print语句的输出示例:

2019-09-29T00:00Z

Z
表示UTC,因此这与您要求的
2019-09-28 20:00:00.0
的时间点相同,假设JVM的时区是北美东部时间(美国/多伦多或美国/纽约)的某个变体

您在调试器中看到的对象看起来非常像
java.sql.Date
对象,因此我将此类型作为起点。
java.sql.Date
类的设计很差,但事实上,它是对已经设计很差的
java.util.Date
类的一个真正的攻击。它也早已过时。因此,如果您可以使用现代类型,例如
LocalDate
,这将非常有利

你的代码出了什么问题?
LocalDate
是没有时间的日期,例如2019-09-29。您试图使用格式模式
yyyy-MM-dd'T'HH:MM:ss.SSS'Z'
格式化一个文件。因此,您要求在结果中包含一天中的时间,但正如我所说,
LocalDate
没有一天中的时间,因此这没有意义。您收到的错误消息实际上非常准确:

不支持的字段:houroday

String result= tempDate.format(dateTimeformatter_Test);

请提供一个复制准确错误的数据。我们应该能够复制代码并自己运行它,而不会出现除您所询问的错误以外的任何其他错误。
date.toString()
是个坏主意,因为格式未指定,可能会更改。看起来您有一个
java.util.Date
java.util.Calendar
LocalDate
也没有时间概念,因此您需要提供一些方法来注入时间(即
LocalDate
LocalDateTime
:/)我认为您的区域偏移错误,因为
2019-09-29T00:00:00.000-0400
2019-09-29 04:00:00
UTC的时间相同,而不是
2019-09-28 20:00.0
,所以除非你在时区
美国/纽约
并且目标时区
-08:00
美国/安克雷奇
),否则你的价值观没有意义。我认为你不是指解析,而是指格式?!解析是将字符串转换为内部形式,在本例中是日期时间对象。格式化是相反的转换。请明确你要找的是哪一个?你需要这种格式做什么?询问,因为它看起来很像SQL时间戳,您不应该将时间戳作为字符串传递给SQL数据库。传递一个
offsetdateme
、一个
Instant
或一个
LocalDateTime
    java.sql.Date inputDate = getFromSomewhere();
    OffsetDateTime dateTimeForDatabase = inputDate.toLocalDate()
            .atStartOfDay(ZoneOffset.UTC)
            .toOffsetDateTime();
    System.out.println(dateTimeForDatabase);

    PreparedStatement stmt = yourDatabaseConnection.prepareStatement(
            "insert into your_table(your_timestamp_col) values (?)");
    stmt.setObject(1, dateTimeForDatabase);
    int rowsInserted = stmt.executeUpdate();