如何将工作日和时间对象解析为今天的下一个逻辑日期?

我在字符串中有一个日期,看起来像MON 07:15 。 我正在尝试使用这段代码将其解析为Date

 System.out.println(new SimpleDateFormat("E kk:mm").parse("MON 07:15")); 

使用上面的代码,打印一个日期,内容如下:

 Mon Jan 05 07:15:00 EET 1970 

我想将日期字符串解析为下一个即将到来的日期。 在发布时,我的当地日期和时间是Fri Aug 08 11:45:00 EEST 2014 ,下一个星期一将是11日,所以我要找的结果日期是Mon Aug 11 07:15:00 EEST 2014 。 我怎么解析这个?


我将要解析的日期和时间对象将来总是存在。

我会将解析与其他所有内容分开。

解析您正在做的值,这会给出错误年份的日期。

从那时起,花时间和星期几 – 这些都是重要的事情。 你可以抛弃其他一切。

接下来,获取当前日期和时间,并执行您需要的任何操作,以便获得正确的日期/时间。 你应该考虑:

  • 你对什么时区感兴趣?
  • 如果当前时间是星期一的06:00,并且您已经被要求在星期一的07:15,这是指今天还是下周一?
  • 如果当前时间是星期一的08:00,并且您被要求在星期一的07:15,这是指今天还是下周一?

通过将解析与计算分开,可以使测试更简单二:分别测试每个操作。 我建议使用某种时钟抽象来表示“一个可以及时获取当前瞬间的对象” – 这样你就可以测试“所需日期/时间”和“当前日期/时间”的各种组合。

理想情况下,使用Java 8或Joda Time中的 java.time – 两者都比java.util.* API好得多。

你看起来像下面的东西?

  DateFormat df = new SimpleDateFormat("E kk:mm"); Date date = df.parse("MON 07:15"); Date today = new Date(); Calendar calendar = Calendar.getInstance(); Calendar calendar1 = Calendar.getInstance(); calendar.setTime(today); calendar1.setTime(date); if (calendar.get(Calendar.DAY_OF_WEEK) == calendar1.get(Calendar.DAY_OF_WEEK)) { String time = df.format(today); Date t1 = df.parse(time); if (t1.before(date)) { calendar.set(Calendar.HOUR, calendar1.get(Calendar.HOUR)); calendar.set(Calendar.MINUTE, calendar1.get(Calendar.MINUTE)); calendar.set(Calendar.SECOND, 0); System.out.println(calendar.getTime()); } else { calendar.add(Calendar.DATE, 7); calendar.set(Calendar.HOUR_OF_DAY, calendar1.get(Calendar.HOUR)); calendar.set(Calendar.MINUTE, calendar1.get(Calendar.MINUTE)); calendar.set(Calendar.SECOND, 0); System.out.println(calendar.getTime()); } } else { int toDay = calendar.get(Calendar.DAY_OF_WEEK); int givenDay = calendar1.get(Calendar.DAY_OF_WEEK); int count = 7 - toDay + givenDay; calendar.add(Calendar.DAY_OF_MONTH, count); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.HOUR_OF_DAY, calendar1.get(Calendar.HOUR)); calendar.set(Calendar.MINUTE, calendar1.get(Calendar.MINUTE)); System.out.println(calendar.getTime()); } 

出局:

  Mon Aug 11 07:15:00 IST 2014 

给我留言,告诉我你的问题是否正确。

这个答案解决了第二部分,即从今天开始的下一个逻辑日期。

避免.Date / .Calendar

与Java捆绑在一起的java.util.Date和.Calendar类非常麻烦。 避免他们。

Joda-Time或java.time

我建议学习如何使用复杂的日期时间库。 在Java中,这意味着:

  • 乔达时间
  • java.time (内置于Java 8,受Joda-Time启发)。

时区

时区对于确定日期和星期几至关重要。 使用适当的时区名称 ,不要使用3或4个字母代码。

如果忽略时区,则将隐式应用JVM的当前默认时区。 这意味着将应用程序从一台计算机移动到另一台计算机时,或者当系统管理员更改主机的时区时,或者当同一JVM中任何应用程序的任何线程中的任何Java代码决定调用setDefault 甚至在您的应用程序中执行。

示例代码以获得下一周的每周

这是使用Joda-Time 2.7的示例代码。

获得您想要/期望的时区。 如果使用UTC ,请使用常量DateTimeZone.UTC

 DateTimeZone zone = DateTimeZone.forID( "America/Montreal" ); 

获取所需的日期时间值。 我在这里使用当前时刻。

 DateTime dateTime = DateTime.now( zone ); 

指定您想要的未来星期几。 请注意,Joda-Time在一周的第一天使用明智的#1,而不是在java.util.Calendar中找到从零开始的计数。 根据国际规范和标准(不是美国常见的星期日),每周的第一天是星期一。

 int dayOfWeek = DateTimeConstants.SATURDAY; 

withDayOfWeek命令可以追溯到时间。 所以我们使用三元运算符( ?: :)来确保我们按需添加一周,以便及时前进。

 DateTime future = ( dateTime.getDayOfWeek() < dayOfWeek ) ? dateTime.withDayOfWeek( dayOfWeek ) : dateTime.plusWeeks( 1 ).withDayOfWeek( dayOfWeek ); 

您可能希望将时间调整为当天的第一时刻,以强调对当天的关注,而不是当天的特定时刻。

 future = future.withTimeAtStartOfDay(); // Adjust time-of-day to first moment of the day to stress the focus on the entire day rather than a specific moment within the day. Or use `LocalDate` class. 

转储到控制台。

 System.out.println( "Next day # " + dayOfWeek + " after " + dateTime + " is " + future ); 

跑步的时候。

 Next day # 6 after 2015-04-18T16:03:36.146-04:00 is 2015-04-25T00:00:00.000-04:00