Change build_time_str format to ISO 8601 with timezone

Use YYYY-MM-DD HH:MM:SS +ZZZZ format instead of the locale-dependent
'%b %d %Y, %H:%M:%S' format. This provides:
- Unambiguous date format (YYYY-MM-DD)
- Timezone information
- Locale-independent formatting
- Better sortability and parseability

Example: "2025-12-15 16:30:27 +0000" instead of "Dec 15 2025, 16:30:27"

Tests validate the format using strptime with '%Y-%m-%d %H:%M:%S %z'.
This commit is contained in:
David Woodhouse
2025-12-15 16:38:44 +00:00
parent c451fbd697
commit 09e9b58eb6
3 changed files with 16 additions and 14 deletions
+1 -1
View File
@@ -340,7 +340,7 @@ def get_build_info() -> tuple[int, int, str]:
"""
config_hash = CORE.config_hash
build_time = int(time.time())
build_time_str = time.strftime("%b %d %Y, %H:%M:%S", time.localtime(build_time))
build_time_str = time.strftime("%Y-%m-%d %H:%M:%S %z", time.localtime(build_time))
return config_hash, build_time, build_time_str
+6 -5
View File
@@ -30,8 +30,8 @@ async def test_build_info(
compilation_time = device_info.compilation_time
assert compilation_time is not None
# Parse the date string - raises ValueError if format is wrong
parsed = datetime.strptime(compilation_time, "%b %d %Y, %H:%M:%S")
# Validate the ISO format: "YYYY-MM-DD HH:MM:SS +ZZZZ"
parsed = datetime.strptime(compilation_time, "%Y-%m-%d %H:%M:%S %z")
assert parsed.year >= time.localtime().tm_year
# Get entities
@@ -98,13 +98,14 @@ async def test_build_info(
f"build_time {build_time} should be within the last hour"
)
# Validate build_time_str matches the same format as compilation_time
# Validate build_time_str matches the new ISO format
build_time_str = build_time_str_state.state
parsed_build_time = datetime.strptime(build_time_str, "%b %d %Y, %H:%M:%S")
# Format: "YYYY-MM-DD HH:MM:SS +ZZZZ"
parsed_build_time = datetime.strptime(build_time_str, "%Y-%m-%d %H:%M:%S %z")
assert parsed_build_time.year >= time.localtime().tm_year
# Verify build_time_str matches what we get from build_time timestamp
expected_str = time.strftime("%b %d %Y, %H:%M:%S", time.localtime(build_time))
expected_str = time.strftime("%Y-%m-%d %H:%M:%S %z", time.localtime(build_time))
assert build_time_str == expected_str, (
f"build_time_str '{build_time_str}' should match timestamp '{expected_str}'"
)
+9 -8
View File
@@ -1194,7 +1194,7 @@ def test_get_build_info_new_build(
assert build_time > 0
assert isinstance(build_time_str, str)
# Verify build_time_str format matches expected pattern
assert len(build_time_str) > 10 # e.g., "Dec 13 2025, 12:00:00"
assert len(build_time_str) >= 19 # e.g., "2025-12-15 16:27:44 +0000"
@patch("esphome.writer.CORE")
@@ -1209,7 +1209,7 @@ def test_get_build_info_always_returns_current_time(
# Create existing build_info.json with matching config_hash and version
existing_build_time = 1700000000
existing_build_time_str = "Nov 14 2023, 22:13:20"
existing_build_time_str = "2023-11-14 22:13:20 +0000"
build_info_path.write_text(
json.dumps(
{
@@ -1248,7 +1248,7 @@ def test_get_build_info_config_changed(
{
"config_hash": 0x12345678, # Different
"build_time": existing_build_time,
"build_time_str": "Nov 14 2023, 22:13:20",
"build_time_str": "2023-11-14 22:13:20 +0000",
"esphome_version": "2025.1.0-dev",
}
)
@@ -1279,7 +1279,7 @@ def test_get_build_info_version_changed(
{
"config_hash": 0x12345678,
"build_time": existing_build_time,
"build_time_str": "Nov 14 2023, 22:13:20",
"build_time_str": "2023-11-14 22:13:20 +0000",
"esphome_version": "2024.12.0", # Old version
}
)
@@ -1346,8 +1346,9 @@ def test_get_build_info_build_time_str_format(
config_hash, build_time, build_time_str = get_build_info()
# Verify the format matches "%b %d %Y, %H:%M:%S" (e.g., "Dec 13 2025, 14:30:45")
parsed = datetime.strptime(build_time_str, "%b %d %Y, %H:%M:%S")
# Verify the format matches "%Y-%m-%d %H:%M:%S %z"
# e.g., "2025-12-15 16:27:44 +0000"
parsed = datetime.strptime(build_time_str, "%Y-%m-%d %H:%M:%S %z")
assert parsed.year >= 2024
@@ -1355,14 +1356,14 @@ def test_generate_build_info_data_h_format() -> None:
"""Test generate_build_info_data_h produces correct header content."""
config_hash = 0x12345678
build_time = 1700000000
build_time_str = "Nov 14 2023, 22:13:20"
build_time_str = "2023-11-14 22:13:20 +0000"
result = generate_build_info_data_h(config_hash, build_time, build_time_str)
assert "#pragma once" in result
assert "#define ESPHOME_CONFIG_HASH 0x12345678U" in result
assert "#define ESPHOME_BUILD_TIME 1700000000" in result
assert 'ESPHOME_BUILD_TIME_STR[] = "Nov 14 2023, 22:13:20"' in result
assert 'ESPHOME_BUILD_TIME_STR[] = "2023-11-14 22:13:20 +0000"' in result
def test_generate_build_info_data_h_esp8266_progmem() -> None: