Make WordPress Core

Opened 3 years ago

Closed 2 years ago

Last modified 2 years ago

#54132 closed defect (bug) (worksforme)

get_calendar functions depends on gmdate instead of date

Reported by: voregnev's profile voregnev Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Date/Time Keywords:
Focuses: Cc:

Description

include/general-template.php
When we use get_calendar() - its generate wrong weeks breaks, because ancient function calendar_week_mod not depends on start day of week variable.

Change History (9)

#1 @sabernhardt
3 years ago

  • Keywords reporter-feedback added

Hi and welcome to Trac!

The $week_begins variable is used for all three calendar_week_mod calculations within the get_calendar function:

$pad = calendar_week_mod( gmdate( 'w', $unixmonth ) - $week_begins );
...
if ( 6 == calendar_week_mod( gmdate( 'w', mktime( 0, 0, 0, $thismonth, $day, $thisyear ) ) - $week_begins ) ) {
...
$pad = 7 - calendar_week_mod( gmdate( 'w', mktime( 0, 0, 0, $thismonth, $day, $thisyear ) ) - $week_begins );

So I think the problem could be somewhere else. I did not have trouble changing the week's start day with the Calendar widget.

  • Is a plugin active that might edit the calendar output with the get_calendar filter?
  • Do you have the get_calendar directly in a theme template file (or a plugin)?
  • Could you upload a screenshot or add other details?
Version 0, edited 3 years ago by sabernhardt (next)

#2 @voregnev
3 years ago

I found that the action of this function is related to the setting of the timezone on the hosting.
for example, run the following code


            echo "\nTZ:".date_default_timezone_get()."\n";
            $week_begins = 1;
            
            $thismonth =11;
            $thisyear = 2021;
            $unixmonth = mktime( 0, 0, 0, $thismonth, 1, $thisyear );
            $last_day  = gmdate( 't', $unixmonth );
            echo "GMUNIXMONTH".gmdate('d.m.Y',$unixmonth)."\n";
            echo "UNIXMONTH".date('d.m.Y',$unixmonth)."\n";
            echo "LASTDAY".$last_day."\n";
            
            $dwgm = gmdate( 'w', $unixmonth );
             echo "DW-GM".$dwgm;
             echo "\nPAD-gm".calendar_week_mod($dwgm - $week_begins)."\n";
            $dwd = date( 'w', $unixmonth );
             echo "DW-DATE".$dwd;
             echo "\nPAD-DATE".calendar_week_mod($dwd - $week_begins)."\n";

My output:

TZ:Europe/Moscow (GMT+3)
GMUNIXMONTH31.10.2021
UNIXMONTH01.11.2021
LASTDAY31
DW-GM0
PAD-gm6
DW-DATE1
PAD-DATE0

Seems we need use date instead gmdate for getting right pad

#3 @sabernhardt
3 years ago

  • Component changed from General to Date/Time
  • Keywords reporter-feedback removed

Thanks for the extra information.

#4 @voregnev
2 years ago

  • Summary changed from Function calendar_week_mod should depends on week_begins to get_calendar functions depends on gmdate instead of date

#5 @voregnev
2 years ago

/wp-includes/general-template.php
@2271

<?php
-   $last_day  = gmdate( 't', $unixmonth );
+   $last_day  = date( 't', $unixmonth );

#6 @SergeyBiryukov
2 years ago

Hi there, thanks for the ticket!

Using gmdate() is intentional as per [45424] / #46438 & #44491, see Date/Time component improvements in WordPress 5.3 for more details.

Using date() instead would actually produce a WPCS error:

----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------    
2271 | ERROR | date() is affected by runtime timezone changes which
     |       | can cause date/time to be incorrectly displayed. Use
     |       | gmdate() instead.
     |       | (WordPress.DateTime.RestrictedFunctions.date_date)
----------------------------------------------------------------------

There might still be a bug here where the timezone is not applied correctly, but I think the solution would look different.

#7 @SergeyBiryukov
2 years ago

  • Keywords reporter-feedback added

In my testing with the Europe/Moscow (GMT+3) timezone, get_calendar() output does respect the "Week Starts On" setting as expected. I think the steps to reproduce the issue on a clean install would be helpful here, ideally with some screenshots, as it's not quite clear to me what the issue is.

Last edited 2 years ago by SergeyBiryukov (previous) (diff)

#8 @voregnev
2 years ago

  • Resolution set to worksforme
  • Status changed from new to closed

Hi!
You was absolutly right! It is problem my hosting only. WP set default time zone to UTC (in wp-settings.php) and calculate all values correctly.

Thanks for help

#9 @SergeyBiryukov
2 years ago

  • Keywords reporter-feedback removed
  • Milestone Awaiting Review deleted

Thanks for the follow-up!

Note: See TracTickets for help on using tickets.