Java 将时间字符串转换为ISO 8601格式
我正在尝试创建一个字符串,格式类似于2015-08-20T08:26:21.000ZJava 将时间字符串转换为ISO 8601格式,java,string,time,Java,String,Time,我正在尝试创建一个字符串,格式类似于2015-08-20T08:26:21.000Z to2015-08-20T08:26:21Z 我知道这可以通过一些字符串拆分技术来实现,但我想知道是否有一个优雅的解决方案(只需对代码进行最小的更改) 以上两个都是时间字符串,我需要的最后一个是ISO8601中的日期 我试过一些类似的问题,比如,但它们实际上并不能解决问题 还尝试使用: SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ
to2015-08-20T08:26:21Z 我知道这可以通过一些字符串拆分技术来实现,但我想知道是否有一个优雅的解决方案(只需对代码进行最小的更改) 以上两个都是时间字符串,我需要的最后一个是ISO8601中的日期 我试过一些类似的问题,比如,但它们实际上并不能解决问题 还尝试使用:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
String nowAsString = df.format(new Date());
但它仍然不进行任何字符串到字符串的转换。获取以下错误:
23:04:13829警告[RuntimeExceptionMapper]捕获的RuntimeException:{}:java.lang.IllegalArgumentException:无法将给定对象格式化为日期
有人可以推荐的图书馆吗
谢谢 您的格式不正确,请尝试以下方法:-
try {
String s = "2015-08-20T08:26:21.000Z";
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
Date d = df.parse(s);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
System.out.println(sdf.format(d));
} catch (ParseException e) {
e.printStackTrace();
}
tl;博士
2015-08-20T08:26:21Z
日期时间格式化程序
如果您只想消除.000
,则使用日期时间对象解析输入字符串值,然后以不同格式生成该日期时间值的新字符串表示形式
ISO 8601
顺便说一下,如果这是您的目标,那么问题的标题就没有意义了,因为第一句中提到的两个字符串都是有效的格式化字符串
2015-08-20T08:26:21.000Z
2015-08-20T08:26:21Z
DateTimeFormatter.ISO\u INSTANT
调用瞬间会使用格式化程序实例生成日期时间值的字符串表示形式。此格式化程序在小数秒左右自动灵活。如果该值有整秒,则不会生成小数点(显然是问题想要的)。对于分数秒,数字以3、6或9为一组显示,以表示高达纳秒分辨率的值。注:此格式可能超过ISO 8601的毫秒限制(小数点后3位)
示例代码
下面是Java8Update51中的一些示例代码
String output = Instant.parse( "2015-08-20T08:26:21.000Z" ).toString( );
System.out.println("output: " + output );
输出:2015-08-20T08:26:21Z
更改为小数秒,.08
String output = Instant.parse( "2015-08-20T08:26:21.08Z" ).toString( );
输出:2015-08-20T08:26:21.080Z
如果对UTC以外的任何时区感兴趣,则从该即时创建一个对象
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , ZoneId.of( "America/Montreal" ) ) ;
可以使用两个DateFormat
对象将未知格式的日期字符串
转换为使用已知格式的日期字符串
,一个动态配置为解析输入字符串
的格式,另一个配置为生成格式化输出字符串
。对于您的情况,输入String
格式未指定,必须由调用者提供,但是,输出String
格式可以配置为使用ISO 8601格式,而无需额外输入。本质上,生成ISO 8601格式化日期字符串
输出需要调用者提供两个输入-一个字符串
包含格式化日期,另一个字符串
包含SimpleDataFormat
格式
以下是描述为Java代码的转换(我故意省略了空检查和验证,根据您的代码添加它们):
如果要修改该方法,请注意,SimpleDateFormat
不是线程安全的,如果没有多线程代码的变通方法,您不应该在静态上下文中使用它(ThreadLocal
通常用于SimpleDateFormat
的变通方法)
另一个“问题”是在构建SimpleDataFormat
对象期间使用Locale
——不要删除Locale
配置。允许系统选择使用默认的区域设置是不安全的,因为这是用户/机器特定的。如果您允许它使用默认的区域设置
,您将面临暂时性错误的风险,因为您的开发机器使用的区域设置
与最终用户的区域设置
不同。您不必使用我选择的英语区域设置
,使用不同的区域设置完全可以(您应该理解该区域设置
的规则,并根据需要修改代码)。然而,noLocale
的规范和系统默认值的使用是不正确的,并且可能会导致在诊断难以捉摸的bug时花费很多令人沮丧的时间
请理解,对于Java8和包含基于JodaTime的类(如Instant
),此解决方案并不理想。我选择使用过时的API来回答问题,因为在你的问题中,这些似乎是你所关心的。如果您使用的是Java 8,我强烈建议您学习和使用这些新类,因为它们在几乎所有可能的方面都是一种改进。使用。请参阅:输入和输出都是字符串。但这些字符串实际上代表不同的时区。DateFormat进行字符串到日期和日期到字符串的转换。您需要字符串到字符串的转换。因此,您可以使用DateFormat进行字符串到日期的转换,而使用另一个进行日期到字符串的转换。不,它们并不代表不同的时区。一个有毫秒部分,另一个没有。这是唯一的区别。最后一个Z表示祖鲁时间,即UTC时区.So org.joda.time.format.DateTimeFormatter?@CodeMonkey所以您的目标是消除.000
?您的标题很混乱,因为f中的两个日期时间字符串
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , ZoneId.of( "America/Montreal" ) ) ;
private String formatDateAsIso8601(final String inputDateAsString, final String inputStringFormat) throws ParseException {
final DateFormat iso8601DateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'", Locale.ENGLISH);
iso8601DateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
final DateFormat inputDateFormatter = new SimpleDateFormat(inputStringFormat, Locale.ENGLISH);
final Date inputDate = inputDateFormatter.parse(inputDateAsString);
return iso8601DateFormatter.format(inputDate);
}