月份最后一天错误

问题描述 投票:0回答:6

我的服务中哪里有获取每月最后一天的功能?

 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 calendar java-6
6个回答
4
投票

我相信这个问题是由于美国的夏令时造成的。

您可以通过将日历的时区设置为不同的时区来更改此设置。

相关问题:使用 java.util.Calendar 添加天数会产生奇怪的结果


1
投票

Java Date 的 API 非常差。相反,我建议您使用Joda Time

在 Joda 中,它看起来像这样:

LocalDate endOfMonth = date.dayOfMonth().withMaximumValue();

0
投票

如果您没有 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.

0
投票

如果您有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。


0
投票

你正在搞乱

TimeZones

当您执行

Date date = format.parse(stringDate);
时,您将使用
Date
对象的
TimeZone
创建一个
DateFormat
对象。理论上,如果所有
TimeZone
DateFormat
对象的
Calendar
都相同,那么应该没问题。检查它们是否与
getTimeZone()
方法一致。

如果第一个

TimeZone
DateFormat
是错误的(例如,是您的
TimeZone
UTC
GMT
),您将在第二个
UTC-008
中获得
TimeZone
转换(以及在
Calendar
)结果自从你从午夜开始以来缺少的一天。

从你的代码来看,

stringDate
本身已在其他地方错误地转换了......


0
投票

tl;博士

YearMonth
.from( LocalDate.parse( "2025-01-23" ) ) 
.atEndOfMonth() 

java.time

您的输入格式符合 ISO 8601,因此直接解析为

java.time.LocalDate

LocalDate date = LocalDate.parse( "2025-01-23" ) ;

获取该日期的月份,作为

java.time.YearMonth

YearMonth ym = YearMonth.from( date ) ;

询问该月的最后一天

LocalDate lastDayOfMonth = ym.atEndOfMonth() ;
© www.soinside.com 2019 - 2024. All rights reserved.