我正在尝试转换String
+时区中的Date
。
我从DateTime
变量(此处:xyz)获取我的字符串。
我的代码:
String abc = xyz.toString("yyyy-MM-ddZZ");
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-ddXXX");
java.util.Date date = sdf.parse(abc);
System.out.println("Date: " + sdf.format(date));
错误:
格式无效:“2017-01-03 + 01:00”格式错误为“+01:00”
如果我尝试SimpleDateFormat("yyyy-MM-dd");
它有效,但没有时区(“+01:00”)
答案 0 :(得分:1)
输入有一个日期 - 年,月,日 - 和偏移量 - difference from UTC - 但要构建java.util.Date
,您还需要时间:小时,分钟,秒,分数秒。
SimpleDateFormat
非常糟糕,因为它有一些“魔力”,将缺少的字段设置为默认值。另一个问题是X
模式不适用于所有Java版本,文档也很糟糕。
您可以使用新的Java 8类,如上所述。使用它们,您可以解析输入,选择要用于时间字段的默认值并转换为java.util.Date
,如果这是您需要的:
DateTimeFormatter fmt = new DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_OFFSET_DATE)
// set hour to midnight
.parseDefaulting(ChronoField.HOUR_OF_DAY, 0).toFormatter();
OffsetDateTime odt = OffsetDateTime.parse("2017-01-03+01:00", fmt); // 2017-01-03T00:00+01:00
OffsetDateTime
将时间设置为午夜,但您可以将其更改为您需要的任何值,而使用SimpleDateFormat
则不可能,因为它使用内部默认值而您不能控制它。
并且日期和偏移量已正确设置为输入字符串中的值。如果您愿意,可以转换为java.util.Date
:
Date date = Date.from(odt.toInstant());
如果您愿意,您还可以获得日期的各个“部分”:
// get just the date
LocalDate localDate = odt.toLocalDate(); // 2017-01-03
// get just the offset
ZoneOffset offset = odt.getOffset(); // +01:00
PS:偏移+01:00
不与时区相同。查看差异here
答案 1 :(得分:0)
String abc = "2017-01-03+01:00";
TemporalAccessor parsed = DateTimeFormatter.ISO_OFFSET_DATE.parse(abc);
LocalDate date = LocalDate.from(parsed);
ZoneOffset offset = ZoneOffset.from(parsed);
System.out.println("Date: " + date + "; offset: " + offset + '.');
打印:
Date: 2017-01-03; offset: +01:00.
我使用的是现代Java日期和时间API java.time
,建议您也这样做。 Date
课程已经过时(对不起,没有双关语),SimpleDateFormat
尤其出了名的麻烦。不要使用它们。现代API可以更好地使用。只有当您无法更改遗留API的java.util.Date
和/或java.util.TimeZone
时,才能进行以下转换:
Date oldfashionedDate = Date.from(date.atStartOfDay(offset).toInstant());
TimeZone oldfashionedTimeZone = TimeZone.getTimeZone(offset);
System.out.println("Old-fashioned date: " + oldfashionedDate
+ "; old-fashioned time-zone: " + oldfashionedTimeZone.getDisplayName() + '.');
在我的电脑上打印:
Old-fashioned date: Tue Jan 03 00:00:00 CET 2017; old-fashioned time-zone: GMT+01:00.
我恰好处于一个与UTC偏移相符的时区,因此转换已经给出了正确的结果。在其他时区,输出会更加混乱,因为Date.toString()
使用JVM的时区设置来生成字符串,但Date
仍然是正确的。
日期 时区? LocalDate
和Date
都不能包含时区,因此您需要分别有偏移信息。有趣的是,您的字符串似乎遵循“ISO-8601-like”格式的偏移日期,甚至由名称中包含ISO的内置格式化程序表示。如果Java包含OffsetDate
或ZonedDate
类,我希望这样的类将您的字符串解析为一个对象,甚至没有明确的格式化程序。不幸的是,据我所知,即使在ThreeTen-Extra项目中也没有这样的课程。
<强>链接强>
java.time
。java.time
一起开发了更多类。答案 2 :(得分:0)
&#34; 2017年1月3日+ 01:00&#34;
我认为它类似于ISO 8601格式的日期字符串,但实际上不是ISO 8601。感谢@Meno Hochschild和@Basil Bourque的指示。
很幸运,此方法适用于此类格式的字符串:javax.xml.bind.DatatypeConverter.parseDateTime
,它将返回Calendar
:
System.out.println(DatatypeConverter.parseDate("2017-01-03+01:00").getTime());
输出:
Tue Jan 03 07:00:00 CST 2017
从方法javadoc:
public static Calendar parseDate(String lexicalXSDDate)
将字符串参数转换为Calendar值
参数:lexicalXSDDate - 包含词法的字符串 xsd的表示:日期。
返回:由...表示的Calendar值 字符串参数。
抛出:IllegalArgumentException - 如果是string 参数不符合XML中定义的词汇值空间 架构第2部分:xsd的数据类型:日期。