Fixed timezone being returned incorrectly
Happened if you've set TZ to non-UTC. Apparently astimezone and replace doesn't do the same thing even if tzinfo is None.
This commit is contained in:
@@ -13,7 +13,7 @@ from spoolman.math import length_from_weight
|
|||||||
def datetime_to_str(dt: datetime) -> str:
|
def datetime_to_str(dt: datetime) -> str:
|
||||||
"""Convert a datetime object to a string."""
|
"""Convert a datetime object to a string."""
|
||||||
if dt.tzinfo is None:
|
if dt.tzinfo is None:
|
||||||
dt = dt.astimezone(tz=timezone.utc)
|
dt = dt.replace(tzinfo=timezone.utc)
|
||||||
return dt.isoformat().replace("+00:00", "Z")
|
return dt.isoformat().replace("+00:00", "Z")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -230,8 +230,8 @@ async def use_weight(db: AsyncSession, spool_id: int, weight: float) -> models.S
|
|||||||
spool = await get_by_id(db, spool_id)
|
spool = await get_by_id(db, spool_id)
|
||||||
|
|
||||||
if spool.first_used is None:
|
if spool.first_used is None:
|
||||||
spool.first_used = datetime.utcnow()
|
spool.first_used = datetime.utcnow().replace(microsecond=0)
|
||||||
spool.last_used = datetime.utcnow()
|
spool.last_used = datetime.utcnow().replace(microsecond=0)
|
||||||
|
|
||||||
await db.commit()
|
await db.commit()
|
||||||
await spool_changed(spool)
|
await spool_changed(spool)
|
||||||
@@ -275,8 +275,8 @@ async def use_length(db: AsyncSession, spool_id: int, length: float) -> models.S
|
|||||||
spool = await get_by_id(db, spool_id)
|
spool = await get_by_id(db, spool_id)
|
||||||
|
|
||||||
if spool.first_used is None:
|
if spool.first_used is None:
|
||||||
spool.first_used = datetime.utcnow()
|
spool.first_used = datetime.utcnow().replace(microsecond=0)
|
||||||
spool.last_used = datetime.utcnow()
|
spool.last_used = datetime.utcnow().replace(microsecond=0)
|
||||||
|
|
||||||
await db.commit()
|
await db.commit()
|
||||||
await spool_changed(spool)
|
await spool_changed(spool)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- COCKROACH_USER=john
|
- COCKROACH_USER=john
|
||||||
- COCKROACH_DATABASE=spoolman
|
- COCKROACH_DATABASE=spoolman
|
||||||
|
- TZ=Asia/Seoul
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test:
|
test:
|
||||||
[
|
[
|
||||||
@@ -26,6 +27,7 @@ services:
|
|||||||
- SPOOLMAN_DB_NAME=spoolman
|
- SPOOLMAN_DB_NAME=spoolman
|
||||||
- SPOOLMAN_DB_USERNAME=john
|
- SPOOLMAN_DB_USERNAME=john
|
||||||
- SPOOLMAN_LOGGING_LEVEL=INFO
|
- SPOOLMAN_LOGGING_LEVEL=INFO
|
||||||
|
- TZ=Europe/Stockholm
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ services:
|
|||||||
- MARIADB_PASSWORD=abc
|
- MARIADB_PASSWORD=abc
|
||||||
- MARIADB_DATABASE=spoolman
|
- MARIADB_DATABASE=spoolman
|
||||||
- MARIADB_MYSQL_LOCALHOST_USER=true
|
- MARIADB_MYSQL_LOCALHOST_USER=true
|
||||||
|
- TZ=Asia/Seoul
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test:
|
test:
|
||||||
[
|
[
|
||||||
@@ -30,6 +31,7 @@ services:
|
|||||||
- SPOOLMAN_DB_USERNAME=john
|
- SPOOLMAN_DB_USERNAME=john
|
||||||
- SPOOLMAN_DB_PASSWORD=abc
|
- SPOOLMAN_DB_PASSWORD=abc
|
||||||
- SPOOLMAN_LOGGING_LEVEL=INFO
|
- SPOOLMAN_LOGGING_LEVEL=INFO
|
||||||
|
- TZ=Europe/Stockholm
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ services:
|
|||||||
image: postgres:11-alpine
|
image: postgres:11-alpine
|
||||||
environment:
|
environment:
|
||||||
- POSTGRES_PASSWORD=abc
|
- POSTGRES_PASSWORD=abc
|
||||||
|
- TZ='GMT+4'
|
||||||
|
- PGTZ='GMT+4'
|
||||||
spoolman:
|
spoolman:
|
||||||
image: donkie/spoolman:test
|
image: donkie/spoolman:test
|
||||||
environment:
|
environment:
|
||||||
@@ -14,6 +16,7 @@ services:
|
|||||||
- SPOOLMAN_DB_USERNAME=postgres
|
- SPOOLMAN_DB_USERNAME=postgres
|
||||||
- SPOOLMAN_DB_PASSWORD=abc
|
- SPOOLMAN_DB_PASSWORD=abc
|
||||||
- SPOOLMAN_LOGGING_LEVEL=INFO
|
- SPOOLMAN_LOGGING_LEVEL=INFO
|
||||||
|
- TZ=Europe/Stockholm
|
||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
tester:
|
tester:
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ services:
|
|||||||
image: donkie/spoolman:test
|
image: donkie/spoolman:test
|
||||||
environment:
|
environment:
|
||||||
- SPOOLMAN_LOGGING_LEVEL=INFO
|
- SPOOLMAN_LOGGING_LEVEL=INFO
|
||||||
|
- TZ=Europe/Stockholm
|
||||||
tester:
|
tester:
|
||||||
image: donkie/spoolman-tester:latest
|
image: donkie/spoolman-tester:latest
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import math
|
import math
|
||||||
|
from datetime import datetime, timezone
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
@@ -41,6 +42,14 @@ def test_use_spool_weight(random_filament: dict[str, Any], use_weight: float):
|
|||||||
assert spool["used_weight"] == pytest.approx(max(use_weight, 0))
|
assert spool["used_weight"] == pytest.approx(max(use_weight, 0))
|
||||||
assert spool["remaining_weight"] == pytest.approx(min(max(start_weight - use_weight, 0), filament_net_weight))
|
assert spool["remaining_weight"] == pytest.approx(min(max(start_weight - use_weight, 0), filament_net_weight))
|
||||||
|
|
||||||
|
# Verify that first_used has been updated
|
||||||
|
diff = abs((datetime.now(tz=timezone.utc) - datetime.fromisoformat(spool["first_used"])).total_seconds())
|
||||||
|
assert diff < 60
|
||||||
|
|
||||||
|
# Verify that last_used has been updated
|
||||||
|
diff = abs((datetime.now(tz=timezone.utc) - datetime.fromisoformat(spool["last_used"])).total_seconds())
|
||||||
|
assert diff < 60
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
httpx.delete(f"{URL}/api/v1/spool/{spool['id']}").raise_for_status()
|
httpx.delete(f"{URL}/api/v1/spool/{spool['id']}").raise_for_status()
|
||||||
|
|
||||||
@@ -56,6 +65,7 @@ def test_use_spool_length(random_filament: dict[str, Any], use_length: float):
|
|||||||
json={
|
json={
|
||||||
"filament_id": random_filament["id"],
|
"filament_id": random_filament["id"],
|
||||||
"remaining_weight": start_weight,
|
"remaining_weight": start_weight,
|
||||||
|
"first_used": "2023-01-01T00:00:00Z",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
result.raise_for_status()
|
result.raise_for_status()
|
||||||
@@ -79,6 +89,13 @@ def test_use_spool_length(random_filament: dict[str, Any], use_length: float):
|
|||||||
assert spool["used_weight"] == pytest.approx(max(use_weight, 0))
|
assert spool["used_weight"] == pytest.approx(max(use_weight, 0))
|
||||||
assert spool["remaining_weight"] == pytest.approx(min(max(start_weight - use_weight, 0), filament_net_weight))
|
assert spool["remaining_weight"] == pytest.approx(min(max(start_weight - use_weight, 0), filament_net_weight))
|
||||||
|
|
||||||
|
# Verify that first_used hasn't been updated since it was already set
|
||||||
|
assert spool["first_used"] == "2023-01-01T00:00:00Z"
|
||||||
|
|
||||||
|
# Verify that last_used has been updated
|
||||||
|
diff = abs((datetime.now(tz=timezone.utc) - datetime.fromisoformat(spool["last_used"])).total_seconds())
|
||||||
|
assert diff < 60
|
||||||
|
|
||||||
# Clean up
|
# Clean up
|
||||||
httpx.delete(f"{URL}/api/v1/spool/{spool['id']}").raise_for_status()
|
httpx.delete(f"{URL}/api/v1/spool/{spool['id']}").raise_for_status()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user