我在Java上的API中使用日期。我想得到今天的日期和时间,将其写入一个类,然后写入一个csv文件(我使用csv文件作为数据存储(。然后,实现获取今天记录的报告的功能,获取报告并将其与今天的日期(确切地说是日期,没有时间(进行比较。最好的方法是什么?现在我把它存储在Timestamp中,但它似乎不正确,我应该使用String吗?那我需要两个解析器?将字符串转换为日期和时间,再将其转换为date?哪个库更适合用于此?
我写了一个从字符串到时间戳的翻译,这是正确的吗?
default Timestamp StringToTimestamp(String date) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-YYYY");
Date parsedDate = null;
try {
parsedDate = dateFormat.parse(date);
} catch (ParseException e) {
e.printStackTrace();
log.error("Error in date parsing");
}
return new Timestamp(parsedDate.getTime());
}
UPD我更改了java.time库的代码,但似乎出了问题
default LocalDate StringToTimestamp(String date) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern('yyyy-mm-dd');
LocalDate date = LocalDate.parse(date, dtf);
return date;
}
UPD我根据答案编辑了代码@OleV.V.它真的很酷
java.time
我建议您使用现代java日期和时间API java.time来进行日期和时间工作。我建议将当前日期和时间与UTC的偏移量写入CSV文件。
OffsetDateTime dateTime = OffsetDateTime.now(ZoneId.systemDefault());
String stringForCsvFile = dateTime.toString();
System.out.println(stringForCsvFile);
刚才在我的时区运行时的输出:
2020-12-26T1:07.368973+01:00
字符串是ISO 8601格式的,这应该是最好的,以避免任何阅读它的人感到意外。java.time的类通常从它们的toString
方法打印ISO 8601的格式。
通常,在编写文件时,您会将一致性的价值高于知道使用了哪个UTC偏移量。如果是,请将UTC时间写入文件:
Instant now = Instant.now();
String stringForCsvFile = now.toString();
2020-12-26T10:02:07.373439Z
无论您使用上面的哪种方式,从文件中读取时间戳后,都可以像这样转换:
ZoneId zone = ZoneId.systemDefault();
String stringFromCsvFile = "2020-12-26T11:02:07.368973+01:00";
ZonedDateTime dateTime = OffsetDateTime.parse(stringFromCsvFile)
.atZoneSameInstant(zone);
LocalDate dateFromCsv = dateTime.toLocalDate();
LocalDate today = LocalDate.now(zone);
System.out.println("Same day? " + dateFromCsv.isEqual(today));
同一天?真实
我已经确保我比较的两个日期都在程序运行的JVM的时区中。请考虑是否有您想要的特定时区,如果有,请将zone
设置为类似ZoneId.of("Asia/Baku")
的时区。重要的是:所有时区的日期都不一样。
如果您想知道日期是早还是晚,请使用LocalDate
的isBefore
或isAfter
方法。
你的代码正确吗
IMHO代码中最糟糕的问题是使用旧的、设计糟糕的日期-时间类:SimpleDateFormat
、Date
和Timestamp
。SimpleDateFormat
是一个臭名昭著的类的麻烦制造者。Date
在Java 1.0中存在严重的设计缺陷,因此大多数构造函数和方法在Java 1.1中已经被弃用。Timestamp
除了在SQL数据库之间传输高精度的时间戳(我们也不再使用它(之外,从来没有其他用途。这是对已经设计糟糕的Date
类的真正破解。此外,我看不出你想要使用Timestamp
的高精度,所以在这里使用它似乎毫无意义。
您的代码中有一个错误:您在格式模式中使用了大写YYYY
。这适用于周-年,仅适用于周数。我试着给你的方法加24-06-2021
。它返回2021-01-04 00:00:00.0
。由于上述错误,现在有5个月20天的假期。显然,SimpleDateFormat
默认为周-年中第1周的开始,而忽略了月份和日期。
顺便说一句,如果您尝试使用java.time使用相同格式的模式字符串进行解析,它至少会告诉您这是错误的。
链接
- Oracle教程:日期时间,解释如何使用java.Time
- 维基百科文章:ISO 8601
- 相关问题:迄今为止java解析字符串