java - SimpleDateFormat 周计算

标签 java date simpledateformat

我在使用 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.getWeekyearDateTime.getWeekOfWeekyear

最佳答案

错误出在您的格式化代码中,而不是 Java。

令人惊讶的行为是由于日期符号中的深奥规则。请注意,ISO 8601(相当困惑)在使用周数时为年份边界指定了不同的规则。特别是,在使用周数时,2010-12-27 被视为 2011 年的一部分。

因此,您应该使用“周年”YYYY 而不是通常的年份 yyyy。 (参见 http://download.oracle.com/javase/7/docs/api/java/util/GregorianCalendar.html#week_yearhttp://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/

相关文章:

javascript - 使用 npm 导入 date-fns

javascript - 如何将 JavaScript 日期转换为 MySQL 日期时间格式?

java - 是否有标准方法可以在 Android 上完成本地化日期组件,例如 1s、1m、1h、1d、1w、1week 等

java - 使用 JSF Facelets 的国际化 (i18n) : Messages in Java-classes

java - web.xml 自定义错误页面不工作

java - 刷新 GZIPOutputStream 然后重置 ByteArrayOutputStream 是否安全?

java - 在java中将EST时间转换为本地时间

grails - Grails日期格式为英语

java - 如何提高包裹在 ThreadLocal 中的 SimpleDateFormat 的性能?

java - 井字游戏。工作不正常