【问题标题】:How to parse HH:mm:ss+/-HH:MM into a date object?如何将 HH:mm:ss+/-HH:MM 解析为日期对象?
【发布时间】:2014-10-09 17:29:54
【问题描述】:

我有一个小时的时间 17:00:00-07:00,我想将其转换/解析为(上午 10 点)。我该怎么做?

【问题讨论】:

  • 分别解析每个对象,然后执行Date 操作。
  • 你应该看看SimpleDateFormat
  • 必须是 Date 对象吗?如果您使用的是 Java 8,则可能需要查看 java.timejava.time.format API。
  • 它不一定是日期对象,我需要将17:00:00-07:00转换为实际时间(上午10点)。
  • 为什么投反对票?这对我来说似乎是一个好问题,没有重复。我在 Joda-Time 中找不到答案,因为 LocalTime 解析忽略了偏移量而不是使用它来调整。

标签: java parsing date time


【解决方案1】:

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

这是一些示例代码,仅依赖于标准 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

【讨论】:

  • 我检查过 SimpleDateFormat,它似乎不支持 +/-HH:MM
  • 该时间格式中+/-之后的部分,假设它是常见的,实际上表示时区。所以我相信模式 X 应该有效。
  • @RealSkeptic 所以展示一些代码来运行而不是猜测。
【解决方案2】:

不正确的问题

问题假定结果应该是上午 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 UTC 开始)。然后我切换到 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 );

运行时。请注意,在下午 5 点加上 7 小时后,我们会看到午夜的钟声,即第二天的第一刻(1 月 2 日而不是 1 日)。

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

为 ISO 8601 输入添加 T

如果您在输入字符串前添加 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();

【讨论】:

  • 如何将这个 17:00:00-07:00 解析为 -> 5pm 并忽略时间偏移?
  • @user3709877 应用desired time zone,例如上面最后一个示例中调用withZone 的第二行中的“America/Los_Angeles”(推荐)。如果您确定要调整偏移量,或者了解withOffsetParsed 方法(可能很诱人,但可能不是最好的方法)。
猜你喜欢
  • 2018-02-20
  • 1970-01-01
  • 1970-01-01
  • 2018-01-09
  • 1970-01-01
  • 1970-01-01
  • 2017-09-06
  • 2014-03-17
  • 1970-01-01
相关资源
最近更新 更多