forked from cameron-simpson/css
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdateutils.py
More file actions
135 lines (107 loc) · 3.36 KB
/
Copy pathdateutils.py
File metadata and controls
135 lines (107 loc) · 3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python
#
''' A few conveniences to do with dates and times.
There are some other PyPI modules providing richer date handling
than the stdlib `datetime` module.
This module mostly contains conveniences used in my other code;
you're welcome to it, but it does not pretend to be large or complete.
'''
# Add flake8 fixes - easy fixes -
# Jonathan Hyry <jonathan.hyry@outlook.com> - 2026-04-05
from datetime import date, datetime, timedelta, tzinfo
from time import localtime, mktime, strftime
__version__ = '20250724-post'
DISTINFO = {
'keywords': ["date", "time", "datetime", "python", "python3"],
'classifiers': [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
],
'install_requires': [],
}
class tzinfoHHMM(tzinfo):
''' tzinfo class based on +HHMM / -HHMM strings.
'''
def __init__(self, shhmm):
sign, hour, minute = shhmm[0], int(shhmm[1:3]), int(shhmm[3:5])
if sign == '+':
sign = 1
elif sign == '-':
sign = -1
else:
raise ValueError(
"%s: invalid sign '%s', should be '+' or '-'" % (
shhmm,
sign,
)
)
self._tzname = shhmm
self.sign = sign
self.hour = hour
self.minute = minute
def utcoffset(self, dt):
return self.hour * 60 + self.minute
def dst(self, dt):
return timedelta(0)
def tzname(self, dt):
return self._tzname
try:
from datetime import timezone # pylint: disable=ungrouped-imports
except ImportError:
UTC = tzinfoHHMM('+0000')
else:
UTC = timezone.utc
def isodate(when=None, dashed=True):
''' Return a date in ISO8601 YYYY-MM-DD format, or YYYYMMDD if not `dashed`.
Modern Pythons have a `datetime.isoformat` method, you should use that.
'''
if when is None:
when = localtime()
if dashed:
format_s = '%Y-%m-%d'
else:
format_s = '%Y%m%d'
return strftime(format_s, when)
def datetime2unixtime(dt):
''' Convert a timezone aware `datetime` to a UNIX timestamp.
*WARNING*: a naive datetime is assumed to be in UTC.
'''
if dt.tzinfo is None:
dt = dt.replace(tzinfo=UTC)
return dt.timestamp()
def unixtime2datetime(unixtime, *, tz: tzinfo = UTC):
''' Convert a a UNIX timestamp to a `datetime` in the timezone `tz`.
*Note*: the default timezone is UTC, not the local timezone.
'''
return datetime.fromtimestamp(unixtime, tz=tz)
def localdate2unixtime(d):
''' Convert a localtime `date` into a UNIX timestamp.
'''
return mktime(date(d.year, d.month, d.day).timetuple())
class UNIXTimeMixin:
''' A mixin for classes with a `.unixtime` attribute,
a `float` storing a UNIX timestamp.
'''
def as_datetime(self, tz: tzinfo = UTC):
''' Return `self.unixtime` as a `datetime`
with the timezone `tz` (default `UTC`).
'''
if not isinstance(tz, tzinfo):
raise TypeError(
'not a datetime.tzinfo instance: tz=%s:%r' %
(tz.__class__.__name__, tz)
)
return unixtime2datetime(self.unixtime, tz=tz)
@property
def datetime(self):
''' The `unixtime` as a UTC `datetime`.
'''
return self.as_datetime(UTC)
@datetime.setter
def datetime(self, dt):
''' Set the `unixtime` from a `datetime`.
The `datetime` may not be naive (`tz.tzinfo` may not be `None`).
'''
if dt.tzinfo is None:
raise ValueError('naive datetime %r' % (dt,))
self.unixtime = dt.timestamp()