Passed
Pull Request — 2.x (#1903)
by Ramon
04:34
created

senaite.core.api.dtime.get_os_timezone()   B

Complexity

Conditions 6

Size

Total Lines 24
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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