WordPress.org

Make WordPress Core

Opened 2 months ago

Closed 8 weeks ago

Last modified 8 weeks ago

#53294 closed enhancement (wontfix)

Adding filter hook to current_time() function

Reported by: wpvar Owned by:
Milestone: Priority: normal
Severity: normal Version: 5.8
Component: Date/Time Keywords: has-patch
Focuses: accessibility Cc:

Description

current_time function uses default PHP class DateTime to generate dates or stamp, For local developers there is no option to modify dates that current_time returns, Therefore returned strings or stamps will always be according to gregorian calendar.

<?php
function current_time( $type, $gmt = 0 ) {
    // Don't use non-GMT timestamp, unless you know the difference and really need to.
    if ( 'timestamp' === $type || 'U' === $type ) {
        return $gmt ? time() : time() + (int) ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
    }
 
    if ( 'mysql' === $type ) {
        $type = 'Y-m-d H:i:s';
    }
 
    $timezone = $gmt ? new DateTimeZone( 'UTC' ) : wp_timezone();
    $datetime = new DateTime( 'now', $timezone );
 
    return $datetime->format( $type );
}

By adding new filter hook, it will help local developers to convert gregorian dates to other calendar types as well:

<?php
function current_time( $type, $gmt = 0 ) {
        // Don't use non-GMT timestamp, unless you know the difference and really need to.
        if ( 'timestamp' === $type || 'U' === $type ) {
                return $gmt ? time() : time() + (int) ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS );
        }

        if ( 'mysql' === $type ) {
                $type = 'Y-m-d H:i:s';
        }

        $timezone = $gmt ? new DateTimeZone( 'UTC' ) : wp_timezone();
        $datetime = new DateTime( 'now', $timezone );
        $datetime = $datetime->format( $type );

        /**
         * Filters current datetime based on the type.
         *
         * @since 5.8.0
         *
         * @param int|string   $datetime Integer if $type is 'timestamp', string otherwise.
         * @param int          $type     Type of time to retrieve.
         * @param int|bool     $gmt      Whether to use GMT timezone.
         * @param DateTimeZone $timezone Timezone.
         */
        $datetime = apply_filters( 'current_time', $datetime, $type, $gmt, $timezone );

        return $datetime;
}

Since many plugin and theme developers use current_time directly to generate current dates, It will enhance alternative calendars usability in WordPress for local and non-gregorian territories users. I think best approach here could be for local developers to ignore mysql and timestamp fields and only convert other formats based on different scenarios and values that hook will return.

Attachments (1)

functions.diff (883 bytes) - added by wpvar 2 months ago.
Patch

Download all attachments as: .zip

Change History (12)

@wpvar
2 months ago

Patch

#1 follow-up: @Rarst
2 months ago

current_time() is only retained for backwards compatibility, by now it's just a thin wrapper around native PHP with unfortunate logic branch producing the problematic "WordPress timestamp" (summed with a time zone offset) case.

In current WordPress code this function shouldn't even be used, so introducing new functionality to it is not on the table.

Adjustments to date output in WordPress are usually handled on localization level, such as wp_date() function/filter.

However I am not sure what you want counts as localization or more fundamental adjustment to whole date calculation?

Open to see some example to understand the needs better, please. :)

#2 in reply to: ↑ 1 @wpvar
2 months ago

Problem is many theme and plugin developers are still using current_time(), Just few examples:
https://github.com/elementor/elementor/search?q=current_time%28
https://github.com/rankmath/seo-by-rank-math/search?q=current_time%28
https://github.com/wp-media/wp-rocket/search?q=current_time%28

Without hooks we cannot convert gregorian date or stamp generated by datetime class to other forms of dates e.g. Solar calendar. Currently we are developing shamsi calendar plugin called WP Shamsi which has more than 10,000 installs. There are many more date system plugins with hundreds of thousands installations as well, now for example there is a plugin that prints or stores date like this example:

<?php
$date = wp_date('Y-m-d H:i:s');
echo $date;

by using wp_date We can convert gregorian date to other date systems like:

<?php
public function shamsi_date($date, $format, $timestamp, $timezone)
{
    return $this->convert($date, $format);
}
add_filter('wp_date', array($this, 'shamsi_date'), 10, 4);

but for current_time():

<?php
$date = current_time( 'mysql' );
echo $date;

There isnt such a functionality and there is no way to alter returned values.

To summarize what the topic is about, i think its fair to say there are many plugins, themes and core as well that are using current_time() function and it will return always uneditable values without existing of hook. This applies to many WordPress users. applying filter can help lots of local users.

Replying to Rarst:

current_time() is only retained for backwards compatibility, by now it's just a thin wrapper around native PHP with unfortunate logic branch producing the problematic "WordPress timestamp" (summed with a time zone offset) case.

In current WordPress code this function shouldn't even be used, so introducing new functionality to it is not on the table.

Adjustments to date output in WordPress are usually handled on localization level, such as wp_date() function/filter.

However I am not sure what you want counts as localization or more fundamental adjustment to whole date calculation?

Open to see some example to understand the needs better, please. :)

