Pac*_*ver 4 java utc parseexception java-7 datetime-parsing
我正在使用Java 1.7。
尝试转换:
2018-05-23T23:18:31.000Z
Run Code Online (Sandbox Code Playgroud)
进入
2018-05-23 23:18:31
Run Code Online (Sandbox Code Playgroud)
DateUtils类:
public class DateUtils {
public static String convertToNewFormat(String dateStr) throws ParseException {
TimeZone utc = TimeZone.getTimeZone("UTC");
SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
sdf.setTimeZone(utc);
Date convertedDate = sdf.parse(dateStr);
return convertedDate.toString();
}
}
Run Code Online (Sandbox Code Playgroud)
尝试使用它时:
String convertedDate = DateUtils.convertToNewFormat("2018-05-23T23:18:31.000Z");
System.out.println(convertedDate);
Run Code Online (Sandbox Code Playgroud)
得到以下异常:
Exception in thread "main" java.text.ParseException: Unparseable date: "2018-05-23T23:22:16.000Z"
at java.text.DateFormat.parse(DateFormat.java:366)
at com.myapp.utils.DateUtils.convertToNewFormat(DateUtils.java:7)
Run Code Online (Sandbox Code Playgroud)
我可能做错了什么?
有没有更简单的方法(例如Apache Commons lib)?
Instant.parse( "2018-05-23T23:18:31.000Z" ) // Parse this String in standard ISO 8601 format as a `Instant`, a point on the timeline in UTC. The `Z` means UTC.
.atOffset( ZoneOffset.UTC ) // Change from `Instant` to the more flexible `OffsetDateTime`.
.format( // Generate a String representing the value of this `OffsetDateTime` object.
DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" ) // Specify a formatting pattern as desired.
) // Returns a `String` object.
Run Code Online (Sandbox Code Playgroud)
2018-05-23 23:18:31
您的输入字符串为标准ISO 8601格式。
解析/生成字符串时,java.time类默认使用这些标准格式。
将T年月日部分与时分秒分开。的Z发音Zulu是“ UTC”。
您正在使用麻烦的旧日期时间类,而该类早已被java.time类取代。DateUtils也不再需要Apache ,因为您还将在java.time中找到其功能。
将该输入字符串解析为一个Instant对象。该Instant级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。
String input = "2018-05-23T23:18:31.000Z" ;
Instant instant = Instant.parse( input ) ;
Run Code Online (Sandbox Code Playgroud)
要生成另一种格式的字符串,我们需要一个更灵活的对象。该Instant班是意味着是一个基本构建块。s convert it to a使用UTC本身作为指定的UTC偏移量,让OffsetDateTime`。
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Run Code Online (Sandbox Code Playgroud)
定义格式模式以匹配所需的输出。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" ) ;
String output = odt.format( f ) ;
Run Code Online (Sandbox Code Playgroud)
提示:考虑使用一些DateTimeFormatter::ofLocalized…方法来自动对每个字符串生成进行本地化,Locale而不是对格式设置模式进行硬编码。
该java.time框架是建立在Java 8和更高版本。这些类取代麻烦的老传统日期时间类,如java.util.Date,Calendar,和SimpleDateFormat。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要类。java.sql.*
在哪里获取java.time类?
该ThreeTen-额外项目与其他类扩展java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。你可能在这里找到一些有用的类,比如Interval,YearWeek,YearQuarter,和更多。
尝试这个。您必须使用一种模式进行解析,而使用另一种模式进行格式化。
public static String convertToNewFormat(String dateStr) throws ParseException {
TimeZone utc = TimeZone.getTimeZone("UTC");
SimpleDateFormat sourceFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
SimpleDateFormat destFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sourceFormat.setTimeZone(utc);
Date convertedDate = sourceFormat.parse(dateStr);
return destFormat.format(convertedDate);
}
Run Code Online (Sandbox Code Playgroud)
对于没有 Java 1.7 限制的其他人:
从 Java 1.8 开始,您可以使用LocalDateTime和ZonedDateTime从包中完成java.time
public static void main(String[] args) {
String sourceDateTime = "2018-05-23T23:18:31.000Z";
DateTimeFormatter sourceFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
DateTimeFormatter targetFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse(sourceDateTime, sourceFormat);
String formatedDateTime = dateTime.atZone(ZoneId.of("UTC")).format(targetFormat);
System.out.println(formatedDateTime);
}
Run Code Online (Sandbox Code Playgroud)
编辑:(见评论)
引自LocalDateTime的 Oracle Java 文档:
LocalDateTime 是一个不可变的日期时间对象,表示日期时间,通常被视为年-月-日-时-分-秒。也可以访问其他日期和时间字段,例如一年中的某一天、一周中的某一天和一年中的一周。时间以纳秒精度表示。例如,值“2nd October 2007 at 13:45.30.123456789”可以存储在 LocalDateTime 中。
此类不存储或表示时区。相反,它是对日期的描述,用于生日,结合挂钟上的当地时间。如果没有偏移量或时区等附加信息,它就无法表示时间线上的瞬间。
OP 要求仅将输入字符串解析为日期时间(如年-月-日-时-分-秒)并且文档说
LocalDateTime ... 表示日期时间,通常被视为年-月-日-时-分-秒
所以这里不会丢失任何重要信息。如果用户需要使用时区...等,则该部分dateTime.atZone(ZoneId.of("UTC"))返回一个ZonedDateTime因此此时再次处理 ZimeZone。
所以不要试图强迫用户使用您在答案中提供的“唯一”解决方案。
| 归档时间: |
|
| 查看次数: |
11017 次 |
| 最近记录: |