Skip to content

Test ext/intl/tests/calendar_clear_variation1.phpt fails with ICU 73.1 #11128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
andypost opened this issue Apr 24, 2023 · 13 comments
Closed

Test ext/intl/tests/calendar_clear_variation1.phpt fails with ICU 73.1 #11128

andypost opened this issue Apr 24, 2023 · 13 comments

Comments

@andypost
Copy link
Contributor

Description

The following code:

latest commit 976d7ed

Resulted in this output:

========DIFF========
     bool(true)
     bool(true)
     bool(false)
- float(1327813567000)
+ float(1330491967000)
     float(1327813567000)
========DONE========

But I expected this test to pass which means that month field is not cleared

var_dump($intlcal->clear(IntlCalendar::FIELD_MONTH));

PHP Version

master

Operating System

Alpinelinux

@andypost
Copy link
Contributor Author

@andypost
Copy link
Contributor Author

Implementation of the method got no changes and no changes at https://unicode-org.github.io/icu-docs/apidoc/dev/icu4c/deprecated.html

U_CFUNC PHP_FUNCTION(intlcal_clear)
{
zend_long field;
bool field_is_null = 1;
CALENDAR_METHOD_INIT_VARS;
if (zend_parse_method_parameters(ZEND_NUM_ARGS(),
getThis(), "O|l!", &object, Calendar_ce_ptr, &field, &field_is_null) == FAILURE) {
RETURN_THROWS();
}
CALENDAR_METHOD_FETCH_OBJECT;
if (field_is_null) {
co->ucal->clear();
} else {
ZEND_VALUE_ERROR_INVALID_FIELD(field, 2);
co->ucal->clear((UCalendarDateFields)field);
}
RETURN_TRUE;
}

@andypost
Copy link
Contributor Author

andypost commented May 7, 2023

Used to build example app and found that clear() cpp method does not work in 72.1 but C-API stop working in 73.1

cal.cpp

#include "unicode/calendar.h"
#include "unicode/gregocal.h"
#include <stdio.h>

using namespace icu;

extern "C" void c_main();

void cpp_main()
{
  //cout << "CPP API " << endl;
  puts("CPP API");
  UErrorCode status = U_ZERO_ERROR;
  GregorianCalendar* gc = new GregorianCalendar(status);
  gc->set(2012, UCAL_FEBRUARY, 29);
  printf("before clear - year: %d, month: %d (%d in the implementation), day: %d\n",
           gc->get(UCAL_YEAR, status),
           gc->get(UCAL_MONTH, status) + 1,
           gc->get(UCAL_MONTH, status),
           gc->get(UCAL_DATE, status));
  gc->clear(UCAL_MONTH);
  gc->clear(UCAL_DATE);
  printf("after clear  - year: %d, month: %d (%d in the implementation), day: %d\n",
           gc->get(UCAL_YEAR, status),
           gc->get(UCAL_MONTH, status) + 1,
           gc->get(UCAL_MONTH, status),
           gc->get(UCAL_DATE, status));
  delete gc;
}

int main()
{
  cpp_main();

  c_main();

  return 0;
}

ccal.c

#include "unicode/ucal.h"
#include <stdio.h>

void c_main()
{
  puts("C API");
  UErrorCode status = U_ZERO_ERROR;
  int32_t i;
  UCalendar *cal = ucal_open(NULL, -1, NULL, UCAL_GREGORIAN, &status);
  ucal_set(cal, UCAL_YEAR, 2012);
  ucal_set(cal, UCAL_MONTH, UCAL_FEBRUARY);
  ucal_set(cal, UCAL_DATE, 29);
  printf("before clear - year: %d, month: %d (%d in the implementation), day: %d\n",
    ucal_get(cal, UCAL_YEAR, &status),
    ucal_get(cal, UCAL_MONTH, &status) + 1,
    ucal_get(cal, UCAL_MONTH, &status),
    ucal_get(cal, UCAL_DATE, &status));
  ucal_clearField(cal, UCAL_MONTH);
  printf("after clear  - year: %d, month: %d (%d in the implementation), day: %d\n",
    ucal_get(cal, UCAL_YEAR, &status),
    ucal_get(cal, UCAL_MONTH, &status) + 1,
    ucal_get(cal, UCAL_MONTH, &status),
    ucal_get(cal, UCAL_DATE, &status));
  ucal_close(cal);
}

@andypost
Copy link
Contributor Author

andypost commented May 7, 2023

The output for

test$ icu-config --version
73.1
test$ ./datecal
CPP API
before clear - year: 2012, month: 2 (1 in the implementation), day: 29
after clear  - year: 2012, month: 2 (1 in the implementation), day: 29
C API
before clear - year: 2012, month: 2 (1 in the implementation), day: 29
after clear  - year: 2012, month: 2 (1 in the implementation), day: 29

and previous (alpine:3.17)

test # icu-config --version
72.1
test # ./datecal 
CPP API
before clear - year: 2012, month: 2 (1 in the implementation), day: 29
after clear  - year: 2012, month: 2 (1 in the implementation), day: 29
C API
before clear - year: 2012, month: 2 (1 in the implementation), day: 29
after clear  - year: 2012, month: 1 (0 in the implementation), day: 29

@andypost
Copy link
Contributor Author

Looks the only way to fix it is to use c++ API

@iluuu1994
Copy link
Member

This fails on macOS on GitHub actions now too, probably due to an update of ICU. @andypost was this reported upstream?

@andypost
Copy link
Contributor Author

Not yet as I failed to find docs for it(

@iluuu1994
Copy link
Member

@andypost I haven't looked at this in detail yet, but I was confused that we're using the C++ API that is broken with 72.1 in your example.

co->ucal->clear();
} else {
ZEND_VALUE_ERROR_INVALID_FIELD(field, 2);
co->ucal->clear((UCalendarDateFields)field);

But the test works fine for me with ICU 72.1. I'm not sure if some specific calendar condition makes it work/fail.

@andypost
Copy link
Contributor Author

yes, the issue started to happen with 73.1 - Alpinelinux used to upgrade earlier so I hit it

@iluuu1994
Copy link
Member

I think this is just a problem with the test. FIELD_ORDINAL_MONTH was introduced in ICU 73. If we're not clearing this field, month will be repopulated with the value from this field. I'll create a PR shortly.

@andypost
Copy link
Contributor Author

I can't find any FIELD_ORDINAL_MONTH mentions, where it from?

iluuu1994 added a commit to iluuu1994/php-src that referenced this issue Jun 23, 2023
ICU 73 introduces the UCAL_ORDINAL_MONTH field. We need to clear it so that
UCAL_MONTH doesn't get repopulated.

Fixes phpGH-11128
@iluuu1994
Copy link
Member

@andypost https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/ucal_8h.html#a02fe23bf33319052733c00c7a09ea912a1a565b5618fbb006c9b48b48f06a0167

It is also flagged as "draft API". It seems weird to me that introducing new fields can break clear, and even weirder that experimental fields can do so. I'm not sure what the right approach is here.

iluuu1994 added a commit to iluuu1994/php-src that referenced this issue Jun 23, 2023
ICU 73 introduces the UCAL_ORDINAL_MONTH field. We need to clear it so that
UCAL_MONTH doesn't get repopulated.

Fixes phpGH-11128
@iluuu1994
Copy link
Member

I created https://unicode-org.atlassian.net/browse/ICU-22424 in the meantime.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants