我在使用 SimpleDateFormat 时得到了一些令人费解的结果,我希望有人可以阐明这个问题。输出:
Time = Mon Dec 27 00:00:00 PST 2010
2010-01 <--- THIS IS WHAT I DON'T UNDERSTAND
Start of week = Sun Dec 26 00:00:00 PST 2010
2010-01
End of Week = Sat Jan 01 23:59:59 PST 2011
2011-01
我是否应该将延续到下一年的一年的最后“一周”视为特例?或者这是解释这个的正确方法吗?显然,当试图按顺序组织周时,顺序是不正确的。调整初始值,2005年12月25日为第53周。我还没有查看 Joda,看看 Joda 是否产生了类似的结果。
相关代码:
private static Date getStartOfWeek( Date d ) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTime( d );
calendar.set( Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek() );
return calendar.getTime();
}
private static Date getEndOfWeek( Date d ) {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTime( d );
calendar.add( Calendar.WEEK_OF_YEAR, 1 );
calendar.set( Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek() );
calendar.add( Calendar.MILLISECOND, -1 );
return calendar.getTime();
}
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set( 2010, Calendar.DECEMBER, 27 );
Date d = calendar.getTime();
Date start = getStartOfWeek( d );
Date end = getEndOfWeek( d );
SimpleDateFormat fmt = new SimpleDateFormat( "yyyy-ww" );
System.out.println( "Time = " + d );
System.out.println( fmt.format( d ) );
System.out.println( "Start of week = " + start );
System.out.println( fmt.format( start ) );
System.out.println( "End of Week = " + end );
System.out.println( fmt.format( end ) );
背景:我在 JasperReports 中使用交叉表(日期分组为周)时发现了这一点。
编辑:我正在使用 JDK 1.6.0_25
编辑:看来我必须使用 Joda 才能获得正确的结果。为了获得一周的开始/结束时间,我最终使用了:LocalDate.withDayOfWeek
。为了检索年份和周数,我使用了 DateTime.getWeekyear
和 DateTime.getWeekOfWeekyear
。
最佳答案
错误出在您的格式化代码中,而不是 Java。
令人惊讶的行为是由于日期符号中的深奥规则。请注意,ISO 8601(相当困惑)在使用周数时为年份边界指定了不同的规则。特别是,在使用周数时,2010-12-27 被视为 2011 年的一部分。
因此,您应该使用“周年”YYYY
而不是通常的年份 yyyy
。 (参见 http://download.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html#week_year 和 http://download.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html 中的最后一个示例。)
此外,日期的标准表示法使用明确的 'W'
,因此您应该改用 new SimpleDateFormat( "YYYY-'W'ww")
。
编辑:还有一个问题。 Java 似乎默认为非标准的 calendar.getMinimalDaysInFirstWeek() == 1
,因此您必须设置
calendar.setMinimalDaysInFirstWeek( 4 );
为了获得正确的年份。
编辑:通过阅读 Calendar
javadoc,您可能还需要将开始日期设置为星期一。此外,YYYY
格式说明符似乎是 Java 1.7 中的新内容。鉴于此,除非您愿意升级到预发布的 Java 版本,否则我建议只使用 Joda Time。
关于java - SimpleDateFormat 周计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6754024/