SimpleDateFormat - 如何防止重新格式化时区

时间:2018-02-08 09:39:23

标签: java datetime simpledateformat datetime-format datetime-parsing

我在解析SimpleDateFormat时更改datetimestamp的外观时出现问题,然后格式化生成的String

下面的代码段演示了此问题。注意:我知道解析然后使用相同的Date格式化相同的日期似乎是徒劳的,但这只是为了证明原理的一个人为的例子:

SimpleDateFormat

输出如下:

  

通缉:2016-03-12T22:00:00.000-00:00

     

实际:2016-03-12T22:00:00.000Z

由于此日期将用于自动化测试以填写表单,因此DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); String dateStringToConvert = "2016-03-12T22:00:00.000-00:00"; try { Date date = dateFormat.parse(dateStringToConvert); String convertedDateString = dateFormat.format(date); System.out.println("Wanted : " + dateStringToConvert); System.out.println("Actual : " + convertedDateString); } catch (ParseException e) { e.printStackTrace(); } 的格式在被datetimestamp解析和格式化后保持完全相同非常重要,所以我不希望它删除SimpleDateFormat并添加-00:00

这似乎是一个非常简单的问题,但我找不到任何明显的答案。

3 个答案:

答案 0 :(得分:2)

正如Jon Skeet在a comment中所说,没有办法硬编码这个特殊要求。

    DateTimeFormatter formatter;
    String dateStringToConvert = "2016-03-12T22:00:00.000-00:00";
    if (dateStringToConvert.endsWith("-00:00")) {
        formatter = new DateTimeFormatterBuilder()
                .appendPattern("uuuu-MM-dd'T'HH:mm:ss.SSS'-00:00'")
                .parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
                .toFormatter();
    } else {
        formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSxxx");
    }
    OffsetDateTime dateTime = OffsetDateTime.parse(dateStringToConvert, formatter);
    String convertedDateString = dateTime.format(formatter);
    System.out.println("Wanted : " + dateStringToConvert);
    System.out.println("Actual : " + convertedDateString);

打印

Wanted : 2016-03-12T22:00:00.000-00:00
Actual : 2016-03-12T22:00:00.000-00:00

正如已经说过的那样,-00:00(负零)的偏移量不等于零偏移量,因此将字符串解析为OffsetDateTime实际上是不正确的。像我这样做。在这种情况下,正确版本的代码将解析为LocalDateTime,并使用相同的格式化程序将LocalDateTime格式化回来。它总体上会长一点,另一方面你不再需要parseDefaulting调用。

我正在使用并热烈推荐现代Java日期和时间API java.time。由于DateDateFormatSimpleDateFormat已经过时,并且已经证明在不同程度上处理起来很麻烦。现代API非常好。

链接: Oracle tutorial: Date Time解释如何使用java.time

答案 1 :(得分:2)

我担心SimpleDateFormat无法帮助你。这个课程设计很差,而且非常有限,更不用说它有的所有问题:https://eyalsch.wordpress.com/2009/05/29/sdf/

如果你有Java 8,只需使用java.time API即可。不确定为什么要将String转换为Date只是为了将其转换回另一个String,但如果您希望最终结果为String且{{1}作为偏移量,那么你可以这样做:

-00:00

这将打印:

  

2016-03-12T22:00:00.000-00:00

答案 2 :(得分:1)

试试这个:

String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
SimpleDateFormat df = new SimpleDateFormat(pattern) {
    public StringBuffer format(Date date, StringBuffer prefix, FieldPosition fieldPosition) {
        StringBuffer finalStr = super.format(date, prefix, fieldPosition);
        finalStr = finalStr.insert(finalStr.length()-2, ':');
        finalStr = finalStr.deleteCharAt(finalStr.length() - 6);
        finalStr = finalStr.insert(finalStr.length() - 5, '-');
        return finalStr;
    };
};
System.out.println(df.format(yourDate));