我正在使用以下代码检索上个月的最后一天-例如:5月。但是它返回的是30天而不是31天。
下面给出的代码
package net.vcmg.date;
import java.util.Calendar;
import java.util.Date;
import org.apache.commons.lang.time.DateUtils;
public class LastDayPreviousMonth {
public static void main(String[] args) {
Date lastDateOfPreviousMonth = addMonths(lastDayOfTheMonth(today()), -1);
System.out.println("lastDateOfPreviousMonth: "+lastDateOfPreviousMonth);
}
//the below method is from Utils.java
public static Date lastDayOfTheMonth(Date d) {
Calendar cal = Calendar.getInstance();
cal.setTime(d);
int actualMax = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
cal.set(Calendar.DAY_OF_MONTH, actualMax);
return cal.getTime();
}
public static Date addMonths(Date date, int numMonths)
{
return DateUtils.addMonths(date, numMonths);
}
public static Date today()
{
return truncDate(now());
}
public static Date now()
{
// will cut-off milliseconds
return new Date( (System.currentTimeMillis()/1000) * 1000);
}
public static Date truncDate (Date date) {
return DateUtils.truncate(date, Calendar.DATE);
}
}
在这里,当我在main方法中调用lastDateOfPreviousMonth时,它仅返回30天。不是31号,实际上可能包含31天。请帮忙。
答案 0 :(得分:6)
Java 8
如果您不限制使用旧的Date
,则最好使用新的java.time.LocalDate
LocalDate previousMonth = LocalDate.now().minusMonths(1);
LocalDate start = previousMonth.withDayOfMonth(1);
LocalDate end = previousMonth.withDayOfMonth(previousMonth.lengthOfMonth());
System.out.println(start);
System.out.println(end);
输出
2019-05-01
2019-05-31
修改
对于您的实现,请更改方法的顺序
addMonths(new Date(), -1)
lastDayOfTheMonth(addMonths(new Date(), -1))
Date lastDateOfPreviousMonth = lastDayOfTheMonth(addMonths(new Date(), -1));
输出
lastDateOfPreviousMonth: Fri May 31 10:46:13 EEST 2019
答案 1 :(得分:1)
尝试一下:
public static void main(String[] args) {
Date lastDateOfPreviousMonth = lastDayOfTheMonth(addMonths(today(), -1));
System.out.println("lastDateOfPreviousMonth: " + lastDateOfPreviousMonth);
}
当您调用today()的lastDayOfTheMonth时将为30。减去一个月后,预期结果将为30,而不是31。
答案 2 :(得分:0)
这是您对程序/算法的思考方式中的逻辑错误。您首先要查找月份的最后一天,在本例中为6月30日。然后减去1个月。这样一来,无论5月有31天的事实,都将是5月30日(DateUtils.addMonths
的文档中并未明确指出这种方式是这样工作的,但它内部使用的是设计不良且过时的Calendar
类,所以这是我们应该期望的。
请按照相反的顺序进行操作。首先找到上个月:
YearMonth lastMonth = YearMonth.now(ZoneId.of("Asia/Kolkata")).minusMonths(1);
2019-05
由于新月并非在所有时区的同一时间点开始,因此建议您如图所示输入所需的时区。
然后只查找该月的最后一天:
LocalDate lastDayOfLastMonth = lastMonth.atEndOfMonth();
2019-05-31
我建议您不要使用Date
和Calendar
。这些课程设计欠佳,而且已经过时。而是使用LocalDate
和java.time(现代Java日期和时间API)中的其他类。这也将使您摆脱对Apache DateUtils
的外部依赖,因为它的功能通常内置于现代类中。