Android 从字符串创建Joda datetime UTC

Android 从字符串创建Joda datetime UTC,android,datetime,jodatime,datetime-parsing,Android,Datetime,Jodatime,Datetime Parsing,我有以下字符串,我想更改为UTC: 2017年8月24日星期四07:38:32 GMT+01:00 我在用乔达时代图书馆 我知道如何创建一个新的Datetime例如newdatetime(DateTimeZone.UTC),但是如何从上面的字符串创建Datetime对象呢 我尝试了以下操作,但出现异常。当然,必须有另一种方法来创建DT对象,而不必截断原始的字符串?如果外部API更改了向我的应用程序发送原始字符串的方式,我的字符串操作代码将失败 DateTimeFormatter df = Dat

我有以下
字符串
,我想更改为UTC:

2017年8月24日星期四07:38:32 GMT+01:00

我在用乔达时代图书馆

我知道如何创建一个新的
Datetime
例如
newdatetime(DateTimeZone.UTC)
,但是如何从上面的
字符串创建
Datetime
对象呢

我尝试了以下操作,但出现异常。当然,必须有另一种方法来创建DT对象,而不必截断原始的
字符串
?如果外部API更改了向我的应用程序发送原始
字符串的方式,我的
字符串操作代码将失败

DateTimeFormatter df = DateTimeFormat.forPattern("dd-MMM-YYYY HH:mm");
        String strOrigTime = "Thu Aug 24 07:38:32 GMT+01:00 2017";
        DateTime dt = DateTime.parse(strOrigTime, df);

        Log.e(TAG, "dt after parse = " + dt.toString());
错误:

Caused by: java.lang.IllegalArgumentException: Invalid format: "Thu Aug 24 07:38:32 GMT+01:00 2017"
    at org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:866)
    at org.joda.time.DateTime.parse(DateTime.java:144)
所使用的格式(
dd-MMM-YYYY-HH:mm
)表示:日(
dd
),后接
-
,后接月(
MMM
),后接
-
,后接年(
YYYY
)等等(更多详细信息)

此格式与输入字符串不匹配(输入字符串的前几天是星期,后几天是月,后几天是小时/分钟/秒,等等)。因此,第一件事是使用与输入匹配的格式,否则将始终出现“无效格式”错误

另一个细节是星期和月份的名称是英文的,因此您还必须使用
java.util.Locale
来指定用于解析输入的语言。如果不使用区域设置,则将使用系统默认设置,并且不能保证始终为英语(而且即使在运行时也可以更改,因此最好指定一个)

我还必须添加“GMT”作为文本,并调用
withOffsetParsed()
,使其在解析的对象中包含偏移量(
+01:00
):

DateTimeFormatter df = DateTimeFormat
    // use a pattern that matches input
    .forPattern("EEE MMM dd HH:mm:ss 'GMT'Z yyyy")
    // use English locale for day of week and month
    .withLocale(Locale.ENGLISH)
    // include the offset (+01:00) in the parsed object
    .withOffsetParsed();
String strOrigTime = "Thu Aug 24 07:38:32 GMT+01:00 2017";
DateTime dt = DateTime.parse(strOrigTime, df);
System.out.println(dt.toString());
输出为:

2017-08-24T07:38:32.000+01:00

然后,您可以将UTC时区设置为此对象:

dt = dt.withZone(DateTimeZone.UTC);
System.out.println(dt.toString());
输出将是:

2017-08-24T06:38:32.000Z

请注意,
withZone
方法保留相同的瞬间(两个日期表示相同的时间点),只是更改了输出中使用的时区。但这两个日期是相等的(它们代表相同的时刻,因为偏移量中的07:38+01:00与UTC中的06:38相同)

如果要将所有日期转换为UTC,还可以在格式化程序中设置:

// set UTC to the formatter
df = df.withZone(DateTimeZone.UTC);
然后,您不需要在
DateTime
对象中调用
withZone
:所有解析的日期都将转换为UTC


您还告诉我,“如果外部API改变了它向我的应用程序发送原始
String
的方式,我的
String
操作代码将失败”

好吧,如果输入
字符串
改变,你也必须改变你的格式-没有其他办法,Joda Time不能仅仅猜测格式是什么,你必须告诉它

如果您想解析多个格式,有一种方法可以创建一个使用许多不同模式的格式化程序,并尝试解析每一种模式,直到其中一种模式起作用(如果没有起作用,则抛出异常)。你可以这样做:

// format 1
DateTimeFormatter f1 = DateTimeFormat
    // use a pattern that matches input
    .forPattern("EEE MMM dd HH:mm:ss 'GMT'Z yyyy")
    // use English locale for day of week and month
    .withLocale(Locale.ENGLISH)
    // include the offset (+01:00) in the parsed object
    .withOffsetParsed();

// format 2
DateTimeFormatter f2 = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss Z");
// array of all possible formats
DateTimeParser[] parsers = { f1.getParser(), f2.getParser() };
// formatter that uses all the possible formats
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    // append array of possible formats
    .append(null, parsers)
    // create formatter
    .toFormatter().withLocale(Locale.ENGLISH).withOffsetParsed()
    // set all parsed objects to UTC
    .withZone(DateTimeZone.UTC);

// parse first format
System.out.println(DateTime.parse("Thu Aug 24 07:38:32 GMT+01:00 2017", formatter));
// parse second format
System.out.println(DateTime.parse("24/08/2017 07:38:32 +01:00", formatter));
这两个日期将被解析为:

2017-08-24T06:38:32.000Z

然后,您可以根据需要向数组中添加新格式


Java新的日期/时间API Joda Time处于维护模式,正在被新的API所取代,因此我不建议使用它启动新项目。甚至在文章中也提到:“请注意,Joda Time被认为是一个基本上“完成”的项目。没有计划进行重大的增强。如果使用Java SE 8,请迁移到Java.Time(JSR-310)。”

如果您不能(或不想)从Joda Time迁移到新API,可以忽略此部分

如果使用<强> java 8 < />,请考虑使用这更容易


如果您正在使用Java编程从字符串中删除起始日期“Thu”和GMT+01:00,然后转换为日期对象引用链接将帮助您@chetanmekha嗨,我已经编辑了帖子,我正在使用Joda libraryHi,哇!非常感谢您如此明确的回答,非常感谢。很好!
// format 1
DateTimeFormatter f1 = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss O yyyy", Locale.ENGLISH);
// format 2
DateTimeFormatter f2 = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss XXX");
// formatter with both formats
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    // add format 1
    .appendOptional(f1)
    // add format 2
    .appendOptional(f2)
    // create formatter
    .toFormatter(Locale.ENGLISH);
// parse first format
System.out.println(Instant.from(formatter.parse("Thu Aug 24 07:38:32 GMT+01:00 2017")));
// parse second format
System.out.println(Instant.from(formatter.parse("24/08/2017 07:38:32 +01:00")));