如果您能想象,这会在我的软件中导致Y2K风格的错误。奇怪的是,一年的计算只发生在一年中的两天,我不太确定如何排除故障。
输出:
03-Jan-2013
02-Jan-2013
01-Jan-2013
31-Dec-2013 ** strange
30-Dec-2013 ** strange
29-Dec-2012
28-Dec-2012
27-Dec-2012
26-Dec-2012
25-Dec-2012
我不确定Java日期实用程序的哪一部分可能导致此类错误。
代码(由于测试非常小,我包含了一个完整的工作程序):
import java.util.Calendar;
import java.util.Date;
import java.text.SimpleDateFormat;
public class DateT {
private static String getFormattedBackscanStartTime(int days) {
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-YYYY");
Calendar workingDate = Calendar.getInstance();
workingDate.add(Calendar.DATE, -1 * days);
String formattedStartTime = dateFormat.format(workingDate.getTime());
return formattedStartTime;
}
public static void main(String args[]) {
for(int i = 35; i < 45; i++) {
System.out.println(getFormattedBackscanStartTime(i));
}
}
}
答案 0 :(得分:34)
这是问题所在:
"dd-MMM-YYYY"
YYYY
是周年,而不是日历年。您想要yyyy
。
2012日历年的最后两天是在2013年的第一周。您通常只应将周年与“一年中的一周”说明符(w
)结合使用。
答案 1 :(得分:6)
我假设你正在使用java 1.7
。
上面的代码段无法与java 1.6
一起使用,因为SimpleDateFormat("dd-MMM-YYYY")
会引发java.lang.IllegalArgumentException
(YYYY在java 1.6
中不可用)
您需要使用yyyy
代替YYYY
。
Y -> week-year
y -> year
修改
适用于yyyy
:
$ java DateT
03-Jan-2013
02-Jan-2013
01-Jan-2013
31-Dec-2012
30-Dec-2012
29-Dec-2012
28-Dec-2012
27-Dec-2012
26-Dec-2012
25-Dec-2012
答案 2 :(得分:3)
问题在于您的日期格式字符串 - 年份应为yyyy
而不是YYYY
。
如果在循环的每次迭代中打印workingDate.getTime()
的值,您将看到它具有预期值:
Thu Jan 03 11:19:33 EST 2013
Wed Jan 02 11:19:33 EST 2013
Tue Jan 01 11:19:33 EST 2013
Mon Dec 31 11:19:33 EST 2012
Sun Dec 30 11:19:33 EST 2012
Sat Dec 29 11:19:33 EST 2012
Fri Dec 28 11:19:33 EST 2012
Thu Dec 27 11:19:33 EST 2012
Wed Dec 26 11:19:33 EST 2012
Tue Dec 25 11:19:33 EST 2012
因此问题在于SimpleDateFormat的用法。
答案 3 :(得分:2)
您需要使用年份小写y。试试这个:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
答案 4 :(得分:2)
为了完整起见,这里是使用LocalDate
的现代答案(正如Basil Bourque在评论中所推荐的那样)。
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class DateT {
private static DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("dd-MMM-uuuu", Locale.US);
private static String getFormattedBackscanStartTime(int days) {
return LocalDate.now(ZoneId.systemDefault()).minusDays(days).format(dateFormatter);
}
public static void main(String args[]) {
for(int i = 155; i < 165; i++) {
System.out.println(getFormattedBackscanStartTime(i));
}
}
}
今天运行这个我
04-Jan-2017
03-Jan-2017
02-Jan-2017
01-Jan-2017
31-Dec-2016
30-Dec-2016
29-Dec-2016
28-Dec-2016
27-Dec-2016
26-Dec-2016
有几点需要注意:
Locale.getDefault()
,您也会告诉读者您已经考虑过区域设置并做出决定。LocalDate.now()
提供明确的时区,告诉读者您已做出决定(例如ZoneId.of("America/New_York")
表示特定时区; ZoneId.systemDefault()
表示JVM当前时区设置)。Calendar
类的代码更简单,更直接。这对于较新的类来说是典型的。uuuu
一年。 yyyy
(小写)也有效,在共同时代(AKA BC)之前几年只会有差异。