繁体   English   中英

如何使用 ZonedDateTime 将日期字符串格式化为日期和时间?

[英]How to format Date string to date and time using ZonedDateTime?

我有类似"2021-06-01"的字符串,我希望将其转换为"2021-06-01T00:00:00+02:00" 我知道,最简单的解决方案是串联字符串:

date = date+"T00:00:00+02:00";

但是,我希望使用ZonedDateTime来做到这一点。 目前我的解决方案是:

  public static String formatDate(String date, DateTimeFormatter formatter) {
    return ZonedDateTime.parse(date).format(formatter);
  }

然后使用以下方法调用此方法:

formatDate('2021-06-01', DateTimeFormatter.ISO_LOCAL_DATE);

但是,它抱怨:

java.time.format.DateTimeParseException: Text '2021-06-01' could not be parsed at index 10

有什么解决办法吗?

LocalDate#atStartOfDay

但是,我希望使用 ZonedDateTime 来完成。

它与您的其他问题相似(不准确)。

import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(getOffsetDateTime("2021-06-01"));
    }

    public static OffsetDateTime getOffsetDateTime(String strDate) {
        return LocalDate.parse(strDate)
                .atStartOfDay(ZoneOffset.of("+02:00"))
                .toOffsetDateTime();
    }
}

Output:

2021-06-01T00:00+02:00

在线演示

如果秒和秒的分数为零,则默认省略(即来自OffsetDateTime#toString )。 如果你想保留它们,你可以使用DateTimeFormatter例如

import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Test
        System.out.println(getOffsetDateTime("2021-06-01"));
        System.out.println(getFormattedOffsetDateTime(getOffsetDateTime("2021-06-01")));
    }

    public static OffsetDateTime getOffsetDateTime(String strDate) {
        return LocalDate.parse(strDate)
                .atStartOfDay(ZoneOffset.of("+02:00"))
                .toOffsetDateTime();
    }

    public static String getFormattedOffsetDateTime(OffsetDateTime odt) {
        return DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssXXX", Locale.ENGLISH).format(odt);
    }
}

Output:

2021-06-01T00:00+02:00
2021-06-01T00:00:00+02:00

在线演示

Trail: Date Time了解有关现代日期时间 API 的更多信息。

您的日期字符串没有时间,也没有区域,因此无法解析为ZonedDateTime 您还使用了错误的DateTimeFormatter来格式化它。 ISO_LOCAL_DATE生成格式yyyy-MM-dd ,而不是您想要的格式。

您应该将日期字符串解析为LocalDate ,它只是一个 date ,因为该字符串中只有那么多信息。

然后,您应该将时间分量和偏移量分量添加到解析的日期,然后对其进行格式化:

public static String formatDate(String date) {
    return LocalDate.parse(date)
        .atStartOfDay() // sets the time to 00:00:00
        .atOffset(ZoneOffset.ofHours(2)) // sets the offset to +02:00
        .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); // formats it using the desired format
}

请注意, atOffset为您提供了OffsetDateTime ,这足以满足您的要求。 如果您真的想使用ZonedDateTime ,只需将其更改为atZone ,它也可以使用,但我认为没有必要。

如果您希望始终具有+02:00小时的偏移量, ZonedDateTime将不是一个好的选择,因为它会考虑夏令时。

这是一个演示,说明了您可能想要使用OffsetDateTime的原因:

假设您有两种方法:

public static String formatDate(String date, int offset) {
    return LocalDate.parse(date)
                    .atStartOfDay(ZoneOffset.ofHours(offset))
                    .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}

public static String formatDate(String date, String zone) {
    return LocalDate.parse(date)
                    .atStartOfDay(ZoneId.of(zone))
                    .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}

就像您的示例"2021-06-01"一样,它们都采用String 第二个参数是第一个方法中的偏移量和第二个方法中的区域名称。

使用与String相同的日期但不同的第二个 arguments 的两种方法,像这样

public static void main(String[] args) {
    String dateOne = "2021-06-11";
    String dateTwo = "2019-11-19";
    String dateThree = "1998-03-27";
    
    String zone = "Europe/Paris";
    int offsetHours = 2;
    
    System.out.println(formatDate(dateOne, offsetHours));
    System.out.println(formatDate(dateOne, zone));
    System.out.println(formatDate(dateTwo, offsetHours));
    System.out.println(formatDate(dateTwo, zone));
    System.out.println(formatDate(dateThree, offsetHours));
    System.out.println(formatDate(dateThree, zone));
}

将产生这个 output

2021-06-11T00:00:00+02:00
2021-06-11T00:00:00+02:00
2019-11-19T00:00:00+02:00
2019-11-19T00:00:00+01:00
1998-03-27T00:00:00+02:00
1998-03-27T00:00:00+01:00

如您所见,由于夏令时存在差异。
这意味着如果您使用ZonedDateTime (以某种方式应该使用它),您的要求应该始终是02:00在您的问题下方的评论中给出。

请注意,这两个示例方法都使用DateTimeFormatter.ISO_OFFSET_DATE_TIME ,它会生成您所需格式的String 您可以安全地将其与ZonedDateTime一起使用,而反过来则不能,这意味着使用DateTimeFormatter.ISO_ZONED_DATE_TIME格式化OffsetDateTime ,因为OffsetDateTime没有关于区域的信息。 ZonedDateTime确实如此,因此始终具有有关(特定于区域的)偏移量的信息。

暂无
暂无

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

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