Skip to content

Fix S3 backup list times shifted by the site's UTC offset (shown twice-offset in history tables)#239

Open
chata wants to merge 1 commit into
wp-media:masterfrom
chata:fix/s3-file-list-double-tz-offset
Open

Fix S3 backup list times shifted by the site's UTC offset (shown twice-offset in history tables)#239
chata wants to merge 1 commit into
wp-media:masterfrom
chata:fix/s3-file-list-double-tz-offset

Conversation

@chata

@chata chata commented Jul 12, 2026

Copy link
Copy Markdown

Fixes #240

Description

BackWPup_Destination_S3::file_update_list() converts the S3 object's LastModified (UTC) into a Unix timestamp and then adds the site's gmt_offset:

$changetime = strtotime((string) $object['LastModified']) + (get_option('gmt_offset') * 3600);

Unix timestamps are timezone-independent, so this shifts the epoch value into the future for sites east of UTC.

All three consumers of this value format it with wp_date(), which already converts the epoch to the site timezone:

  • the backups history table: components/table-row-backups.php (lines 9-10)
  • the legacy backups page: inc/class-page-backups.php (column_time())
  • the S3 file list (download/restore view): $files[$filecounter]['time'] within the same method, later rendered through wp_date()

The offset therefore gets applied twice. On a UTC+9 (Asia/Tokyo) site, every backup stored on an S3-compatible destination is displayed 9 hours in the future: a scheduled backup that ran at 0:00 JST shows as "9:00 AM", a manual backup taken at 1:40 PM shows as "10:40 PM". Backups stored on the local folder destination display correctly, which makes the S3 rows look inconsistent next to them.

Fix

Drop the gmt_offset addition and keep the true epoch. This makes all three views show the correct backup time. It also brings S3 in line with the other remote destinations (Dropbox, MS Azure, RSC), which already use the raw epoch without an offset.

Retention pruning is unaffected: $backupfilelist is keyed by $changetime only for sorting, and removing a uniform shift does not change the ordering.

How to reproduce

  1. Set the site timezone to a non-UTC zone (e.g. Asia/Tokyo, UTC+9) in Settings → General.
  2. Configure a job with an S3 (or S3-compatible, e.g. Cloudflare R2) destination and run it.
  3. Open BackWPup → Backups History: the row shows the backup 9 hours in the future, while the filename (which uses site-local time) and a backup stored on the server show the correct time.

Tested on BackWPup 5.7.4 / WordPress with PHP 8.4 against Cloudflare R2 (S3-compatible).

BackWPup_Destination_S3::file_get_list() converts the S3 object's
LastModified (UTC) to a Unix timestamp and then adds the site's
gmt_offset to it. Unix timestamps are timezone-independent, so this
shifts the epoch value into the future for sites east of UTC.

Both the new backups history table (components/table-row-backups.php)
and the legacy backups page (inc/class-page-backups.php) format this
value with wp_date(), which already converts to the site timezone.
The pre-shifted timestamp therefore gets the offset applied twice:
on a UTC+9 site every S3/R2 backup is displayed 9 hours in the
future (e.g. a backup taken at 13:40 JST shows as 10:40 PM), while
backups stored in the local folder destination display correctly.

Dropping the offset keeps retention pruning intact (
keys shift uniformly, so their order is unchanged) and makes both
tables show the true backup time.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

S3 backup list times are shifted by the site's UTC offset (timezone offset applied twice)

1 participant