Passed
Push — 2.x ( 2d6cc3...84f108 )
by Jordi
06:01
created

senaite.core.api.dtime   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 200
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 39
eloc 93
dl 0
loc 200
rs 9.28
c 0
b 0
f 0

14 Functions

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