Opened 4 weeks ago
Closed 3 weeks ago
#64496 closed defect (bug) (fixed)
Type Error with gmdate() in dashboard Activity widget
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 7.0 | Priority: | normal |
| Severity: | normal | Version: | 6.9 |
| Component: | Administration | Keywords: | has-patch |
| Focuses: | ui | Cc: |
Description (last modified by )
Uncaught Error: gmdate(): Argument #2 ($timestamp) must be of type ?int, string given in wp-admin/includes/dashboard.php on line 1017 Call stack: gmdate() wp-admin/includes/dashboard.php:1017 wp_dashboard_recent_posts() wp-admin/includes/dashboard.php:940 wp_dashboard_site_activity() wp-admin/includes/template.php:1453 do_meta_boxes() wp-admin/includes/dashboard.php:271 wp_dashboard() wp-admin/index.php:204 Query Monitor
Attachments (3)
Change History (12)
This ticket was mentioned in PR #10723 on WordPress/wordpress-develop by 3deiva.
4 weeks ago
#2
- Keywords has-patch added
This pull request fixes a PHP 8.3 fatal error in the WordPress dashboard Recent Posts widget.
In wp_dashboard_recent_posts(), get_the_time( 'U' ) returns a string, but gmdate() requires an integer or null in PHP 8.3. This causes a TypeError and breaks the admin dashboard when running WordPress on PHP 8.3.
The fix casts the timestamp to an integer before passing it to gmdate(), restoring compatibility while keeping the existing behavior unchanged.
#3
@
4 weeks ago
- Keywords reporter-feedback added
I'm not able to reproduce this issue. For me on PHP 8.3, get_the_time( 'U' ) does return an int. Do you have a get_the_time filter that is returning something else?
See on PHP Playground:
<?php global $post; $post = get_posts()[0]; $time = get_the_time( 'U' ); echo "get_the_time( 'U' ) === "; var_dump( $time );
Results in:
get_the_time( 'U' ) === int(1764702503)
#4
@
4 weeks ago
- Description modified (diff)
- Focuses php-compatibility removed
- Keywords php8.3 removed
- Summary changed from Uncaught Error: gmdate(): Argument #2 ($timestamp) must be of type ?int, string given in wp-admin/includes/dashboard.php on line 1017 to Type Error with gmdate() in dashboard Activity widget
#60629 reported the error message earlier.
A directory search lists some of the plugins that might filter the 'get_the_time' information.
I removed the PHP 8.3 keyword and PHP compatibility focus.
- I did not receive errors or warnings when the filtered date was a numeric string or boolean
false. - A non-numeric string resulted in a fatal error with PHP 8.0.30, and 7.4.33 gave a warning for the same.
Testing
I added var_dump($time); immediately after $time = get_the_time( 'U' ); in wp_dashboard_recent_posts() to show the output type in my local trunk installation. Also, my time zone is UTC-6, which likely explains why the numeric string value is 6 hours different than the integer.
With no plugins, the Activity widget used integers and displayed the relative post dates.
int 1768214078Today, 10:34 amint 1762863730Nov 11th 2025, 12:22 pm
Simple Location changed get_the_date output to a numeric string, but it still gave the same post dates.
string '1768235678'Today, 10:34 amstring '1762885330'Nov 11th 2025, 12:22 pm
Hide/Remove Metadata, set to Hide By PHP and Hide published date, returned false in the filter. Then the Activity widget showed today's date without the time, still including the comma and space.
boolean falseJan 12th 2026,boolean falseJan 12th 2026,
WP Last Modified Info also can return false with its 'get_the_time' filter, but that specifically does not run in the admin area.
I reproduced the fatal error by returning a string in a custom must-use plugin.
add_filter( 'get_the_time', function ( $the_time ) { return 'gotcha'; } );
string 'gotcha'( ! ) Fatal error: Uncaught TypeError: gmdate(): Argument #2 ($timestamp) must be of type ?int, string given in ...\wp-admin\includes\dashboard.php on line 1017 ( ! ) TypeError: gmdate(): Argument #2 ($timestamp) must be of type ?int, string given in ...\wp-admin\includes\dashboard.php on line 1017
Correcting
Plugin filters could need to avoid changing the 'get_the_time' output when is_admin or when the $format is 'U'.
If Core should update the Activity widget, I think it could change the list item <span> contents if the timestamp is not an integer. Casting to an integer might work with the Simple Location plugin, but other non-integer values are likely inappropriate (for comparison or display).
#5
@
4 weeks ago
- Keywords needs-patch added; has-patch reporter-feedback removed
- Milestone changed from Awaiting Review to 7.0
@sabernhardt Yeah, if get_the_time( 'U' ) doesn't return a value which is_numeric(), what about just passing it straight through to be displayed?
Otherwise, I think it would make sense to just omit the SPAN entirely, treating it as if get_the_time( 'U' ) returned empty (as it can also return false).
#6
@
4 weeks ago
This probably would be better as a pull request, but the .diff was easier for me.
64496.diff treats any non-integer as unreliable and ignores it in the Activity widget. It uses is_int() instead of is_numeric() because I noticed a problem with Simple Location's numeric string. When I changed a post's published date to 11:34pm yesterday, the widget said the post was published Today because it was within the GMT offset.
I chose to keep the <span> element and leave it empty when it does not have the timestamp. This does not look good, but removing it might not look any better. The first element in each list item has a width of 160 to 200 pixels and column gap of 10 pixels.
- If the
<span>is empty, that results in 170 to 210 pixels of blank space. - If the
<span>is removed, the post title link width can be restricted unnecessarily, but it would be aligned with the "Recently Published" heading. - If
get_the_time( 'U' )returns a non-integer with one list item, but not all of them, removing the<span>would put that post link in the same column as dates for the other list items. I changed the output for only post 1361 by adding the following filter in my must-use plugin:add_filter( 'get_the_time', function ( $the_time, $format, $post ) { if ( isset( $post->ID ) && 1361 === $post->ID ) { $the_time = 'gotcha'; } return $the_time; }, 10, 3 );
The empty space can also hint that something is amiss without displaying an error or _doing_it_wrong message.
This ticket was mentioned in PR #10729 on WordPress/wordpress-develop by @westonruter.
4 weeks ago
#7
- Keywords has-patch added; needs-patch removed
#8
@
4 weeks ago
- Owner set to westonruter
- Status changed from new to reviewing
@sabernhardt I added your patch to a PR, but I also iterated on it a bit with a proposal. What if we just use the full date format when $relative doesn't return an int?
-
src/wp-admin/includes/dashboard.php
a b function wp_dashboard_recent_posts( $args ) { 1014 1014 1015 1015 $time = get_the_time( 'U' ); 1016 1016 1017 if ( gmdate( 'Y-m-d', $time ) === $today ) { 1017 if ( ! is_int( $time ) ) { 1018 /* translators: Date and time format for recent posts on the dashboard, from a different calendar year, see https://www.php.net/manual/datetime.format.php */ 1019 $relative = date_i18n( __( 'M jS Y' ), $time ); 1020 } elseif ( gmdate( 'Y-m-d', $time ) === $today ) { 1018 1021 $relative = __( 'Today' ); 1019 1022 } elseif ( gmdate( 'Y-m-d', $time ) === $tomorrow ) { 1020 1023 $relative = __( 'Tomorrow' );
Screen shoot Admin pannel