On Fri, 26 Aug 2022 18:56:31 GMT, Naoto Sato <na...@openjdk.org> wrote:

>> After `test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java` testcase was 
>> integrated, it failed on the AIX platform.
>> 
>> Error output
>> 
>> STDERR:
>>  stdout: [];
>>  stderr: [Exception in thread "main" java.lang.RuntimeException: Got 
>> unexpected timezone information: Thu Aug 25 09:29:10 CEST 2022
>>         at CustomTzIDCheckDST.runTZTest(CustomTzIDCheckDST.java:71)
>>         at CustomTzIDCheckDST.main(CustomTzIDCheckDST.java:50)
>> ]
>> 
>> 
>> By my investigation, `TZ=MEZ-1MESZ,M3.5.0,M10.5.0` timezone was changed to 
>> `Europe/Berlin` timezone on AIX platform.
>> It seems this situation is happened because older AIX did not support 
>> `MEZ-1MESZ,M3.5.0,M10.5.0` timezone by TZ environment variable.
>> https://www.ibm.com/support/pages/managing-time-zone-variable-posix
>> AIX special code was implemented into 
>> `src/java.base/unix/native/libjava/TimeZone_md.c`.
>> Current AIX supports `TZ=EST5EDT,M3.2.0/2:00:00,M11.1.0/2:00:00` style.
>> I think implementation change is required. 
>> 
>> Some pre-submit tests are failed, but I think these are not related this 
>> change since modified parts are just for AIX platform.
>
> src/java.base/unix/native/libjava/TimeZone_md.c line 589:
> 
>> 587:     // But Hotspot does not support XPG_SUS_ENV=ON.
>> 588:     // Ignore daylight saving settings to calculate current time 
>> difference
>> 589:     localtm.tm_isdst = 0;
> 
> Is it OK to reset it always? Could this defy the original purpose of the fix 
> to https://bugs.openjdk.org/browse/JDK-8285838?

I executed test program 
[JDK-8285838](https://bugs.openjdk.org/browse/JDK-8285838) on RHEL8 x86_64.
TZ="MEZ-1MESZ,M3.5.0,M10.5.0" means I'm on daylight saving time on today. 
By JDK18

$ TZ="MEZ-1MESZ,M3.5.0,M10.5.0" jdk-18/bin/java -showversion TimeTest.java
openjdk version "18" 2022-03-22
OpenJDK Runtime Environment (build 18+36-2087)
OpenJDK 64-Bit Server VM (build 18+36-2087, mixed mode, sharing)
Calendar.getInstance().getTime() = Thu Sep 01 11:52:09 GMT+01:00 2022
SimpleDateFormat = 01.09.2022 11:52:09.747

By JDK20

$ TZ="MEZ-1MESZ,M3.5.0,M10.5.0" jdk-20-b12/bin/java -showversion TimeTest.java
openjdk version "20-ea" 2023-03-21
OpenJDK Runtime Environment (build 20-ea+12-790)
OpenJDK 64-Bit Server VM (build 20-ea+12-790, mixed mode, sharing)
Calendar.getInstance().getTime() = Thu Sep 01 12:52:21 GMT+02:00 2022
SimpleDateFormat = 01.09.2022 12:52:21.269

Expected result is GMT+02:00.
It means the output is the current time difference between GMT and MESZ.

On modified build

$ TZ="MEZ-1MESZ,M3.5.0,M10.5.0" 
jdk/build/aix-ppc64-server-release/images/jdk/bin/java TimeTest.java
Calendar.getInstance().getTime() = Thu Sep 01 12:53:12 GMT+02:00 2022
SimpleDateFormat = 01.09.2022 12:53:12.930


According to AIX docs for mktime()
https://www.ibm.com/docs/en/aix/7.2?topic=c-ctime-localtime-gmtime-mktime-difftime-asctime-tzset-subroutine

> The value of the ```tm_isdst``` field determines the following actions of the 
> **mktime** subroutine:
> "0" means "Initially presumes that Daylight Saving Time (DST) is not in 
> effect."

If daylight saving time ends by August, timezone should be GMT+01:00

$ TZ="MEZ-1MESZ,M3.5.0,M8.5.0" 
jdk/build/aix-ppc64-server-release/images/jdk/bin/java TimeTest.java  
Calendar.getInstance().getTime() = Thu Sep 01 11:53:36 GMT+01:00 2022
SimpleDateFormat = 01.09.2022 11:53:36.189


According to simple C testcase

$ cat sf.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
int main(void)
{
    char buf[100];
    struct tm localtm;
    struct tm gmt;
    time_t clock = time(NULL);
    int gmt_off;

#if defined(_AIX)
    putenv("XPG_SUS_ENV=ON");
#endif
    if (localtime_r(&clock, &localtm) == NULL) {
        return 1;
    }
    if (gmtime_r(&clock, &gmt) == NULL) {
        return 1;
    }
    strftime(buf, sizeof(buf),"%z", &localtm);
    printf("strftime: %s\n",buf);
    localtm.tm_isdst = 0;
    gmt_off = (int)(difftime(mktime(&localtm), mktime(&gmt)) / 60.0);
    sprintf(buf, (const char *)"%c%02.2d%02.2d",
            gmt_off < 0 ? '-' : '+' , abs(gmt_off / 60), gmt_off % 60);
    printf("difftime: %s\n",buf);
    return 0;
}

On RHEL8:

$ TZ="MEZ-1MESZ,M3.5.0,M10.5.0" ./sf
strftime: +0200
difftime: +0200
$ TZ="ZZZ-1ZZZZ-3,M3.5.0,M10.5.0" ./sf
strftime: +0300
difftime: +0300
$ TZ="ZZZ-1ZZZZ-3,M3.5.0,M8.5.0" ./sf
strftime: +0100
difftime: +0100

On AIX:

$ TZ="MEZ-1MESZ,M3.5.0,M10.5.0" ./sf
strftime: +0200
difftime: +0200
$ TZ="ZZZ-1ZZZZ-3,M3.5.0,M10.5.0" ./sf
strftime: +0300
difftime: +0300
$ TZ="ZZZ-1ZZZZ-3,M3.5.0,M8.5.0" ./sf
strftime: +0100
difftime: +0100

I assume the modified code should be fine.

-------------

PR: https://git.openjdk.org/jdk/pull/10036

Reply via email to