Skip to content

Commit 076c0ce

Browse files
LamentXU123NickSdotdevnexen
committed
ext/intl: Implement IntlRelativeDateTimeFormatter
Add locale-aware formatting of relative offsets, enum-based style, capitalization and unit options, and custom NumberFormatter support. Observe subsequent NumberFormatter configuration changes and cover formatting, error handling, and object lifetime in tests. RFC: https://wiki.php.net/rfc/reldateformatter Co-authored-by: NickSdot <32384907+NickSdot@users.noreply.github.com> Co-authored-by: David Carlier <devnexen@gmail.com>
1 parent b9ea38e commit 076c0ce

35 files changed

Lines changed: 2574 additions & 2 deletions

‎NEWS‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ PHP NEWS
2323
throwing a ValueError. (Marc Bennewitz)
2424

2525
- Intl:
26+
. Added IntlRelativeDateTimeFormatter for locale-aware relative date and time
27+
formatting, with enums for styles, capitalization contexts, and units.
28+
(Weilin Du)
2629
. Added Transliterator::toRules() and transliterator_to_rules().
2730
(Weilin Du, David Carlier)
2831
. Fixed Collator attribute and strength methods not rejecting an

‎UPGRADING‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ PHP 8.7 UPGRADE NOTES
5050
array of CURLFile or CURLStringFile objects to CURLOPT_POSTFIELDS.
5151

5252
- Intl:
53+
. Added IntlRelativeDateTimeFormatter to format relative date and time offsets
54+
using locale-specific text, such as "yesterday" or "in 3 days". Its format()
55+
method uses a textual form when available and a numeric form otherwise,
56+
while formatNumeric() always uses a numeric form. combineDateAndTime()
57+
combines already formatted date and time strings according to the locale.
58+
The constructor accepts an optional NumberFormatter to customize numeric
59+
output; subsequent configuration changes to that object are reflected in
60+
formatting results. Styles, capitalization contexts, and units are selected
61+
using the IntlRelativeDateTimeFormatterStyle,
62+
IntlRelativeDateTimeFormatterCapitalization, and
63+
IntlRelativeDateTimeFormatterUnit enums, respectively.
64+
RFC: https://wiki.php.net/rfc/reldateformatter
5365
. Locale::acceptFromHttp() and locale_accept_from_http() now accept an
5466
optional $availableLocales array argument. When given, the
5567
Accept-Language header is matched against these locales instead of all
@@ -95,6 +107,11 @@ PHP 8.7 UPGRADE NOTES
95107
========================================
96108

97109
- Intl:
110+
. IntlRelativeDateTimeFormatter
111+
. enum IntlRelativeDateTimeFormatterStyle
112+
. enum IntlRelativeDateTimeFormatterCapitalization
113+
. enum IntlRelativeDateTimeFormatterUnit
114+
RFC: https://wiki.php.net/rfc/reldateformatter
98115
. Added IntlNumberFormatter class to format a number with a given locale
99116
and ICU number skeleton, which also covers measurement units, e.g.
100117
"measure-unit/speed-kilometer-per-hour unit-width-full-name".

‎ext/intl/CREDITS‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
Internationalization
2-
Ed Batutis, David Carlier, Vladimir Iordanov, Dmitry Lakhtyuk, Stanislav Malyshev, Vadim Savchuk, Kirti Velankar
2+
Ed Batutis, David Carlier, Weilin Du, Vladimir Iordanov, Dmitry Lakhtyuk, Stanislav Malyshev, Vadim Savchuk, Kirti Velankar

‎ext/intl/config.m4‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ if test "$PHP_INTL" != "no"; then
7575
breakiterator/codepointiterator_internal.cpp \
7676
breakiterator/codepointiterator_methods.cpp \
7777
listformatter/listformatter_class.cpp \
78+
reldateformatter/reldateformatter_class.cpp \
7879
transliterator/transliterator_class.cpp \
7980
transliterator/transliterator_methods.cpp \
8081
idn/idn.cpp \
@@ -125,6 +126,7 @@ if test "$PHP_INTL" != "no"; then
125126
$ext_builddir/idn
126127
$ext_builddir/locale
127128
$ext_builddir/listformatter
129+
$ext_builddir/reldateformatter
128130
$ext_builddir/msgformat
129131
$ext_builddir/normalizer
130132
$ext_builddir/numberformatter

