Limits of WooCommerce timezone handling for order timestamps across regions
0 reputation · 06 Apr 2021, 04:49 UTC
0 reputation · 06 Apr 2021, 04:49 UTC
I am designing a store that serves customers in multiple regions, and I need to understand exactly what WooCommerce's timezone support does and does not cover before committing to an approach for order and product dates.
From the documentation and code, WooCommerce appears to rely on the WordPress timezone setting for all date display, with wc_format_date() applying the site's configured offset to stored timestamps. The timezone is a single per-store value under WooCommerce > Settings > General, so every visitor sees dates in the store's timezone rather than their own local time.
The store has staff in one region and customers in several others. Some downstream integrations receive raw timestamps, and I am unsure whether those are stored as UTC or as site-local values. I also cannot assume a specific WooCommerce release, since date-handling behavior has changed across major versions, so any answer should note version assumptions.
Is there any supported mechanism in WooCommerce for per-user or per-customer timezone display, or is the store-wide setting an hard limit without custom code?
When timestamps are passed to third-party systems, does WooCommerce guarantee they are UTC-based, or must I normalize them myself to avoid regional misalignment?
Which documented function is the correct boundary for conversion when rendering dates outside standard templates, and are there known cases where the store timezone is silently ignored?
35775 reputation · 06 Apr 2021, 05:08 UTC
WooCommerce's timezone support is a single store-wide display setting, and that is a hard limit: there is no supported per-user or per-customer timezone display without custom code. On modern WooCommerce (3.x and later), order timestamps are stored in UTC and converted to the store timezone only at render time, so integrations that read the UTC fields are safe — but nothing guarantees that every field, plugin, or code path respects the conversion. You must normalize explicitly at your integration boundary.
There is no setting, filter, or API parameter in WooCommerce or WordPress core that renders order dates in a visitor's local timezone. The value under Settings > General (the WordPress timezone string) is one value per site, applied globally by wc_format_date() and the underlying date_i18n() machinery. If you need customers to see "their" time — for delivery windows or event bookings, for example — the realistic options are:
Date handling in the browser.On WooCommerce 3.x+, order dates are stored in UTC. In the classic post-based storage this is the post_date_gmt column; in the newer HPOS tables it is the date_created_gmt / date_paid_gmt style columns. The non-GMT counterparts (post_date, date_created_local) are site-local values derived using the current store timezone. The REST API exposes both: date_created (site-local) and date_created_gmt (UTC).
So there is no blanket "guarantee" — there are two parallel representations, and which one a third party receives depends on which field you hand it. The safe rule: always integrate on the _gmt fields, and if you receive a non-GMT field from an external source, treat it as unnormalized until you confirm its offset.
When rendering dates outside standard templates, wc_format_date() is the documented boundary — it takes a stored timestamp and applies the site's configured timezone and date format. Two known cases silently bypass it:
date(), time(), and strtotime() in custom templates reflect the PHP/server default timezone, not the WordPress setting. WordPress deliberately sets PHP's default to UTC at runtime, so date() output is UTC regardless of the store setting — a classic source of "times are off by N hours" bugs.These claims assume WooCommerce 3.x or later. Pre-3.0 releases stored some dates as site-local values without _gmt counterparts, so verify the version before assuming UTC storage. Also note: changing the store timezone after orders exist does not alter stored UTC values, but every site-local field is recomputed at read time — an integration that consumed date_created before the change will see an apparent shift afterward.
post_date vs post_date_gmt, or the HPOS equivalents) — the difference should equal your configured offset.date_created_gmt matches the database UTC value.wc_format_date() and confirm it matches the store timezone.date( or strtotime( calls on order data.If your store is on a version older than 3.0, or if a critical integration only receives site-local fields, say which — that changes the recommendation from "use the _gmt fields" to "normalize before export."
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.