java - 如何使用 T 和 Z 将 LocalDate 格式化为 ISO 8601?
问题描述
我正在尝试生成随机日期和时间,并将其转换为"yyyy-MM-dd'T'HH:mm:ss'Z'"
格式。
这是我尝试过的:
public static String generateRandomDateAndTimeInString() {
LocalDate date = LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70))));
System.out.println("date and time :: " + date.toString());
return formatDate(date) ;
}
public static String formatDate(LocalDate date){
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
return dateFormat.format(date);
}
但是在该行dateFormat.format(date)
中,它抱怨:
java.lang.IllegalArgumentException:无法将给定对象格式化为日期
第二个问题是, print 的输出不包含时间:
date :: 1998-12-24
我不知道如何让它工作。
解决方案
永远不要使用格式化java.time
类型SimpleDateFormat
使用SimpleDateFormat
,您应该只格式化旧的日期时间类型,例如java.util.Date
. 为了格式化java.time
日期时间类型,您需要使用DateTimeFormatter
.
永远不要用Z
单引号括起来
Z
在格式中用单引号括起来是一个错误。该符号Z
代表zulu
并指定UTC+00:00
。如果将其括在单引号中,则它仅表示字符文字,Z
并且不会UTC+00:00
在解析时起作用。
您不需要明确使用格式化程序
对于此要求,您不需要显式使用格式化程序,因为它OffsetDateTime#toString
已经以您需要的格式返回字符串。但是,如果对象中的秒数为零OffsetDateTime
,则相同的和随后的较小单位将被截断OffsetDateTime#toString
。如果您需要完整格式而不考虑seconds的值,那么当然,您将不得不使用DateTimeFormatter
.
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Random;
public class Main {
public static void main(String[] args) {
System.out.println(generateRandomDateAndTimeInString());
}
public static String generateRandomDateAndTimeInString() {
LocalDate date = LocalDate.now().minus(Period.ofDays((new Random().nextInt(365 * 70))));
System.out.println("date and time :: " + date.toString());
return formatDate(date);
}
public static String formatDate(LocalDate date) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
// return date.atStartOfDay().atOffset(ZoneOffset.UTC).toString();
return date.atStartOfDay().atOffset(ZoneOffset.UTC).format(dtf);
}
}
示例运行:
date and time :: 1996-09-05
1996-09-05T00:00:00Z
请注意,日期时间 APIjava.util
及其格式化 APISimpleDateFormat
已过时且容易出错。建议完全停止使用它们并切换到现代日期时间 API。
- 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。
- 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请通过 desugaring和How to use ThreeTenABP in Android Project检查Java 8+ APIs available。
从Trail: Date Time了解有关现代日期时间 API 的更多信息。
SimpleDateFormat
如果您仍因任何原因需要使用:
在一天的开始时转换LocalDate
为ZonedDateTime
和ZoneOffset.UTC
➡️ 转换ZonedDateTime
为Instant
➡️java.util.Date
从Instant
.
public static String formatDate(LocalDate date) {
Date utilDate = Date.from(date.atStartOfDay(ZoneOffset.UTC).toInstant());
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
return dateFormat.format(utilDate);
}
推荐阅读
- python - 比较两个表并提取与两者相似的列
- javascript - React - 如何渲染字段数组的映射(对单个表单问题的多个响应)
- javascript - Node.js - 从 javascript 文件调用 javascript 函数
- java - 使用自定义keycloak的用户存储提供者JAVA登录Mysql
- javascript - 如何使用返回的 JSON 数据过滤掉重复的名称
- android - 如何使用 getReference 访问更具体的位置?
- c - Bit bang DATA 和 CLOCK 同步问题
- java - Java AWS DynamoDB如何增加数字
- sql - SQL CASE WHEN 问题?
- python - 为什么我的 CUDA 突然可以在 Pytorch 上工作,但在 Tensorflow 上却不行?