Skip to content

Commit 58d322b

Browse files
committed
datetime conversion
1 parent ca8fbf8 commit 58d322b

File tree

8 files changed

+65
-90
lines changed

8 files changed

+65
-90
lines changed

delta_backend/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM public.ecr.aws/lambda/python:3.10 AS base
1+
FROM public.ecr.aws/lambda/python:3.11 AS base
22

33
# Create a non-root user with a specific UID and GID
44
RUN mkdir -p /home/appuser && \

delta_backend/poetry.lock

Lines changed: 27 additions & 53 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

delta_backend/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ packages = [
99
]
1010

1111
[tool.poetry.dependencies]
12-
python = "~3.10"
12+
python = "~3.11"
1313
boto3 = "~1.26.90"
1414
mypy-boto3-dynamodb = "^1.26.164"
1515
moto = "~4.2.11"

delta_backend/src/ConversionChecker.py

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Handles the transformation logic for each field based on the schema
33
# Root and base type expression checker functions
44
import ExceptionMessages
5-
from datetime import datetime,timezone
5+
from datetime import datetime,timedelta, timezone
66
from zoneinfo import ZoneInfo
77
import re
88
from LookUpData import LookUpData
@@ -136,40 +136,36 @@ def _convertToDateTime(self, expressionRule, fieldName, fieldValue, summarise, r
136136
if not fieldValue:
137137
return ""
138138

139-
# Reject partial dates like "2024" or "2024-05"
140-
if re.match(r"^\d{4}(-\d{2})?$", fieldValue):
141-
raise RecordError(
142-
ExceptionMessages.RECORD_CHECK_FAILED,
143-
f"{fieldName} rejected: partial datetime not accepted.",
144-
f"Invalid partial datetime: {fieldValue}",
145-
)
146139
try:
147-
dt = datetime.fromisoformat(fieldValue)
148-
except ValueError:
140+
if not expressionRule:
141+
# Handle YYYYMMDD format to
142+
dt = datetime.strptime(fieldValue, "%Y%m%d")
143+
dt = dt.replace(hour=0, minute=0, second=0)
144+
else:
145+
dt = datetime.fromisoformat(fieldValue)
146+
if dt.tzinfo is None:
147+
dt = dt.replace(tzinfo=timezone.utc)
148+
except Exception as e:
149149
if report_unexpected_exception:
150-
return f"Unexpected format: {fieldValue}"
150+
self._log_error(fieldName, fieldValue, e)
151+
return ""
151152

152153
# Allow only +00:00 or +01:00 offsets (UTC and BST) and reject unsupported timezones
153154
offset = dt.utcoffset()
154-
allowed_offsets = [ZoneInfo("UTC").utcoffset(dt),
155-
ZoneInfo("Europe/London").utcoffset(dt)]
156-
if offset not in allowed_offsets:
157-
raise RecordError(
158-
ExceptionMessages.RECORD_CHECK_FAILED,
159-
f"{fieldName} rejected: unsupported timezone.",
160-
f"Unsupported offset: {offset}",
161-
)
155+
allowed_offsets = [timedelta(hours=0), timedelta(hours=1)]
156+
if offset is not None and offset not in allowed_offsets:
157+
if report_unexpected_exception:
158+
self._log_error(fieldName, fieldValue, "Unsupported Format or offset")
159+
return ""
162160

163161
# Convert to UTC
164-
dt_utc = dt.astimezone(ZoneInfo("UTC")).replace(microsecond=0)
165-
166-
format_str = expressionRule.replace("format:", "")
162+
dt_utc = dt.replace(microsecond=0)
167163

168-
if format_str == "csv-utc":
164+
if expressionRule == "csv-utc":
169165
formatted = dt_utc.strftime("%Y%m%dT%H%M%S%z")
170166
return formatted.replace("+0000", "00").replace("+0100", "01")
171167

172-
return dt_utc.strftime(format_str)
168+
return dt_utc.strftime("%Y%m%dT%H%M%S%z")
173169

174170
# Not Empty Validate - Returns exactly what is in the extracted fields no parsing or logic needed
175171
def _convertToNotEmpty(self, expressionRule, fieldName, fieldValue, summarise, report_unexpected_exception):

delta_backend/src/ConversionLayout.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
"expression": {
6969
"expressionName": "Date Convert",
7070
"expressionType": "DATETIME",
71-
"expressionRule": "format:csv-utc"
71+
"expressionRule": "csv-utc"
7272
}
7373
},
7474
{

delta_backend/src/Converter.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,12 @@ def extract_patient_details(self, json_data, FlatFieldName):
137137
self._cached_values = {}
138138

139139
if not self._cached_values:
140-
occurrence_time = datetime.fromisoformat(json_data.get("occurrenceDateTime", ""))
140+
try:
141+
occurrence_time = datetime.fromisoformat(json_data.get("occurrenceDateTime", ""))
142+
except Exception as e:
143+
message = "DateTime conversion error [%s]: %s" % (e.__class__.__name__, e)
144+
error = self._log_error(message, code=ExceptionMessages.UNEXPECTED_EXCEPTION)
145+
return error
141146
patient = get_patient(json_data)
142147
if not patient:
143148
return None

delta_backend/tests/sample_data/fhir_sample.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@
7272
"patient": {
7373
"reference": "#Pat1"
7474
},
75-
"occurrenceDateTime": "2021-02-07T13:28:17+00:00",
76-
"recorded": "2025-02-07",
75+
"occurrenceDateTime": "2021-05-07T12:24:37.67867+01:00",
76+
"recorded": "2025-01-01T00:00:00.00",
7777
"primarySource": "True",
7878
"manufacturer": {
7979
"display": "AstraZeneca Ltd"
@@ -86,7 +86,7 @@
8686
}
8787
},
8888
"lotNumber": "4120Z001",
89-
"expirationDate": "2024-10-12",
89+
"expirationDate": "2024-10-05",
9090
"site": {
9191
"coding": [
9292
{

delta_backend/tests/test_convert_to_flat_json.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -462,19 +462,19 @@ def test_convert_to_date_time(self, MockLookUpData):
462462
checker = ConversionChecker(dataParser, summarise=False, report_unexpected_exception=True)
463463

464464
valid_date_time = "2022-01-01T12:00:00+00:00"
465-
result = checker._convertToDateTime("%Y%m%dT%H%M%S", "fieldName", valid_date_time, False, True)
466-
self.assertEqual(result, "20220101T120000")
465+
result = checker._convertToDateTime("csv-utc", "fieldName", valid_date_time, False, True)
466+
self.assertEqual(result, "20220101T12000000")
467467

468468
valid_csv_utc = "2022-01-01T13:28:17+00:00"
469-
result = checker._convertToDateTime("format:csv-utc", "fieldName", valid_csv_utc, False, True)
469+
result = checker._convertToDateTime("csv-utc", "fieldName", valid_csv_utc, False, True)
470470
self.assertEqual(result, "20220101T13281700")
471471

472472
invalid_date_time = "invalid_date_time"
473-
result = checker._convertToDateTime("format:%Y%m%dT%H%M%S", "fieldName", invalid_date_time, False, True)
474-
self.assertEqual(result, "Unexpected format: invalid_date_time")
473+
result = checker._convertToDateTime("csv-utc", "fieldName", invalid_date_time, False, True)
474+
self.assertEqual(result, "")
475475

476476
# Empty input returns blank
477-
result = checker._convertToDateTime("format:%Y%m%dT%H%M%S", "fieldName", "", False, True)
477+
result = checker._convertToDateTime("csv-utc", "fieldName", "", False, True)
478478
self.assertEqual(result, "")
479479

480480
@patch("ConversionChecker.LookUpData")

0 commit comments

Comments
 (0)