utcoffset.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. # -*- coding: utf-8 -*-
  2. # Copyright (c) 2021, Brandon Nielsen
  3. # All rights reserved.
  4. #
  5. # This software may be modified and distributed under the terms
  6. # of the BSD license. See the LICENSE file for details.
  7. import datetime
  8. class UTCOffset(datetime.tzinfo):
  9. def __init__(self, name=None, minutes=None):
  10. # We build an offset in this manner since the
  11. # tzinfo class must have an init
  12. # "method that can be called with no arguments"
  13. self._name = name
  14. if minutes is not None:
  15. self._utcdelta = datetime.timedelta(minutes=minutes)
  16. else:
  17. self._utcdelta = None
  18. def __repr__(self):
  19. if self._utcdelta >= datetime.timedelta(hours=0):
  20. return "+{0} UTC".format(self._utcdelta)
  21. # From the docs:
  22. # String representations of timedelta objects are normalized
  23. # similarly to their internal representation. This leads to
  24. # somewhat unusual results for negative timedeltas.
  25. # Clean this up for printing purposes
  26. # Negative deltas start at -1 day
  27. correcteddays = abs(self._utcdelta.days + 1)
  28. # Negative deltas have a positive seconds
  29. deltaseconds = (24 * 60 * 60) - self._utcdelta.seconds
  30. # (24 hours / day) * (60 minutes / hour) * (60 seconds / hour)
  31. days, remainder = divmod(deltaseconds, 24 * 60 * 60)
  32. # (1 hour) * (60 minutes / hour) * (60 seconds / hour)
  33. hours, remainder = divmod(remainder, 1 * 60 * 60)
  34. # (1 minute) * (60 seconds / minute)
  35. minutes, seconds = divmod(remainder, 1 * 60)
  36. # Add any remaining days to the correcteddays count
  37. correcteddays += days
  38. if correcteddays == 0:
  39. return "-{0}:{1:02}:{2:02} UTC".format(hours, minutes, seconds)
  40. elif correcteddays == 1:
  41. return "-1 day, {0}:{1:02}:{2:02} UTC".format(hours, minutes, seconds)
  42. return "-{0} days, {1}:{2:02}:{3:02} UTC".format(
  43. correcteddays, hours, minutes, seconds
  44. )
  45. def utcoffset(self, dt):
  46. return self._utcdelta
  47. def tzname(self, dt):
  48. return self._name
  49. def dst(self, dt):
  50. # ISO 8601 specifies offsets should be different if DST is required,
  51. # instead of allowing for a DST to be specified
  52. # https://docs.python.org/2/library/datetime.html#datetime.tzinfo.dst
  53. return datetime.timedelta(0)