Passed
Pull Request — 2.x (#1903)
by Ramon
05:22
created

senaite.core.api.dtime.is_timezone_aware()   A

Complexity

Conditions 1

Size

Total Lines 7
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
# -*- coding: utf-8 -*-
2
3
import os
4
import time
5
from datetime import date
6
from datetime import datetime
7
from time import tzname
8
9
import pytz
10
from bika.lims import logger
11
from DateTime import DateTime
12
13
14
def is_d(dt):
15
    """Check if the date is a Python `date` object
16
17
    :param dt: date to check
18
    :returns: True when the date is a Python `date`
19
    """
20
    return type(dt) is date
21
22
23
def is_dt(dt):
24
    """Check if the date is a Python `datetime` object
25
26
    :param dt: date to check
27
    :returns: True when the date is a Python `datetime`
28
    """
29
    return type(dt) is datetime
30
31
32
def is_DT(dt):
33
    """Check if the date is a Zope `DateTime` object
34
35
    :param dt: object to check
36
    :returns: True when the object is a Zope `DateTime`
37
    """
38
    return type(dt) is DateTime
39
40
41
def is_date(dt):
42
    """Check if the date is a datetime or DateTime object
43
44
    :param dt: date to check
45
    :returns: True when the object is either a datetime or DateTime
46
    """
47
    if is_d(dt):
48
        return True
49
    if is_dt(dt):
50
        return True
51
    if is_DT(dt):
52
        return True
53
    return False
54
55
56
def is_timezone_naive(dt):
57
    """Check if the date is timezone naive
58
59
    :param dt: date to check
60
    :returns: True when the date has no timezone
61
    """
62
    if is_d(dt):
63
        return True
64
    elif is_DT(dt):
65
        return dt.timezoneNaive()
66
    elif is_dt(dt):
67
        return dt.tzinfo is None
68
    raise TypeError("Expected a date, got '%r'" % type(dt))
69
70
71
def is_timezone_aware(dt):
72
    """Check if the date is timezone aware
73
74
    :param dt: date to check
75
    :returns: True when the date has a timezone
76
    """
77
    return not is_timezone_naive(dt)
78
79
80
def to_DT(dt):
81
    """Convert to DateTime
82
83
    :param dt: DateTime/datetime/date
84
    :returns: DateTime object
85
    """
86
    if is_DT(dt):
87
        return dt
88
    elif is_dt(dt):
89
        return DateTime(dt.isoformat())
90
    elif is_d(dt):
91
        dt = datetime(dt.year, dt.month, dt.day)
92
        return DateTime(dt.isoformat())
93
    raise TypeError("Expected datetime, got '%r'" % type(dt))
94
95
96
def to_dt(dt):
97
    """Convert to datetime
98
99
    :param dt: DateTime/datetime/date
100
    :returns: datetime object
101
    """
102
    if is_DT(dt):
103
        return dt.asdatetime()
104
    elif is_dt(dt):
105
        return dt
106
    elif is_d(dt):
107
        return datetime(dt.year, dt.month, dt.day)
108
    raise TypeError("Expected DateTime, got '%r'" % type(dt))
109
110
111
def is_valid_timezone(timezone):
112
    """Checks if the timezone is a valid pytz/Olson name
113
114
    :param timezone: pytz/Olson timezone name
115
    :returns: True when the timezone is a valid zone
116
    """
117
    try:
118
        pytz.timezone(timezone)
119
        return True
120
    except pytz.UnknownTimeZoneError:
121
        return False
122
123
124
def get_os_timezone():
125
    """Return the default timezone of the system
126
127
    :returns: OS timezone or UTC
128
    """
129
    fallback = "UTC"
130
    timezone = None
131
    if "TZ" in os.environ.keys():
132
        # Timezone from OS env var
133
        timezone = os.environ["TZ"]
134
    if not timezone:
135
        # Timezone from python time
136
        zones = tzname
137
        if zones and len(zones) > 0:
138
            timezone = zones[0]
139
        else:
140
            # Default fallback = UTC
141
            logger.warn(
142
                "Operating system\'s timezone cannot be found. "
143
                "Falling back to UTC.")
144
            timezone = fallback
145
    if not is_valid_timezone(timezone):
146
        return fallback
147
    return timezone
148
149
150
def to_zone(dt, timezone):
151
    """Convert date to timezone
152
153
    Adds the timezone for timezone naive datetimes
154
155
    :param dt: date object
156
    :param timezone: timezone
157
    :returns: date converted to timezone
158
    """
159
    if is_dt(dt):
160
        zone = pytz.timezone(timezone)
161
        if is_timezone_aware(dt):
162
            return dt.astimezone(zone)
163
        return zone.localize(dt)
164
    if is_DT(dt):
165
        # NOTE: This shifts the time according to the TZ offset
166
        return dt.toZone(timezone)
167
168
169
def to_timestamp(dt):
170
    """Generate a Portable Operating System Interface (POSIX) timestamp
171
172
    :param dt: date object
173
    :returns: timestamp in seconds
174
    """
175
    timestamp = 0
176
    if is_DT(dt):
177
        timestamp = dt.timeTime()
178
    elif is_dt(dt):
179
        timestamp = time.mktime(dt.timetuple())
180
    return timestamp
181
182
183
def from_timestamp(timestamp):
184
    """Generate a datetime object from a POSIX timestamp
185
186
    :param timestamp: POSIX timestamp
187
    :returns: datetime object
188
    """
189
190
    return datetime.utcfromtimestamp(timestamp)
191
192
193
def to_iso_format(dt):
194
    """Convert to ISO format
195
    """
196
    if is_dt(dt):
197
        return dt.isoformat()
198
    elif is_DT(dt):
199
        return dt.ISO()
200
    return None
201