#3 follow-up: @Rarst
2 months ago

Your plugin doesn't have a readme in English, so I can't read that unfortunately.

So far this still looks to me like it belongs to the localization layer. If the third party plugins output time directly to user bypassing the localization, that's probably on them to improve.

To be honest I have trouble even thinking through how many things might break if you start changing up current_time(). And you are still not giving me actual example of what you want to achieve there.

#4 in reply to: ↑ 3 @wpvar
8 weeks ago

Thanks for checking issue out @Rarst
Basically what we want to achieve is converting front-end dates. for example:

GregorianSolarLunar...
2021/05/311400/03/101442/10/19...

List of calendars

So far this still looks to me like it belongs to the localization layer. If the third party plugins output time directly to user bypassing the localization, that's probably on them to improve.

I totally agree with you on this, Best solution would be for developers to do not use current_time on front-end (But they are widely using anyway).
Maybe checking right usage of current_time on hosted plugins/themes during validation process would help or adding extra description on current_times reference page as a reminder to avoid usage of current_time on front-end generated dates and instead using wp_date.

Replying to Rarst:

Your plugin doesn't have a readme in English, so I can't read that unfortunately.

So far this still looks to me like it belongs to the localization layer. If the third party plugins output time directly to user bypassing the localization, that's probably on them to improve.

To be honest I have trouble even thinking through how many things might break if you start changing up current_time(). And you are still not giving me actual example of what you want to achieve there.

#5 follow-up: @Rarst
8 weeks ago

I think we need a carefully considered deprecation pass for much of old Date/Time bits, just been busy with other things. :) Will get to it eventually.

My concern is that dragging localization into computation layer is unpredictable and harmful. There is no flexibility to concept of "current time as reported by PHP" (other than legacy WP timestamp silliness, sigh) and I don't think it should be introduced or enabled.

I do think that users should be able to localize time display to whatever system they would like!

But underlying computation is inherently constrained by PHP language and that's not something to mess with for presentation purposes. The damage that WP caused when it corrupted PHP mechanics by introducing offset timestamps took many years to mitigate and remainders will be around forever.

Last edited 8 weeks ago by Rarst (previous) (diff)

#6 in reply to: ↑ 5 @wpvar
8 weeks ago

Yes saving time stamps other than PHPs native stamp (gregorian) into database is absolute disaster and it will cause unresolvable problems and conflicts, Therefore wp_date is ideal function, its functionality is to retrieve not store dates and also we can get stamp by $timestamp variable in hook and validate it to be gregorian otherwise ignore any date changes. there is almost 600 years gap between solar and gregorian dates and its not complicate to validate incoming timestamp.
Based on your explanation I agree its not a good idea to modify current_time and problems may it cause, Limiting its front-end usage by improving documentation or consider future deprecation may be much better approaches.

Thank you for your explanation ;)

Replying to Rarst:

I think we need a carefully considered deprecation pass for much of old Date/Time bits, just been busy with other things. :) Will get to it eventually.

My concern is that dragging localization into computation layer is unpredictable and harmful. There is no flexibility to concept of "current time as reported by PHP" (other than legacy WP timestamp silliness, sigh) and I don't think it should be introduced or enabled.

I do think that users should be able to localize time display to whatever system they would like!

But underlying computation is inherently constrained by PHP language and that's not something to mess with for presentation purposes. The damage that WP caused when it corrupted PHP mechanics by introducing offset timestamps took many years to mitigate and remainders will be around forever.

#7 @Rarst
8 weeks ago

  • Milestone Awaiting Review deleted
  • Resolution set to wontfix
  • Status changed from new to closed

#8 follow-up: @apedog
8 weeks ago

I'm just re-opening this for further discussion.

There's a thematically related ticket #28636 that at one point had a suggestion for a wp_strtotime API (which would be a wrapper for new DateTime( $input, wp_timezone() )).

I think perhaps WordPress core should provide wrapper-function/abstraction-layer/wordpress-way for working with PHP DateTime and timestamps.

Much in the same way wp_remote_get/request abstracts cURL etc and lets devs make requests without using the underpinning mechanisms and parsing.

The API should be simple and reliable.
But a wp_give_me_timestamp_based_on_these_prameters( ...args ) or wp_give_me_datetime_based_on_these_prameters( ...args ) or
wp_give_me_now_based_on_these_parameters() could be useful.

#9 @apedog
8 weeks ago

  • Resolution wontfix deleted
  • Status changed from closed to reopened

#10 in reply to: ↑ 8 @Rarst
8 weeks ago

  • Resolution set to wontfix
  • Status changed from reopened to closed

Replying to apedog:

I'm just re-opening this for further discussion.

I think perhaps WordPress core should provide wrapper-function/abstraction-layer/wordpress-way for working with PHP DateTime and timestamps.

That has nothing to do with adding filter to current_time().

Feel free to open a new ticket about your needs and ideas for API additions, happy to discuss.

This ticket was mentioned in Slack in #core-datetime by apedog. View the logs.


8 weeks ago

Note: See TracTickets for help on using tickets.