| 259 | } |
| 260 | |
| 261 | int DateValue::Iso8601WeekOfYear() const { |
| 262 | if (UNLIKELY(!IsValid())) return -1; |
| 263 | const cctz::civil_day today = EPOCH_DATE + days_since_epoch_; |
| 264 | const cctz::civil_day first_monday = GetFirstIso8601MondayOfYear(today.year()); |
| 265 | const cctz::civil_day last_sunday = GetLastIso8601SundayOfYear(today.year()); |
| 266 | |
| 267 | // 0001-01-01 is Monday in the proleptic Gregorian calendar. |
| 268 | // 0001-01-01 belongs to year 0001. |
| 269 | // 9999-12-31 is Friday in the proleptic Gregorian calendar. |
| 270 | // 9999-12-31 belongs to year 9999. |
| 271 | if (today >= first_monday && today <= last_sunday) { |
| 272 | return (today - first_monday) / 7 + 1; |
| 273 | } else if (today > last_sunday) { |
| 274 | DCHECK(today.year() >= MIN_YEAR && today.year() < MAX_YEAR); |
| 275 | return 1; |
| 276 | } else { |
| 277 | DCHECK(today < first_monday); |
| 278 | DCHECK(today.year() > MIN_YEAR && today.year() <= MAX_YEAR); |
| 279 | cctz::civil_day prev_jan1 = cctz::civil_day(today.year() - 1, 1, 1); |
| 280 | cctz::civil_day prev_first_monday; |
| 281 | if (cctz::get_weekday(prev_jan1) <= cctz::weekday::thursday) { |
| 282 | // Get the previous Monday if 'prev_jan1' is not already a Monday. |
| 283 | prev_first_monday = cctz::next_weekday(prev_jan1, cctz::weekday::monday) - 7; |
| 284 | } else { |
| 285 | // Get the next Monday. |
| 286 | prev_first_monday = cctz::next_weekday(prev_jan1, cctz::weekday::monday); |
| 287 | } |
| 288 | return (today - prev_first_monday) / 7 + 1; |
| 289 | } |
| 290 | } |
| 291 | |
| 292 | int DateValue::Iso8601WeekNumberingYear() const { |
| 293 | if (UNLIKELY(!IsValid())) return -1; |