日历实现:添加日期时遇到问题

huangapple go评论57阅读模式
英文:

Calendar implementation: trouble to add days to date

问题

我的任务是:
实现一个公共方法 public void advance(),该方法将日期向前移动一天。在这个练习中,我们假设每个月有30天。注意:在某些情况下,你需要改变月份和年份的值。

我已经完成了以下代码:

public class SimpleDate {

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

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

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

    public boolean before(SimpleDate 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;
    }

    public void advance() {
        if (this.day < 30) {
            this.day += 1;
        }
        if (this.day == 30 && this.month == 12) {
            this.day = 1;
            this.month = 1;
            this.year += 1;
        }
        if (this.day == 30) {
            this.day = 1;
            this.month += 1;
        }
    }

    public void advance(int howManyDays) {
        if (howManyDays < 30) {
            if (this.day < 30 && (this.day + howManyDays < 30)) {
                this.day += howManyDays;
            }
            if (this.day == 30 && this.month == 12) {
                this.day = howManyDays;
                advance();
            }
            if (this.day == 30) {
                this.day = howManyDays;
                this.month += 1;
            }
        }
        if (howManyDays == 30 && this.month == 12) {
            this.day = howManyDays;
            advance();
        }
        if (howManyDays == 30) {
            this.month += 1;
        }
    }

    public SimpleDate afterNumberOfDays(int days) {
   
        SimpleDate obj = new SimpleDate(days, this.month, this.year);
        return obj;
    
    }
}

但是当我使用以下测试代码进行测试时:

SimpleDate date = new SimpleDate(30, 12, 2011);
date.advance(3);

现在日期应该是 3.1.2012。
预期输出:[3.1.2012],但实际输出:[4.12.2011]

英文:

My task is:
Implement the method public void advance() that moves the date by one day. In this exercise we assume that each month has 30 day. NB! In certain situations you need to change the values of month and year.

I have done this:

public class SimpleDate {
private int day;
private int month;
private int year;
public SimpleDate(int day, int month, int year) {
this.day = day;
this.month = month;
this.year = year;
}
@Override
public String toString() {
return this.day + &quot;.&quot; + this.month + &quot;.&quot; + this.year;
}
public boolean before(SimpleDate compared) {
if (this.year &lt; compared.year) {
return true;
}
if (this.year == compared.year &amp;&amp; this.month &lt; compared.month) {
return true;
}
if (this.year == compared.year &amp;&amp; this.month == compared.month &amp;&amp;
this.day &lt; compared.day) {
return true;
}
return false;
}
public void advance(){
if(this.day&lt;30){
this.day += 1;
}    
if(this.day==30 &amp;&amp; this.month==12){
this.day = 1;
this.month=1;
this.year +=1;
}
if(this.day==30){
this.day = 1;
this.month +=1;
}
}
public void advance(int howManyDays){
if(howManyDays &lt; 30){
if(this.day&lt;30 &amp;&amp; (this.day + howManyDays &lt; 30)){
this.day += howManyDays;
}
if(this.day==30 &amp;&amp; this.month==12){
this.day = howManyDays;
advance();
}
if(this.day==30){
this.day = howManyDays;
this.month +=1;
} 
}
if(howManyDays== 30 &amp;&amp; this.month==12){
this.day = howManyDays;
advance();
}
if(howManyDays == 30){
this.month += 1;
}
}
public SimpleDate afterNumberOfDays(int days){
SimpleDate obj = new SimpleDate(days, this.month,this.year);
return obj;
}
}

But when I test it with:

SimpleDate date = new SimpleDate(30, 12, 2011);  date.advance(3);

Now the date should be 3.1.2012.
expected:[3.1.2012] but was:[4.12.2011]

答案1

得分: 1

这是因为您设置了日期,然后调用了 advance()。所以日期变成了 3,但现在您使用日期 3.12.2011 调用了 advance(),结果应该是 4.12.2011

您可以通过两种方式解决这个问题:

低效的方式

只需连续调用 advance()howManyDays 次:

public void advance(int howManyDays){
for(int i = 1; i <= howManyDays; i++)
advance();
}

高效的方式

这是一种通用的方式,适用于任何天数(甚至大量的天数):

