| 404 | } |
| 405 | |
| 406 | bool DateValue::MonthsBetween(const DateValue& other, double* months_between) const { |
| 407 | DCHECK(months_between != nullptr); |
| 408 | if (UNLIKELY(!IsValid() || !other.IsValid())) return false; |
| 409 | |
| 410 | const cctz::civil_day today = EPOCH_DATE + days_since_epoch_; |
| 411 | const cctz::civil_month month(today); |
| 412 | const cctz::civil_day last_day_of_month = cctz::civil_day(month + 1) - 1; |
| 413 | |
| 414 | const cctz::civil_day other_date = EPOCH_DATE + other.days_since_epoch_; |
| 415 | const cctz::civil_month other_month(other_date); |
| 416 | const cctz::civil_day last_day_of_other_month = cctz::civil_day(other_month + 1) - 1; |
| 417 | |
| 418 | // If both dates are last days of different months they don't contribute |
| 419 | // a fractional value to the number of months, therefore there is no need to |
| 420 | // calculate difference in their days. |
| 421 | int days_diff = 0; |
| 422 | if (today != last_day_of_month || other_date != last_day_of_other_month) { |
| 423 | days_diff = today.day() - other_date.day(); |
| 424 | } |
| 425 | |
| 426 | *months_between = (today.year() - other_date.year()) * 12 + |
| 427 | today.month() - other_date.month() + (static_cast<double>(days_diff) / 31.0); |
| 428 | return true; |
| 429 | } |
| 430 | |
| 431 | string DateValue::ToString() const { |
| 432 | string s; |