英文:
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 + "." + 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;
}
}
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 <= 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 <= 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 > 30) {
this.day -= 30;
this.month++;
}
//Subtracts out the months till within range, incrementing years
while(this.month > 12) {
this.month -= 12;
this.year++;
}
}
答案3
得分: 1
在你的测试案例中,你传入了这个代码块:
if(this.day==30 && this.month==12){
this.day = howManyDays;
advance();
}
进入这个代码块时,你有 day==30
,month==12
,howManyDays==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 && this.month==12){
this.day = howManyDays;
advance();
}
When entering this block, you have day==30
, month==12
, howManyDays==3
.
- You set day to
howManyDays
, sonow day==3
. - You call
advance()
, as day is 3, day is incremented then theadvance()
method returns. - There is no other valid
if
condition,advance(3)
method returns.
Only the day
field has changed.
Call advance()
before setting the day and it should works.
if(this.day==30 && 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 day
is 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论