public void advance(int howManyDays){
if(howManyDays + this.day <= 30){
this.day += howManyDays;
return;
}
int monthsToAdd = (howManyDays + this.day) / 30;
int yearsToAdd = (monthsToAdd + this.month) / 12;
int day = (howManyDays + this.day) % 30;
int month = (monthsToAdd + this.month) % 12;
if(month == 0) month = 12;
this.day = day;
this.month = month;
this.year += yearsToAdd;
}
public void advance(){
advance(1);
}
英文:

This happens because you set the date and than call advance(). So the day changed to 3 but now you advance is called with the date 3.12.2011 which results in 4.12.2011 as it should.

You can solve it in 2 ways:

inefficient way

Just call advance, howManyDays times:

public void advance(int howManyDays){
for(int i = 1; i &lt;= howManyDays; i++)
advance();
}

Efficient way

this is a general way that will work for every amount of days (even large number of days):

public void advance(int howManyDays){
if(howManyDays + this.day &lt;= 30){
this.day += howManyDays;
return;
}
int monthsToAdd = (howManyDays + this.day) / 30;
int yearsToAdd = (monthsToAdd + this.month) / 12;
int day = (howManyDays + this.day) % 30;
int month = (monthsToAdd + this.month) % 12;
if(month == 0) month = 12;
this.day = day;
this.month = month;
this.year += yearsToAdd;
}
public void advance(){
advance(1);
}

答案2

得分: 1

我建议您在这里简化您的方法,使用while循环而不是多个嵌套的if语句...

public void advance(int howManyDays) {
this.day += howManyDays;
// 通过减去不超过范围的天数,增加月份
while (this.day > 30) {
this.day -= 30;
this.month++;
}
// 通过减去不超过范围的月份,增加年份
while (this.month > 12) {
this.month -= 12;
this.year++;
}
}
英文:

I recommend just simplifying your approach on this with while loops instead of the multiple and nested if statements...

public void advance(int howManyDays) {
this.day += howManyDays;
//Subtracts out the days till within range, incrementing months
while(this.day &gt; 30) {
this.day -= 30;
this.month++;
}
//Subtracts out the months till within range, incrementing years
while(this.month &gt; 12) {
this.month -= 12;
this.year++;
}
}

答案3

得分: 1

在你的测试案例中,你传入了这个代码块:

if(this.day==30 && this.month==12){
    this.day = howManyDays;
    advance();
}

进入这个代码块时,你有 day==30month==12howManyDays==3

  • 你将 day 设置为 howManyDays,因此现在 day==3
  • 你调用了 advance(),由于 day 是 3,day 被递增,然后 advance() 方法返回。
  • 没有其他有效的 if 条件,advance(3) 方法返回。

只有 day 字段发生了变化。

在设置日期之前调用 advance(),这样应该可以正常工作。

if(this.day==30 && this.month==12){
    advance(); // 前往下一天,必要时更改月份/年份
    this.day = howManyDays-1; // advance() 已经向前推进了一天
}

你的代码还存在其他问题,但我会让你找到并修复它们。(例如:如果 day 是 27,而 howManyDays 是 3,会怎么样?)

我强烈建议你学会使用逐步调试器来处理这些简单的逻辑问题。这是一项有价值且非常有用的技能。

英文:

In your test case, you pass in this block:

        if(this.day==30 &amp;&amp; this.month==12){
this.day = howManyDays;
advance();
}

When entering this block, you have day==30, month==12, howManyDays==3.

  • You set day to howManyDays, so now day==3.
  • You call advance(), as day is 3, day is incremented then the advance()method returns.
  • There is no other valid ifcondition, advance(3)method returns.

Only the dayfield has changed.

Call advance()before setting the day and it should works.

        if(this.day==30 &amp;&amp; this.month==12){
advance(); // go to the next day, change the month/year if necessary
this.day = howManyDays-1; // advance() already goes one day forward
}

There are other issues with your code but I let you find them and fix them. (ex: what if dayis 27 and howManyDays is 3 ?)

I strongly suggest you to learn to use a step-by-step debugger to handle those easy logic issues. That's a valuable and very useful skill.

huangapple
  • 本文由 发表于 2020年4月3日 21:14:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/61012747.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定