【问题标题】:Java: Convert String to Date in with Time Zone variableJava:使用时区变量将字符串转换为日期
【发布时间】:2012-03-21 09:55:27
【问题描述】:

我编写了一个函数来将日期字符串(星期四,2012 年 3 月 1 日 13:57:06 -0600)转换为日期变量。 我依靠 SimpleDateFormat 进行转换。转换发生,但结果日期是“Thu Sep 01 11:00:06 GMT-08:00 2016”,我无法理解。我为 Format 字符串尝试了不同的选项,但仍然无效。任何帮助表示赞赏。谢谢。

我为格式字符串尝试的选项是: 1) E, dd MMM yyyy HH:MM:ss Z 2) EEE, dd MMM yyyy HH:MM:ss ZZZZ

private Date Convert_To_Date() {

        Date dt = null;

        String str = "Thu, 1 Mar 2012 13:57:06 -0600";
        SimpleDateFormat formatter = new SimpleDateFormat("E, dd MMM yyyy HH:MM:ss Z");

        try {
            dt = formatter.parse(str);
        }
        catch ( ParseException pe) {
            System.out.println(pe.getMessage());
        }

        //String strDt = dt.toString(); 
        System.out.println(dt);

        return dt;
    }

【问题讨论】:

    标签: java


    【解决方案1】:

    tl;博士

    ZonedDateTime.parse( 
        "Thu, 1 Mar 2012 13:57:06 -0600" ,    // Input complies with RFC 1123 & RFC 822.
        DateTimeFormatter.RFC_1123_DATE_TIME  // Hard-coded to English locale.
    ).toString()
    

    2012-03-01T13:57:06-06:00

    java.time

    现代方法使用 java.time 类来代替麻烦的旧旧日期时间类。

    RFC 1123 / RFC 822

    您的输入字符串恰好符合RFC 1123 / RFC 822java.time.DateTimeFormatter 类为该格式定义了一个常量 DateTimeFormatter.RFC_1123_DATE_TIME

    String input = "Thu, 1 Mar 2012 13:57:06 -0600" ;
    DateTimeFormatter f = DateTimeFormatter.RFC_1123_DATE_TIME ;
    ZonedDateTime zdt = ZonedDateTime.parse( input , f ) ;
    

    2012-03-01T13:57:06-06:00

    那些 RFC 很旧。该格式现在已被ISO 8601 标准所取代。旧格式很糟糕:假设是英语,容忍各种各样的内容,并且难以解析。

    大多数现代协议和标准都使用ISO 8601 格式将日期时间值作为文本进行交换。该标准定义的格式是实用的,即使跨文化也很明确,易于机器解析,并且易于人类阅读以进行调试/记录。

    java.time 类在解析/生成字符串时默认使用 ISO 8601 格式,如上面的示例所示。


    关于java.time

    java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

    Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

    要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

    使用符合JDBC 4.2 或更高版本的JDBC driver,您可以直接与您的数据库交换java.time 对象。不需要字符串或 java.sql.* 类。

    从哪里获取 java.time 类?

    ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

    【讨论】:

      【解决方案2】:

      日期格式字符串中的几个小错误:

      您在小时中匹配分钟的模式应该是“mm”,而不是“MM”(匹配一年中的月份)。详情请见SimpleDateFormat

      此外,您在月份中匹配天数的模式应该是“d”而不是“dd”,因为“模式字母的数量是最小位数,较短的数字会用零填充到这个数量。对于解析时,将忽略模式字母的数量,除非需要分隔两个相邻的字段。”

      【讨论】:

        【解决方案3】:

        我认为问题在于您在几分钟内使用“M”而不是“m”。这对我来说很好:

        import java.text.*;
        import java.util.*;
        
        public class Test {
            public static void main(String[] args) throws Exception {
                String text = "Thu, 1 Mar 2012 13:57:06 -0600";
                // Note the explicit locale. Let's not leave it as the system default :)
                DateFormat formatter = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z", 
                                                            Locale.US);
        
                Date dt = formatter.parse(text);
                System.out.println(dt);
            }
        }
        

        (正如 sgmorrison 所指出的,您也可以使用 d 而不是 dd,这将更准确地描述您的格式 - 但 dd 在这种情况下适用于解析。)

        【讨论】:

          猜你喜欢
          • 2011-05-11
          • 1970-01-01
          • 2020-09-24
          • 2014-07-03
          • 1970-01-01
          • 2017-07-29
          • 1970-01-01
          • 2016-09-07
          • 1970-01-01
          相关资源
          最近更新 更多