- 已关闭**。此问题需要details or clarity。当前不接受答案。
- 想要改进此问题?**添加详细信息并通过editing this post阐明问题。
4天前关闭。
此帖子已于3天前编辑并提交审核,未能重新打开帖子:
原始关闭原因未解决
Improve this question
我正在尝试将java.sql.timestamp四舍五入到最近的一天。所有的时间戳都是UTC时间。
在这个位置https://stackoverflow.com/a/60100403/9745488,我看到了一种方法来达到小时,但我似乎不能弄清楚。
1800000似乎是30分钟的毫秒,所以对我来说,12小时将是43200000ms。60000 * 60似乎是1小时的毫秒。我试着做(60000 * 60 * 24),但结果就是不正确。如何进行舍入?
public class SqlTimestamp {
public static void main(String...strings) {
Timestamp[] timestamps = {
new Timestamp(Timestamp.valueOf("2023-02-19 00:00:00.000000000").getTime()),
new Timestamp(Timestamp.valueOf("2023-02-25 23:59:59.999999999").getTime()),
new Timestamp(Timestamp.valueOf("2023-02-25 12:00:00.000000000").getTime()),
new Timestamp(Timestamp.valueOf("2023-02-25 12:29:00.000000000").getTime()),
new Timestamp(Timestamp.valueOf("2023-02-25 12:30:00.000000000").getTime()),
new Timestamp(Timestamp.valueOf("2023-02-25 12:29:59.999999999").getTime()),
};
for(int i = 0; i < timestamps.length; i++) {
System.out.println("Original timestamp value=" + timestamps[i].toString());
System.out.println("round to nearest hour=" + Timestamp.from(Instant.ofEpochMilli(((timestamps[i].getTime()+1800000)/(60000*60))*(60000*60))) );
System.out.println("round to nearest day=" + Timestamp.from(Instant.ofEpochMilli((((timestamps[i].getTime()+43200000)/(60000*60*24))*(60000*60*24)) ) ) );
}
2条答案
按热度按时间6ojccjat1#
核心问题是:
java.sql.Timestamp
对象表示不带时区信息的瞬间。这意味着,你想要的是完全不可能的-你的timestamp对象只是跟踪一个时间点,在某个时间点,在一个地区是2022年1月5日,在另一个地区是1月6日。“某个时间点”不能翻译成日期,除非把它本地化到某个时区。
如果它是
java.sql.Timestamp
,那么有两件事似乎是显而易见的:.getTimestamp()
来获得这个值,这是 * 不正确的 * -这是一个常见的错误,因为类的整个java.util.Date
层次结构都是不正确的,而且名称也很糟糕(例如,Date表示时间中的某个时刻,而根本不是日期。只需阅读例如.getYear()
上的弃用通知即可获得一些证明)。这意味着您真正需要做的是正确地从数据库中读取数据。
getDate
和getTimestamp
都是您永远不应该使用的过时方法-因为它们返回的类型是损坏的。正确的调用类似于.getObject(idx, LocalDate.class)
或.getObject(idx, ZonedDateTime.class)
。JDBC规范(v5)保证这将工作,但这里最好的事情是检查您的数据库类型实际是什么,阅读它们实际表示的内容,然后从java.time
包中选择正确的类型,然后试着确认它是否工作。如果由于某种原因,您被遗留代码卡住了,那么要知道政治时区的变化将会发生,并且会破坏一些东西(比如最新的JDK在时区文件中去掉了1970年代以前的支持,因为tzdata项目决定这么做,或者国家只是简单地切换时区。。所有欧洲大陆都将很快这样做,所以这不是一些'是的,是的,永远不会发生'的假设!)-准备好奇怪的错误,突然你的'最近的日期'四舍五入开始四舍五入上午11:20,当你期望它四舍五入下来,诸如此类的事情。
尽管如此,最好还是尽可能写得干净一些,所以,把过时的瞬时值转换成未过时的数据类型来表示瞬时值,然后从那里开始转换:
如果你真的想要'nearest',尽管这有点奇怪,但没有现成的方法可以做到这一点。在
ZonedDateTime
范围内,截断到最近的一天,加上一天,取两者的平均值,然后检查是否已经过了中点,以确定是否需要加上一天。o8x7eapl2#
我想这可能是你四舍五入到最近的一天所追求的东西: