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

senaite.core.api.dtime.is_d()   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
from datetime import date
5
from datetime import datetime
6
from time import tzname
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 isinstance(dt, 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 isinstance(dt, 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 isinstance(dt, 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_dt(dt):
47
        return True
48
    if is_DT(dt):
49
        return True
50
    return False
51
52
53
def is_timezone_naive(dt):
54
    """Check if the date is timezone naive
55
56
    :param dt: date to check
57
    :returns: True when the date has no timezone
58
    """
59
    if is_DT(dt):
60
        return dt.timezoneNaive()
61
    elif is_dt(dt):
62
        return dt.tzinfo is None
63
    raise TypeError("Expected a date, got '%r'" % type(dt))
64
65
66
def is_timezone_aware(dt):
67
    """Check if the date is timezone aware
68
69
    :param dt: date to check
70
    :returns: True when the date has a timezone
71
    """
72
    return not is_timezone_naive(dt)
73
74
75
def to_DT(dt):
76
    """Convert to DateTime
77
78
    :param dt: DateTime/datetime/date
79
    :returns: DateTime object
80
    """
81
    if is_DT(dt):
82
        return dt
83
    elif is_dt(dt):
84
        return DateTime(dt.isoformat())
85
    elif is_d(dt):
86
        dt = datetime(dt.year, dt.month, dt.day)
87
        return DateTime(dt.isoformat())
88
    raise TypeError("Expected datetime, got '%r'" % type(dt))
89
90
91
def to_dt(dt):
92
    """Convert to datetime
93
94
    :param dt: DateTime/datetime/date
95
    :returns: datetime object
96
    """
97
    if is_DT(dt):
98
        return dt.asdatetime()
99
    elif is_dt(dt):
100
        return dt
101
    elif is_d(dt):
102
        return datetime(dt.year, dt.month, dt.day)
103
    raise TypeError("Expected DateTime, got '%r'" % type(dt))
104
105
106
def is_valid_timezone(timezone):
107
    """Checks if the timezone is a valid pytz/Olson name
108
109
    :param timezone: pytz/Olson timezone name
110
    :returns: True when the timezone is a valid zone
111
    """
112
    try:
113
        pytz.timezone(timezone)
114
        return True
115
    except pytz.UnknownTimeZoneError:
116
        return False
117
118
119
def get_os_timezone():
120
    """Return the default timezone of the system
121
122
    :returns: OS timezone or UTC
123
    """
124
    fallback = "UTC"
125
    timezone = None
126
    if "TZ" in os.environ.keys():
127
        # Timezone from OS env var
128
        timezone = os.environ["TZ"]
129
    if not timezone:
130
        # Timezone from python time
131
        zones = tzname
132
        if zones and len(zones) > 0:
133
            timezone = zones[0]
134
        else:
135
            # Default fallback = UTC
136
            logger.warn(
137
                "Operating system\'s timezone cannot be found. "
138
                "Falling back to UTC.")
139
            timezone = fallback
140
    if not is_valid_timezone(timezone):
141
        return fallback
142
    return timezone
143
144
145
def to_zone(dt, timezone):
146
    """Convert date to timezone
147
148
    Adds the timezone for timezone naive datetimes
149
150
    :param dt: date object
151
    :param timezone: timezone
152
    :returns: date converted to timezone
153
    """
154
    if is_dt(dt):
155
        zone = pytz.timezone(timezone)
156
        if is_timezone_aware(dt):
157
            return dt.astimezone(zone)
158
        return zone.localize(dt)
159
    if is_DT(dt):
160
        # NOTE: This shifts the time according to the TZ offset
161
        return dt.toZone(timezone)
162