‎ext/intl/config.w32‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ if (PHP_INTL != "no") {
4242
ADD_SOURCES(configure_module_dirname + "/listformatter", "\
4343
listformatter_class.cpp \
4444
", "intl");
45+
ADD_SOURCES(configure_module_dirname + "/reldateformatter", "\
46+
reldateformatter_class.cpp \
47+
", "intl");
4548
ADD_SOURCES(configure_module_dirname + "/locale", "\
4649
locale.cpp \
4750
locale_class.cpp \

‎ext/intl/formatter/formatter_attr.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ U_CFUNC PHP_FUNCTION( numfmt_set_attribute )
181181

182182
INTL_METHOD_CHECK_STATUS( nfo, "Error setting attribute value" );
183183

184+
nfo->configuration_version++;
184185
RETURN_TRUE;
185186
}
186187
/* }}} */
@@ -212,6 +213,7 @@ U_CFUNC PHP_FUNCTION( numfmt_set_text_attribute )
212213
unum_setTextAttribute(FORMATTER_UNUM(nfo), static_cast<UNumberFormatTextAttribute>(attribute), svalue.getBuffer(), svalue.length(), &INTL_DATA_ERROR_CODE(nfo));
213214
INTL_METHOD_CHECK_STATUS( nfo, "Error setting text attribute" );
214215

216+
nfo->configuration_version++;
215217
RETURN_TRUE;
216218
}
217219
/* }}} */
@@ -293,6 +295,7 @@ U_CFUNC PHP_FUNCTION( numfmt_set_symbol )
293295
unum_setSymbol(FORMATTER_UNUM(nfo), symbol, svalue.getBuffer(), svalue.length(), &INTL_DATA_ERROR_CODE(nfo));
294296
INTL_METHOD_CHECK_STATUS( nfo, "Error setting symbol value" );
295297

298+
nfo->configuration_version++;
296299
RETURN_TRUE;
297300
}
298301
/* }}} */
@@ -363,6 +366,7 @@ U_CFUNC PHP_FUNCTION( numfmt_set_pattern )
363366
RETURN_FALSE;
364367
}
365368

369+
nfo->configuration_version++;
366370
RETURN_TRUE;
367371
}
368372
/* }}} */

‎ext/intl/formatter/formatter_class.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ U_CFUNC zend_object *NumberFormatter_object_create(zend_class_entry *ce)
5252

5353
intern = reinterpret_cast<NumberFormatter_object *>(zend_object_alloc(sizeof(NumberFormatter_object), ce));
5454
formatter_data_init( &intern->nf_data );
55+
intern->configuration_version = 0;
5556
zend_object_std_init( &intern->zo, ce );
5657
object_properties_init(&intern->zo, ce);
5758

@@ -68,6 +69,7 @@ U_CFUNC zend_object *NumberFormatter_object_clone(zend_object *object)
6869

6970
/* clone standard parts */
7071
zend_objects_clone_members(&new_nfo->zo, &nfo->zo);
72+
new_nfo->configuration_version = nfo->configuration_version;
7173

7274
/* clone formatter object. It may fail, the destruction code must handle this case */
7375
if (FORMATTER_OBJECT(nfo) != nullptr) {

‎ext/intl/formatter/formatter_class.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ extern "C" {
2929

3030
typedef struct {
3131
formatter_data nf_data;
32+
uint64_t configuration_version;
3233
zend_object zo;
3334
} NumberFormatter_object;
3435

‎ext/intl/php_intl.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include "locale/locale_class.h"
4343

4444
#include "listformatter/listformatter_class.h"
45+
#include "reldateformatter/reldateformatter_class.h"
4546
#include "numberformatter/numberformatter_class.h"
4647
#include "rangeformatter/rangeformatter_class.h"
4748

@@ -190,6 +191,9 @@ PHP_MINIT_FUNCTION( intl )
190191
/* Register 'ListFormatter' PHP class */
191192
listformatter_register_class( );
192193

194+
/* Register 'IntlRelativeDateTimeFormatter' PHP class */
195+
reldateformatter_register_class( );
196+
193197
#if U_ICU_VERSION_MAJOR_NUM >= 63
194198
/* Register 'IntlNumberFormatter' PHP class */
195199
numberformatter_register_class( );
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
/**
4+
* @generate-class-entries
5+
* @generate-c-enums
6+
*/
7+
8+
enum IntlRelativeDateTimeFormatterStyle
9+
{
10+
case Long;
11+
case Short;
12+
case Narrow;
13+
}
14+
15+
enum IntlRelativeDateTimeFormatterCapitalization
16+
{
17+
case None;
18+
case MiddleOfSentence;
19+
case BeginningOfSentence;
20+
case UiListAndMenu;
21+
case Standalone;
22+
}
23+
24+
enum IntlRelativeDateTimeFormatterUnit
25+
{
26+
case Year;
27+
case Quarter;
28+
case Month;
29+
case Week;
30+
case Day;
31+
case Hour;
32+
case Minute;
33+
case Second;
34+
case Sunday;
35+
case Monday;
36+
case Tuesday;
37+
case Wednesday;
38+
case Thursday;
39+
case Friday;
40+
case Saturday;
41+
}
42+
43+
/**
44+
* @not-serializable
45+
* @strict-properties
46+
*/
47+
final class IntlRelativeDateTimeFormatter
48+
{
49+
public function __construct(
50+
?string $locale = null,
51+
IntlRelativeDateTimeFormatterStyle $style = IntlRelativeDateTimeFormatterStyle::Long,
52+
IntlRelativeDateTimeFormatterCapitalization $capitalizationContext = IntlRelativeDateTimeFormatterCapitalization::None,
53+
?NumberFormatter $numberFormatter = null,
54+
) {}
55+
56+
public function format(int|float $offset, IntlRelativeDateTimeFormatterUnit $unit): string|false {}
57+
58+
public function formatNumeric(int|float $offset, IntlRelativeDateTimeFormatterUnit $unit): string|false {}
59+
60+
public function combineDateAndTime(string $relativeDate, string $time): string|false {}
61+
62+
public function getErrorCode(): int {}
63+
64+
public function getErrorMessage(): string {}
65+
}

0 commit comments

Comments
 (0)