Skip to content

Commit 406542d

Browse files
feat: (low-code cdk) datetime format with milliseconds (#369)
1 parent a402288 commit 406542d

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

airbyte_cdk/sources/declarative/datetime/datetime_parser.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ def parse(self, date: Union[str, int], format: str) -> datetime.datetime:
3131
return datetime.datetime.fromtimestamp(float(date), tz=datetime.timezone.utc)
3232
elif format == "%ms":
3333
return self._UNIX_EPOCH + datetime.timedelta(milliseconds=int(date))
34-
34+
elif "%_ms" in format:
35+
format = format.replace("%_ms", "%f")
3536
parsed_datetime = datetime.datetime.strptime(str(date), format)
3637
if self._is_naive(parsed_datetime):
3738
return parsed_datetime.replace(tzinfo=datetime.timezone.utc)
@@ -48,6 +49,11 @@ def format(self, dt: datetime.datetime, format: str) -> str:
4849
if format == "%ms":
4950
# timstamp() returns a float representing the number of seconds since the unix epoch
5051
return str(int(dt.timestamp() * 1000))
52+
if "%_ms" in format:
53+
_format = format.replace("%_ms", "%f")
54+
milliseconds = int(dt.microsecond / 1000)
55+
formatted_dt = dt.strftime(_format).replace(dt.strftime("%f"), "%03d" % milliseconds)
56+
return formatted_dt
5157
else:
5258
return dt.strftime(format)
5359

airbyte_cdk/sources/declarative/declarative_component_schema.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,7 @@ definitions:
844844
* **%M**: Minute (zero-padded) - `00`, `01`, ..., `59`
845845
* **%S**: Second (zero-padded) - `00`, `01`, ..., `59`
846846
* **%f**: Microsecond (zero-padded to 6 digits) - `000000`
847+
* **%_ms**: Millisecond (zero-padded to 3 digits) - `000`
847848
* **%z**: UTC offset - `(empty)`, `+0000`, `-04:00`
848849
* **%Z**: Time zone name - `(empty)`, `UTC`, `GMT`
849850
* **%j**: Day of the year (zero-padded) - `001`, `002`, ..., `366`
@@ -2401,6 +2402,7 @@ definitions:
24012402
* **%M**: Minute (zero-padded) - `00`, `01`, ..., `59`
24022403
* **%S**: Second (zero-padded) - `00`, `01`, ..., `59`
24032404
* **%f**: Microsecond (zero-padded to 6 digits) - `000000`, `000001`, ..., `999999`
2405+
* **%_ms**: Millisecond (zero-padded to 3 digits) - `000`, `001`, ..., `999`
24042406
* **%z**: UTC offset - `(empty)`, `+0000`, `-04:00`
24052407
* **%Z**: Time zone name - `(empty)`, `UTC`, `GMT`
24062408
* **%j**: Day of the year (zero-padded) - `001`, `002`, ..., `366`

unit_tests/sources/declarative/datetime/test_datetime_parser.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@
5050
"%Y%m%d",
5151
datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc),
5252
),
53+
(
54+
"test_parse_format_datetime_with__ms",
55+
"2021-11-22T08:41:55.640Z",
56+
"%Y-%m-%dT%H:%M:%S.%_msZ",
57+
datetime.datetime(2021, 11, 22, 8, 41, 55, 640000, tzinfo=datetime.timezone.utc),
58+
),
5359
],
5460
)
5561
def test_parse_date(test_name, input_date, date_format, expected_output_date):
@@ -91,6 +97,12 @@ def test_parse_date(test_name, input_date, date_format, expected_output_date):
9197
"%Y%m%d",
9298
"20210101",
9399
),
100+
(
101+
"test_parse_format_datetime_with__ms",
102+
datetime.datetime(2021, 11, 22, 8, 41, 55, 640000, tzinfo=datetime.timezone.utc),
103+
"%Y-%m-%dT%H:%M:%S.%_msZ",
104+
"2021-11-22T08:41:55.640Z",
105+
),
94106
],
95107
)
96108
def test_format_datetime(test_name, input_dt, datetimeformat, expected_output):

0 commit comments

Comments
 (0)