Calendar c = Calendar.getInstance();
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
c.setTime( sdf.parse("31/12/2010"));
out.println( c.get( Calendar.WEEK_OF_YEAR ) );
打印数字1。
Joda时间也会发生相同的情况。
:)
Calendar c = Calendar.getInstance();
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
c.setTime( sdf.parse("31/12/2010"));
out.println( c.get( Calendar.WEEK_OF_YEAR ) );
打印数字1。
Joda时间也会发生相同的情况。
:)
周年定义与所使用的语言环境(Locale
)有关。
在美国,如何定义已经在其他帖子中讨论过。例如在德国 (DIN 1355-1 / ISO 8601) 中:一年的第一周是指新年中拥有4天或以上的第一周。
*周的第一天为星期一,最后一天为星期日。
而Java的Calendar
则会注意所处的语言环境。例如:
public static void main(String[] args) throws ParseException {
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date lastDec2010 = sdf.parse("31/12/2010");
Calendar calUs = Calendar.getInstance(Locale.US);
calUs.setTime(lastDec2010);
Calendar calDe = Calendar.getInstance(Locale.GERMAN);
calDe.setTime(lastDec2010);
System.out.println( "us: " + calUs.get( Calendar.WEEK_OF_YEAR ) );
System.out.println( "de: " + calDe.get( Calendar.WEEK_OF_YEAR ) );
}
输出:
us: 1
de: 52
补充说明 对于美国(我认为墨西哥也是这样),第1周是包括1月1日的那个星期。-- 因此,如果1月1日是星期六,则前一天(12月31日)属于同一周,在这种情况下,这一天属于2011年的第1周。
Calendar c = Calendar.getInstance();
c.setMinimalDaysInFirstWeek(7);//anything more than 1 will work in this year
DateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
c.setTime( sdf.parse("31/12/2010"));
System.out.println( c.get( Calendar.WEEK_OF_YEAR ) );
返回:
52
java.time.LocalDate.parse(
"31/12/2010" ,
DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.UK )
)
.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR )
52
或者,添加一个库,然后...
org.threeten.extra.YearWeek.from( // Convert from a `LocalDate` object to a `YearWeek` object representing the entire week of that date’s week-based year.
java.time.LocalDate.parse( "31/12/2010" , DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( Locale.UK )
).getWeek() // Extract an integer number of that week of week-based-year, either 1-52 or 1-53 depending on the year.
52
java.util.Calendar
类中一周的定义因Locale
而异。这个令人困扰的类及其伙伴 java.util.Date
已被内置于 Java 8 及更高版本中的 java.time 框架所取代。
IsoFields
类使用 ISO 8601 标准来定义一周:一周始终从星期一开始,第一周包含日历年的第一个星期四。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 );
有很多方法来定义“一周”和“一年的第一周”。
然而,有一个主要的标准定义:ISO 8601标准。该标准定义了一年中的周,包括一年的第一周。
一年中第一个星期四所在的那个星期
标准周从星期一开始,到星期日结束。
基于周的一年的第1周是指日历年中的第一个星期四所在的周。
java.time类通过IsoFields
类支持ISO 8601周,该类包含三个实现了TemporalField
的常量:
WEEK_OF_WEEK_BASED_YEAR
:周数,基于年份计算WEEK_BASED_YEAR
:基于周的年份WEEK_BASED_YEARS
:周数所在的年份调用LocalDate::get
来访问TemporalField
。
LocalDate ld = LocalDate.parse( "2010-12-31" ) ;
int weekOfWeekBasedYear = ld.get( IsoFields.WEEK_OF_WEEK_BASED_YEAR ) ;
int yearOfWeekBasedYear = ld.get( IsoFields.WEEK_BASED_YEAR ) ;
ld.toString(): 2010-12-31
weekOfWeekBasedYear: 52
yearOfWeekBasedYear: 2010
ISO 8601标准定义了一个文本格式和基于周的年份值的含义:yyyy-Www
。对于特定日期,添加从1到7编号的星期一至星期日的星期几:yyyy-Www-d
。
构造这样一个字符串。
String outputWeek = String.format( "%04d" , yearOfWeekBasedYear ) + "-W" + String.format( "%02d" , weekOfWeekBasedYear ) ;
String outputDate = outputWeek + "-" + ld.getDayOfWeek().getValue() ;
2010-W52-5
YearWeek
如果您在项目中添加ThreeTen-Extra库,则此工作将变得更加容易。然后使用YearWeek
类。
YearWeek yw = YearWeek.from( ld ) ; // Determine ISO 8601 week of a `LocalDate`.
String output = yw.toString() ;
2010-W52
并解析。
YearWeek yearWeek = YearWeek.parse( "2010-W52" ) ;
yearWeek.toString(): 2010-W52
确定一个日期。传递一个表示星期一至星期日的java.time.DayOfWeek
枚举对象。
LocalDate localDate = yw.atDay( DayOfWeek.MONDAY ) ;
localDate.toString(): 2010-12-27
我强烈建议将这个库添加到你的项目中。这样,你可以传递智能对象而不是愚蠢的整数。这样做可以使你的代码更加自我说明,提供type-safety,并确保有效值。
java.time 框架内置于 Java 8 及更高版本。这些类替代了老旧的 遗留 日期时间类,如 java.util.Date
、Calendar
和 SimpleDateFormat
。
Joda-Time项目现在处于维护模式,建议迁移到java.time类。
了解更多信息,请参阅Oracle教程。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310。
使用符合JDBC 4.2或更高版本的JDBC驱动程序,您可以直接与数据库交换java.time对象,无需字符串或java.sql.*类。
如何获取java.time类?
ThreeTen-Extra项目通过扩展java.time提供了额外的类。该项目是java.time可能未来添加内容的试验场。您可能会在这里找到一些有用的类,例如Interval
, YearWeek
, YearQuarter
和更多。
如需更详细信息,请参见类似问题中我的答案:
...并参见类似问题中我的答案:
这是因为周的起始时间与当地相关。
在美国,第1周从1月1日前的星期日开始。在2010年,这是12月26日。这就是为什么12月31日仍然是第1周。
在欧洲,第1周从1月1日前的星期一开始。在2010年,这是12月27日。这也是为什么在欧洲,12月31日仍然是第1周。
正如被接受的答案中所指定的,一年中的周数是与Locale
相关的。
演示:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.WeekFields;
import java.util.Locale;
class Main {
public static void main(String[] args) {
DateTimeFormatter parser = DateTimeFormatter.ofPattern("dd/MM/uuuu", Locale.ROOT);
LocalDate date = LocalDate.parse("31/12/2010", parser);
System.out.println(date.get(WeekFields.of(Locale.US).weekOfWeekBasedYear()));
System.out.println(date.get(WeekFields.of(Locale.GERMANY).weekOfWeekBasedYear()));
}
}
输出:
1
52
了解有关现代日期时间 API 的更多信息,请参阅 教程:日期时间。