Proposal: add IntlDatePatternGenerator#6771
Conversation
| --SKIPIF-- | ||
| <?php | ||
| if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?> | ||
| <?php if (version_compare(INTL_ICU_VERSION, '50.1.2', '<')) die('skip for ICU < 50.1.2'); ?> |
There was a problem hiding this comment.
As an aside:
This line is included in almost all intl dateformat tests - there, it is used in this form:
<?php if (version_compare(INTL_ICU_VERSION, '50.1.2') >= 0) die('skip for ICU < 50.1.2'); ?>This, however, ends up skipping the test on my machine (INTL_ICU_VERSION === '67.1'). I assume version_compare is used incorrectly here? Should this be fixed for all other tests as well (and switched to what is the more readable form in my opinion)? Is this line still necessary (as PHP 7.4 requires ICU 50.1)?
There was a problem hiding this comment.
Skip messages are a bit deceptive: if fact, die('skip for ICU < 50.1.2'); means that the test is skipped because it's for ICU < 50.1.2. It also took quite some time for me to get accustomed to this.
If ICU 50.1 is required now then these tests are probably not in use anymore 🤔
There was a problem hiding this comment.
And I don't think the version_compare is necessary for this test.
There was a problem hiding this comment.
Ah yes, that explains the message.
I still dont understand why these tests are not required for newer ICU versions - I would expect basic tests like
to still be in use for newer versions/after PHP 7.4.
(For an incomplete list of affected tests, this is the commit that starts skipping a bunch of them for ICU >= 51.2 (was later changed to 50.1): 4840b0a)
There was a problem hiding this comment.
Tests for other ICU versions are under _variant2, _variant3 etc.
There was a problem hiding this comment.
If ICU 50.1 is required now then these tests are probably not in use anymore thinking
I believe the reason why these tests still exist is that our requirement is ICU 50.1, while this checks for ICU 50.1.2.
Though maybe we can bump up the requirements slightly, it looks like RHEL 7 nowadays ships with ICU 50.2 (according to https://rpms.remirepo.net/rpmphp/zoom.php?rpm=icu). @remicollet Would a 50.2 requirement be safe?
There was a problem hiding this comment.
The same RHEL version comes with PHP 5: https://rpms.remirepo.net/rpmphp/zoom.php?rpm=php so is RHEL even supposed to dictate what PHP 8 should do?
| --SKIPIF-- | ||
| <?php | ||
| if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?> | ||
| <?php if (version_compare(INTL_ICU_VERSION, '50.1.2', '<')) die('skip for ICU < 50.1.2'); ?> |
There was a problem hiding this comment.
And I don't think the version_compare is necessary for this test.
d3bb97c to
2eaed3c
Compare
|
@kocsismate Thank you for the review! |
| DTPATTERNGEN_METHOD_FETCH_OBJECT_NO_CHECK; | ||
|
|
||
| if (dtpgo->dtpg != NULL) { | ||
| intl_errors_set(DTPATTERNGEN_ERROR_P(dtpgo), U_ILLEGAL_ARGUMENT_ERROR, "datetimepatterngenerator_create: cannot call constructor twice", 0); |
There was a problem hiding this comment.
What's the reason of this? I see that the check is from IntlDateFormatter, but I don't know why these are necessary.
There was a problem hiding this comment.
For IntlDateFormatter, there is this test:
php-src/ext/intl/tests/bug62081.phpt
Lines 12 to 13 in 8d743d5
How is that (anti-)pattern handled in other cases?
|
|
||
| intl_stringFromChar(skeleton_uncleaned, skeleton_str, skeleton_len, DTPATTERNGEN_ERROR_CODE_P(dtpgo)); | ||
|
|
||
| INTL_METHOD_CHECK_STATUS(dtpgo, "datetimepatterngenerator_get_best_pattern: skeleton was not a valid UTF-8 string"); |
There was a problem hiding this comment.
| INTL_METHOD_CHECK_STATUS(dtpgo, "datetimepatterngenerator_get_best_pattern: skeleton was not a valid UTF-8 string"); | |
| INTL_METHOD_CHECK_STATUS(dtpgo, "Skeleton is not a valid UTF-8 string"); |
So the function name shouldn't be added (it's superfluous), the message should start with a capital character, and AFAIR we don't use past tense
There was a problem hiding this comment.
Also, I'm wondering if we can consider an invalid UTF-8 skeleton a programmatic error? As far as I see, we can, because the input should come from the programmer, not from the user. If my hypothesis is ok, then we could throw an exception instead of these warnings, like this:
zend_argument_value_error(2, "must be a valid UTF-8 string") (the 2 should be adapted in case of the method counterpart, since $skeleton is the 1st parameter there).
Last year, we migrated hundreds of warnings to exceptions, so it would be nice to follow this practice here as well, if possible.
There was a problem hiding this comment.
I have adjusted the messages.
I would agree that this is most likely a programming error - I used a warning here for consistency with similar cases (eg. IntlDateFormatter::setPattern()), but I can switch to using an exception if preferred.
cb8c1c5 to
5084f32
Compare
5084f32 to
068cceb
Compare
05f307a to
5b74562
Compare
|
Rebased and removed the legacy procedural API. |
|
Looks like this needs a rebase. While at it, it would be great to add a mention of the new class in the UPGRADING file. |
Co-authored-by: Nikita Popov <nikita.ppv@googlemail.com>
7e50a00 to
19ffd97
Compare
|
Rebased. |
|
Just checking - am I reading things correctly when I say that the two procedural functions mentioned in the RFC were not implemented in the final merged implementation ? |
|
@jrfnl, ugh, apparently not. I wonder whether that has been explicitly discussed, or was just forgotten. |
|
@jrfnl That was discussed and dropped during the vote, see: https://externals.io/message/114473#114658 and the messages following it. |
|
Thanks @cmb69 and @deltragon for your quick responses. Just wanted to verify as I'm working on adding detecting for the PHP 8.1 features/deprecations to PHPCompatibility. |
Note: in contrast to the original RFC proposal, [the procedural functions mentioned in the RFC were not included in the final implementation](php/php-src#6771 (comment)). Includes unit test. Refs: * https://www.php.net/manual/en/migration81.new-classes.php#migration81.new-classes.intl * https://wiki.php.net/rfc/intldatetimepatterngenerator * php/php-src#6771 * php/php-src@ae9f6e7
ICU exposes the DateTimePatternGenerator class that allows generating a formatting pattern from a given "skeleton" for a given locale.
This allows more flexibility than the current
$formatargument ofIntlDateFormatter::format(), which takes either a few pre-defined constants or a hard-coded format.This functionality also has been requested in the past.
For example, if an application requires a format that will always use the long version of a year, but the short version of a month (eg. "MM/dd/YYYY" for "en_US", or "dd.MM.YYYY" for "de_DE"), one is out of luck.
IntlDateFormatter::SHORTwill use the short year for "de_DE" ("dd.MM.YY"), andIntlDateFormatter::MEDIUMwill use the long version of a month for "en_US" ("MMM dd, YYYY").With
IntlDatePatternGenerator::getBestPattern(), a skeleton can be provided to generate the appropriate pattern for a given locale.In the use-case given above, the skeleton "YYYYMMdd" will generate the desired patterns for each locale, which can then be passed to
IntlDateFormatter::format().Note about the implementation:
This had been previously implemented as a static method on
IntlDateFormatter, creating a newDateTimePatternGeneratoron every call.It is now a separate class that has to be instantiated before use. This leaves us open to implementing other methods/options provided by the underlying
DateTimePatternGenerator. I am not sure if there is any use in those, however, asgetBestPattern()seems to be the only one with a real-world use-case to me.(Note: I am aware that this needs to go to internals/an RFC first. I'm currently having issues with my email provider that prevent me from subscribing to/sending to the list. I will send this proposal once these are resolved).