错误的月份的最后一天

时间:2015-01-27 14:57:18

标签: java calendar java-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"

5 个答案:

答案 0 :(得分:4)

我认为这个问题是由美国Day Light saving time造成的。

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

相关问题:Adding days with java.util.Calendar gives strange results

答案 1 :(得分:1)

Java Date的API很差。我会建议你使用Joda Time而不是这个。

在Joda看起来像这样:

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

答案 2 :(得分: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.

答案 3 :(得分: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。

答案 4 :(得分:0)

你正在弄乱TimeZones

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

如果第一个TimeZone的{​​{1}}错误(例如您的DateFormatTimeZoneUTC),您将获得第二个GMT(以及UTC-008)中的TimeZone转换导致自午夜开始以来缺失的一天。

从您的代码判断,Calendar本身在其他地方被错误地转换了......