Skip to content

Commit 708a051

Browse files
committed
Support date strings in date API
1 parent b1f8126 commit 708a051

File tree

2 files changed

+85
-5
lines changed

2 files changed

+85
-5
lines changed

src/senaite/core/api/dtime.py

+42-5
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,23 @@
55
from datetime import date
66
from datetime import datetime
77

8+
import six
9+
810
import pytz
911
from bika.lims import logger
1012
from DateTime import DateTime
13+
from DateTime.DateTime import DateError
14+
from DateTime.DateTime import SyntaxError
15+
from DateTime.DateTime import TimeError
16+
17+
18+
def is_str(obj):
19+
"""Check if the given object is a string
20+
21+
:param obj: arbitrary object
22+
:returns: True when the object is a string
23+
"""
24+
return isinstance(obj, six.string_types)
1125

1226

1327
def is_d(dt):
@@ -43,6 +57,9 @@ def is_date(dt):
4357
:param dt: date to check
4458
:returns: True when the object is either a datetime or DateTime
4559
"""
60+
if is_str(dt):
61+
DT = to_DT(dt)
62+
return is_date(DT)
4663
if is_d(dt):
4764
return True
4865
if is_dt(dt):
@@ -64,6 +81,9 @@ def is_timezone_naive(dt):
6481
return dt.timezoneNaive()
6582
elif is_dt(dt):
6683
return dt.tzinfo is None
84+
elif is_str(dt):
85+
DT = to_DT(dt)
86+
return is_timezone_naive(DT)
6787
raise TypeError("Expected a date, got '%r'" % type(dt))
6888

6989

@@ -84,12 +104,18 @@ def to_DT(dt):
84104
"""
85105
if is_DT(dt):
86106
return dt
107+
elif is_str(dt):
108+
try:
109+
return DateTime(dt)
110+
except (DateError, TimeError, SyntaxError, IndexError):
111+
return None
87112
elif is_dt(dt):
88113
return DateTime(dt.isoformat())
89114
elif is_d(dt):
90115
dt = datetime(dt.year, dt.month, dt.day)
91116
return DateTime(dt.isoformat())
92-
raise TypeError("Expected datetime, got '%r'" % type(dt))
117+
else:
118+
return None
93119

94120

95121
def to_dt(dt):
@@ -100,11 +126,15 @@ def to_dt(dt):
100126
"""
101127
if is_DT(dt):
102128
return dt.asdatetime()
129+
elif is_str(dt):
130+
DT = to_DT(dt)
131+
return to_dt(DT)
103132
elif is_dt(dt):
104133
return dt
105134
elif is_d(dt):
106135
return datetime(dt.year, dt.month, dt.day)
107-
raise TypeError("Expected DateTime, got '%r'" % type(dt))
136+
else:
137+
return None
108138

109139

110140
def is_valid_timezone(timezone):
@@ -155,14 +185,16 @@ def to_zone(dt, timezone):
155185
:param timezone: timezone
156186
:returns: date converted to timezone
157187
"""
158-
if is_dt(dt):
188+
if is_dt(dt) or is_d(dt):
189+
dt = to_dt(dt)
159190
zone = pytz.timezone(timezone)
160191
if is_timezone_aware(dt):
161192
return dt.astimezone(zone)
162193
return zone.localize(dt)
163-
if is_DT(dt):
194+
elif is_DT(dt):
164195
# NOTE: This shifts the time according to the TZ offset
165196
return dt.toZone(timezone)
197+
raise TypeError("Expected a date, got '%r'" % type(dt))
166198

167199

168200
def to_timestamp(dt):
@@ -176,6 +208,9 @@ def to_timestamp(dt):
176208
timestamp = dt.timeTime()
177209
elif is_dt(dt):
178210
timestamp = time.mktime(dt.timetuple())
211+
elif is_str(dt):
212+
DT = to_DT(dt)
213+
return to_timestamp(DT)
179214
return timestamp
180215

181216

