【问题标题】:Parse Java TDate format in Java在 Java 中解析 Java 日期格式
【发布时间】:2011-10-20 15:59:32
【问题描述】:

如何解析 Java TDate ?我想将其解析为 java Date 对象。日期值为 2011-11-22T00:00:00-06:00

【问题讨论】:

  • 顺便说一句,您从哪里得到术语“TDate”?我以前从未听说过。
  • 也许你的意思是 ISO 8601“组合日期和时间”格式en.wikipedia.org/wiki/ISO_8601

标签: java parsing date


【解决方案1】:

您可以使用SimpleDateFormat

DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
// Set time zone, locale etc

Date date = format.parse(text);

我个人强烈建议您使用 Joda Time 而不是内置的 Java 类型,但这是一个单独的讨论......

【讨论】:

  • +1:用于使用 JodaTime;我相信T 需要用单引号括起来'T' 而且你需要一个时区。
  • 我收到java.lang.IllegalArgumentException: Illegal pattern character 'T'
  • @PeterLawrey:谢谢 - 现已修复。
  • 对不起,打错了。此代码不解析偏移量-06:00 ,而是使用最有可能给出错误时间的 JVM 的默认时区。请参阅 Arvind Kumar Avinash 的正确答案。为了您自己,请更喜欢使用 java.time。
  • @OleV.V.:我的 猜测 是在前 5 分钟内编辑了问题(因此没有历史记录),但在我写完答案之后。我同意它与问题中指定的值不匹配,我想我已经发现了。至于更喜欢 java.time - 我完全同意,但这是在 2011 年写的......
【解决方案2】:

java.time

java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用2014年3月发布的modern Date-Time API*

使用现代日期时间 API java.time 的解决方案:

现代日期时间 API 基于 ISO 8601,只要日期时间字符串符合 ISO 8601 标准,就不需要明确使用 DateTimeFormatter 对象。

由于您的日期时间字符串 2011-11-22T00:00:00-06:00 已经符合带有时区偏移的 ISO 8601 日期时间格式,您可以直接将其解析为 OffsetDateTime

演示:

import java.time.OffsetDateTime;

public class Main {
    public static void main(String[] args) {
        OffsetDateTime odt = OffsetDateTime.parse("2011-11-22T00:00:00-06:00");
        System.out.println(odt);
    }
}

输出:

2011-11-22T00:00-06:00

ONLINE DEMO

Trail: Date Time 了解有关现代日期时间 API 的更多信息。

一些重要说明:

  1. 如果您要处理 JDBC,请查看 this answerthis answer
  2. 如果您需要将此OffsetDateTime 的对象转换为具有不同ZoneOffsetOffsetDateTime 对象,您可以使用OffsetDateTime#withOffsetSameInstant 来实现,例如
OffsetDateTime odtWithOffsetTwoHours = odt.withOffsetSameInstant(ZoneOffset.of("+02:00"));
OffsetDateTime odtInUtc = odt.withOffsetSameInstant(ZoneOffset.UTC);
  1. 出于任何原因,如果您需要将此OffsetDateTime 的对象转换为java.util.Date 的对象,您可以按如下方式进行:
Date date = Date.from(odt.toInstant());

使用旧版 Date-Time API 的解决方案:

正如我已经提到的,您应该尽量避免容易出错的旧版 API。只是为了完整起见,我在下面使用旧版 API 编写了解决方案。

由于您的日期时间字符串的时区偏移量为-06:00,因此解析它的正确格式为

y-M-d'T'H:m:sXXX

请注意,对于解析,单个 y 可以同时满足两位数和四位数的年份表示。同样,单个m 可以同时满足一位数和两位数的月份。其他字段的行为也类似。

演示:

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

public class Main {
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("y-M-d'T'H:m:sXXX", Locale.ENGLISH);
        Date date = sdf.parse("2011-11-22T00:00:00-06:00");
        // Display in the default format i.e. the value of date#toString
        System.out.println(date);

        // #################Display in custom format and timezone#################
        // At timezone offset of -06:00 hours
        sdf.setTimeZone(TimeZone.getTimeZone("GMT-06:00"));
        System.out.println(sdf.format(date));
        
        // In UTC
        sdf.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
        System.out.println(sdf.format(date));

        // In New York
        sdf.setTimeZone(TimeZone.getTimeZone("America/New_York"));
        System.out.println(sdf.format(date));
    }
}

输出:

Tue Nov 22 06:00:00 GMT 2011
2011-11-22T0:0:0-06:00
2011-11-22T6:0:0Z
2011-11-22T1:0:0-05:00

ONLINE DEMO

注意java.util.Date 对象不是像modern Date-Time types 那样的真实日期时间对象;相反,它表示自称为“纪元”的标准基准时间以来的毫秒数,即January 1, 1970, 00:00:00 GMT(或 UTC)。由于它不包含任何格式和时区信息,因此它应用格式 EEE MMM dd HH:mm:ss z yyyy 和 JVM 的时区来返回从该毫秒值派生的 Date#toString 的值。如果您需要以不同的格式和时区打印日期时间,则需要使用具有所需格式和适用时区的SimpleDateFormat,如上面的代码所示。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

【讨论】:

    猜你喜欢
    • 2015-08-13
    • 2017-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    相关资源
    最近更新 更多