我为这个解析感到疯狂。 代码如下:
try {
String if_modified_since = "Sat Sep 23 23:08:37 CST 2017";
DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("EEE MMM dd HH:mm:ss zzz yyyy");
DateTime dt_if_modified_since = DateTime.parse(if_modified_since, dateTimeFormatter);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
错误消息是:
java.lang.IllegalArgumentException:格式无效:“星期六9月23日23:08:37 CST 2017”
我试过了:
dateTimeFormatter.withLocale(Locale.US);
它不起作用。 如何解决?
答案 0 :(得分:1)
我正在使用Joda-Time 2.9.9并且您的代码运行正常(“CST”被解析为America/Chicago
时区)。但它是not guaranteed to work all the time,对于所有版本和时区,甚至我得到的结果都是有争议的,因为芝加哥目前处于夏令时,所以它应该是“CDT”(甚至是javadoc关于z
模式说:时区名称('z')无法解析)。
这是因为短时区名称(例如“CST”和“EST”)是ambiguous and not standard。 “CST”可以是Central Standard Time,Cuba Standard Time和China Standard Time。在某些API中,某些名称会映射到任意默认值,但不能保证它们适用于所有这些名称。
即使我们只考虑美国的CST,也有不止一个区域(多个时区)使用它。唯一明确的名称是IANA timezones names(始终采用Region/City
格式,如America/Chicago
或Europe/Berlin
),您应该尽可能使用这些名称。
考虑您的输入(Sat Sep 23 23:08:37 CST 2017
)和发布问题的时间(以及目前美国中部地区处于夏令时的事实,they're actually in "CDT"),我的猜测是这个输入是指中国(但我可能错了,所以你必须验证这个输入产生的时区)。
无论如何,如果您对与“CST”对应的时区做出任意选择,则可以解析此String
,并使用org.joda.time.format.DateTimeFormatterBuilder
创建格式化程序。我还使用java.util.Locale
将语言设置为英语(解析月份和星期几)。如果您没有指定语言环境,它将使用JVM默认值,并且不保证始终为英语:
String if_modified_since = "Sat Sep 23 23:08:37 CST 2017";
// map of my arbritrary choices for timezones
Map<String, DateTimeZone> preferredZones = new HashMap<String, DateTimeZone>();
// CST maps to a Chinese timezone
preferredZones.put("CST", DateTimeZone.forID("Asia/Shanghai"));
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// date/time
.appendPattern("EEE MMM dd HH:mm:ss ")
// zone name - use my map of arbitrary choices
.appendTimeZoneShortName(preferredZones)
// year
.appendPattern(" yyyy")
// create formatter with English locale
.toFormatter().withLocale(Locale.US);
DateTime dt = DateTime.parse(if_modified_since, fmt);
正如我所说,我选择了Asia/Shanghai
时区,但你必须检查输入对应的正确时区是什么。您可以致电DateTimeZone.getAvailableIDs()
获取所有可用区域的列表(并选择最适合您情况的区域)。
Joda-Time处于维护模式,正在被新的API取代,因此我不建议使用它来启动新项目。即使在joda's website中它也说:“请注意,Joda-Time被认为是一个很大程度上”完成“的项目。没有计划大的增强。如果使用Java SE 8,请迁移到java.time(JSR) -310)。“即可。
如果您不能(或不想)从Joda-Time迁移到新API,则可以忽略此部分。
如果您使用的是 Java 8 ,请考虑使用new java.time API。它更容易,less bugged and less error-prone than the old APIs。
如果您使用的是 Java&lt; = 7 ,则可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。对于 Android ,您还需要ThreeTenABP(更多关于如何使用它here)。
以下代码适用于两者。
唯一的区别是包名称(在Java 8中为java.time
,在ThreeTen Backport(或Android的ThreeTenABP)中为org.threeten.bp
),但类和方法名称是相同的
代码与Joda的代码非常相似,您还必须对时区做出任意选择(由于“CST”的模糊性)。首先,我创建一个格式化程序,然后将输入解析为ZonedDateTime
(表示时区中的日期和时间的类):
String if_modified_since = "Sat Sep 23 23:08:37 CST 2017";
// set of preferred zones
Set<ZoneId> preferredZones = new HashSet<ZoneId>();
// my arbitrary choice for CST
preferredZones.add(ZoneId.of("Asia/Shanghai"));
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// date/time
.appendPattern("EEE MMM dd HH:mm:ss ")
// zone name - use my arbitrary choices
.appendZoneText(TextStyle.SHORT, preferredZones)
// year
.appendPattern(" yyyy")
// create formatter with English locale
.toFormatter(Locale.US);
ZonedDateTime z = ZonedDateTime.parse(if_modified_since, fmt);
请注意,我不需要说“CST是亚洲/上海”。 API找到短名称(CST),并使用Set
作为参考(因此选择Asia/Shanghai
),在具有该短名称的所有区域中决定使用哪个区域。
答案 1 :(得分:0)
我刚测试了你的代码,它编译并正确运行。我正在使用jodatime 1.0.3。
确保您拥有包含权:
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
答案 2 :(得分:0)
JodaTime似乎只期望工作日的两个字母(如果你使用EEE);如果我使用它,你的代码对我有用:
String if_modified_since = "Sa Sep 23 23:08:37 CST 2017";
(版本:Joda-time 2.9.9)