如何将 java.sql.Timestamp 增加 14 天?

Posted

技术标签:

【中文标题】如何将 java.sql.Timestamp 增加 14 天?【英文标题】:How do I increment a java.sql.Timestamp by 14 days? 【发布时间】:2011-11-18 23:40:37 【问题描述】:

我有一个应用程序,它以时间戳作为 sql 选择的开始日期和结束日期的边界,我想填充一个哈希图,其中自今年的第一个星期一以来的周数作为值和周数作为钥匙。我发现使用时间戳真的很难,而且我对添加 86,400,000 秒来增加一天感觉不太好,因为这不考虑闰日、小时、秒。

我打算在上面加上 13 天 23 小时 59 分 59 秒,这样我就可以在地图中以星期为关键字查找开始日期,然后使用开始日期来获取结束日期。

所以我想尝试得到这样的东西:

Week  startDate              endDate
1     2011-01-03 00:00:00    2011-01-16 23:59:59
2     2011-01-17 00:00:00    2011-01-30 23:59:59

地图中的前两列和最后一列是在查找后计算的。如何安全地增加 java.sql.Timestamp?

【问题讨论】:

您需要担心的唯一问题是闰秒,而且每隔几年就会发生一次。如果您的程序自 1970 年以来一直在运行,它将总共关闭 24 秒。你增加 8640 万秒的计划是完全可行的。 使用 Calendar 或 Joda 怎么样? joda-time.sourceforge.net 我想真正的问题是......您是否将其确定为您的应用程序的阻止程序?如果你还没有,那就去吧。如果它是一个问题,它会出现,然后你可以解决它。 不是您问题的答案,而是一个尝试的建议:您提到时间戳用作开始日期和结束日期的边界。与其在 java 中计算结束日期时间戳,然后在查询中传递它,为什么不传递您拥有的开始日期时间戳,然后使用基于它的数据库日期/时间函数计算结束日期时间戳? 您是否有某些理由需要一个准确、包容的timestamp?为什么不使用包含->排除范围(datetimestamp)呢?所以,>= startDate AND < endDate - 然后只需添加 14 天,您根本不必担心秒... 【参考方案1】:
java.sql.Timestamp ts = ...
Calendar cal = Calendar.getInstance();
cal.setTime(ts);
cal.add(Calendar.DAY_OF_WEEK, 14);
ts.setTime(cal.getTime().getTime()); // or
ts = new Timestamp(cal.getTime().getTime());

这将在您的默认时区正确地满足白天时间的转换。如果需要,您可以告诉 Calendar 类使用不同的时区。

【讨论】:

这只会在您的虚拟机有更新列表的情况下正确考虑夏令时。 JodaTime 允许为此使用标准源 - 据推测,为此的 VM 更新一直很慢。 我怀疑更新缓慢的一个原因是“企业”用户停留在至少 10 年历史的 jvm 上......另一方面,大多数操作系统都设法保留时区列表包含所有需要的信息的信息。 jre 应该真正使用它。在我的 linux 笔记本电脑上,它似乎设置到 2499...【参考方案2】:

值得注意的是,14 天并不总是 14 * 24 * 3600 秒。当您有夏令时,这可能会更短或更长。从历史上看,它可能比这复杂得多。

相反,我建议使用 JodaTime 或 Calendar 来执行与时区相关的计算。

【讨论】:

那真的很重要吗?只要您使用 UTC,就不会遇到此问题。 SQL 大多不使用 UTC。特别是如果你没有明确提及它。 如果您使用的是 GMT 或任何没有夏令时的时区,这不是问题。我想标记 14 天可能包含没有 24 小时的一天。 Java 不支持像 GMT 那样的闰秒,但 UTC 支持。 ;)【参考方案3】:

Java 8

Timestamp old;
ZonedDateTime zonedDateTime = old.toInstant().atZone(ZoneId.of("UTC"));
Timestamp new = Timestamp.from(zonedDateTime.plus(14, ChronoUnit.DAYS).toInstant());

【讨论】:

java.security.Timestamp吗? java.sql.Timestamp? @EugeneA 是java.sql.Timestamp 为什么需要 ZonedDateTime? Timestamp new = Timestamp.from(old.toInstant().plus(14, ChronoUnit.DAYS));【参考方案4】:
private Long dayToMiliseconds(int days)
    Long result = Long.valueOf(days * 24 * 60 * 60 * 1000);
    return result;


public Timestamp addDays(int days, Timestamp t1) throws Exception
    if(days < 0)
        throw new Exception("Day in wrong format.");
    
    Long miliseconds = dayToMiliseconds(days);
    return new Timestamp(t1.getTime() + miliseconds);

【讨论】:

【参考方案5】:
Timestamp my14DaysAfter = Timestamp.valueOf(myTimestamp.toLocalDateTime().plusDays(14));

【讨论】:

那里不应该有一个减号吗? 问题是递增的......但也存在减号...... @WaiHaLee 改了,谢谢!

以上是关于如何将 java.sql.Timestamp 增加 14 天?的主要内容,如果未能解决你的问题,请参考以下文章

将 LocalDate 转换为 LocalDateTime 或 java.sql.Timestamp

Java中如何将字符串转化为Timestamp格式的 !

将 java.sql.Timestamp 类型存储到 HSQL 数据库中

将 Java 字符串转换为 sql.Timestamp

将 java.sql.Timestamp 转换为 Java 8 ZonedDateTime?

将 java.time.Instant 转换为没有区域偏移的 java.sql.Timestamp