diff --git a/public/astronomical_conversions.php b/public/astronomical_conversions.php index a904527..ccd0846 100644 --- a/public/astronomical_conversions.php +++ b/public/astronomical_conversions.php @@ -1021,7 +1021,7 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur }); const parseUtcDateTime = function (value) { - const match = String(value).trim().match(/^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2})(?::(\d{2}))?)?$/); + const match = String(value).trim().match(/^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2})(?::(\d{2})(?:[.,](\d{1,3}))?)?)?$/); if (!match) { return null; } @@ -1032,7 +1032,8 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur const hour = Number(match[4] || '0'); const minute = Number(match[5] || '0'); const second = Number(match[6] || '0'); - const date = new Date(Date.UTC(year, month - 1, day, hour, minute, second)); + const millisecond = Number((match[7] || '0').padEnd(3, '0')); + const date = new Date(Date.UTC(year, month - 1, day, hour, minute, second, millisecond)); return Number.isNaN(date.getTime()) ? null : date; }; @@ -1054,7 +1055,7 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur date.getUTCSeconds().toString().padStart(2, '0') ]; - return parts.join('-') + ' ' + timeParts.join(':'); + return parts.join('-') + ' ' + timeParts.join(':') + '.' + date.getUTCMilliseconds().toString().padStart(3, '0'); }; const formatUtcDateTimeGerman = function (date) { @@ -1074,11 +1075,11 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur date.getUTCSeconds().toString().padStart(2, '0') ]; - return parts.join('.') + ' ' + timeParts.join(':'); + return parts.join('.') + ' ' + timeParts.join(':') + ',' + date.getUTCMilliseconds().toString().padStart(3, '0'); }; const parseUtcDateTimeGerman = function (value) { - const match = String(value).trim().match(/^(\d{2})\.(\d{2})\.(\d{4})(?:[ ](\d{2}):(\d{2})(?::(\d{2}))?)?$/); + const match = String(value).trim().match(/^(\d{2})\.(\d{2})\.(\d{4})(?:[ ](\d{2}):(\d{2})(?::(\d{2})(?:[.,](\d{1,3}))?)?)?$/); if (!match) { return null; } @@ -1089,7 +1090,8 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur const hour = Number(match[4] || '0'); const minute = Number(match[5] || '0'); const second = Number(match[6] || '0'); - const date = new Date(Date.UTC(year, month - 1, day, hour, minute, second)); + const millisecond = Number((match[7] || '0').padEnd(3, '0')); + const date = new Date(Date.UTC(year, month - 1, day, hour, minute, second, millisecond)); return Number.isNaN(date.getTime()) ? null : date; }; @@ -1101,6 +1103,9 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur isSyncingTimePicker = true; timeUtcPicker.setDate(date, false); + if (timeUtcPicker.altInput) { + timeUtcPicker.altInput.value = formatUtcDateTimeGerman(date); + } isSyncingTimePicker = false; }; @@ -1138,14 +1143,14 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur updateTimeFrom('utc'); if (instance.altInput) { - instance.altInput.setAttribute('placeholder', 'TT.MM.JJJJ HH:MM:SS'); + instance.altInput.setAttribute('placeholder', 'TT.MM.JJJJ HH:MM:SS,mmm'); } } }); if (timeUtcPicker.altInput) { timeUtcPicker.altInput.classList.add('astro-conv-input'); - timeUtcPicker.altInput.setAttribute('placeholder', 'TT.MM.JJJJ HH:MM:SS'); + timeUtcPicker.altInput.setAttribute('placeholder', 'TT.MM.JJJJ HH:MM:SS,mmm'); } } diff --git a/public/py/__pycache__/astronomical_conversions.cpython-314.pyc b/public/py/__pycache__/astronomical_conversions.cpython-314.pyc index a6e945a..9c37d7b 100644 Binary files a/public/py/__pycache__/astronomical_conversions.cpython-314.pyc and b/public/py/__pycache__/astronomical_conversions.cpython-314.pyc differ diff --git a/public/py/astronomical_conversions.py b/public/py/astronomical_conversions.py index c36d797..4c7e661 100644 --- a/public/py/astronomical_conversions.py +++ b/public/py/astronomical_conversions.py @@ -129,11 +129,13 @@ def format_decimal_german(value: Decimal | float | int | None, *, max_fraction_d def format_utc_datetime(dt_utc: datetime) -> str: - return dt_utc.astimezone(timezone.utc).strftime("%Y-%m-%d %H:%M:%S") + dt_utc = dt_utc.astimezone(timezone.utc) + return dt_utc.strftime("%Y-%m-%d %H:%M:%S") + f".{dt_utc.microsecond // 1000:03d}" def format_german_datetime(dt_utc: datetime) -> str: - return dt_utc.astimezone(timezone.utc).strftime("%d.%m.%Y %H:%M:%S") + dt_utc = dt_utc.astimezone(timezone.utc) + return dt_utc.strftime("%d.%m.%Y %H:%M:%S") + f",{dt_utc.microsecond // 1000:03d}" def format_clock(hours_value: float) -> str: @@ -161,9 +163,10 @@ def parse_utc_datetime(value: str) -> datetime | None: if text == "": return None - for fmt in ("%Y-%m-%d %H:%M:%S", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M", "%Y-%m-%d"): + normalized = text.replace(",", ".") + for fmt in ("%Y-%m-%d %H:%M:%S.%f", "%Y-%m-%dT%H:%M:%S.%f", "%Y-%m-%d %H:%M:%S", "%Y-%m-%dT%H:%M:%S", "%Y-%m-%d %H:%M", "%Y-%m-%d"): try: - parsed = datetime.strptime(text, fmt) + parsed = datetime.strptime(normalized, fmt) return parsed.replace(tzinfo=timezone.utc) except ValueError: continue