@@ -185,7 +220,6 @@ def from_timestamp(timestamp):
185220
:param timestamp: POSIX timestamp
186221
:returns: datetime object
187222
"""
188-
189223
return datetime.utcfromtimestamp(timestamp)
190224

191225

@@ -196,4 +230,7 @@ def to_iso_format(dt):
196230
return dt.isoformat()
197231
elif is_DT(dt):
198232
return dt.ISO()
233+
elif is_str(dt):
234+
DT = to_DT(dt)
235+
return to_iso_format(DT)
199236
return None

src/senaite/core/tests/doctests/API_datetime.rst

+43
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,15 @@ Check if an object represents a date
8585
True
8686

8787
>>> dtime.is_date("2021-12-24")
88+
True
89+
90+
>>> dtime.is_date("2021-12-24T12:00:00")
91+
True
92+
93+
>>> dtime.is_date("2021-12-24T12:00:00+01:00")
94+
True
95+
96+
>>> dtime.is_date("Hello World")
8897
False
8998

9099
>>> dtime.is_date(object())
@@ -103,6 +112,15 @@ Check if a datetime object is TZ naive
103112
>>> dtime.is_timezone_naive(DateTime())
104113
False
105114

115+
>>> dtime.is_timezone_naive("2021-12-24")
116+
True
117+
118+
>>> dtime.is_timezone_naive("2021-12-24T12:00:00")
119+
True
120+
121+
>>> dtime.is_timezone_naive("2021-12-24T12:00:00+01:00")
122+
False
123+
106124

107125
Check if a datetime object is TZ aware
108126
......................................
@@ -116,6 +134,15 @@ Check if a datetime object is TZ aware
116134
>>> dtime.is_timezone_aware(DateTime())
117135
True
118136

137+
>>> dtime.is_timezone_aware("2021-12-24")
138+
False
139+
140+
>>> dtime.is_timezone_aware("2021-12-24T12:00:00")
141+
False
142+
143+
>>> dtime.is_timezone_aware("2021-12-24T12:00:00+01:00")
144+
True
145+
119146

120147
Convert to DateTime
121148
...................
@@ -128,6 +155,9 @@ Timezone naive datetimes are converterd to `GMT+0`:
128155
>>> dt
129156
datetime.datetime(2021, 12, 24, 12, 0)
130157

158+
>>> dtime.to_DT(DATE)
159+
DateTime('2021/12/24 12:00:00 GMT+0')
160+
131161
>>> dtime.to_DT(dt)
132162
DateTime('2021/12/24 12:00:00 GMT+0')
133163

@@ -233,6 +263,13 @@ Convert `datetime` objects to a timezone:
233263
>>> dtime.to_zone(dt_utc, "CET")
234264
datetime.datetime(1970, 1, 1, 2, 0, tzinfo=<DstTzInfo 'CET' CET+1:00:00 STD>)
235265

266+
Convert `date` objects to a timezone (converts to `datetime`):
267+
268+
>>> d = date.fromordinal(dt.toordinal())
269+
>>> d_utc = dtime.to_zone(d, "UTC")
270+
>>> d_utc
271+
datetime.datetime(1970, 1, 1, 0, 0, tzinfo=<UTC>)
272+
236273
Convert `DateTime` objects to a timezone:
237274

238275
>>> DT = DateTime(DATE)
@@ -252,6 +289,9 @@ Make a POSIX timestamp
252289
>>> DT = DateTime(DATE)
253290
>>> dt = datetime.strptime(DATE, DATEFORMAT)
254291

292+
>>> dtime.to_timestamp(DATE)
293+
3600.0
294+
255295
>>> dtime.to_timestamp(dt)
256296
3600.0
257297

@@ -271,6 +311,9 @@ Convert to ISO format
271311
>>> dt_local
272312
datetime.datetime(2021, 8, 1, 12, 0, tzinfo=<DstTzInfo 'CET' CEST+2:00:00 DST>)
273313

314+
>>> dtime.to_iso_format(DATE)
315+
'2021-08-01T12:00:00'
316+
274317
>>> dtime.to_iso_format(dt_local)
275318
'2021-08-01T12:00:00+02:00'
276319

0 commit comments

Comments
 (0)