Skip to content

Commit 383ebb3

Browse files
feat: add timestamp_to_datetime macro
1 parent daf7d48 commit 383ebb3

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

airbyte_cdk/sources/declarative/interpolation/macros.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,24 @@ def timestamp(dt: Union[float, str]) -> Union[int, float]:
7171
return str_to_datetime(dt).astimezone(pytz.utc).timestamp()
7272

7373

74+
def timestamp_to_datetime(ts: Union[int, float, str]) -> datetime.datetime:
75+
"""
76+
Converts a Unix timestamp to a datetime object with UTC timezone.
77+
78+
Usage:
79+
"{{ timestamp_to_datetime(1658505815) }}"
80+
81+
:param ts: Unix timestamp (in seconds) to convert to datetime
82+
:return: datetime object in UTC timezone
83+
"""
84+
try:
85+
ts_value = float(ts)
86+
except (TypeError, ValueError) as exc:
87+
raise ValueError(f"Invalid timestamp value: {ts}") from exc
88+
89+
return datetime.datetime.fromtimestamp(ts_value, tz=pytz.utc)
90+
91+
7492
def str_to_datetime(s: str) -> datetime.datetime:
7593
"""
7694
Converts a string to a datetime object with UTC timezone
@@ -222,6 +240,7 @@ def generate_uuid() -> str:
222240
now_utc,
223241
today_utc,
224242
timestamp,
243+
timestamp_to_datetime,
225244
max,
226245
min,
227246
day_delta,

unit_tests/sources/declarative/interpolation/test_macros.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
[
1616
("test_now_utc", "now_utc", True),
1717
("test_today_utc", "today_utc", True),
18+
("test_timestamp_to_datetime", "timestamp_to_datetime", True),
1819
("test_max", "max", True),
1920
("test_min", "min", True),
2021
("test_day_delta", "day_delta", True),
@@ -176,6 +177,38 @@ def test_timestamp(test_name, input_value, expected_output):
176177
assert actual_output == expected_output
177178

178179

180+
@pytest.mark.parametrize(
181+
"test_name, input_value, expected_output",
182+
[
183+
(
184+
"test_seconds_int",
185+
1646006400,
186+
datetime.datetime(2022, 2, 28, 0, 0, tzinfo=datetime.timezone.utc),
187+
),
188+
(
189+
"test_seconds_float",
190+
1646006400.5,
191+
datetime.datetime(2022, 2, 28, 0, 0, 0, 500000, tzinfo=datetime.timezone.utc),
192+
),
193+
(
194+
"test_seconds_string",
195+
"1646006400",
196+
datetime.datetime(2022, 2, 28, 0, 0, tzinfo=datetime.timezone.utc),
197+
),
198+
],
199+
)
200+
def test_timestamp_to_datetime(test_name, input_value, expected_output):
201+
timestamp_to_datetime_fn = macros["timestamp_to_datetime"]
202+
actual_output = timestamp_to_datetime_fn(input_value)
203+
assert actual_output == expected_output
204+
205+
206+
def test_timestamp_to_datetime_invalid_value():
207+
timestamp_to_datetime_fn = macros["timestamp_to_datetime"]
208+
with pytest.raises(ValueError):
209+
timestamp_to_datetime_fn("invalid-timestamp")
210+
211+
179212
def test_utc_datetime_to_local_timestamp_conversion():
180213
"""
181214
This test ensures correct timezone handling independent of the timezone of the system on which the sync is running.

0 commit comments

Comments
 (0)