You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Java Calendar对象返回错误的WEEK_OF_YEAR与WEEK_OF_MONTH?

解决Calendar中WEEK_OF_YEAR和WEEK_OF_MONTH的错误返回问题

Hey there, let's break down why you're seeing those unexpected week values with your GregorianCalendar instance. First, let's pin down the date you're working with: that timestamp 1514678400000 corresponds to UTC 2017-12-31 00:00:00, which is a Sunday.

问题原因分析

1. WEEK_OF_YEAR返回1而非预期值

The issue here boils down to how GregorianCalendar defines weeks by default. Most locales (like US English) set Sunday as the first day of the week, and consider the week containing January 1st as the first week of the year.

Since January 1, 2018 is a Monday, the preceding Sunday (December 31, 2017) gets grouped into 2018's first week—hence the WEEK_OF_YEAR value of 1. If you're expecting ISO-standard weeks (Monday start, first week of the year must have at least 4 days), this date should fall in 2017's 52nd week.

2. WEEK_OF_MONTH返回6而非预期的5

Again, this is tied to the default week start rule. With Sunday as the first day of the week:

  • The first week of December 2017 includes Dec 1 (Fri) through Dec 3 (Sun)
  • Each subsequent week runs Sunday to Saturday
  • By this count, Dec 25 (Mon) to Dec 31 (Sun) would be the 5th week—but if your Calendar is using a different rule (like counting the first full week of the month as week 1), it might inflate the count to 6. The core problem is that Calendar's week calculations are locale-dependent and ambiguous by default.

解决方案

推荐:使用Java 8+的java.time API (JSR-310)

The old Date/Calendar classes are legacy and full of these kinds of ambiguities. The modern java.time package fixes this with clear, standard-based rules. Here's how to get your expected values:

// Parse the timestamp to a UTC date
Instant instant = Instant.ofEpochMilli(1514678400000L);
ZonedDateTime zdt = instant.atZone(ZoneOffset.UTC);

// Get ISO-standard week values (Monday start, proper year-week alignment)
int weekOfYear = zdt.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR);
int weekOfMonth = zdt.get(ChronoField.ALIGNED_WEEK_OF_MONTH);

System.out.println("ISO Week of Year: " + weekOfYear); // Outputs 52
System.out.println("ISO Week of Month: " + weekOfMonth); // Outputs 5

兼容方案:调整GregorianCalendar的周规则

If you must stick with Calendar for compatibility reasons, explicitly set the week start and minimal days in the first week to match your expected rules:

Calendar cal = GregorianCalendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setTimeInMillis(1514678400000L);

// Set Monday as the first day of the week (ISO standard)
cal.setFirstDayOfWeek(Calendar.MONDAY);
// Require at least 4 days in the first week of the year (ISO standard)
cal.setMinimalDaysInFirstWeek(4);

int weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
int weekOfMonth = cal.get(Calendar.WEEK_OF_MONTH);

System.out.println("Fixed Week of Year: " + weekOfYear); // Outputs 52
System.out.println("Fixed Week of Month: " + weekOfMonth); // Outputs 5

关键总结

  • Legacy Calendar's week calculations depend heavily on the default locale, which leads to unexpected results if you don't explicitly configure it.
  • The java.time API uses clear, standard rules by default, eliminating these ambiguities entirely.

内容的提问来源于stack exchange,提问作者gangatharan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:07:02