Java日期年计算按年份停止两天
如果你能想象的话,这在我的软件中造成了一个Y2K类型的错误。奇怪的是,一年内只发生两天的“关”计算,我不太确定如何排除故障 输出:Java日期年计算按年份停止两天,java,date,calendar,simpledateformat,Java,Date,Calendar,Simpledateformat,如果你能想象的话,这在我的软件中造成了一个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日期实用程序的哪一部分会导致这样的错误 代码(因为测试太小,我包含
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;
导入java.util.Date;
导入java.text.simpleDataFormat;
公共类日期{
私有静态字符串getFormattedBackscanStartTime(整数天){
SimpleDataFormat dateFormat=新的SimpleDataFormat(“dd MMM YYYY”);
日历工作日期=Calendar.getInstance();
workingDate.add(Calendar.DATE,-1*天);
String formattedStartTime=dateFormat.format(workingDate.getTime());
返回格式化的开始时间;
}
公共静态void main(字符串参数[]){
对于(int i=35;i<45;i++){
System.out.println(getFormattedBackscanStartTime(i));
}
}
}
这就是问题所在:
"dd-MMM-YYYY"
YYYY
是周年,而不是日历年。您想要的是yyyy
2012日历年的最后两天是2013年第一周。通常应仅将周-年与“年中的周”说明符(
w
)一起使用。问题在于日期格式字符串-年应为yyyy
而不是yyyy
Y -> week-year
y -> year
如果在循环的每个迭代中打印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的用法。年度需要使用小写y。试试这个:
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
我假设您使用的是
Java1.7
上面的代码片段将不适用于java 1.6
,因为SimpleDataFormat(“dd-MMM-YYYY”)
将引发java.lang.IllegalArgumentException
(yyyyy在java 1.6
中不可用)
您需要使用yyyy
而不是yyy
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
为了完整起见,下面是使用
LocalDate
(由Basil Bourque在评论中推荐)的现代答案
需要注意的几点:
- 为格式化程序提供一个显式的区域设置,以控制输出的语言。即使您只是传递了
,您也在告诉读者您已经考虑了Locale并做出了决定Locale.getDefault()
- 类似地,为
指定一个明确的时区,告诉读者您已经做出了决定(例如LocalDate.now()
用于特定时区;ZoneId.of(“美国/纽约”)
用于JVM的当前时区设置)ZoneId.systemDefault()
- 我发现代码比使用老式的
类的代码更简单、更直接。这对于较新的类是典型的Calendar
- 我已经使用
一年了uuu
(小写)也能起作用,在普通纪元(又名公元前)之前的几年里只会有不同yyyy
Calendar
&SimpleDateFormat
类现在已启用。被班级取代了。现代方法使用LocalDate
、ZoneId
和DateTimeFormatter
类。请将LocalDate分开。现在,
行分成单独的命令,以便您可以看到正在使用的类。以及。。。下面是一种从java.util.Date
转换的方法:如果您使用的库依赖于旧日期,则不确定这是否有意义。
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