【问题标题】:How to specify a timezone for a joda DateTime object?如何为 joda DateTime 对象指定时区?
【发布时间】:2014-05-29 17:42:14
【问题描述】:

我有一个函数可以将字符串转换为 joda time 对象并对其进行格式化。

public static String getFormattedDatetime(String someDate) {
    DateTime newDate = DateTime.parse(someDate, DateTimeFormat.forPattern("yy-MM-dd HH:mm:ss.SSS")).minusHours(7);
    String formattedDate = newDate.toString("dd-MMM-yy hh:mm a");

    return formattedDate;
}

该函数接受字符串并返回格式化的 DateTime 就好了,但是我在为其分配 TimeZone 时遇到了麻烦。我传入的字符串代表我需要转换为 PST/PDT 的数据库中的 UTC 时间。我想不出一种方法来 1)为新的 DateTime 对象分配一个时区,2)将该对象的时区转换为 PST/PDT。现在我正在用 .minusHours 处理这个问题。当然不理想。

【问题讨论】:

    标签: java jodatime


    【解决方案1】:

    在任何情况下都不应使用.minusHours(7),因为它会在半年中出错,并且DateTime 对象仍会认为它是UTC。

    使用.withZone(DateTimeZone.forID("America/Los_Angeles"));

    Here is a list of all time zones supported by Joda Time with their corresponding IDs

    我建议将forID() 调用生成的常量重构为代码中适当位置的static final 字段,并在需要进行转换的任何地方使用它。


    您可能知道,但为了安全起见,DateTime 对象是 IMMUTABLE,这意味着 withZone 调用将返回一个全新的 DateTime 实例,并且将 改变原始对象的区域。


    @anotherdave 在 cmets 中提出了一个很好的观点。您在问题中说 PST,但 PST 仅使用半年(因为夏令时)。我假设您指的是洛杉矶、西雅图等地的当前时间,而不是具体的 PST 区域,因为这些城市在下半年使用 PDT。但是,如果您确实需要 PST 100% 的时间,您可以使用 forID("PST");

    【讨论】:

    • 另外,除非您特别想要“PST”,而不是例如“洛杉矶的当前时间”我会使用 durron 的“America/Los_Angeles”示例而不是 DateTimeZone.forID("PST") — 在夏令时期间按地区名称呼叫应该返回 PDT,而按 PST 呼叫会总是返回 PST。
    • 我试过了。像这样:DateTime newDate = DateTime.parse(someDate, DateTimeFormat.forPattern("yy-MM-dd HH:mm:ss.SSS")).withZone(DateTimeZone.forID("America/Los_Angeles")); 它仍然没有转换日期。这段代码是否只是为我的对象分配了一个区域而没有实际转换它?我是否需要先为其分配 UTC 时区,然后再转换为 PST?
    • @QuidFacis 我的帖子是您提出的问题的正确答案。如果您已经尝试过,但它没有创建您想要的行为,请编辑您的问题,使用确切的字符串输入、您使用的确切调用、您期望的结果对象应该是什么以及什么结果对象实际上是。
    • @durron597 如问题中所述,输入是一个字符串,该字符串被解析为函数内的 DateTime 对象。输入无关紧要,因为该 parse 方法总是以函数指定的模式返回有效的 DateTime 对象。时区方法不应该适用于任何 DateTime 对象吗?
    • @QuidFacis 如果我不知道问题是什么,我无法帮助您。如果我的回答没有解决您的问题,那么我显然不明白到底出了什么问题。我推荐的编辑将帮助我更准确地了解您遇到的问题。 Please read this help center postthis one for more details
    【解决方案2】:

    已解决:

    public static String getFormattedDatetime(String someDate) {
    
        DateTime newDate = DateTime.parse(someDate, DateTimeFormat.forPattern("yy-MM-dd  HH:mm:ss.SSS"));
            LocalDateTime zonedDate = LocalDateTime.parse(newDate, DateTimeFormat.forPattern("yy-MM-dd HH:mm:ss.SSS"));
            DateTime finalZonedDate = zonedDate.toDateTime(DateTimeZone.UTC);
            String formattedDate = newDate.toString("dd-MMM-yy hh:mm a");
            return formattedDate;
        }
    

    当我将字符串转换为变量时,我必须使用 joda 的 LocalDateTime 类来分配时区。然后我不得不单独转换区域。

    【讨论】:

      【解决方案3】:

      更新:如果有人只想更改 TimeZone 而不是实际日期。然后你可以使用下面的代码:

      DateTime dateTime = DateTime.parse(date.toString(), DateTimeFormat.forPattern("yyyy-MM-dd")).withZoneRetainFields(DateTimeZone.forID("PST"));  // it will change timezone to PST but not the actual date field value.
      

      【讨论】:

        猜你喜欢
        • 2015-02-13
        • 1970-01-01
        • 1970-01-01
        • 2013-10-20
        • 2011-06-07
        • 2018-07-02
        • 1970-01-01
        • 2018-04-07
        • 1970-01-01
        相关资源
        最近更新 更多