JodaTime使用EXIF元数据中的Date字符串抛出IllegalArgumentException

时间:2014-11-27 15:38:41

标签: java date datetime jodatime

我正在编写一些代码来存储数据库中上传图像的元数据。其中一个领域是照片拍摄日期。 API I'm using以字符串格式

返回捕获日期
Sat Nov 01 20:08:07 UTC 2014

但是,Joda Time在创建DateTimeLocalDateTime时会抛出IllegalArgumentException。相反,java.util.Date接受字符串格式并创建一个没有问题的Date对象。

一种解决方案是

Date tempDate = new Date("Sat Nov 01 20:08:07 UTC 2014");
DateTime captureDate = new DateTime(tempDate);

但这需要创建两个单独的对象来保留一个。鉴于上面的字符串格式,是否可以说服JodaTime创建DateTime对象而无需中间Date初始化?

2 个答案:

答案 0 :(得分:3)

采用DateTime的Joda Time LocalDateObject构造函数包含以下文档:

  

字符串格式由ISODateTimeFormat.dateTimeParser()描述。

您提供的文字是ISO格式的

相反,您应该为您正在使用的格式创建DateTimeFormatter,例如:通过DateTimeFormat.forPattern,指定区域设置,时区等。(您的示例中不清楚它的始终是否为UTC,或者您是否需要时区处理。)

例如:

private static final DateTimeFormatter DATETIME_PARSER =
    DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss 'UTC' yyyy")
        .withLocale(Locale.US)
        .withZoneUTC();

...

DateTime dateTime = DATETIME_PARSER.parseDateTime(text);

答案 1 :(得分:1)

java.time

java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*

另外,下面引用的是来自 home page of Joda-Time 的通知:

<块引用>

请注意,从 Java SE 8 开始,要求用户迁移到 java.time (JSR-310) - JDK 的核心部分,取代了该项目。

不要为时区使用固定文本:

不要为时区使用固定文本(例如 'UTC'),因为该方法可能无法用于其他语言环境。

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

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "Sat Nov 01 20:08:07 UTC 2014";
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("E MMM d H:m:s z u", Locale.ENGLISH);
        ZonedDateTime zdt = ZonedDateTime.parse(strDateTime, dtf);
        System.out.println(zdt);
    }
}

输出:

2014-11-01T20:08:07Z[Etc/UTC]

ONLINE DEMO

出于任何原因,如果您需要将 ZonedDateTime 的这个对象转换为 java.util.Date 的对象,您可以这样做:

Date date = Date.from(zdt.toInstant());

Trail: Date Time 了解有关现代 Date-Time API 的更多信息。

只是为了完整性

为了完整起见,我使用 Joda Date-Time API 编写了以下解决方案:

import java.util.Locale;

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "Sat Nov 01 20:08:07 UTC 2014";
        DateTimeFormatter dtf = DateTimeFormat.forPattern("E MMM d H:m:s z y").withLocale(Locale.ENGLISH);
        DateTime dt = dtf.parseDateTime(strDateTime);
        System.out.println(dt);
    }
}

输出:

2014-11-01T20:08:07.000Z

* 出于任何原因,如果您必须坚持使用 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