找到两个日期之间差异的方法

时间:2017-01-12 19:37:38

标签: java

我的方法有效,因为我只想知道多年来的差异,我的问题是我这样做效率很低。我觉得有一种更简单,更美观的方式来编写方法。

编辑:我必须编写自己的方法。我也不喜欢不用自己的方式使用高级的东西,这是第一年程序员的范畴。

public int differenceInYears(MyDate comparedDate) {
        int difference = 0;
        if (this.year > comparedDate.year) {
            if (this.month > comparedDate.month) {
                difference = this.year - comparedDate.year;
            }
            else if (this.month == comparedDate.month) {
                if (this.day >= comparedDate.day) {
                    difference = this.year - comparedDate.year;
                }
                else {
                    difference = this.year - comparedDate.year - 1;
                }
            }
            else {
                difference = this.year - comparedDate.year - 1;
            }
        }
        if (comparedDate.year > this.year) {
            if (comparedDate.month > this.month) {
                difference = comparedDate.year - this.year;
            }
            else if (comparedDate.month == this.month) {
                if (comparedDate.day >= this.day) {
                    difference = comparedDate.year - this.year;
                }
                else {
                    difference = comparedDate.year - this.year - 1;
                }
            }
            else {
                difference = comparedDate.year - this.year - 1;
            }
        }
        return difference;
    }

我将在下面添加MyDate类用于上下文:

public class MyDate {

    private int day;
    private int month;
    private int year;

    public MyDate(int day, int montd, int year) {
        this.day = day;
        this.month = montd;
        this.year = year;
    }

    public String toString() {
        return this.day + "." + this.month + "." + this.year;
    }

    public boolean earlier(MyDate compared) {
        if (this.year < compared.year) {
            return true;
        }

        if (this.year == compared.year && this.month < compared.month) {
            return true;
        }

        if (this.year == compared.year && this.month == compared.month
                && this.day < compared.day) {
            return true;
        }

        return false;
    }

3 个答案:

答案 0 :(得分:3)

我会假设您的方法正常工作。怎么改进?您可以做的第一件事是消除所有重复的this.year - comparedDate.yearcomparedDate.year - this.year计算。无论如何,你都可以使用它们,所以让它们放在各自if块的顶部。

public int differenceInYears(MyDate comparedDate) {
    int difference;

    if (this.year > comparedDate.year) {
        difference = this.year - comparedDate.year;

        if (this.month > comparedDate.month) {
        }
        else if (this.month == comparedDate.month) {
            if (this.day >= comparedDate.day) {
            }
            else {
                difference -= 1;
            }
        }
        else {
            difference -= 1;
        }
    }
    if (comparedDate.year > this.year) {
        difference = comparedDate.year - this.year;

        if (comparedDate.month > this.month) {
        }
        else if (comparedDate.month == this.month) {
            if (comparedDate.day >= this.day) {
            }
            else {
                difference -= 1;
            }
        }
        else {
            difference -= 1;
        }
    }

    return difference;
}

接下来,让我们摆脱那些空枝。

public int differenceInYears(MyDate comparedDate) {
    int difference;

    if (this.year > comparedDate.year) {
        difference = this.year - comparedDate.year;

        if (this.month == comparedDate.month) {
            if (this.day < comparedDate.day) {
                difference -= 1;
            }
        }
        else if (this.month < comparedDate.month) {
            difference -= 1;
        }
    }
    if (comparedDate.year > this.year) {
        difference = comparedDate.year - this.year;

        if (comparedDate.month == this.month) {
            if (comparedDate.day < this.day) {
                difference -= 1;
            }
        }
        else if (comparedDate.month < this.month) {
            difference -= 1;
        }
    }

    return difference;
}

现在让我们看看我们是否可以将&&||的某些条件挤压在一起。

public int differenceInYears(MyDate comparedDate) {
    int difference;

    if (this.year > comparedDate.year) {
        difference = this.year - comparedDate.year;

        if (this.month == comparedDate.month && this.day < comparedDate.day ||
            this.month < comparedDate.month)
        {
            difference -= 1;
        }
    }
    if (comparedDate.year > this.year) {
        difference = comparedDate.year - this.year;

        if (comparedDate.month == this.month && comparedDate.day < this.day ||
            comparedDate.month < this.month)
        {
            difference -= 1;
        }
    }

    return difference;
}

这两个街区看起来非常相似,不是吗?我们可以通过有条件地交换thiscomparedDate来合并它们。让ab分别为更早和更晚的日期。

public int differenceInYears(MyDate comparedDate) {
    MyDate a = (this.year < comparedDate.year) ? this : comparedDate;
    MyDate b = (this.year < comparedDate.year) ? comparedDate : this;

    int difference = b.year - a.year;

    if (a.year < b.year) {
        if (a.month == b.month && a.day < b.day ||
            a.month < b.month)
        {
            difference -= 1;
        }
    }

    return difference;
}

最后一次挤压。

public int differenceInYears(MyDate comparedDate) {
    MyDate a = (this.year < comparedDate.year) ? this : comparedDate;
    MyDate b = (this.year < comparedDate.year) ? comparedDate : this;

    int difference = b.year - a.year;

    if (a.year < b.year &&
       (a.month == b.month && a.day < b.day ||
        a.month < b.month))
    {
        difference -= 1;
    }

    return difference;
}

答案 1 :(得分:1)

好的,经过一番考虑,我觉得这看起来可能更好一些:

public int differenceInYears(MyDate comparedDate){
    //Calculate days total
    long daysTotalThisDate = this.year * 365 + this.month * 30 + this.day;
    long daysTotalComparedDate = comparedDate.year * 365 + comparedDate.month * 30 + comparedDate.day;

    //Get absolute value
    long differenceInDays = daysTotalThisDate - daysTotalComparedDate;
    if (differenceInDays < 0){
        differenceInDays *= -1;
    }

    //the (int) cast will always round down, so anything under 365 will be 0
    return (int) differenceInDays / 365;
}

这不考虑闰年。

在人们认为我对daysTotal...的计算错误之前。你是对的。但是我对两次计算都做错了,所以考虑到我们只需要计算年份而不是几天的差异,最终结果仍然可以。

答案 2 :(得分:0)

这里的关键点是:有时&#34;复杂&#34;计算是必需的。

从这个意义上说:不要担心效率低下。你应该把时间花在尝试编写真正可读的代码上;非常像约翰的答案指导你。一般来说,您会将原则视为&#34; single layer of abstraction&#34;例如原则;避免这种冗长的if / else级联。

另一个关键点:此类作业完美用于单元测试。换句话说:你应该首先编写一些简单的测试用例,只需用各种(预先选择的)输入日期调用你的方法;然后检查是否返回了预期的结果。

换句话说:

您首先专注于编写许多测试用例,您可以确定您的实现是正确的...因为这使您能够重构您的代码而不是害怕打破它。

使用JUnit非常简单:

@Test
public testDifferenceIs0 {
  MyDate thisYear = new MyDate(1,1,2017);
  MyDate thisYearToo = new MyDate(1,1,2017);
  assertThat(thisYear.differenceInYears(thisYearToo), is(0));
}

例如。