What's happening with the strftime() and date() output modifiers?

Both of these modifiers call strftime() which is deprecated in PHP 8.1 and will be removed in PHP 9.

If they’re rewritten to use date(), they’ll break existing code, since the formatting tokens are different. They’ll also lose the ability to translate things like day and month names into languages other than English.

They could use the new DateTime object, but it also gives only English output (and the format strings would still be wrong).

The only alternative that I know of that will handle multiple languages is the IntlDateFormatter object, which is fairly complicated and requires the Intl extension to PHP. I think it would also break existing code unless the strftime() format characters are translated to the date() format.

My version of XAMPP doesn’t have the Intl extension and I’m not sure how common it is in typical PHP installations.

One solution would be to use the date() function or DateTime, and include MODX language tags in the format string, which would have to be escaped, letter-by-letter in the format string, or replaced with escaped tokens, extracted before calling date(), then put back later.

Another solution might be to create a :DateTime output modifier with an option to use the IntlDateFormatter methods for those who know the Intl extension is installed.

I’m hoping that there’s a simple solution that I haven’t thought of.

1 Like

Hi @bobray,

I do non believe there’s an issue for this right now. Can you create a GitHub issue for the deprecation of strftime(). Something that was mused internally (just now) would be to add the modern equivalent since this is only deprecation and it will enable folks to use the more modern approach.

Also, there are going to be so many massive changes in PHP 9 that this specific issue is going to be one of possibly hundreds.

We’re currently working through changes for PHP 8.1 compatibility for 3 and 2.

There is already a similar issue on GitHub.

1 Like

Sure. I know that work is being done on the core functionality around it, however, it would be good to have a separate issue related to the Output Modifiers as it would be worked on separately. Though, the solutions may be related/shared.

The issue with the output modifiers is it needs to have a solution for locale-aware output. Most of the other uses in the core did not need this and will be converted to locale-independent formatting via date() or DateTime*::format(). xPDO did provide a way to format with stftime via xPDOObject::get(), but I have chosen to just deprecate that and will not be adding a locale-aware solution to replace it in the xPDOObject::get() method.

1 Like

nesbot/carbon does support locales.

Eek. That looks like a bit of overkill to solve one simple problem.

One thing I was thinking about is a function to translate the strftime() format string so it would work with DateTime::format() or date(). I think I’m close to doing that (I could be wrong). It could be part of a class that extends DateTime, or not.

For locale awareness, one solution would be to add the short and long day and month names to the MODX lexicon, and translate them during the transformation of the format string.

Another way would be to use a class with a boolean property that allowed launching IntlDateFormatter::format(), instead of ::format().

I think this could be integrated with the filters without breaking things, but it would slow down execution somewhat.

I’d rather not see this in the core. It could be great as an extra component like a custom filter.

I don’t think that would be a good idea. I’m aiming to reduce the core and the things we need to maintain as developers and as translators.

My preference would be to add new filters that support the IntlDateFormatter format and just deprecate the existing filters that rely on strftime. They could be used up until someone moves to PHP 9 and give plenty of time for changing the usages in a site.

1 Like

To be frank, I’m extremely disappointed this RFC was even accepted into PHP 8.1.

Having the same fomat placeholders in JS and PHP is quite nice and Carbon is not that bad as a DateTime extender. A smaller just formatting class would be better, but why invent the wheel twice?

It would make a fine extra with custom output filters. I don’t see any valid reason for that to be in core, however.

Same here. I was astounded to find that the DateTime class was limited to English output, especially considering all the other bells and whistles it has.

I found this encouraging note at Dreamhost:

The intl extension is enabled by default on PHP versions above 7.2

I imagine by PHP 9, it will be universally installed and enabled.

How about a :dateFormat filter that uses date() and an :intlDateFormat filter that uses the DateTime class?

And how about putting the strtotime() conversion inside the filter if the input is identified as a timestamp, so the user doesn’t have to chain two output modifiers?

Also, how about an extra containing a snippet called something like MyDate that could make the existing :date and :strftime filters work without strftime() so users could just change the filter name in the tags (assuming that such a snippet is possible)?

1 Like

not sure, if that would help

2 Likes

@bruno17 That’s very cool. Thanks for pointing it out. But do you the status of that function? Is it part of PHP 8.1, a proposed addition to 8.1, or just a helpful function people can use?

AFAIU this is just a function people can use as a strftime replacement in PHP 8.1

It worked for me, thanks.

  • On MODX 2.8.6 and PHP 8.1 (which goes with recent Ubuntu release) I have managed to get an error in Manager area for Clear Cache functionality and it’s about Deprecation of strftime. So, my temp (but fast) solution that worked was creating a plugin with even on OnMODXInit:
<?php
switch ($modx->event->name) {
    case 'OnMODXInit':
        $file = MODX_ASSETS_PATH . 'components/app/vendor/autoload.php';

        if (file_exists($file)) {
            require_once $file;
            
        }
        break;
}

As you can see I got the function installed into my ASSETS folder + components/app/ via shell command: composer require php81_bc/strftime (yeah the above gist is now a repo GitHub - alphp/strftime: This provides a cross-platform alternative to strftime() for when it will be removed from PHP)