从字符串转换为时间戳并返回
Translating from a String to a Timestamp and back
我在 Java 上使用 API 中的日期。我想获取今天的日期和时间,将其写入 class,然后写入 csv 文件(我使用 csv 文件作为数据存储)。然后,实现获取今天记录报表的功能,获取并与今天的日期(就是日期,不带时间)进行比较。做这个的最好方式是什么?现在我将它存储在 Timestamp 中,但它似乎不正确,我应该使用 String 吗?那我需要两个解析器?要将字符串转换为日期和时间,然后再将其转换为日期?哪个库更适合用于此?
我写了一个从字符串到时间戳的翻译,这个正确吗?
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());
}
更新
我更改了 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.time,现代 Java 日期和时间 API,作为您的日期和时间工作。我建议将当前日期和时间与 UTC 的偏移量写入 CSV 文件。
OffsetDateTime dateTime = OffsetDateTime.now(ZoneId.systemDefault());
String stringForCsvFile = dateTime.toString();
System.out.println(stringForCsvFile);
刚才在我的时区运行时的输出:
2020-12-26T11:02:07.368973+01:00
字符串是ISO 8601格式,应该是最好的,以免大家阅读时感到意外。 java.time 的 classes 通常从他们的 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));
Same day? true
我已确保我比较的两个日期都在程序所在的 JVM 的时区内 运行。请考虑是否有您想要的特定时区,如果有,请将 zone
设置为 ZoneId.of("Asia/Baku")
之类的内容。这很重要:所有时区的日期都不会相同。
如果想知道日期是早还是晚,使用LocalDate
的isBefore
或isAfter
方法。
你的代码正确吗?
恕我直言,您的代码中最糟糕的问题是使用旧的且设计不佳的日期时间 classes:SimpleDateFormat
、Date
和 Timestamp
。 SimpleDateFormat
是臭名昭著的 class 麻烦制造者。 Date
在 Java 1.0 中有严重的设计缺陷,因此大多数构造函数和方法在 Java 1.1 中已经被弃用。 Timestamp
除了在 SQL 数据库之间传输高精度时间戳(我们也不再使用它)之外,从来没有用于其他目的。在已经设计得很糟糕的 Date
class 之上,这是一个真正的 hack。此外,我没有看到您想要使用 Timestamp
的高精度,因此在这里使用它似乎毫无意义。
您的代码中存在错误:您在格式模式中使用了大写 YYYY
。这适用于周年,仅对周数有用。我试着给你的方法 24-06-2021
。它返回 2021-01-04 00:00:00.0
。由于提到的错误,它休息了 5 个月 20 天。显然 SimpleDateFormat
默认为周年第 1 周的开始,并忽略月份和日期。
顺便说一句,如果您尝试使用与 java.time 相同的格式模式字符串进行解析,它至少会告诉您这是错误的。
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Wikipedia article: ISO 8601
- Related question: java parsing string to date
我在 Java 上使用 API 中的日期。我想获取今天的日期和时间,将其写入 class,然后写入 csv 文件(我使用 csv 文件作为数据存储)。然后,实现获取今天记录报表的功能,获取并与今天的日期(就是日期,不带时间)进行比较。做这个的最好方式是什么?现在我将它存储在 Timestamp 中,但它似乎不正确,我应该使用 String 吗?那我需要两个解析器?要将字符串转换为日期和时间,然后再将其转换为日期?哪个库更适合用于此?
我写了一个从字符串到时间戳的翻译,这个正确吗?
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());
}
更新 我更改了 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.time,现代 Java 日期和时间 API,作为您的日期和时间工作。我建议将当前日期和时间与 UTC 的偏移量写入 CSV 文件。
OffsetDateTime dateTime = OffsetDateTime.now(ZoneId.systemDefault());
String stringForCsvFile = dateTime.toString();
System.out.println(stringForCsvFile);
刚才在我的时区运行时的输出:
2020-12-26T11:02:07.368973+01:00
字符串是ISO 8601格式,应该是最好的,以免大家阅读时感到意外。 java.time 的 classes 通常从他们的 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));
Same day? true
我已确保我比较的两个日期都在程序所在的 JVM 的时区内 运行。请考虑是否有您想要的特定时区,如果有,请将 zone
设置为 ZoneId.of("Asia/Baku")
之类的内容。这很重要:所有时区的日期都不会相同。
如果想知道日期是早还是晚,使用LocalDate
的isBefore
或isAfter
方法。
你的代码正确吗?
恕我直言,您的代码中最糟糕的问题是使用旧的且设计不佳的日期时间 classes:SimpleDateFormat
、Date
和 Timestamp
。 SimpleDateFormat
是臭名昭著的 class 麻烦制造者。 Date
在 Java 1.0 中有严重的设计缺陷,因此大多数构造函数和方法在 Java 1.1 中已经被弃用。 Timestamp
除了在 SQL 数据库之间传输高精度时间戳(我们也不再使用它)之外,从来没有用于其他目的。在已经设计得很糟糕的 Date
class 之上,这是一个真正的 hack。此外,我没有看到您想要使用 Timestamp
的高精度,因此在这里使用它似乎毫无意义。
您的代码中存在错误:您在格式模式中使用了大写 YYYY
。这适用于周年,仅对周数有用。我试着给你的方法 24-06-2021
。它返回 2021-01-04 00:00:00.0
。由于提到的错误,它休息了 5 个月 20 天。显然 SimpleDateFormat
默认为周年第 1 周的开始,并忽略月份和日期。
顺便说一句,如果您尝试使用与 java.time 相同的格式模式字符串进行解析,它至少会告诉您这是错误的。
链接
- Oracle tutorial: Date Time 解释如何使用 java.time.
- Wikipedia article: ISO 8601
- Related question: java parsing string to date