将YYYY-MM-DDThh:mm:ssTZD格式的日期字符串转换为本地时间

在我的Spring Boot应用程序中,我必须不使用JODA将ISO 8601日期时间转换为localdatetime。目前我正在做的是

String receivedDateTime = "2019-11-13T00:11:08+05:00";

ZonedDateTime zonedDateTime = ZonedDateTime.parse(receivedDateTime);

DateFormat utcFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        utcFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date date = new Date();
        try {
            date = utcFormat.parse(zonedDateTime.toString());
        } catch (ParseException e) {
            e.printStackTrace();
        }

当我将带有+00:00的receiveDateTime用作“ 2019-11-13T00:11:08 + 00:00”时,它不会给出任何解析错误,但不会进行任何转换。当我最后使用+01:00时,它还会给出解析错误。

更新:1

根据@Deadpool答案,我使用它的方式是

String receivedDateTime  = "2019-11-13T00:11:08+05:00";

        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                .optionalStart().appendOffset("+HH:MM","+00:00").optionalEnd()
                .optionalStart().appendOffset("+HHMM","0000").optionalEnd()
                .toFormatter();

        OffsetDateTime dt = OffsetDateTime.parse(receivedDateTime,formatter);
        LocalDateTime ldt = dt.toLocalDateTime();

        System.out.println(ldt);

,它打印的 ldt 的值为 2019-11-13T00:11:08

更新2: 我尝试使用同一示例的C#,它给了我这个日期时间 {2019-11-12 11:11:08 AM} ,它看起来正确,因为输入时间是格林尼治标准时间+5小时,而本地时间是美国东部时间。因此,当它转换后,它可以追溯到11月12日。这是代码

var timeString = "2019-11-13T00:11:08+05:00";
DateTime d2 = DateTime.Parse(timeString,null,System.Globalization.DateTimeStyles.RoundtripKind);
Console.WriteLine("Hello World!" + d2);

更新3:归结为以下解决方案输入字符串“ 2019-11-13T06:01:41 + 00:00”,输出为本地日期“ 2019-11-13T00:01” :41“,系统默认的ZoneId为” America / Chicago“,即格林尼治标准时间-06:00

private LocalDateTime convertUtcStringToLocalDateTime(String UtcDateTime) {
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
                .optionalStart().appendOffset("+HH:MM","0000").optionalEnd()
                .toFormatter();

        OffsetDateTime dateTime = OffsetDateTime.parse(UtcDateTime,formatter);
        return dateTime.atZonesameInstant(ZoneId.of(ZoneId.systemDefault().getId())).toLocalDateTime();
    }
thebestme_1 回答:将YYYY-MM-DDThh:mm:ssTZD格式的日期字符串转换为本地时间

通过使用DateTimeFormatter,您可以通过将日期格式设置为可选的offset来自定义日期格式

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
            .optionalStart().appendOffset("+HH:MM","+00:00").optionalEnd()
            .optionalStart().appendOffset("+HHMM","0000").optionalEnd()
            .toFormatter();

然后使用OffsetDateTime解析具有偏移量的字符串

  

在ISO-8601日历系统中与UTC /格林威治时间偏移的日期时间,例如2007-12-03T10:15:30 + 01:00。

OffsetDateTime dateTime =  OffsetDateTime.parse("2019-11-13T00:11:08+0000",formatter);

OffsetDateTime dateTime =  OffsetDateTime.parse("2019-11-13T00:11:08+05:00",formatter);

如果要将其转换为本地时区时间LocalDateTime,请使用atZoneWithSameInstant()

LocalDateTime local = dateTime.atZoneSameInstant(ZoneId.of("America/New_York")).toLocalDateTime()

注意:请勿使用旧的旧框架SimpleDateFormatutil.Date

,

仅使用java.time,这比您想像的要简单:

    String receivedDateTime = "2019-11-13T00:11:08+05:00";

    OffsetDateTime parsedDateTime = OffsetDateTime.parse(receivedDateTime);
    ZonedDateTime dateTimeInMyTimeZone
            = parsedDateTime.atZoneSameInstant(ZoneId.systemDefault());
    System.out.println(dateTimeInMyTimeZone);

当我在美国/多伦多时区运行此命令时,输出为:

  

2019-11-12T14:11:08-05:00 [美国/多伦多]

由于您的字符串包含偏移量+05:00,并且没有像Asia/Karachi这样的时区,因此请使用OffsetDateTime进行解析。然后使用atZoneSameInstant方法转换为您的本地时区。即使您询问了当地时间,也不要欺骗使用LocalDateTime。该类表示日期和时间没有任何时区,这不是您所需要的(根本不需要)。

幸运的是,很容易避免使用旧类SimpleDateFormatDateFormatTimeZoneDate。它们的设计总是很差,尤其是前两个非常麻烦。他们都已经过时了。取而代之的是从Java.time(现代的Java日期和时间API)获得我们梦想中的所有功能。

您的代码中发生了什么?

请勿在格式模式字符串中使用'Z'(我再说一遍,请勿使用SimpleDateFormat)。

无论您使用ZonedDateTime还是OffsetDateTime,当您使用偏移量为零(由toString解析)的+00:00时,偏移量都打印为{{1 }},它与格式模式字符串中的Z匹配,因此可以进行第二次解析。只解析一次,转换回字符串然后再次解析就不必要了。当原始偏移为'Z'+01:00时更糟。它们从+05:00开始再次呈现相同的效果,因此与toString不匹配,这导致了您的'Z'从不在格式模式字符串中使用ParseException'Z'表示偏移量为零,需要将其解析为偏移量才能获得正确的结果。

本文链接:https://www.f2er.com/3114332.html

大家都在问