Java 如何检查日期数组是否从今天开始连续?

Java 如何检查日期数组是否从今天开始连续?,java,arrays,date,date-comparison,Java,Arrays,Date,Date Comparison,我有一个从用户每次完成任务开始的唯一日期数组。我想检查数组中的日期是否与今天的日期(包括今天的日期)连续 如果数组包含日期:“2017/6/2、2017/6/3、2017/6/4、2017/6/5”,则根据今天的日期为2017/6/5,函数将返回4,因为从今天开始并包括今天,有4个连续的日期 如果数组包含日期“2017/6/22017/6/32017/6/4”,则它将返回0,因为数组不包含今天的日期。否则,计数将在非连续日期中断 List<Date> dateList = new A

我有一个从用户每次完成任务开始的唯一日期数组。我想检查数组中的日期是否与今天的日期(包括今天的日期)连续

如果数组包含日期:
“2017/6/2、2017/6/3、2017/6/4、2017/6/5”
,则根据今天的日期为
2017/6/5
,函数将返回
4
,因为从今天开始并包括今天,有4个连续的日期

如果数组包含日期
“2017/6/22017/6/32017/6/4”
,则它将返回
0
,因为数组不包含今天的日期。否则,计数将在非连续日期中断

List<Date> dateList = new ArrayList<Date>();
int count = 0;
Date todayDate = new Date();

for (int i=0; i<dateList.size(); i++){
    // Check if dates within the array are consecutive from todayDate, if so then increment count by 1.
}
List dateList=new ArrayList();
整数计数=0;
Date todayDate=新日期();

对于(int i=0;i有很多方法可以更清晰地书写它:

  • 使用新的日期API
  • 使用图书馆
  • 但是,在这种情况下,使用旧的日期类,我会这样做:

    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();
    }
    
    publicstaticvoidmain(字符串[]args){
    long millisInDay=时间单位.DAYS.toMillis(1);
    列表日期=数组。asList(新日期(“2017/6/2”)、新日期(“2017/6/3”)、新日期(“2017/6/4”)、新日期(“2017/6/5”);
    System.out.println(getSequentialNumber(毫秒,日期));
    }
    私有静态int getSequentialNumber(长百万天,列表日期){
    整数计数=0;
    datenow=setMidnight(Calendar.getInstance().getTime());
    对于(int i=dates.size()-1;i>=0;i--){
    Date Date=setMidnight(dates.get(i));
    if(date.getTime()==now.getTime()){
    计数++;
    }
    now.setTime(now.getTime()-millisInDay);
    }
    返回计数;
    }
    私有静态日期设置午夜(日期){
    日历=Calendar.getInstance();
    日历。设置时间(日期);
    calendar.set(calendar.MINUTE,0);
    calendar.set(calendar.毫秒,0);
    日历.set(calendar.HOUR,0);
    calendar.set(calendar.SECOND,0);
    calendar.set(calendar.HOUR\u OF_DAY,0);
    返回calendar.getTime();
    }
    
    有很多方法可以让它写得更清楚:

  • 使用新的日期API
  • 使用图书馆
  • 但是,在这种情况下,使用旧的日期类,我会这样做:

    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();
    }
    
    publicstaticvoidmain(字符串[]args){
    long millisInDay=时间单位.DAYS.toMillis(1);
    列表日期=数组。asList(新日期(“2017/6/2”)、新日期(“2017/6/3”)、新日期(“2017/6/4”)、新日期(“2017/6/5”);
    System.out.println(getSequentialNumber(毫秒,日期));
    }
    私有静态int getSequentialNumber(长百万天,列表日期){
    整数计数=0;
    datenow=setMidnight(Calendar.getInstance().getTime());
    对于(int i=dates.size()-1;i>=0;i--){
    Date Date=setMidnight(dates.get(i));
    if(date.getTime()==now.getTime()){
    计数++;
    }
    now.setTime(now.getTime()-millisInDay);
    }
    返回计数;
    }
    私有静态日期设置午夜(日期){
    日历=Calendar.getInstance();
    日历。设置时间(日期);
    calendar.set(calendar.MINUTE,0);
    calendar.set(calendar.毫秒,0);
    日历.set(calendar.HOUR,0);
    calendar.set(calendar.SECOND,0);
    calendar.set(calendar.HOUR\u OF_DAY,0);
    返回calendar.getTime();
    }
    
    <代码> > p>如果使用<强> java 8 < /强>,考虑使用它。它更容易,


    如果使用的是 < > >使用<强> java 8 < /强>,考虑使用它。


    如果您使用的是Java如果我正确理解了这个需求,那么您就有一个
    Date
    对象数组,按日期排序,并保证不会在同一天有两个
    Date
    对象,但可能在两天之间有间隔。您的目标是返回只包含连续数据的最大子数组的长度天,还包括当前日期,如果没有这样的子数组,则返回0。当前日期可能位于该子数组中的任何位置,不一定在开始或结束处

    不清楚您是否需要支持跨年度边界,但我会这样假设。我还假设列表中的所有
    Date
    对象都位于同一时区,该时区也是您运行的设备的时区。如果不是这样,您应该参考以获取有关测试两个
    日期是否相同的更多信息对象指的是同一天

    如果您使用
    Calendar
    对象而不是
    Date
    对象,那么执行此操作相当简单。您不需要任何第三方库,因为
    Date
    Calendar
    都是标准Android API的一部分。我建议分两个阶段执行此操作:首先在数组中搜索当前日期,然后扫描In两个方向上的日期间隔或数组边界。然后只需计算每个方向上可以走多远

    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);
    }
    
    public int getDateSpanCount(列表日期列表){
    final int n=dateList.size();
    今天的最终日历=Calendar.getInstance();
    最终日历其他=Calendar.getInstance();
    整数计数=0;
    //在日期数组中首次搜索今天
    int posToday=-1;
    对于(int i=0;i=0){
    计数+++;//至少今天计数
    final Calendar probe=Calendar.getInstance();
    //从今天日期的位置向后扫描
    对于(int-prevPos=posToday-1;prevPos>=0;prevPos--){
    最终日期prev=dateList.get(prevPos);
    探头设置时间(上一次);
    其他。添加(日历日/年份,-1);
    如果(A每日(探头、其他)){
    计数++;
    其他.设置时间(上一次);
    }否则{
    打破
    }
    }
    //其他时间重置
    other.setTime(today.getTime());
    //从今天日期的位置向前扫描
    对于(int-nextPos=posToday+1;nextPosList<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
    
    public LocalDate convert(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }
    
    // if your Date has no toInstant method, try this:
    public LocalDate convert(Date date) {
        return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
    }
    
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/M/d");
    LocalDate d = LocalDate.parse("2017/6/2", formatter); // 2017-06-02
    
    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);
    }