错误的月份最后一天
Wrong last day of month
我的服务中哪里有获取月份最后一天的函数?
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日期很差API。相反,我建议您使用 Joda Time。
在 Joda 中它看起来像这样:
LocalDate endOfMonth = date.dayOfMonth().withMaximumValue();
我认为这个问题是由于 Day Light saving time 在美国造成的。
您可以通过将日历的时区设置为不同的时区来更改此设置。
相关问题:Adding days with java.util.Calendar gives strange results
如果你没有 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));
}
}
但是结果是一样的
Date 2015-01-27 becomes 2015-01-31.
Date 2015-02-02 becomes 2015-02-28.
你在搞乱 TimeZones
。
当您执行 Date date = format.parse(stringDate);
时,您正在使用 DateFormat
对象的 TimeZone
创建一个 Date
对象。理论上,如果 TimeZone
对于所有 DateFormat
和 Calendar
对象都是相同的,你应该没问题。检查它们是否与 getTimeZone()
方法一致。
如果第一个 DateFormat
的 TimeZone
是错误的(例如,是你的 TimeZone
或 UTC
或 GMT
),你会得到一个UTC-008
第二个 TimeZone
(和 Calendar
)的转换导致您从午夜开始后缺少一天。
从您的代码判断 stringDate
本身在其他地方被错误地转换了...
我的服务中哪里有获取月份最后一天的函数?
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日期很差API。相反,我建议您使用 Joda Time。
在 Joda 中它看起来像这样:
LocalDate endOfMonth = date.dayOfMonth().withMaximumValue();
我认为这个问题是由于 Day Light saving time 在美国造成的。
您可以通过将日历的时区设置为不同的时区来更改此设置。
相关问题:Adding days with java.util.Calendar gives strange results
如果你没有 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));
}
}
但是结果是一样的
Date 2015-01-27 becomes 2015-01-31.
Date 2015-02-02 becomes 2015-02-28.
你在搞乱 TimeZones
。
当您执行 Date date = format.parse(stringDate);
时,您正在使用 DateFormat
对象的 TimeZone
创建一个 Date
对象。理论上,如果 TimeZone
对于所有 DateFormat
和 Calendar
对象都是相同的,你应该没问题。检查它们是否与 getTimeZone()
方法一致。
如果第一个 DateFormat
的 TimeZone
是错误的(例如,是你的 TimeZone
或 UTC
或 GMT
),你会得到一个UTC-008
第二个 TimeZone
(和 Calendar
)的转换导致您从午夜开始后缺少一天。
从您的代码判断 stringDate
本身在其他地方被错误地转换了...