diff --git a/changedetectionio/notification_service.py b/changedetectionio/notification_service.py
index d478d56eb..356b39e05 100644
--- a/changedetectionio/notification_service.py
+++ b/changedetectionio/notification_service.py
@@ -61,6 +61,7 @@ class NotificationContextData(dict):
super().__init__({
'base_url': None,
'change_datetime': None,
+ 'change_datetime_z': None,
'current_snapshot': None,
'diff': None,
'diff_added': None,
@@ -119,6 +120,16 @@ class NotificationContextData(dict):
super().__setitem__(key, value)
+def timestamp_to_localtime_iso8601(timestamp):
+ # Interpret timestamp as UTC
+ dt_utc = datetime.datetime.fromtimestamp(int(timestamp), tz=pytz.UTC)
+
+ # Convert to local timezone
+ local_dt = dt_utc.astimezone()
+
+ # Return ISO 8601 format
+ return local_dt.isoformat()
+
def timestamp_to_localtime(timestamp):
# Format the date using locale-aware formatting with timezone
# Pass tz=UTC so fromtimestamp() interprets the epoch correctly as UTC,
@@ -204,6 +215,7 @@ def set_basic_notification_vars(current_snapshot, prev_snapshot, watch, triggere
'prev_snapshot': prev_snapshot,
'screenshot': watch.get_screenshot() if watch and watch.get('notification_screenshot') else None,
'change_datetime': timestamp_to_localtime(timestamp_changed) if timestamp_changed else None,
+ 'change_datetime_z': timestamp_to_localtime_iso8601(timestamp_changed) if timestamp_changed else None,
'triggered_text': triggered_text,
'uuid': watch.get('uuid') if watch else None,
'watch_url': watch.get('url') if watch else None,
diff --git a/changedetectionio/templates/_common_fields.html b/changedetectionio/templates/_common_fields.html
index b3cb8a7f1..d89955a26 100644
--- a/changedetectionio/templates/_common_fields.html
+++ b/changedetectionio/templates/_common_fields.html
@@ -44,6 +44,18 @@
{{ '{{preview_url}}' }} |
{{ _('The URL of the preview page generated by changedetection.io.') }} |
+
+ {{ '{{change_datime}}' }} |
+ {{ _('Date/time of the change in \'%Y-%m-%d %H:%M:%S %Z\' format') }} |
+
+
+ {{ '{{change_datime_z}}' }} |
+ {{ _('Date/time of the change in ISO-8601 format') }} |
+
+
+ {{ '{{diff_url}}' }} |
+ {{ _('The URL of the diff output for the watch.') }} |
+
{{ '{{diff_url}}' }} |
{{ _('The URL of the diff output for the watch.') }} |
diff --git a/changedetectionio/tests/test_notification.py b/changedetectionio/tests/test_notification.py
index fbd80960e..f5715b472 100644
--- a/changedetectionio/tests/test_notification.py
+++ b/changedetectionio/tests/test_notification.py
@@ -109,6 +109,7 @@ def test_check_notification(client, live_server, measure_memory_usage, datastore
"Diff Full: {{diff_full}}\n"
"Diff as Patch: {{diff_patch}}\n"
"Change datetime: {{change_datetime}}\n"
+ "Change datetime Z: {{change_datetime_z}}\n"
":-)",
"notification_screenshot": True,
"notification_format": 'text'}
@@ -136,8 +137,6 @@ def test_check_notification(client, live_server, measure_memory_usage, datastore
assert bytes(notification_url.encode('utf-8')) in res.data
assert bytes("New ChangeDetection.io Notification".encode('utf-8')) in res.data
-
-
## Now recheck, and it should have sent the notification
wait_for_all_checks(client)
set_modified_response(datastore_path=datastore_path)
@@ -181,11 +180,14 @@ def test_check_notification(client, live_server, measure_memory_usage, datastore
# timestamp worked
import time
- from changedetectionio.notification_service import timestamp_to_localtime
+ from changedetectionio.notification_service import timestamp_to_localtime, timestamp_to_localtime_iso8601
# Could be from a few seconds ago (when the notification was fired vs in this test checking), so check for any
times_possible = [timestamp_to_localtime(int(time.time()) - i) for i in range(15)]
assert any(t in notification_submission for t in times_possible)
+ times_possible = [timestamp_to_localtime_iso8601(int(time.time()) - i) for i in range(15)]
+ assert any(t in notification_submission for t in times_possible)
+
# We keep PNG screenshots for now
# IF THIS FAILS YOU SHOULD BE TESTING WITH ENV VAR REMOVE_REQUESTS_OLD_SCREENSHOTS=False