asDate method
Return a date built using our values. If no date portion is set, use the 'Epoch' of January 1, 1970.
Implementation
DateTime asDate({int retries = 3}) {
// TODO(alanknight): Validate the date, especially for things which
// can crash the VM, e.g. large month values.
if (_date != null) return _date!;
DateTime preliminaryResult;
final hasCentury = !_hasAmbiguousCentury || year < 0 || year >= 100;
if (hasCentury) {
preliminaryResult = _dateTimeConstructor(year, month, dayOrDayOfYear,
hour24, minute, second, fractionalSecond, utc);
} else {
var now = clock.now();
if (utc) {
now = now.toUtc();
}
const lookBehindYears = 80;
var lowerDate = _offsetYear(now, -lookBehindYears);
var upperDate = _offsetYear(now, 100 - lookBehindYears);
var lowerCentury = (lowerDate.year ~/ 100) * 100;
var upperCentury = (upperDate.year ~/ 100) * 100;
preliminaryResult = _dateTimeConstructor(upperCentury + year, month,
dayOrDayOfYear, hour24, minute, second, fractionalSecond, utc);
// Our interval must be half-open since there otherwise could be ambiguity
// for a date that is exactly 20 years in the future or exactly 80 years
// in the past (mod 100). We'll treat the lower-bound date as the
// exclusive bound because:
// * It's farther away from the present, and we're less likely to care
// about it.
// * By the time this function exits, time will have advanced to favor
// the upper-bound date.
//
// We don't actually need to check both bounds.
if (preliminaryResult.compareTo(upperDate) <= 0) {
// Within range.
assert(preliminaryResult.compareTo(lowerDate) > 0);
} else {
preliminaryResult = _dateTimeConstructor(lowerCentury + year, month,
dayOrDayOfYear, hour24, minute, second, fractionalSecond, utc);
}
}
if (utc && hasCentury) {
_date = preliminaryResult;
} else {
_date = _correctForErrors(preliminaryResult, retries);
}
return _date!;
}