【问题标题】:How to calculate next week?下周如何计算?
【发布时间】:2015-09-16 05:31:05
【问题描述】:

我想精确计算从给定日期开始一周的时间,但我得到的输出提前一小时。

代码:

long DURATION = 7 * 24 * 60 * 60 * 1000;
System.out.println("    now: " + new Date(System.currentTimeMillis()));
System.out.println("next week: " + new Date(System.currentTimeMillis() + DURATION));

输出:

now: Wed Sep 16 09:52:36 IRDT 2015
next week: Wed Sep 23 08:52:36 IRST 2015

如何正确计算?

【问题讨论】:

  • 使用 Java 8 的 Time API,使用 JodaTime,使用 Calendar 以保持理智,但不要尝试使用毫秒算术
  • @MadProgrammer 实际上,如果你还没有使用 Joda Time,现在你最好改用threetenbp
  • 不确定CalendarUtilDate time library for gwt 是否有帮助
  • 您的原始程序运行正常。 “Wed Sep 16 09:52:36 IRDT 2015”和“Wed Sep 23 08:52:36 IRST 2015”之间的差正好是一周。如果第二个日期是“Wed Sep 23 09:52:36 IRST 2015”,则差异将是一周零一小时,这不符合您“精确计算一周时间”的要求。还是您的意思是“大约一周内同一工作日的同一时间”?
  • Duh duh du-daaaah,Rule #9

标签: java time


【解决方案1】:

永远,永远不要依赖毫秒算术,有太多的规则和陷阱使其有价值(即使在很短的时间内),而是使用专用库,如 Java 8 的 Time API、JodaTime 甚至 @ 987654321@

Java 8

LocalDateTime now = LocalDateTime.now();
LocalDateTime then = now.plusDays(7);

System.out.println(now);
System.out.println(then);

哪些输出

2015-09-16T15:34:14.771
2015-09-23T15:34:14.771

乔达时间

LocalDateTime now = LocalDateTime.now();
LocalDateTime then = now.plusDays(7);

System.out.println(now);
System.out.println(then);

哪些输出

2015-09-16T15:35:19.954
2015-09-23T15:35:19.954

日历

当您无法使用 Java 8 或 JodaTime 时

Calendar cal = Calendar.getInstance();
Date now = cal.getTime();
cal.add(Calendar.DATE, 7);
Date then = cal.getTime();

System.out.println(now);
System.out.println(then);

哪些输出

Wed Sep 16 15:36:39 EST 2015
Wed Sep 23 15:36:39 EST 2015

nb:您似乎遇到的“问题”根本不是问题,只是在此期间,您的时区似乎已进入/退出日光节省,所以Date 正在显示时间,它的偏移量是正确的

【讨论】:

  • 此代码仅在用户碰巧位于两个日期之间没有时区更改的时区时才有效。例如,添加行 - cal.setTimeZone(TimeZone.getTimeZone("Iran")); - 在您的“日历”示例中会产生不同的输出。因此,这些示例不适用于将伊朗作为默认时区的用户(例如原始发帖人)。
  • 取一个给定的日期并加上7天应该对日期的底层表示几乎没有影响,日期的格式如何表示将归结为当地的具体要求,但底层的毫秒表示将保持不变,因为它基于单个时间点。此外,我的论点不是关于日期值的格式如何改变,而是关于 dat 算术的更好机制是什么
  • 我同意。但是,结果与在 OP 的示例中添加毫秒没有任何不同。 OP 遇到的问题来自两个日期的不同时区表示,无法通过以不同方式添加 7 天来解决。
  • 那么他们并不是真正的问题(除了他们使用糟糕的方法来实现它的事实),夏令时发生变化的事实并没有改变事实结果仍然是未来+7天,有偏移
【解决方案2】:

试试这个

Calendar cal = Calendar.getInstance();

System.out.println(cal.getTime());

cal.add(Calendar.DAY_OF_MONTH, 7);

System.out.println(cal.getTime());

【讨论】:

    【解决方案3】:

    不同是因为时区不同。 IRDT 是 +0430,IRST 是 +0330

    要解决此问题,您可以使用 JodaTime

    LocalDateTime now = LocalDateTime.now();
    LocalDateTime nextweek = now.plusDays(7);
    System.out.println(now);
    System.out.println(nextweek);
    

    【讨论】:

      【解决方案4】:

      正如其他人所说。最好使用 Calendar 或 JodaTime 库。 但问题是为什么您没有得到想要的结果。 这是因为currentTimeMillis() 计算“计算机时间”和协调世界时 (UTC) 之间的时间。现在考虑以下情况。

      long DURATION = 7 * 24 * 60 * 60 * 1000;
      Date now = new Date();
      Date nextWeek = new Date(now.getTime() + DURATION);
      System.out.println("      now: " + now);
      System.out.println("next week: " + nextWeek);
      

      这里Date.getTime() 每次从格林威治标准时间 00:00:00 开始计算时间,然后在转换为字符串时将给出您当地时区的时间。

      编辑: 我错了。原因如simon所说。

      真正的“为什么”是 IRDT(伊朗夏令时)在 9 月结束 第 22 位。这就是为什么 OP 帖子中的第一个日期(9 月 16 日)是 显示为 IRDT,第二个日期(9 月 23 日)显示为 伊斯特。因为 IRST(伊朗标准时间)比 IRDT 早一小时 显示的时间是 08:52:36 而不是 09:52:36。

      【讨论】:

      • @Alen 你能告诉我你的 TImeZone 和语言环境吗?
      • 真正的“为什么”是 IRDT(伊朗夏令时)于 9 月 22 日结束。这就是为什么 OP 帖子中的第一个日期(9 月 16 日)显示为 IRDT,第二个日期(9 月 23 日)显示为 IRST。因为 IRST(伊朗标准时间)比 IRDT 早一小时,所以显示的时间是 08:52:36 而不是 09:52:36。
      猜你喜欢
      • 2014-03-08
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多