Confirmed bug: date shifts +1 day in Meta getter / Dynamic Data “Date YYYYMMDD to WordPress date” formatter

0

Hi Greenshift team,

File: rest.php (Greenshift Query & Meta addon)
Function: gspb_data_post_processor($data, $postprocessor, $post_id, $replaceLabel, $icon)
Case: $postprocessor == ‘ymd’ (“Date YYYYMMDD to WordPress date” in the Meta getter / Dynamic Data UI)

Current code:

$date = DateTime::createFromFormat(‘Ymd’, $data);
$data = $date ? wp_date(get_option(‘date_format’), $date->format(‘U’)) : $data;

Bug:
DateTime::createFromFormat(‘Ymd’, $data) is given a format string with no time component. PHP fills any field not present in the format with the current date/time rather than midnight (documented PHP behaviour, not an edge case). That leaked current time-of-day is then baked into the Unix timestamp via ->format(‘U’). wp_date() adds the site’s UTC offset on top of that timestamp for display. Whenever the leaked current time is late enough in the day that adding the site offset pushes past midnight, the displayed date rolls over to the next calendar day.

Environment:

  • GreenShift – Animation and Page Builder Blocks: 13.1.4
  • Greenshift Query and Meta Addon: 5.9.7
  • WordPress: 7.0.2
  • PHP: 8.4.23
  • ACF PRO: 6.8.6
  • Theme: Blocksy 2.1.50 (parent theme), custom child theme on top
  • Site timezone: Europe/Amsterdam (UTC+1 winter / UTC+2 summer, DST)

Reproduction:
An ACF Date Picker field storing 20260813 renders correctly as “13 augustus 2026” when the block is rendered during the day, but renders as “14 augustus 2026” when rendered in the last ~2 hours before local midnight (less for UTC+1 sites). Confirmed independently with a standalone PHP repro:

date_default_timezone_set(‘UTC’);
$acf_value = ‘20260813’;
$now_utc = ‘2026-07-29 22:40:00’; // 00:40 local in Amsterdam, UTC+2
$dt = DateTime::createFromFormat(‘Ymd H:i:s’, $acf_value . ‘ ‘ . substr($now_utc, 11), new DateTimeZone(‘UTC’));
$local = (clone $dt)->setTimezone(new DateTimeZone(‘Europe/Amsterdam’));
echo $local->format(‘Y-m-d H:i:s’);
// Output: 2026-08-14 00:40:00 — one day ahead of the stored 20260813

Fix:
Add an explicit setTime(0,0,0) before formatting to a timestamp:

$date = DateTime::createFromFormat(‘Ymd’, $data);
if ($date) {
$date->setTime(0, 0, 0);
$data = wp_date(get_option(‘date_format’), $date->format(‘U’));
}

Note: gspb_data_post_processor() has no function_exists() guard, so we can’t safely override it from our own theme/mu-plugin without risking a fatal redeclare error on the next addon update – we do need a fix shipped in the addon itself.

Separate observation, possibly related: the same ‘ymd’ postprocessor is also invoked from the REST endpoint /wp-json/greenshift/v1/get-dynamic-part/ (function GSPB_make_dynamic_text / gspb_get_dynamic_part_callback), used to hydrate placeholders for dynamic fields on other block types (e.g. Icon List) client-side. On our site we occasionally see the raw, unconverted placeholder value (e.g. “20260912”) left in the markup, suggesting that REST call sometimes doesn’t complete. Not sure if that’s a separate issue or related to the above – flagging it in case it’s useful context.

Could you take a look at this en confirm?

Thanks in advance.

Lars De Ruijter

Replies

Post a Reply