fix: correct Rockbox's local wall-clock timestamps to UTC
Build and publish container / build (pull_request) Successful in 4m23s

Rockbox has no concept of a timezone. Its clock holds local time, and it
builds log timestamps with mktime(get_time()) -- but firmware/libc/mktime.c
is plain calendar arithmetic applying no offset, so the RTC's local fields
come out as though they were UTC. The number in the log is ahead of the real
instant by whatever the offset was, and Last.fm stores UTC, so every play
submitted during BST landed an hour in the future.

Rockbox states this itself: its scrobbler plugin writes #TZ/UNKNOWN, and the
AUDIOSCROBBLER spec allows #TZ/UTC only for a device that actually converted.
The correction belongs to the consumer.

Each timestamp is decoded back to its wall-clock fields and reinterpreted in
the player's zone, per play rather than as one offset over the whole log, so
a log spanning a daylight saving change converts each side correctly. A log
declaring #TZ/UTC is left alone rather than shifted twice.

The zone defaults to this machine's, overridable with --device-timezone or
ROCKBOX_TIMEZONE. Deriving it needs the whole IANA name: /etc/localtime
resolves into the tzdata tree, and taking only the final component yields
"London", which no database holds, silently falling back to a fixed offset
that is wrong for half the year.

Since Rockbox cannot adjust for daylight saving on its own, the player's
clock has to be changed by hand twice a year. Any play converting to a future
time is now reported, which is what a forgotten adjustment looks like.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Emma Thorpe
2026-08-27 15:32:54 +01:00
co-authored by Claude Opus 5
parent 8d6885c46a
commit c12d2328e5
4 changed files with 332 additions and 7 deletions
+11
View File
@@ -41,6 +41,12 @@ Submitting scrobbles needs LASTFM_API_KEY and LASTFM_API_SECRET; it is skipped
with a note when they are unset. Scrobbling is a write method and needs the
secret, unlike the read-only calls elsewhere in these projects.
Rockbox has no notion of a timezone: its clock holds local wall time and its
logs record that, not UTC. Set ROCKBOX_TIMEZONE to the zone the player's clock
is keeping (an IANA name, such as Europe/London) if it differs from this
machine's, which is otherwise assumed. Getting it wrong shifts every scrobble
by the difference.
The mirror is the directory holding the artist folders. The destination is
where those folders should end up on the device -- not the card root, unless
that is genuinely where you want them:
@@ -158,6 +164,11 @@ if $scrobble; then
else
scrobble_options=()
$dry_run && scrobble_options+=(--dry-run)
# Rockbox keeps local wall time with no notion of a zone, so its
# timestamps are not the UTC Last.fm expects. Naming the zone the
# player's clock is set to lets them be corrected.
[ -n "${ROCKBOX_TIMEZONE:-}" ] &&
scrobble_options+=(--device-timezone "$ROCKBOX_TIMEZONE")
# --mirror lets it convert Rockbox's own playback.log, so the on-device
# scrobbler plugin never has to be run. The device root, not the music
# directory: the logs live in .rockbox.