diff --git a/changedetectionio/flask_app.py b/changedetectionio/flask_app.py index 2f6be5c1..b6166006 100644 --- a/changedetectionio/flask_app.py +++ b/changedetectionio/flask_app.py @@ -84,7 +84,7 @@ csrf = CSRFProtect() csrf.init_app(app) notification_debug_log=[] -# get locale ready +# Locale for correct presentation of prices etc default_locale = locale.getdefaultlocale() logger.info(f"System locale default is {default_locale}") try: @@ -159,6 +159,21 @@ def _jinja2_filter_pagination_slice(arr, skip): return arr +def app_get_system_time(): + from zoneinfo import ZoneInfo # Built-in timezone support in Python 3.9+ + + system_timezone = datastore.data['settings']['application'].get('timezone') + if not system_timezone: + system_timezone = os.environ.get("TZ") + + try: + system_zone = ZoneInfo(system_timezone) + except Exception as e: + logger.warning(f'Warning, unable to use timezone "{system_timezone}" defaulting to UTC- {str(e)}') + system_zone = ZoneInfo("UTC") # Fallback to UTC if the timezone is invalid + + return system_zone + @app.template_filter('format_seconds_ago') def _jinja2_filter_seconds_precise(timestamp): if timestamp == False: @@ -243,6 +258,9 @@ def changedetection_app(config=None, datastore_o=None): # (instead of the global var) app.config['DATASTORE'] = datastore_o + # Just to check (it will output some debug if not) + app_get_system_time() + login_manager = flask_login.LoginManager(app) login_manager.login_view = 'login' app.secret_key = init_app_secret(config['datastore_path']) @@ -882,6 +900,7 @@ def changedetection_app(config=None, datastore_o=None): @login_optionally_required def settings_page(): from changedetectionio import forms + from datetime import datetime default = deepcopy(datastore.data['settings']) if datastore.proxy_list is not None: @@ -949,6 +968,13 @@ def changedetection_app(config=None, datastore_o=None): else: flash("An error occurred, please see below.", "error") + + system_timezone = app_get_system_time() + system_time = datetime.now(system_timezone) + + # Fallback for locale formatting + formatted_system_time = system_time.strftime("%Y-%m-%d %H:%M:%S %Z%z") # Locale-aware time + output = render_template("settings.html", api_key=datastore.data['settings']['application'].get('api_access_token'), emailprefix=os.getenv('NOTIFICATION_MAIL_BUTTON_PREFIX', False), @@ -956,7 +982,9 @@ def changedetection_app(config=None, datastore_o=None): form=form, hide_remove_pass=os.getenv("SALTED_PASS", False), min_system_recheck_seconds=int(os.getenv('MINIMUM_SECONDS_RECHECK_TIME', 3)), - settings_application=datastore.data['settings']['application'] + settings_application=datastore.data['settings']['application'], + system_time=formatted_system_time, + timezone_name=system_timezone ) return output @@ -1709,7 +1737,6 @@ def notification_runner(): def ticker_thread_check_time_launch_checks(): import random from changedetectionio import update_worker - proxy_last_called_time = {} recheck_time_minimum_seconds = int(os.getenv('MINIMUM_SECONDS_RECHECK_TIME', 3)) diff --git a/changedetectionio/model/App.py b/changedetectionio/model/App.py index fdd627ed..f148671c 100644 --- a/changedetectionio/model/App.py +++ b/changedetectionio/model/App.py @@ -52,7 +52,8 @@ class model(dict): 'schema_version' : 0, 'shared_diff_access': False, 'webdriver_delay': None , # Extra delay in seconds before extracting text - 'tags': {} #@todo use Tag.model initialisers + 'tags': {}, #@todo use Tag.model initialisers + 'timezone': None, } } } diff --git a/changedetectionio/templates/settings.html b/changedetectionio/templates/settings.html index 53006c62..50ffebf5 100644 --- a/changedetectionio/templates/settings.html +++ b/changedetectionio/templates/settings.html @@ -78,6 +78,10 @@ {{ render_checkbox_field(form.application.form.empty_pages_are_a_change) }}
+Local Time: {{ system_time }}
+Timezone: {{ timezone_name }}
+