Skip to content

Commit 49a63f1

Browse files
adalpariclaude
andauthored
Fix stats off-by-an-hour by reading the site's named timezone (#23124)
The site-info endpoint returns the Olson timezone under `options.timezone`, not `timezone_string`, so the previous fix silently fell back to the stale numeric `gmt_offset`, shifting the stats "day" boundary by an hour across DST. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 315af65 commit 49a63f1

3 files changed

Lines changed: 40 additions & 3 deletions

File tree

libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/site/SiteRestClient.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,8 +1087,11 @@ class SiteRestClient @Inject constructor(
10871087
site.hasWooCommerce = from.options.woocommerce_is_active
10881088
site.adminUrl = from.options.admin_url
10891089
site.loginUrl = from.options.login_url
1090-
site.timezone = if (!from.options.timezone_string.isNullOrEmpty()) {
1091-
from.options.timezone_string
1090+
// Prefer the named Olson timezone (e.g. "Europe/Madrid") over the numeric gmt_offset so
1091+
// DST is handled correctly. The numeric offset reflects only the offset at fetch time and
1092+
// goes stale across DST transitions, which shifts the stats "day" boundary by an hour.
1093+
site.timezone = if (!from.options.timezone.isNullOrEmpty()) {
1094+
from.options.timezone
10921095
} else {
10931096
from.options.gmt_offset
10941097
}

libs/fluxc/src/main/java/org/wordpress/android/fluxc/network/rest/wpcom/site/SiteWPComRestResponse.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ public static class Options {
2323
public String admin_url;
2424
public String login_url;
2525
public String gmt_offset;
26-
public String timezone_string;
26+
// The site info endpoints (/me/sites, /sites/$id) expose the Olson timezone under "timezone"
27+
// (e.g. "Europe/Madrid"). Note the site *settings* endpoint uses "timezone_string" instead.
28+
public String timezone;
2729
public String frame_nonce;
2830
public String unmapped_url;
2931
public String max_upload_size;

libs/fluxc/src/test/java/org/wordpress/android/fluxc/network/rest/wpcom/site/SiteRestClientTest.kt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,38 @@ class SiteRestClientTest {
9898
)
9999
}
100100

101+
@Test
102+
fun `maps named Olson timezone from options timezone field`() = test {
103+
val response = SiteWPComRestResponse()
104+
response.ID = siteId
105+
response.URL = "site.com"
106+
response.options = SiteWPComRestResponse.Options().apply {
107+
timezone = "Europe/Madrid"
108+
gmt_offset = "1"
109+
}
110+
111+
initSiteResponse(response)
112+
113+
val responseModel = restClient.fetchSite(site)
114+
assertThat(responseModel.timezone).isEqualTo("Europe/Madrid")
115+
}
116+
117+
@Test
118+
fun `falls back to gmt_offset when options timezone is empty`() = test {
119+
val response = SiteWPComRestResponse()
120+
response.ID = siteId
121+
response.URL = "site.com"
122+
response.options = SiteWPComRestResponse.Options().apply {
123+
timezone = ""
124+
gmt_offset = "-5"
125+
}
126+
127+
initSiteResponse(response)
128+
129+
val responseModel = restClient.fetchSite(site)
130+
assertThat(responseModel.timezone).isEqualTo("-5")
131+
}
132+
101133
@Test
102134
fun `fetchSite returns error when API call fails`() = test {
103135
val errorMessage = "message"

0 commit comments

Comments
 (0)