在 java/ Kotlin 中将日期字符串从“2020-05-08T11:01:48.3300000Z”日期时间字符串格式化为 m/d/yyyy 的正确方法是什么
What is the correct way to format a date string to m/d/yyyy from "2020-05-08T11:01:48.3300000Z" datetime string in java/ Kotlin
我正在尝试格式化从服务器接收到的 DateTime 字符串。我使用了以下格式并且 none 正在工作 - AppConstants.API_DATE_TIME_FORMAT =
- `"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"`
- `"yyyy-MM-dd'T'HH:mm:ss.SSSZ'Z'"`
- `"yyyy-MM-dd'T'HH:mm:ss.SSSZ"`
- `"yyyy-MM-dd'T'HH:mm:ss.SSSXX'Z'"`
- `"yyyy-MM-dd'T'hh:mm:ss.SSSSSS'Z'"`
and -
fun getFormattedDate(apiFormatDateTime: String): String {
return try{
val parser = SimpleDateFormat(AppConstants.API_DATE_TIME_FORMAT, Locale.getDefault())
val formatter = SimpleDateFormat(AppConstants.UI_DATE_FORMAT, Locale.getDefault())
val date = parser.parse(apiFormatDateTime)!!
formatter.format(date)
}catch (ex : Exception){
apiFormatDateTime
}
}
这个有效
String d="2020-05-08T11:01:48.3300000Z";
DateFormat originalFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'");
DateFormat targetFormat = new SimpleDateFormat("yyyyMMdd");
Date date = originalFormat.parse(d);
String formattedDate = targetFormat.format(date);
System.out.println("date==>"+formattedDate);
输出::
date==>20200508
您可以尝试使用 LocalDateTime 和 DateTimeFormatter
String str = "1986-04-08 12:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.of(1986, Month.APRIL, 8, 12, 30);
String formattedDateTime = dateTime.format(formatter); // "1986-04-08 12:30"
归功于:
您可以像下面这样尝试
try {
XMLGregorianCalendar dt = DatatypeFactory.newInstance().newXMLGregorianCalendar("2020-05-13T12:12:12.123456Z");
String dateValue = new SimpleDateFormat("MM/dd/yyyy").format(dt.toGregorianCalendar().getTime());
System.out.println("datevalue="+dateValue);
} catch (DatatypeConfigurationException e) {
e.printStackTrace();
}
输出:datevalue=05/13/2020
这是我从 UTC 格式获取日期和时间的方法 -
const val API_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'"
const val UI_DATE_FORMAT = "MM/dd/yyyy"
const val UI_TIME_FORMAT = "hh:mm:ss a"
/**
* Function for getting date from api datetime string
* @return formatted time
*/
fun getFormattedDate(apiFormatDateTime: String): String {
return try{
val parser = SimpleDateFormat(AppConstants.API_DATE_TIME_FORMAT, Locale.getDefault())
parser.timeZone = TimeZone.getTimeZone("UTC")
val formatter = SimpleDateFormat(AppConstants.UI_DATE_FORMAT, Locale.getDefault())
val date = parser.parse(apiFormatDateTime)!!
formatter.timeZone = TimeZone.getDefault()
formatter.format(date)
}catch (ex : Exception){
apiFormatDateTime
}
}
/**
* Function for getting time from api datetime string
* @return formatted time
*/
fun getFormattedTime(apiFormatDateTime: String): String {
return try{
val parser = SimpleDateFormat(AppConstants.API_DATE_TIME_FORMAT, Locale.getDefault())
parser.timeZone = TimeZone.getTimeZone("UTC")
val formatter = SimpleDateFormat(AppConstants.UI_TIME_FORMAT, Locale.getDefault())
formatter.timeZone = TimeZone.getDefault()
formatter.format(parser.parse(apiFormatDateTime)!!)
}catch (ex : Exception){
apiFormatDateTime
}
}
java.time
我建议您使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。在Java(因为这是我能写的):
ZoneId zone = ZoneId.of("Asia/Kolkata");
DateTimeFormatter uiDateFormatter = DateTimeFormatter.ofPattern("M/d/uuuu");
String isoF8601ormatDateTime = "2020-05-08T11:01:48.3300000Z";
Instant time = Instant.parse(isoF8601ormatDateTime);
String uiString = time.atZone(zone)
.format(uiDateFormatter);
System.out.println(uiString);
输出为:
5/8/2020
注意事项:
- 您的 API 的格式是 ISO 8601。java.time 的 类 将最常见的 ISO 8601 变体解析为默认格式,也就是说,我们不需要指定任何格式化程序.
- 我的代码还在格式化之前将日期转换为用户的时区。大多数用户都会期望这一点。请把你用户的时区放在我放的地方 Asia/Kolkata.
额外信息:格式化时间,也在用户的时区:
DateTimeFormatter uiTimeFormatter
= DateTimeFormatter.ofPattern("hh:mm:ss a", Locale.ENGLISH);
String uiTimeString = time.atZone(zone).format(uiTimeFormatter);
System.out.println(uiTimeString);
04:31:48 PM
您的尝试出了什么问题?
SimpleDateFormat
无法正确解析秒的 7 位小数。它只支持毫秒,正好是三位小数。 SimpleDateFormat
需要 3300000 毫秒,即 3300 秒或将近一个小时,它会添加到解析时间中。
传入字符串中的 Z
是 UTC 偏移量(零),需要这样解析,否则您将得到不正确的结果。
Z
不带引号将解析像 +0000
这样的偏移量,但不会解析 Z
。 XX
将解析 Z
,但该尝试失败了,因为您在 Z
. 之后还需要(一个)Z
- 您在格式化前没有转换为用户的时区。
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Wikipedia article: ISO 8601
我正在尝试格式化从服务器接收到的 DateTime 字符串。我使用了以下格式并且 none 正在工作 - AppConstants.API_DATE_TIME_FORMAT =
- `"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"`
- `"yyyy-MM-dd'T'HH:mm:ss.SSSZ'Z'"`
- `"yyyy-MM-dd'T'HH:mm:ss.SSSZ"`
- `"yyyy-MM-dd'T'HH:mm:ss.SSSXX'Z'"`
- `"yyyy-MM-dd'T'hh:mm:ss.SSSSSS'Z'"`
and -
fun getFormattedDate(apiFormatDateTime: String): String {
return try{
val parser = SimpleDateFormat(AppConstants.API_DATE_TIME_FORMAT, Locale.getDefault())
val formatter = SimpleDateFormat(AppConstants.UI_DATE_FORMAT, Locale.getDefault())
val date = parser.parse(apiFormatDateTime)!!
formatter.format(date)
}catch (ex : Exception){
apiFormatDateTime
}
}
这个有效
String d="2020-05-08T11:01:48.3300000Z";
DateFormat originalFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'");
DateFormat targetFormat = new SimpleDateFormat("yyyyMMdd");
Date date = originalFormat.parse(d);
String formattedDate = targetFormat.format(date);
System.out.println("date==>"+formattedDate);
输出::
date==>20200508
您可以尝试使用 LocalDateTime 和 DateTimeFormatter
String str = "1986-04-08 12:30";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.parse(str, formatter);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTime = LocalDateTime.of(1986, Month.APRIL, 8, 12, 30);
String formattedDateTime = dateTime.format(formatter); // "1986-04-08 12:30"
归功于:
您可以像下面这样尝试
try {
XMLGregorianCalendar dt = DatatypeFactory.newInstance().newXMLGregorianCalendar("2020-05-13T12:12:12.123456Z");
String dateValue = new SimpleDateFormat("MM/dd/yyyy").format(dt.toGregorianCalendar().getTime());
System.out.println("datevalue="+dateValue);
} catch (DatatypeConfigurationException e) {
e.printStackTrace();
}
输出:datevalue=05/13/2020
这是我从 UTC 格式获取日期和时间的方法 -
const val API_DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z'"
const val UI_DATE_FORMAT = "MM/dd/yyyy"
const val UI_TIME_FORMAT = "hh:mm:ss a"
/**
* Function for getting date from api datetime string
* @return formatted time
*/
fun getFormattedDate(apiFormatDateTime: String): String {
return try{
val parser = SimpleDateFormat(AppConstants.API_DATE_TIME_FORMAT, Locale.getDefault())
parser.timeZone = TimeZone.getTimeZone("UTC")
val formatter = SimpleDateFormat(AppConstants.UI_DATE_FORMAT, Locale.getDefault())
val date = parser.parse(apiFormatDateTime)!!
formatter.timeZone = TimeZone.getDefault()
formatter.format(date)
}catch (ex : Exception){
apiFormatDateTime
}
}
/**
* Function for getting time from api datetime string
* @return formatted time
*/
fun getFormattedTime(apiFormatDateTime: String): String {
return try{
val parser = SimpleDateFormat(AppConstants.API_DATE_TIME_FORMAT, Locale.getDefault())
parser.timeZone = TimeZone.getTimeZone("UTC")
val formatter = SimpleDateFormat(AppConstants.UI_TIME_FORMAT, Locale.getDefault())
formatter.timeZone = TimeZone.getDefault()
formatter.format(parser.parse(apiFormatDateTime)!!)
}catch (ex : Exception){
apiFormatDateTime
}
}
java.time
我建议您使用 java.time,现代 Java 日期和时间 API,作为您的日期和时间工作。在Java(因为这是我能写的):
ZoneId zone = ZoneId.of("Asia/Kolkata");
DateTimeFormatter uiDateFormatter = DateTimeFormatter.ofPattern("M/d/uuuu");
String isoF8601ormatDateTime = "2020-05-08T11:01:48.3300000Z";
Instant time = Instant.parse(isoF8601ormatDateTime);
String uiString = time.atZone(zone)
.format(uiDateFormatter);
System.out.println(uiString);
输出为:
5/8/2020
注意事项:
- 您的 API 的格式是 ISO 8601。java.time 的 类 将最常见的 ISO 8601 变体解析为默认格式,也就是说,我们不需要指定任何格式化程序.
- 我的代码还在格式化之前将日期转换为用户的时区。大多数用户都会期望这一点。请把你用户的时区放在我放的地方 Asia/Kolkata.
额外信息:格式化时间,也在用户的时区:
DateTimeFormatter uiTimeFormatter
= DateTimeFormatter.ofPattern("hh:mm:ss a", Locale.ENGLISH);
String uiTimeString = time.atZone(zone).format(uiTimeFormatter);
System.out.println(uiTimeString);
04:31:48 PM
您的尝试出了什么问题?
SimpleDateFormat
无法正确解析秒的 7 位小数。它只支持毫秒,正好是三位小数。SimpleDateFormat
需要 3300000 毫秒,即 3300 秒或将近一个小时,它会添加到解析时间中。
传入字符串中的 Z
是 UTC 偏移量(零),需要这样解析,否则您将得到不正确的结果。Z
不带引号将解析像+0000
这样的偏移量,但不会解析Z
。XX
将解析Z
,但该尝试失败了,因为您在Z
. 之后还需要(一个)- 您在格式化前没有转换为用户的时区。
Z
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Wikipedia article: ISO 8601