如何将HH:mm:ss +/- HH:MM解析为日期对象?

时间:2014-10-09 17:29:54

标签: java parsing date time

我有一个小时时间17:00:00-07:00我想转换/解析它(上午10点)。我该怎么办?

2 个答案:

答案 0 :(得分:2)

使用SimpleDateFormat类的parse方法,并为输入字符串指定适当的模式。这会将其转换为日期对象。如果要转换回另一种格式的字符串,请使用另一个format对象的SimpleDateFormat方法。但请注意你的时区。

以下是一些示例代码,仅依赖于标准Java库

import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.TimeZone;

class TimeTest {

    public static void main( String[] args ) {

        String [] testData = {
            "17:00:00-07:00",
            "19:00:00+03:00",
            "15:04:00-10:00"
        };

        SimpleDateFormat inputFormat = new SimpleDateFormat( "HH:mm:ssXXX" );
        SimpleDateFormat outputFormat = new SimpleDateFormat( "h:mm a" );
        outputFormat.setTimeZone(TimeZone.getTimeZone("UTC"));

        for ( String str: testData ) {
            try {
                Date dateObj = inputFormat.parse( str );
                System.out.println(str + " -> " + outputFormat.format(dateObj));
            } catch ( ParseException e ) {
                System.err.println( "Could not parse " + str );
            }
        }
    }
}

此代码的输出为:

17:00:00-07:00 -> 12:00 AM
19:00:00+03:00 -> 4:00 PM
15:04:00-10:00 -> 1:04 AM

答案 1 :(得分:1)

不正确的问题

该问题假设结果应该是上午10点(10:00:00)。这是不正确的。

根据ISO 8601标准和其他标准,-07:00的偏移意味着UTC后面的时间为7小时"。不要将其作为带有减法符号的代数公式读出。恰恰相反,翻转标志以制定公式以到达UTC

因此值17:00:00-07:00会调整为00:00:00(第二天)。在晚上5点加7小时后,您将进入午夜

解决方案

我一开始认为可以使用DateTimeFormatter来解析,然后在Joda-Time中实例化LocalTime类。但是本地时间解析器忽略(截断)偏移量而不是将其作为调整应用。

因此,作为一种解决方法,我使用DateTime来解析时间,好像发生在Unix纪元的第一天(1970年世纪初)。然后我切换到LocalTime对象。

String input = "17:00:00-07:00";
DateTimeFormatter formatter = DateTimeFormat.forPattern( "HH:mm:ssZ" ); 
DateTime dateTime = formatter.parseDateTime( input ).withZone( DateTimeZone.UTC );
LocalTime localTime = dateTime.toLocalTime();

转储到控制台。

System.out.println( "dateTime: " + dateTime );
System.out.println( "localTime: " + localTime );

运行时。请注意,如果将7个小时添加到下午5点,我们将进入午夜,即第二天的第一个时刻( 1月2日而不是1 )。

dateTime: 1970-01-02T00:00:00.000Z
localTime: 00:00:00.000

前置T对于ISO 8601输入

如果您在输入字符串前加T以符合ISO 8601,则可以使用Joda-Time的内置默认解析器来省略一行代码。

String input = "T" + "17:00:00-07:00"; // Prepend a "T" to comply with ISO 8601 format.
DateTime dateTime = new DateTime( input ).withZone( DateTimeZone.UTC ); // Pass standard string to constructor of DateTime. Or pass to static method DateTime.parse().
LocalTime localTime = dateTime.toLocalTime();