Skip to content

Commit 3a61d19

Browse files
committed
Backport 132072077aa4a15db108989e3d17e6d9249d3ba2
Signed-off-by: Sruthy Jayan <srutjay1@in.ibm.com>
1 parent 0cda7c9 commit 3a61d19

3 files changed

Lines changed: 158 additions & 23 deletions

File tree

src/java.base/unix/native/libjava/TimeZone_md.c

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -369,33 +369,15 @@ getPlatformTimeZoneID()
369369
}
370370

371371
static char *
372-
mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
372+
getJavaTimezoneFromPlatform(const char *tz_buf, size_t tz_len, const char *mapfilename) {
373373
FILE *tzmapf;
374-
char mapfilename[PATH_MAX + 1];
375374
char line[256];
376375
int linecount = 0;
377-
char *tz_buf = NULL;
378-
char *temp_tz = NULL;
379376
char *javatz = NULL;
380-
size_t tz_len = 0;
381-
382-
/* On AIX, the TZ environment variable may end with a comma
383-
* followed by modifier fields until early AIX6.1.
384-
* This restriction has been removed from AIX7. */
385377

386-
tz_buf = strdup(tz);
387-
tz_len = strlen(tz_buf);
388-
389-
/* Open tzmappings file, with buffer overrun check */
390-
if ((strlen(java_home_dir) + 15) > PATH_MAX) {
391-
jio_fprintf(stderr, "Path %s/lib/tzmappings exceeds maximum path length\n", java_home_dir);
392-
goto tzerr;
393-
}
394-
strcpy(mapfilename, java_home_dir);
395-
strcat(mapfilename, "/lib/tzmappings");
396378
if ((tzmapf = fopen(mapfilename, "r")) == NULL) {
397379
jio_fprintf(stderr, "can't open %s\n", mapfilename);
398-
goto tzerr;
380+
return NULL;
399381
}
400382

401383
while (fgets(line, sizeof(line), tzmapf) != NULL) {
@@ -448,10 +430,58 @@ mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
448430
break;
449431
}
450432
}
433+
451434
(void) fclose(tzmapf);
435+
return javatz;
436+
}
437+
438+
static char *
439+
mapPlatformToJavaTimezone(const char *java_home_dir, const char *tz) {
440+
char mapfilename[PATH_MAX + 1];
441+
char *tz_buf = NULL;
442+
char *javatz = NULL;
443+
char *temp_tz = NULL;
444+
size_t tz_len = 0;
445+
446+
/* On AIX, the TZ environment variable may end with a comma
447+
* followed by modifier fields until early AIX6.1.
448+
* This restriction has been removed from AIX7. */
449+
450+
tz_buf = strdup(tz);
451+
if (tz_buf == NULL) {
452+
jio_fprintf(stderr, "Failed to allocate timezone buffer\n");
453+
goto tzerr;
454+
}
455+
tz_len = strlen(tz_buf);
456+
457+
/* Open tzmappings file, with buffer overrun check */
458+
if ((strlen(java_home_dir) + 15) > PATH_MAX) {
459+
jio_fprintf(stderr, "Path %s/lib/tzmappings exceeds maximum path length\n", java_home_dir);
460+
goto tzerr;
461+
}
462+
strcpy(mapfilename, java_home_dir);
463+
strcat(mapfilename, "/lib/tzmappings");
464+
465+
// First attempt to find the Java timezone for the full tz string
466+
javatz = getJavaTimezoneFromPlatform(tz_buf, tz_len, mapfilename);
467+
468+
// If no match was found, check for timezone with truncated value
469+
if (javatz == NULL) {
470+
temp_tz = strchr(tz, ',');
471+
tz_len = (temp_tz == NULL) ? strlen(tz) : temp_tz - tz;
472+
free((void *) tz_buf);
473+
tz_buf = (char *)malloc(tz_len + 1);
474+
if (tz_buf == NULL) {
475+
jio_fprintf(stderr, "Failed to allocate timezone buffer\n");
476+
goto tzerr;
477+
}
478+
memcpy(tz_buf, tz, tz_len);
479+
tz_buf[tz_len] = '\0';
480+
javatz = getJavaTimezoneFromPlatform(tz_buf, tz_len, mapfilename);
481+
}
452482

453483
tzerr:
454-
if (tz_buf != NULL ) {
484+
if (tz_buf != NULL) {
455485
free((void *) tz_buf);
456486
}
457487

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/* @test
25+
* @bug 8380993
26+
* @library /test/lib
27+
* @summary Validates AIX timezone mapping behavior where POSIX TZ strings
28+
* with comma-separated DST rules are truncated and mapped through tzmappings
29+
* to the expected IANA timezone IDs.
30+
* @requires os.family == "aix"
31+
* @run main/othervm AIXTzMappingTest
32+
*/
33+
34+
import java.util.TimeZone;
35+
36+
import jdk.test.lib.process.ProcessTools;
37+
import jdk.test.lib.process.OutputAnalyzer;
38+
39+
public class AIXTzMappingTest {
40+
41+
// POSIX TZ strings that should be mapped via tzmappings
42+
private static final String TZ_CET = "CET-1CEST,M3.5.0,M10.5.0";
43+
private static final String TZ_MEZ = "MEZ-1MESZ,M3.5.0,M10.5.0/3";
44+
45+
private static final String ID_PARIS = "Europe/Paris";
46+
private static final String ID_BERLIN = "Europe/Berlin";
47+
48+
public static void main(String[] args) throws Throwable {
49+
if (args.length == 0) {
50+
runWithTZ(TZ_CET, ID_PARIS);
51+
runWithTZ(TZ_MEZ, ID_BERLIN);
52+
} else if (args.length == 1) {
53+
runTZTest(args[0]);
54+
} else {
55+
throw new RuntimeException(
56+
"Expected 0 or 1 arguments, got " + args.length);
57+
}
58+
}
59+
60+
private static void runWithTZ(String tz, String expectedId)
61+
throws Throwable {
62+
ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
63+
"AIXTzMappingTest", expectedId);
64+
65+
pb.environment().put("TZ", tz);
66+
67+
OutputAnalyzer output = ProcessTools.executeProcess(pb);
68+
output.shouldHaveExitValue(0);
69+
}
70+
71+
/*
72+
* On AIX, POSIX TZ strings such as:
73+
* CET-1CEST,M3.5.0,M10.5.0
74+
* MEZ-1MESZ,M3.5.0,M10.5.0/3
75+
* are truncated at the comma and mapped through tzmappings to
76+
* IANA timezone IDs.
77+
*
78+
* This test verifies that the expected IANA timezone ID is selected.
79+
*/
80+
private static void runTZTest(String expectedId) {
81+
String tzStr = System.getenv("TZ");
82+
83+
if (tzStr == null) {
84+
throw new RuntimeException(
85+
"Got unexpected timezone information: TZ is null");
86+
}
87+
88+
TimeZone tz = TimeZone.getDefault();
89+
String tzId = tz.getID();
90+
91+
if (!expectedId.equals(tzId)) {
92+
throw new RuntimeException(
93+
"Expected timezone ID " + expectedId
94+
+ " but got " + tzId
95+
+ " for TZ=" + tzStr);
96+
}
97+
98+
System.out.println(
99+
"AIX timezone mapping test passed: "
100+
+ tzId + " for TZ=" + tzStr);
101+
}
102+
}

test/jdk/java/util/TimeZone/CustomTzIDCheckDST.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2026, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,10 @@
2626
* @library /test/lib
2727
* @summary This test will ensure that daylight savings rules are followed
2828
* appropriately when setting a custom timezone ID via the TZ env variable.
29-
* @requires os.family != "windows"
29+
* AIX is excluded because it uses a different timezone mapping mechanism
30+
* through the tzmappings file; see AIXTzMappingTest.java for AIX-specific
31+
* coverage.
32+
* @requires os.family != "windows" & os.family != "aix"
3033
* @run main/othervm CustomTzIDCheckDST
3134
*/
3235

0 commit comments

Comments
 (0)