英文:
Best way to Change java.sql.TimeStamp to UTC format in Java
问题
我已尝试多种方法之一是使用SimpleDateFormatter,现在尝试如下:
import java.sql.Timestamp;
public static String getCorrectTimeFormat(Timestamp time) {
return time.toInstant().toString();
}
但问题是,我在编写单元测试时意识到的,时间会被修改。
Timestamp timeStamp = Timestamp.valueOf("2020-07-22 12:26:51.599");
String res = UserUtil.getCorrectTimeFormat(timeStamp);
assertThat(res).isEqualTo("2020-07-22T12:26:51.599Z");
这始终无法通过,因为它会自动转换为"2020-07-22T11:26:51.599Z"。
英文:
I have tried multiple ways one of them using SimpleDateFromatter and now trying
import java.sql.Timestamp;
public static String getCorrectTimeFormat(Timestamp time) {
return time.toInstant().toString();
}
But the problem is which I realized during writing unit test is, the time gets modified.
Timestamp timeStamp = Timestamp.valueOf("2020-07-22 12:26:51.599");
String res = UserUtil.getCorrectTimeFormat(timeStamp);
assertThat(res).isEqualTo("2020-07-22T12:26:51.599Z");
This never passes as the it auto converts to "2020-07-22T11:26:51.599Z"
答案1
得分: 2
- 最好完全避免使用
java.sql.Timestamp
。我会向你展示如何做。 - 你得到的结果是正确的,正如我认为你已经发现的那样。
从数据库获取 java.time 类型
自从 JDBC 4.2 以来,我们可以直接从 ResultSet
中获取 java.time 类型。如果你的数据库值是 timestamp with time zone
(推荐),例如:
OffsetDateTime odt = rs.getObject(
"your_timestamp_with_time_zone_column", OffsetDateTime.class);
String utcString = odt.withOffsetSameInstant(ZoneOffset.UTC).toString();
如果你的数据库值是没有时区的 timestamp
(不推荐),我们只能从中获取一个 LocalDateTime
,它不定义一个特定的时间点。要转换为 Instant
,我们需要知道数据库使用的时区。例如:
ZoneId databaseTimeZone = ZoneId.of("Europe/Paris");
LocalDateTime ldt = rs.getObject(
"your_timestamp_column", LocalDateTime.class);
String utcString = ldt.atZone(databaseTimeZone)
.withZoneSameInstant(ZoneOffset.UTC)
.toString();
如果你的数据库使用了以 UTC 为偏移量的时区,最好使用 ZoneOffset
而不是 ZoneId
:
ZoneOffset databaseOffset = ZoneOffset.UTC;
LocalDateTime ldt = rs.getObject(
"your_timestamp_column", LocalDateTime.class);
String utcString = ldt.atOffset(databaseOffset).toString();
你观察到的结果是正确的
java.sql.Timestamp
以 JVM 的默认时区混淆地打印,而 Timestamp.valueOf()
同样混淆地假设了那个时区。所以假设你的时区在今年的这个时间偏移量为 +01:00(比如英国、爱尔兰、葡萄牙、摩洛哥和突尼斯等),从 2020-07-22 12:26:51.599
到 2020-07-22T11:26:51.599Z
的转换是正确的。
英文:
- It’s best to avoid
jqva.sql.Timestamp
completely. I’ll show you how. - The result you got is correct, as I think you have already discovered.
Get java.time types from your database
Since JDBC 4.2 we can directly get java.time types from a ResultSet
. If your database value is a timestamp with time zone
(recommended), for example:
OffsetDateTime odt = rs.getObject(
"your_timestamp_with_time_zone_column", OffsetDateTime.class);
String utcString = odt.withOffsetSameInstant(ZoneOffset.UTC).toString();
If your database value is a timestamp
without time zone (not recommended), we can only get a LocalDateTime
from it, which doesn’t define a point in time. To convert to Instant
we need to rely on knowing which time zone the database uses. For example:
ZoneId datebaseTimeZone = ZoneId.of("Europe/Paris");
LocalDateTime ldt = rs.getObject(
"your_timestamp_column", LocalDateTime.class);
String utcString = ldt.atZone(datebaseTimeZone)
.withZoneSameInstant(ZoneOffset.UTC)
.toString();
If your database uses UTC, which counts as an offset, it’s better to use ZoneOffset
than ZoneId
:
ZoneOffset datebaseOffset = ZoneOffset.UTC;
LocalDateTime ldt = rs.getObject(
"your_timestamp_column", LocalDateTime.class);
String utcString = ldt.atOffset(datebaseOffset).toString();
Your observed result is correct
java.sql.Timestamp
confusingly prints in the default time zone of the JVM, and Timestamp.valueOf()
equally confusingly assumes that time zone. So assuming that your time zone is at offset +01:00 at this time of year (such as Great Britain, Ireland, Portugal, Morocco and Tunesia, for example), the conversion from 2020-07-22 12:26:51.599
to 2020-07-22T11:26:51.599Z
is correct.
答案2
得分: 1
你可以使用 Java 8 的时间类 ZonedDateTime:
//1 - 默认格式
String timeStamp = "2019-03-27T10:15:30";
ZonedDateTime localTimeObj = ZonedDateTime.parse(timeStamp);
//2 - 指定格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss a z");
String timeStamp1 = "2019-03-27 10:15:30 AM";
ZonedDateTime localTimeObj1 = ZonedDateTime.parse(timeStamp1, formatter);
//从 ZonedDateTime 获取 LocalDate
LocalDate localDate = localTimeObj1.toLocalDate();
//从带有 UTC 时区的 ZonedDateTime 获取时间戳
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
英文:
You can use java 8 time ZonedDateTime class :
//1 - default pattern
String timeStamp = "2019-03-27T10:15:30";
ZonedDateTime localTimeObj = ZonedDateTime.parse(time);
//2 - specified pattern
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss a z");
String timeStamp1 = "2019-03-27 10:15:30 AM";
ZonedDateTime localTimeObj1 = ZonedDateTime.parse(timeStamp1, formatter);
//To get LocalDate from ZonedDateTime
LocalDate localDate = localTimeObj1.toLocalDate()
//To get timestamp from zoneddatetime with utc timezone
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论