【问题标题】:DateFormatter is not printing value in the given formatDateFormatter 未以给定格式打印值
【发布时间】:2016-10-12 10:25:53
【问题描述】:

我的日期时间格式字符串是:yyyy-MM-dd'T'HH:mm:ss.SSSZ
我正在使用 Joda Time 的DateTimeFormatter 以上述格式打印我的日期。

现在,将日期视为

2016/04/01 23:00:00

那么它应该已经打印出来了

2016-04-01T23:00:00.000Z

但是,它会打印出来

2016-04-01T23:00:00.000+0200

请帮助我以字符串格式中指定的相同格式打印日期。

【问题讨论】:

  • 请提供生成此行为的完整代码 sn-p

标签: java date datetime jodatime datetime-format


【解决方案1】:

2016-04-01T23:00:00.000Z != 2016-04-01T23:00:00.000+0200

Basil Bourque 对wrong answer 的评论如下:

不,不,不。你所做的只是附加文本,创造一个虚假。如果 您的日期时间表示时区中的一个时刻,即两个小时 在 UTC 之前,例如 Europe/Helsinki,然后你在最后打一个 Z 上面写着Zulu,意思是UTC,你现在在撒谎,代表 值相差两个小时。这就像替换美元符号 价格带有欧元货币符号但未能更改 号码。

只是为了说明他提到的内容:

£100 != $100

2016-04-01T23:00:00.000Z 中的 Z 是零时区偏移量的 timezone designator。它代表 Zulu 并指定 Etc/UTC 时区(其时区偏移量为 +00:00 小时)。同一时刻将以不同的值呈现在不同的时区,例如

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        Instant instant = Instant.parse("2016-04-01T23:00:00.000Z");

        ZonedDateTime zdtNewYork = instant.atZone(ZoneId.of("America/New_York"));
        ZonedDateTime zdtIndia = instant.atZone(ZoneId.of("Asia/Kolkata"));
        ZonedDateTime zdtNepal = instant.atZone(ZoneId.of("Asia/Kathmandu"));

        System.out.println(zdtNewYork);
        System.out.println(zdtIndia);
        System.out.println(zdtNepal);

        // Or at a fixed timezone offset of +02:00 hours
        OffsetDateTime odtWithTwoHoursOffset = instant.atOffset(ZoneOffset.of("+02:00"));
        System.out.println(odtWithTwoHoursOffset);
    }
}

输出:

2016-04-01T19:00-04:00[America/New_York]
2016-04-02T04:30+05:30[Asia/Kolkata]
2016-04-02T04:45+05:45[Asia/Kathmandu]
2016-04-02T01:00+02:00

要进一步理解这个概念,请尝试将日期时间从一个时区转换为另一个时区,例如我已经展示了将纽约日期时间转换为 UTC。我已经展示了另一个时区偏移为+02:00 小时的日期时间转换为UTC。

import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        // #######Example of converting a date-time from one timezone to another#####
        ZonedDateTime zdtNewYork = ZonedDateTime.parse("2016-04-01T19:00-04:00[America/New_York]");

        Instant instant = zdtNewYork.toInstant();
        System.out.println(instant);

        // Or as ZonedDateTime
        ZonedDateTime zdtUtc = zdtNewYork.withZoneSameInstant(ZoneId.of("Etc/UTC"));
        System.out.println(zdtUtc);

        // Alternatively, this can be obtained from instant
        zdtUtc = instant.atZone(ZoneId.of("Etc/UTC"));
        System.out.println(zdtUtc);
        // ###########################################################################

        System.out.println();

        // #####Example of converting a date-time at a fixed timezone offset to UTC###
        OffsetDateTime odtNewYork = OffsetDateTime.parse("2016-04-02T01:00+02:00");

        instant = odtNewYork.toInstant();
        System.out.println(instant);

        // Alternatively
        OffsetDateTime odtUtc = odtNewYork.withOffsetSameInstant(ZoneOffset.UTC);
        System.out.println(odtUtc);

        // Alternatively,
        odtUtc = instant.atOffset(ZoneOffset.UTC);
        System.out.println(odtUtc);
        // ###########################################################################
    }
}

输出:

2016-04-01T23:00:00Z
2016-04-01T23:00Z[Etc/UTC]
2016-04-01T23:00Z[Etc/UTC]

2016-04-01T23:00:00Z
2016-04-01T23:00Z
2016-04-01T23:00Z

【讨论】:

    【解决方案2】:

    根据https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.htmlZ有特殊含义:

    Z       zone-offset
    

    如果你想用 ': 转义 Z 引用 Z

    yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
    

    例如:

    java.time.LocalDateTime date = java.time.LocalDateTime.now();
    java.time.format.DateTimeFormatter formatter = java.time.format.DateTimeFormatter
                    .ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    java.lang.String text = date.format(formatter);
    System.out.println(text);
    

    打印

    2016-06-11T18:39:41.962Z
    

    【讨论】:

    • 非常感谢@AnatolyS。我错过了 Z 周围的单引号。
    • 不,不,不。你所做的只是附加文本,创造一个虚假。如果您的日期时间代表比 UTC 早两个小时的时区中的某个时刻,例如 Europe/Helsinki,并且您在末尾打一个 Z,上面写着 Zulu 并表示 UTC,那么您现在是在撒谎,表示相差两个小时的值。这就像用欧元货币符号替换价格中的美元符号但未能更改数字一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多