GraphQL Order Timestamps vs Store-Scoped Timezone Config: Where Should Conversion Happen?
0 reputation · 15 Jun 2020, 06:30 UTC
0 reputation · 15 Jun 2020, 06:30 UTC
We are exposing order data from Magento 2.x through the native GraphQL API to a headless storefront. Date fields such as created_at come back as UTC ISO 8601 strings, while the store view is configured with a regional timezone under Stores > Configuration > General > Locale Options. The storefront must display order times in the shopper's local store timezone, and we need to decide where that conversion belongs.
All timestamps are stored in UTC in the database, and PHP's date.timezone must remain UTC for Magento's internal conversion logic to work correctly. The schema appears to offer no built-in directive or argument to return dates pre-converted to the store timezone, so a custom resolver or client-side conversion seems necessary. We also have third-party modules that read the store timezone via ScopeConfigInterface, and we are concerned about double-conversion if a custom GraphQL resolver applies TimezoneInterface formatting while a module has already adjusted the value. Assume a current Magento 2.4.x release; behavior should be verified against the installed version.
\Magento\Framework\Stdlib\DateTime\TimezoneInterface the supported extension point, or is client-side conversion the intended pattern?35275 reputation · 15 Jun 2020, 16:52 UTC
For Magento 2.4.x the correct place to shift an order’s created_at from UTC to the store view’s timezone is inside a custom GraphQL resolver that uses \\Magento\\Framework\\Stdlib\\DateTime\\TimezoneInterface. The PHP date.timezone setting must stay UTC, and the resolver should read the store‑scoped timezone via ScopeConfigInterface or StoreManagerInterface. Client‑side conversion is discouraged because the schema offers no built‑in argument for it.
The native GraphQL schema exposes datetime fields as raw UTC ISO‑8601 strings. There is no directive that automatically applies the store view’s offset. Magento’s extension point for GraphQL is ResolverInterface, which is the documented way to transform data before it is sent to the client. Using TimezoneInterface inside a resolver gives you precise control while keeping core logic untouched.
Some third‑party modules may already format dates for display. To prevent applying the offset twice, run the resolver only on the raw UTC value. A simple check is to examine whether the incoming string ends with +00:00 or Z; if it does, skip conversion. If you cannot rely on the format, coordinate with any module that touches the field to disable its own conversion or expose a flag you can read.
When the request contains the X‑Magento‑Store header (or the store cookie is set), Magento resolves the store view and therefore the timezone configured under Stores > Configuration > General > Locale Options. The resolver can obtain the current store ID via \\Magento\\Store\\Model\\StoreManagerInterface or from the GraphQL ContextInterface. The same timezone will be applied to every field resolved for that request, ensuring consistency across the payload.
\\Magento\\Framework\\GraphQl\\ResolverInterface.\\Magento\\Framework\\Stdlib\\DateTime\\TimezoneInterface and \\Magento\\Store\\Model\\StoreManagerInterface.resolve(), fetch the raw UTC value from the order entity.timezone->date($utcValue, $storeTimezone) to shift it to the store’s offset.etc/graphql/di.xml to override or extend the existing field.Because the output depends on the store, the resolver must be marked as cache‑able by store ID. If you use Varnish or full‑page caching, add the store ID to the cache key or disable caching for this field.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.