如何在给定日期的情况下获得一年中的一周? 我尝试了以下代码:
Calendar sDateCalendar = new GregorianCalendar();
sDateCalendar.set(Integer.parseInt(sDateYearAAAA), Integer.parseInt(sDateMonthMM)-1, Integer.parseInt(sDateDayDD));
System.out.format("sDateCalendar %tc\n", sDateCalendar);
iStartWeek = sDateCalendar.getWeekYear();
System.out.println("iStartWeek "+iStartWeek+ " "+sDateCalendar.WEEK_OF_YEAR);
我得到: sDateCalendar lun 4 月 23 日 11:58:39 CEST 2012 iStartWeek 2012 3
而一年中正确的星期是 17。有人可以帮助我吗?
最佳答案
tl;dr
一年一周 defined by the ISO 8601标准为从星期一开始并且第一周包含日历年的第一个星期四,使用 YearWeek
来自 ThreeTen-Extra 的类(class)为 Java 内置的 java.time 类添加功能的库。
org.threeten.extra.YearWeek
.from(
LocalDate.of( 2012 , Month.APRIL , 23 )
)
.toString()
2012-W17
一周的定义
您需要定义一年中的一周。
- 一个常见的定义是第 1 周是 1 月 1 日。
- 一些平均第 1 周是一年中的第一周,是一周的第一天(例如美国的星期日)。
- 标准ISO 8601意思是that week # 1 holds the first Thursday , 一周总是从星期一开始。一年可以有 52 或 53 周。第一周/最后一周可以有一个不同于日历年的基于周的年份。
请注意,旧的 java.util.Calendar 类对周的定义因 Locale 而异。 .
出于多种原因,您应该避免使用旧的 java.util.Date/.Calendar 类。而是使用新的 java.time 框架。
java.time
Java 8 及更高版本带有 java.time框架。灵感来自 Joda-Time ,由 JSR 310 定义,并由 ThreeTen-Extra 扩展项目。参见 Tutorial .
这是获取 ISO 8601 标准周的一些示例代码。
获取日期(因此是一周)取决于时区。
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
IsoFields
类定义了基于周的年份。我们可以要求:
- 一年中的周数 (
WEEK_OF_WEEK_BASED_YEAR
) - 基于周的年份 (
WEEK_BASED_YEAR
)。
首先我们获取当前日期时间。
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
询问那个日期时间对象,询问标准的基于周的年份。
int week = now.get ( IsoFields.WEEK_OF_WEEK_BASED_YEAR );
int weekYear = now.get ( IsoFields.WEEK_BASED_YEAR );
转储到控制台。
System.out.println ( "now: " + now + " is week: " + week + " of weekYear: " + weekYear );
now: 2016-01-17T20:55:27.263-05:00[America/Montreal] is week: 2 of weekYear: 2016
有关详细信息,请参阅此类似问题:How to calculate Date from ISO8601 week number in Java
WeekFields
在 java.time 中,您还可以调用 WeekFields
类,例如 WeekFields.ISO.weekBasedYear()
.应该与 Java 8 或更高版本的 IsoFields
具有相同的效果(Java 8 早期版本中的一些 bugs were fixed)。
年周
对于标准ISO 8601周,考虑添加 ThreeTen-Extra库到您的项目以使用 YearWeek
类。
YearWeek yw = YearWeek.of( 2012 , 17 ) ;
关于java.time
java.time框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧类 legacy日期时间类,例如 java.util.Date
, Calendar
, & SimpleDateFormat
.
要了解更多信息,请参阅 Oracle Tutorial .并在 Stack Overflow 中搜索许多示例和解释。规范为 JSR 310 .
Joda-Time项目,现在在maintenance mode , 建议迁移到 java.time类。
您可以直接与您的数据库交换java.time 对象。使用JDBC driver符合 JDBC 4.2或以后。不需要字符串,不需要 java.sql.*
类。 Hibernate 5 和 JPA 2.2 支持 java.time。
从哪里获取 java.time 类?
- Java SE 8 , Java SE 9 , Java SE 10 , Java SE 11 , 以及后来的 - 标准 Java API 的一部分,带有捆绑实现。
- Java 9带来了一些次要功能和修复。
- Java SE 6和 Java SE 7
- 在 ThreeTen-Backport 中,大部分 java.time 功能都向后移植到 Java 6 和 7。 .
- Android
- 更高版本的 Android(26+)捆绑了 java.time 类的实现。
- 对于早期的 Android (<26),称为 API desugaring 的进程带来一个subset of the java.time Android 最初未内置的功能。
- 如果脱糖没有提供您需要的东西,ThreeTenABP项目改编ThreeTen-Backport (上面提到的)Android。参见 How to use ThreeTenABP… .
关于java获取给定日期的一年中的第几周,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10278410/