【问题标题】:Sort an array of dates based on the current date根据当前日期对日期数组进行排序
【发布时间】:2013-12-09 08:01:02
【问题描述】:

我有一个数组:

|YYYY-MM-DD||YYYY-MM-DD||YYYY-MM-DD||...||....||....

现在我向系统查询当前日期,并根据该日期对数组进行排序,年份无关紧要,月份和日期很重要。我想要索引 0 处最近的日期和最后的最远日期。

例如有三个日期 1999-04-04、1789-03-01、2012-05-04

如果是四月份: 排序后的数组应该像

1999-04-04、2012-05-04、1789-03-01。

我在寻找逻辑,而不是要求做功课。我读了很多关于这个主题的书,但我无法设计出一条道路。帮助将不胜感激。

【问题讨论】:

  • 实现比较器并使用 compare()。你可以添加逻辑来忽略年份,只检查月份和日期..
  • 好的,让我检查一下。
  • 您可以尝试实现 Comparator 并使用 Days.daysBetween(date1,date2) 检查您在 public int compare(T o1, T o2) 中的日期

标签: java arrays sorting date


【解决方案1】:

我希望我的数组被排序,年份与月份和日期无关 是重要的。我想要索引 0 处最近的日期和最远的日期 最后日期。

您需要首先根据月份和日期进行排序:在比较任意两个日期时ঃ

首先对日期列表进行排序:

  1. 比较月份,如果它们不相等,则返回差值(月 1 - 月 2)作为比较结果
  2. 如果月份相等,则返回当月的差值作为比较结果

所以实现的Comparable<Date>compareTo(Date o) 函数看起来像:

    @Override
    public int compareTo(Date o) {
    Calendar cal1 = Calendar.getInstance();
    cal1.setTime(this.date);
    Calendar cal2 = Calendar.getInstance();
    cal2.setTime(o);

    int month1 = cal1.get(Calendar.MONTH); 
    int month2 = cal2.get(Calendar.MONTH);

    if(month1 < month2) 
      return -1;
    else if(month1 == month2) 
      return cal1.get(Calendar.DAY_OF_MONTH) - cal2.get(Calendar.DAY_OF_MONTH);

    else return 1; 

  }

排序后,您可以将列表四舍五入,认为它是循环的。例如假设排序列表(不包括年份,因为它不相关):

JAN 20, FEB 5, SEP 18, OCT 9, OCT 20, NOV 23

如果我们的支点(与日期相比的结束日期)是OCT 11,则选择与其最近的较大(大于支点的最小日期)日期,则为OCT 20。您只需使用 for 循环即可找到它。现在,我们只需要将它四舍五入,认为它是圆形的:

OCT 20, NOV 23 --> JAN 20, FEB 5, SEP 18, OCT 9

正式地,找到与我们基于月份和日期的枢轴相比立即更大日期的索引i(尝试使用 compareTo 示例),然后创建一个新列表,插入从索引i 开始的元素到@ 987654330@ 然后0i-1,这里n 是Date 列表的大小。

【讨论】:

  • 我喜欢这个逻辑 :) 我也在尝试这个!
  • 使用compareTo方法的body来实现Comparator接口的compare方法可以吗? (只需将当前时间分配给两个 compare 参数之一。)
【解决方案2】:

您肯定希望实现java.util.Comparator 并将其传递给您的排序方法。其中的代码实际上应该比较候选日期和当前日期之间天数的绝对差。

【讨论】:

    【解决方案3】:

    实现java.util.Comparator。比较器可以在构造函数中获取日期并将其作为参考日期存储在属性中。然后,compare() 方法可以决定哪个已传递日期更接近参考日期(根据您喜欢的 close 的任何定义)。

    然后可以将比较器与数组一起传递给Array.sort(T[] a, Comparator&lt;? super T&gt; c)

    【讨论】:

    • @user2822178,明明使用比较器实际上并不能解决问题。我们不应该每次都根据最接近的日期对其进行排序。检查我的答案
    • @Sage 使用比较器显然解决问题。它只需要是一个实现要求的比较器。检查我的答案!!!!1
    • method can then decide which one of the passed dates is closer to the reference date (according to whatever definition of close you prefer).:OP 实际上想要对日期列表进行排序,以便与目标数据透视(日期)比较的任何特定日期都将在开头。排序将按照从小到大的顺序进行。然后应格外小心以满足 OP 的要求。尽管您没有指定月份和日期的比较关系来对 OP 实际上想知道的列表进行排序,但我假设您显然知道这一点:)
    【解决方案4】:

    其实写代码比解释简单:

    Arrays.sort(array, new Comparator<Date>()
    {
        Calendar now = Calendar.getInstance();
    
        @Override
        public int compare(Date d1, Date d2)
        {
            Calendar c1 = Calendar.getInstance();
            c1.setTime(d1);
            c1.set(Calendar.YEAR, now.get(Calendar.YEAR)); // year is irrilevant for d1
    
            Calendar c2 = Calendar.getInstance();
            c2.setTime(d2);
            c2.set(Calendar.YEAR, now.get(Calendar.YEAR)); // year is irrilevant for d2
    
            Long distance1 = Long.MAX_VALUE;
            Long distance2 = Long.MAX_VALUE;
    
            for(int i : new Integer[] { -1, 0, 1 })
            {
                c1.set(Calendar.YEAR, now.get(Calendar.YEAR) + i);
                c2.set(Calendar.YEAR, now.get(Calendar.YEAR) + i);
    
                Long temp1 = Math.abs(c1.getTimeInMillis() - now.getTimeInMillis());
                Long temp2 = Math.abs(c2.getTimeInMillis() - now.getTimeInMillis());
    
                distance1 = Math.min(distance1, temp1);
                distance2 = Math.min(distance2, temp2);
            }
    
            return distance1.compareTo(distance2);
        }
    });
    

    【讨论】:

    • 谢谢你,我按照逻辑:)
    猜你喜欢
    • 1970-01-01
    • 2019-06-18
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 1970-01-01
    相关资源
    最近更新 更多