[wp-trac] [WordPress Trac] #63772: get_calendar() shows incorrect month-end due to current_time() timezone issue

WordPress Trac noreply at wordpress.org
Sat Aug 2 11:32:00 UTC 2025


#63772: get_calendar() shows incorrect month-end due to current_time() timezone
issue
-----------------------------------+------------------------------
 Reporter:  smilkobutawp           |       Owner:  (none)
     Type:  defect (bug)           |      Status:  new
 Priority:  normal                 |   Milestone:  Awaiting Review
Component:  Date/Time              |     Version:  6.8.2
 Severity:  normal                 |  Resolution:
 Keywords:  has-patch 2nd-opinion  |     Focuses:
-----------------------------------+------------------------------
Changes (by autotutorial):

 * keywords:  has-patch => has-patch 2nd-opinion


Comment:

 Replying to [ticket:63772 smilkobutawp]:
 > The get_calendar() function in WordPress incorrectly calculates the
 number of days in the current month when the site timezone is set to UTC+9
 (e.g., Asia/Tokyo) and the current time is near the end of the month
 (e.g., July 31st around 22:00–23:59 JST).
 > 🔁 Steps to Reproduce:
 >
 > 1. Set your WordPress site timezone to Asia/Tokyo (UTC+9).
 >
 > 2. Visit a page that displays the default calendar widget.
 >
 > 3. On July 31, 2025, at 22:37 JST, observe that the calendar for July
 only shows up to the 30th, even though July has 31 days.
 >
 > 4. Inspect wp-includes/general-template.php, where get_calendar() uses
 the following:
 >
 > $thisyear  = (int) current_time( 'Y' );
 > $thismonth = (int) current_time( 'm' );
 > $unixmonth = mktime( 0, 0, 0, $thismonth, 1, $thisyear );
 > $last_day  = gmdate( 't', $unixmonth );
 >
 > This calculation yields an incorrect $thismonth = 8 (August), causing
 $last_day = 30 instead of 31 for July.
 > 🧠 Technical Cause:
 >
 > current_time('Y') and current_time('m') are localized string values, but
 they are influenced by UTC time logic internally, especially near the date
 change boundary. As a result, the calendar may "roll over" to the next
 month prematurely.
 > ✅ Suggested Fix:
 >
 > Use current_time('timestamp') or better yet, rely on the correct
 timezone-aware approach using wp_timezone():
 >
 > $dt = new DateTimeImmutable( 'now', wp_timezone() );
 > $thisyear = (int) $dt->format( 'Y' );
 > $thismonth = (int) $dt->format( 'm' );
 > $unixmonth = $dt->setDate( $thisyear, $thismonth, 1 )->getTimestamp();
 > $last_day = gmdate( 't', $unixmonth );
 >
 > ✅ Confirmed Result:
 >
 > On 2025-07-31 22:37 JST, this code correctly yields:
 >
 > $thisyear = 2025
 > $thismonth = 7
 > $last_day = 31
 >
 > This provides accurate calendar generation behavior, aligned with local
 timezone settings.
 >
 > Please consider updating get_calendar() to use timezone-aware logic in
 future versions to prevent subtle bugs in calendar rendering for
 international users.

 WordPress sets UTC timezone as default and the mktime function also used
 UTC. https://github.com/WordPress/WordPress/blob/master/wp-
 settings.php#L72 If the theme or plugin or anything else is different from
 UTC it is not a CORE WordPress bug.
 {{{#!php
 <?php

 $original = date_default_timezone_set( 'Europe/Berlin');
 $WordPress = date_default_timezone_set('UTC');
 $tz = timezone_open( 'Asia/Tokyo' );
 $date = date_create( '2025-07-30 22:30:00', $tz );
 $thisyear = (int) date_format( $date,  'Y' );
 $thismonth = (int) date_format( $date, 'm' );
 $unixmonth = mktime( 0, 0, 0, $thismonth, 1, $thisyear ); // if set
 Europe/Berlin 1751320800 (+02:00)
 $last_day = gmdate( 't', $unixmonth );
 var_dump($unixmonth, $thismonth, $last_day, $WordPress);
 ?>
 }}}

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/63772#comment:8>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list