【问题标题】:How do I increment a java.sql.Timestamp by 14 days?如何将 java.sql.Timestamp 增加 14 天?
【发布时间】: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?为什么不使用包含->排除范围(date 或 timestamp)呢?所以,>= startDate AND < endDate - 然后只需添加 14 天,您根本不必担心秒...

标签: java sql timestamp increment


【解决方案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 改了,谢谢!
    猜你喜欢
    • 2016-12-24
    • 2011-03-15
    • 2018-02-06
    • 2014-11-23
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    • 2021-05-19
    相关资源
    最近更新 更多