How to check array of dates are consecutive from todays date?
从用户每次完成任务开始,我就有一系列独特的日期。我想检查数组中的日期是否连续,包括今天的日期。
如果数组包含日期:
如果数组包含日期
1 2 3 4 5 6 7 |
如果使用Java 8,请考虑使用新的JavaTimeAPI。与旧的API相比,它更容易、更少被窃听和更少出错。
如果您使用的是Java <=7,您可以使用StuteTeN后端,这是Java 8新的日期/时间类的一个很大的后端。对于Android,有三个etenabp(更多关于如何使用它)。
尽管您也可以使用jodatime,但它已经被新的API中断并替换了,我不建议用joda启动新的项目吗?即使在Joda的网站上,它也说:"请注意,Joda时间被认为是一个很大程度上"完成"的项目。没有计划进行重大改进。如果使用JavaSE 8,请迁移到JavaTimes(JSR-310)。
由于您只想比较日期(日/月/年),而不想比较时间(小时/分钟/秒),所以最好的选择是使用
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public int count(List<LocalDate> dateList, LocalDate today) { if (!dateList.contains(today)) { // today is not in the list, return 0 return 0; } int count = 0; LocalDate prev = dateList.get(0); // get first date from list for (int i = 1; i < dateList.size(); i++) { LocalDate next = dateList.get(i); if (prev.plusDays(1).equals(next)) { // difference between dates is one day count++; } else { // difference between dates is not 1 // Do what? return 0? throw exception? } prev = next; } return count + 1; // didn't count the first element, adding 1 } |
号
测试此方法:
1 2 3 4 5 6 7 8 | List<LocalDate> dateList = new ArrayList<>(); dateList.add(LocalDate.of(2017, 6, 2)); dateList.add(LocalDate.of(2017, 6, 3)); dateList.add(LocalDate.of(2017, 6, 4)); dateList.add(LocalDate.of(2017, 6, 5)); LocalDate today = LocalDate.now(); System.out.println(count(dateList, today)); // 4 |
另一个测试(当今天不在列表中时)
1 2 3 4 5 6 7 | List<LocalDate> dateList = new ArrayList<>(); dateList.add(LocalDate.of(2017, 6, 2)); dateList.add(LocalDate.of(2017, 6, 3)); dateList.add(LocalDate.of(2017, 6, 4)); LocalDate today = LocalDate.now(); System.out.println(count(dateList, today)); // 0 |
。
笔记:
- 由于没有规定在不连续的日子里该怎么做(返回
0 或抛出异常),我留下了这部分评论。但是将它添加到代码中应该很简单 如果你想把
java.util.Date 转换成LocalDate 的话,你可以这样做(使用这个答案的代码,如果你有任何问题,在这个链接中有完整的解释):我知道你想连续检查几天(所以日期之间相差一天)。但是如果你想检查上一个日期是否在下一个日期之前(不管多少天),你可以把
if (prev.plusDays(1).equals(next)) 改为if (prev.isBefore(next)) 。我不确定是不是这样,但是如果你愿意,你也可以直接把一个
String 解析成一个LocalDate (所以你不需要创建很多Date 对象),使用DateTimeFormatter :1
2DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/M/d");
LocalDate d = LocalDate.parse("2017/6/2", formatter); // 2017-06-02。
如果我理解正确的要求,您有一组按日期排序的
目前还不清楚你是否需要支持跨越年份界限,但我想是这样。我还假设列表中的所有
如果使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | public int getDateSpanCount(List<Date> dateList) { final int n = dateList.size(); final Calendar today = Calendar.getInstance(); final Calendar other = Calendar.getInstance(); int count = 0; // First search for today in the date array int posToday = -1; for (int i=0; i<n; i++) { other.setTime(dateList.get(i)); if (areSameDay(today, other)) { posToday = i; break; } } // If today is in the list, count the size of the sub-array containing today if (posToday >= 0) { count++; // count today, at least final Calendar probe = Calendar.getInstance(); // scan backwards from position of today's date for (int prevPos = posToday - 1; prevPos >= 0; prevPos--) { final Date prev = dateList.get(prevPos); probe.setTime(prev); other.add(Calendar.DAY_OF_YEAR, -1); if (areSameDay(probe, other)) { count++; other.setTime(prev); } else { break; } } // reset the other time other.setTime(today.getTime()); // scan forward from position of today's date for (int nextPos = posToday + 1; nextPos < n; nextPos++) { final Date next = dateList.get(nextPos); probe.setTime(next); other.add(Calendar.DAY_OF_YEAR, 1); if (areSameDay(probe, other)) { count++; other.setTime(next); } else { break; } } } return count; } /** Test whether two Calendar objects are set to the same day */ private static boolean areSameDay(Calendar c1, Calendar c2) { // see discussion above if dates may not all be for the local time zone return c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR) && c1.get(Calendar.DAY_OF_YEAR) == c2.get(Calendar.DAY_OF_YEAR); } |
。
有很多方法可以写得更清楚:
但是,在这种情况下,使用旧的日期类,我会这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | public static void main(String[] args) { long millisInDay = TimeUnit.DAYS.toMillis(1); List<Date> dates = Arrays.asList(new Date("2017/6/2"), new Date("2017/6/3"), new Date("2017/6/4"), new Date("2017/6/5")); System.out.println(getSequentialNumber(millisInDay, dates)); } private static int getSequentialNumber(long millisInDay, List<Date> dates) { int count = 0; Date now = setMidnight(Calendar.getInstance().getTime()); for (int i = dates.size() - 1; i >= 0; i--) { Date date = setMidnight(dates.get(i)); if (date.getTime() == now.getTime()) { count++; } now.setTime(now.getTime() - millisInDay); } return count; } private static Date setMidnight(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.MILLISECOND, 0); calendar.set(Calendar.HOUR, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.HOUR_OF_DAY, 0); return calendar.getTime(); } |