Пример #1
0
  def __add__(self, period_tensor):
    """Adds a tensor of periods.

    When adding months or years, the resulting day of the month is decreased
    to the largest valid value if necessary. E.g. 31.03.2020 + 1 month =
    30.04.2020, 29.02.2020 + 1 year = 28.02.2021.

    Args:
      period_tensor: A `PeriodTensor` object broadcastable to the shape of
      "self".

    Returns:
      The new instance of DateTensor.

    #### Example
    ```python
    dates = tff.datetime.dates_from_tuples([(2020, 2, 25), (2020, 3, 31)])
    new_dates = dates + tff.datetime.month()
    # DateTensor([(2020, 3, 25), (2020, 4, 30)])

    new_dates = dates + tff.datetime.month([1, 2])
    # DateTensor([(2020, 3, 25), (2020, 5, 31)])
    ```
    """
    period_type = period_tensor.period_type()

    if period_type == constants.PeriodType.DAY:
      ordinals = self._ordinals + period_tensor.quantity()
      return from_ordinals(ordinals)

    if period_type == constants.PeriodType.WEEK:
      return self + periods.PeriodTensor(period_tensor.quantity() * 7,
                                         constants.PeriodType.DAY)

    def adjust_day(year, month, day):
      return tf.math.minimum(day, _num_days_in_month(month, year))

    if period_type == constants.PeriodType.MONTH:
      m = self._months - 1 + period_tensor.quantity()
      y = self._years + m // 12
      m = m % 12 + 1
      d = adjust_day(y, m, self._days)
      return from_year_month_day(y, m, d, validate=False)

    if period_type == constants.PeriodType.YEAR:
      y = self._years + period_tensor.quantity()
      # Use tf.shape to handle the case of dynamically shaped `y`
      m = tf.broadcast_to(self._months, tf.shape(y))
      d = adjust_day(y, m, self._days)
      return from_year_month_day(y, m, d, validate=False)

    raise ValueError("Unrecognized period type: {}".format(period_type))
Пример #2
0
  def __sub__(self, period_tensor):
    """Subtracts a tensor of periods.

    When subtracting months or years, the resulting day of the month is
    decreased to the largest valid value if necessary. E.g. 31.03.2020 - 1 month
    = 29.02.2020, 29.02.2020 - 1 year = 28.02.2019.

    Args:
      period_tensor: a PeriodTensor object broadcastable to the shape of "self".

    Returns:
      The new instance of DateTensor.
    """
    return self + periods.PeriodTensor(-period_tensor.quantity(),
                                       period_tensor.period_type())
    def subtract_period_and_roll(
            self,
            date_tensor,
            period_tensor,
            roll_convention=constants.BusinessDayConvention.NONE):
        """Subtracts given periods from given dates and rolls to business days.

    The original dates are not rolled prior to subtraction.

    Args:
      date_tensor: DateTensor of dates to subtract from.
      period_tensor: PeriodTensor broadcastable to `date_tensor`.
      roll_convention: BusinessDayConvention. Determines how to roll a date that
        falls on a holiday.

    Returns:
      The resulting DateTensor.
    """
        minus_period_tensor = periods.PeriodTensor(-period_tensor.quantity(),
                                                   period_tensor.period_type())
        return self.add_period_and_roll(date_tensor, minus_period_tensor,
                                        roll_convention)