
WooCommerce 商品促销日期前端显示时,起始日比后台设置早一天,而结束日正确;根本原因是时区处理不当,需将 getTimestamp() 替换为 getOffsetTimestamp() 以确保时间戳包含本地时区偏移。
woocommerce 商品促销日期前端显示时,起始日比后台设置早一天,而结束日正确;根本原因是时区处理不当,需将 `gettimestamp()` 替换为 `getoffsettimestamp()` 以确保时间戳包含本地时区偏移。
在 WooCommerce 中,商品的促销起止时间(date_on_sale_from / date_on_sale_to)以 WC_DateTime 对象形式存储,该对象继承自 PHP 的 DateTimeImmutable,并内置了 WordPress 时区支持。关键区别在于:
- getTimestamp() 返回的是 UTC 时间戳(即忽略站点时区,强制转换为 UTC 的秒数),导致调用 date_i18n() 时,系统会再次按当前时区偏移渲染,造成重复时区计算,最终起始日期“提前一天”;
- getOffsetTimestamp() 则返回 已应用站点时区偏移的时间戳(即等效于 strtotime( $datetime->format('Y-m-d H:i:s') )),能与 date_i18n() 完美协同,确保日期准确对应后台所设。
以下是修正后的完整代码(已优化冗余逻辑、增强健壮性):
function customize_woocommerce_get_price_html( $price, $product ) {
// 仅在单个商品页且为简单商品或变体时执行
if ( ! is_product() || ! in_array( $product->get_type(), [ 'simple', 'variation' ], true ) ) {
return $price;
}
$start = $product->get_date_on_sale_from();
$end = $product->get_date_on_sale_to();
// 检查促销日期是否有效(非空且为 WC_DateTime 实例)
if ( ! $start || ! $end || ! $start instanceof WC_DateTime || ! $end instanceof WC_DateTime ) {
return $price;
}
// 使用 getOffsetTimestamp() 避免时区偏差
$start_formatted = date_i18n( 'j F Y', $start->getOffsetTimestamp() );
$end_formatted = date_i18n( 'j F Y', $end->getOffsetTimestamp() );
$sale_schedule = sprintf(
'<div class="sale-schedule">
<p>%s<span>%s</span></p>
<p>%s<span>%s</span></p>
</div>',
esc_html__( 'Start discount', 'woocommerce' ),
esc_html( $start_formatted ),
esc_html__( 'End discount', 'woocommerce' ),
esc_html( $end_formatted )
);
// 安全替换原价格 HTML 中的 </del> 标签(兼容不同价格结构)
return str_replace( '</del>', '</del>' . $sale_schedule, $price );
}
add_filter( 'woocommerce_get_price_html', 'customize_woocommerce_get_price_html', 100, 2 );✅ 注意事项:
- 务必使用 getOffsetTimestamp() 而非 getTimestamp(),这是解决“起始日提前一天”问题的核心;
- date_i18n() 本身依赖 WordPress 时区设置(timezone_string),因此确保 WordPress 设置 → 常规 → 时区 已正确配置;
- 推荐添加类型检查(instanceof WC_DateTime)和空值判断,避免 PHP 警告;
- 若主题或插件修改了价格 HTML 结构(如移除
标签),建议改用更鲁棒的 DOM 注入方式(如 woocommerce_after_shop_loop_item_title 钩子),而非字符串替换。
此方案兼顾准确性、可维护性与安全性,适用于所有标准 WooCommerce 环境(≥6.0),是处理促销日期时区问题的最佳实践。

















