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
(self, period_tensor)
| 292 | return tf.rank(self._ordinals) |
| 293 | |
| 294 | def __add__(self, period_tensor): |
| 295 | """Adds a tensor of periods. |
| 296 | |
| 297 | When adding months or years, the resulting day of the month is decreased |
| 298 | to the largest valid value if necessary. E.g. 31.03.2020 + 1 month = |
| 299 | 30.04.2020, 29.02.2020 + 1 year = 28.02.2021. |
| 300 | |
| 301 | Args: |
| 302 | period_tensor: A `PeriodTensor` object broadcastable to the shape of |
| 303 | "self". |
| 304 | |
| 305 | Returns: |
| 306 | The new instance of DateTensor. |
| 307 | |
| 308 | #### Example |
| 309 | ```python |
| 310 | dates = tff.datetime.dates_from_tuples([(2020, 2, 25), (2020, 3, 31)]) |
| 311 | new_dates = dates + tff.datetime.month() |
| 312 | # DateTensor([(2020, 3, 25), (2020, 4, 30)]) |
| 313 | |
| 314 | new_dates = dates + tff.datetime.month([1, 2]) |
| 315 | # DateTensor([(2020, 3, 25), (2020, 5, 31)]) |
| 316 | ``` |
| 317 | """ |
| 318 | period_type = period_tensor.period_type() |
| 319 | |
| 320 | if period_type == constants.PeriodType.DAY: |
| 321 | ordinals = self._ordinals + period_tensor.quantity() |
| 322 | return from_ordinals(ordinals) |
| 323 | |
| 324 | if period_type == constants.PeriodType.WEEK: |
| 325 | return self + periods.PeriodTensor(period_tensor.quantity() * 7, |
| 326 | constants.PeriodType.DAY) |
| 327 | |
| 328 | def adjust_day(year, month, day): |
| 329 | return tf.math.minimum(day, _num_days_in_month(month, year)) |
| 330 | |
| 331 | if period_type == constants.PeriodType.MONTH: |
| 332 | m = self._months - 1 + period_tensor.quantity() |
| 333 | y = self._years + m // 12 |
| 334 | m = m % 12 + 1 |
| 335 | d = adjust_day(y, m, self._days) |
| 336 | return from_year_month_day(y, m, d, validate=False) |
| 337 | |
| 338 | if period_type == constants.PeriodType.YEAR: |
| 339 | y = self._years + period_tensor.quantity() |
| 340 | # Use tf.shape to handle the case of dynamically shaped `y` |
| 341 | m = tf.broadcast_to(self._months, tf.shape(y)) |
| 342 | d = adjust_day(y, m, self._days) |
| 343 | return from_year_month_day(y, m, d, validate=False) |
| 344 | |
| 345 | raise ValueError("Unrecognized period type: {}".format(period_type)) |
| 346 | |
| 347 | def __sub__(self, period_tensor): |
| 348 | """Subtracts a tensor of periods. |
nothing calls this directly
no test coverage detected