withDate method

DateTime withDate(
  1. DateTime dateTime
)

Adds current IsoDuration to a specified dateTime (or subtracts if IsoDuration is negative).

Both years and months must not be decimal, otherwise it is not possible to accurately calculate and return from it new DateTime.

It is recommended to work with UTC DateTime due to DST (Daylight Saving Time). DateTime by default uses local time!

Example:

final dur = IsoDuration(hours: 2, minutes: 30);
final dateTime = DateTime(2021, 1, 20, 8); // 2021-01-20 08:00:00.000
dur.withDate(dateTime); // 2021-01-20 10:30:00.000

Implementation

DateTime withDate(DateTime dateTime) {
  assert(
    !years.isDecimal() && !months.isDecimal(),
    'Years and months must not be decimal!',
  );

  if (isZero) {
    return dateTime;
  }

  if (isPrecise) {
    final microseconds = (toSeconds().secsToMicrosecs()).truncate();
    if (isNegative) {
      final duration = Duration(microseconds: microseconds * -1);
      return dateTime.subtract(duration);
    }
    return dateTime.add(Duration(microseconds: microseconds));
  }

  final newDate = dateTime.isUtc
      ? DateTime.utc(
          dateTime.year + years.truncate(),
          dateTime.month + months.truncate(),
          dateTime.day,
          dateTime.hour,
          dateTime.minute,
          dateTime.millisecond,
          dateTime.microsecond,
        )
      : DateTime(
          dateTime.year + years.truncate(),
          dateTime.month + months.truncate(),
          dateTime.day,
          dateTime.hour,
          dateTime.minute,
          dateTime.millisecond,
          dateTime.microsecond,
        );

  final precisePart = copyWith(years: 0, months: 0);
  final microseconds = precisePart.toSeconds().secsToMicrosecs().truncate();

  if (isNegative) {
    return newDate.subtract(Duration(microseconds: microseconds * -1));
  }

  return newDate.add(Duration(microseconds: microseconds));
}