我的服务中哪里有获取每月最后一天的功能?
DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
Date date = format.parse(stringDate);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MONTH, 1);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.add(Calendar.DATE, -1);
Date lastDayOfMonth = calendar.getTime();
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(lastDayOfMonth);
所以,这个方法在其他地方也能正确工作,但在美国,最后一天总是 29(最后一天 - 1)
stringDate 是格式为“yyyy-MM-dd”的日期
Java Date 的 API 非常差。相反,我建议您使用Joda Time。
在 Joda 中,它看起来像这样:
LocalDate endOfMonth = date.dayOfMonth().withMaximumValue();
如果您没有 Java 8,这与 JodaTime 非常紧凑。
import org.joda.time.DateTime;
public class SoLastDay {
public DateTime lastDay(final String yyyy_MM_dd) {
DateTime givenDate = new DateTime(yyyy_MM_dd);
return givenDate.dayOfMonth().withMaximumValue();
}
}
还有一个小测试...
@Test
public void testLastDay() throws Exception {
SoLastDay soLastDay = new SoLastDay();
String date1 = "2015-01-27";
System.out.printf("Date %s becomes %s.\n", date1, soLastDay.lastDay(date1).toString("yyyy-MM-dd"));
String date2 = "2015-02-02";
System.out.printf("Date %s becomes %s.\n", date2, soLastDay.lastDay(date2).toString("yyyy-MM-dd"));
}
测试结果:
Date 2015-01-27 becomes 2015-01-31.
Date 2015-02-02 becomes 2015-02-28.
如果您有有Java 8,您可以使用如下代码:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
public class SoLastDayJava8 {
static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
public LocalDate lastDay(final String yyyy_MM_dd) {
LocalDate givenDate = LocalDate.parse(yyyy_MM_dd, formatter);
return givenDate.with(TemporalAdjusters.lastDayOfMonth());
}
}
测试代码稍有改动。
public class SoLastDayJava8Test {
@Test
public void testLastDay() throws Exception {
SoLastDayJava8 soLastDay = new SoLastDayJava8();
String date1 = "2015-01-27";
System.out.printf("Date %s becomes %s.\n", date1, soLastDay.lastDay(date1));
String date2 = "2015-02-02";
System.out.printf("Date %s becomes %s.\n", date2, soLastDay.lastDay(date2));
}
}
但结果是一样的。
日期 2015-01-27 变为 2015-01-31。
日期 2015-02-02 变为 2015-02-28。
你正在搞乱
TimeZones
。
当您执行
Date date = format.parse(stringDate);
时,您将使用 Date
对象的 TimeZone
创建一个 DateFormat
对象。理论上,如果所有 TimeZone
和 DateFormat
对象的 Calendar
都相同,那么应该没问题。检查它们是否与getTimeZone()
方法一致。
如果第一个
TimeZone
的 DateFormat
是错误的(例如,是您的 TimeZone
或 UTC
或 GMT
),您将在第二个 UTC-008
中获得 TimeZone
转换(以及在Calendar
)结果自从你从午夜开始以来缺少的一天。
从你的代码来看,
stringDate
本身已在其他地方错误地转换了......
YearMonth
.from( LocalDate.parse( "2025-01-23" ) )
.atEndOfMonth()
您的输入格式符合 ISO 8601,因此直接解析为
java.time.LocalDate
。
LocalDate date = LocalDate.parse( "2025-01-23" ) ;
java.time.YearMonth
。
YearMonth ym = YearMonth.from( date ) ;
询问该月的最后一天。
LocalDate lastDayOfMonth = ym.atEndOfMonth() ;