如何转换UTC日期字符串并删除Java中的T和Z?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/50498949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert UTC Date String and remove the T and Z in Java?
提问by PacificNW_Lover
Am using Java 1.7.
我使用的是 Java 1.7。
Trying to convert:
尝试转换:
2018-05-23T23:18:31.000Z
into
进入
2018-05-23 23:18:31
DateUtils class:
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();
}
}
When trying to use it:
尝试使用它时:
String convertedDate = DateUtils.convertToNewFormat("2018-05-23T23:18:31.000Z");
System.out.println(convertedDate);
Get the following exception:
得到以下异常:
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)
What am I possibly doing wrong?
我可能做错了什么?
Is there an easier way to do is (e.g. Apache Commons lib)?
有没有更简单的方法(例如Apache Commons lib)?
采纳答案by jkumaranc
Try this. You have to use one pattern for parsing and another for formatting.
尝试这个。您必须使用一种模式进行解析,使用另一种模式进行格式化。
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);
}
回答by M?nh Quy?t Nguy?n
YYYY
does not match with year part. In java 7 you need yyyy
.
YYYY
与年份部分不匹配。在 Java 7 中,您需要yyyy
.
For T
, use 'T'
to match it
对于T
,使用'T'
来匹配它
You're also missing the faction of millsecond part: .SSS
您还缺少毫秒部分的派系: .SSS
Try this:
尝试这个:
String dateStr="2018-05-23T23:18:31.000Z";
TimeZone utc = TimeZone.getTimeZone("UTC");
SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss.SSS'Z'");
sdf.setTimeZone(utc);
Date convertedDate = sdf.parse(dateStr);
convertedDate.toString();
回答by Rami.Q
For others without Java 1.7 Restrictions:
对于没有 Java 1.7 限制的其他人:
Since Java 1.8 you can do it using LocalDateTime
and ZonedDateTime
from the package java.time
从 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);
}
EDIT: (see Comments)
编辑:(见评论)
Quote from the Oracle Java documentation of LocalDateTime:
引自LocalDateTime的 Oracle Java 文档:
LocalDateTime is an immutable date-time object that represents a date-time, often viewed as year-month-day-hour-minute-second. Other date and time fields, such as day-of-year, day-of-week and week-of-year, can also be accessed. Time is represented to nanosecond precision. For example, the value "2nd October 2007 at 13:45.30.123456789" can be stored in a LocalDateTime.
This class does not store or represent a time-zone. Instead, it is a description of the date, as used for birthdays, combined with the local time as seen on a wall clock. It cannot represent an instant on the time-line without additional information such as an offset or time-zone.
LocalDateTime 是一个不可变的日期时间对象,表示日期时间,通常被视为年-月-日-时-分-秒。也可以访问其他日期和时间字段,例如一年中的某一天、一周中的某一天和一年中的一周。时间以纳秒精度表示。例如,值“2nd October 2007 at 13:45.30.123456789”可以存储在 LocalDateTime 中。
此类不存储或表示时区。相反,它是对日期的描述,用于生日,结合挂钟上的当地时间。如果没有偏移量或时区等附加信息,它就无法表示时间线上的瞬间。
the OP is asking to JUST parsing an Input String to a date-time (as year-month-day-hour-minute-second) and the Documentation says
OP 要求仅将输入字符串解析为日期时间(如年-月-日-时-分-秒)并且文档说
LocalDateTime ... represents a date-time, often viewed as year-month-day-hour-minute-second
LocalDateTime ... 表示日期时间,通常被视为年-月-日-时-分-秒
so no important information are lost here. And the part dateTime.atZone(ZoneId.of("UTC"))
returns a ZonedDateTime
so the ZimeZone is handled at this point again if the user needs to work with the timezone ...etc.
所以这里不会丢失任何重要信息。如果用户需要使用时区...等,则该部分dateTime.atZone(ZoneId.of("UTC"))
返回一个ZonedDateTime
因此此时再次处理 ZimeZone。
so don't try to force users to use the "One and Only" solution you present in your answer.
所以不要试图强迫用户使用您在答案中提供的“唯一”解决方案。
回答by Basil Bourque
tl;dr
tl;博士
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.
2018-05-23 23:18:31
2018-05-23 23:18:31
ISO 8601
ISO 8601
Your input string is in standard ISO 8601format.
您的输入字符串采用标准ISO 8601格式。
The java.timeclasses use these standard formats by default when parsing/generating strings.
所述java.time类解析/生成字符串时默认使用这些标准格式。
The T
separates the year-month-day portion from the hour-minute-second. The Z
is pronounced Zulu
and means UTC.
将T
年-月-日部分与时-分-秒分开。TheZ
的发音Zulu
是UTC。
java.time
时间
You are using troublesome old date-time classes that were supplanted years ago by the java.timeclasses. The Apache DateUtils
is also no longer needed, as you will find its functionality in java.timeas well.
您正在使用麻烦的旧日期时间类,这些类在多年前被java.time类取代。ApacheDateUtils
也不再需要,因为您也将在java.time 中找到它的功能。
Parse that input string as a Instant
object. The Instant
class represents a moment on the timeline in UTCwith a resolution of nanoseconds(up to nine (9) digits of a decimal fraction).
将该输入字符串解析为Instant
对象。该Instant
级表示时间轴上的时刻UTC,分辨率为纳秒(最多小数的9个位数)。
String input = "2018-05-23T23:18:31.000Z" ;
Instant instant = Instant.parse( input ) ;
To generate a string in another format, we need a more flexible object. The Instant
class is meant to be a basic building block. Lets convert it to a
OffsetDateTime`, using UTC itself as the specified offset-from-UTC.
要生成另一种格式的字符串,我们需要一个更灵活的对象。该Instant
班是意味着是一个基本构建块。让s convert it to a
OffsetDateTime`,使用 UTC 本身作为指定的 UTC 偏移量。
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
Define a formatting pattern to match your desired output.
定义格式模式以匹配所需的输出。
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuu-MM-dd HH:mm:ss" ) ;
String output = odt.format( f ) ;
Tip: Consider using DateTimeFormatter::ofLocalized…
methods to automatically localize the String generation per some Locale
rather than hard-coding a formatting pattern.
提示:考虑使用DateTimeFormatter::ofLocalized…
方法来自动本地化每个字符串的生成,Locale
而不是硬编码格式模式。
About java.time
关于java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*
classes.
您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, Java SE 10, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android (<26), the ThreeTenABPproject adapts ThreeTen-Backport(mentioned above). See How to use ThreeTenABP….
- Java SE 8、Java SE 9、Java SE 10及更高版本
- 内置。
- 具有捆绑实现的标准 Java API 的一部分。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 多的java.time功能后移植到Java 6和7在ThreeTen-反向移植。
- 安卓
- java.time 类的更高版本的 Android 捆绑实现。
- 对于早期的 Android(<26),ThreeTenABP项目采用了ThreeTen-Backport(上面提到过)。请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
回答by Jose
In Kotlin and using ThreeTenABP,
在 Kotlin 中并使用 ThreeTenABP,
fun getIsoString(year: Int, month: Int, day: Int): String {
val localTime = ZonedDateTime.of(year, month, day, 0, 0, 0, 0, ZoneId.of("Z"))
val utcTime = localTime.toOffsetDateTime().withOffsetSameInstant(ZoneOffset.UTC)
val isoString = utcTime.toInstant().toString() // 1940-15-12T00:00:00Z
val formattedIsoString = val formattedIsoString =
Instant.parse(isoString)
.atOffset(ZoneOffset.UTC)
.format(DateTimeFormatter
.ofPattern("uuuu-MM-dd'T'HH:mm:ss")) // 'T' in quotes so that it is retained.
return formattedIsoString
}
// print it
print(getIsoString(1940, 15, 12)) // 1940-15-12T00:00:00