util.py 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. from decimal import ROUND_FLOOR, Decimal
  2. def quot2(dividend: Decimal, divisor: Decimal) -> Decimal:
  3. return (dividend / divisor).to_integral_value(rounding=ROUND_FLOOR)
  4. def mod2(dividend: Decimal, divisor: Decimal) -> Decimal:
  5. return dividend - quot2(dividend, divisor) * divisor
  6. def quot3(value: Decimal, low: Decimal, high: Decimal) -> Decimal:
  7. dividend = value - low
  8. divisor = high - low
  9. return (dividend / divisor).to_integral_value(rounding=ROUND_FLOOR)
  10. def mod3(value: Decimal, low: Decimal, high: Decimal) -> Decimal:
  11. dividend = value - low
  12. divisor = high - low
  13. return mod2(dividend, divisor) + low
  14. def max_day_in_month(year: Decimal, month: Decimal) -> Decimal:
  15. norm_month = int(mod3(month, Decimal(1), Decimal(13)))
  16. norm_year = year + quot3(month, Decimal(1), Decimal(13))
  17. if norm_month in (1, 3, 5, 7, 8, 10, 12):
  18. return Decimal(31)
  19. if norm_month in (4, 6, 9, 11):
  20. return Decimal(30)
  21. is_leap_year = (
  22. mod2(norm_year, Decimal(400)) == 0
  23. or mod2(norm_year, Decimal(100)) != 0
  24. and mod2(norm_year, Decimal(4)) == 0
  25. )
  26. if norm_month == 2 and is_leap_year:
  27. return Decimal(29)
  28. return Decimal(28)