Skip to content

Commit f5c0fc3

Browse files
DeigueRealCLanger
authored andcommitted
8288377: [REDO] DST not applying properly with zone id offset set with TZ env variable
Backport-of: 3c3256414f7df049cdd6c8519fbcea0d818a1a33
1 parent ab6f746 commit f5c0fc3

File tree

2 files changed

+98
-40
lines changed

2 files changed

+98
-40
lines changed

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

Lines changed: 21 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -525,58 +525,39 @@ findJavaTZ_md(const char *java_home_dir)
525525
/**
526526
* Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00")
527527
*/
528-
529-
#if defined(MACOSX)
530-
531528
char *
532529
getGMTOffsetID()
533530
{
534-
time_t offset;
535-
char sign, buf[32];
536-
struct tm local_tm;
537-
time_t clock;
538-
539-
clock = time(NULL);
540-
if (localtime_r(&clock, &local_tm) == NULL) {
531+
char buf[32];
532+
char offset[6];
533+
struct tm localtm;
534+
time_t clock = time(NULL);
535+
if (localtime_r(&clock, &localtm) == NULL) {
541536
return strdup("GMT");
542537
}
543-
offset = (time_t)local_tm.tm_gmtoff;
544-
if (offset == 0) {
538+
539+
#if defined(MACOSX)
540+
time_t gmt_offset;
541+
gmt_offset = (time_t)localtm.tm_gmtoff;
542+
if (gmt_offset == 0) {
545543
return strdup("GMT");
546544
}
547-
if (offset > 0) {
548-
sign = '+';
549-
} else {
550-
offset = -offset;
551-
sign = '-';
552-
}
553-
sprintf(buf, (const char *)"GMT%c%02d:%02d",
554-
sign, (int)(offset/3600), (int)((offset%3600)/60));
555-
return strdup(buf);
556-
}
557-
558545
#else
546+
struct tm gmt;
547+
if (gmtime_r(&clock, &gmt) == NULL) {
548+
return strdup("GMT");
549+
}
559550

560-
char *
561-
getGMTOffsetID()
562-
{
563-
time_t offset;
564-
char sign, buf[32];
565-
offset = timezone;
566-
567-
if (offset == 0) {
551+
if(localtm.tm_hour == gmt.tm_hour && localtm.tm_min == gmt.tm_min) {
568552
return strdup("GMT");
569553
}
554+
#endif
570555

571-
/* Note that the time offset direction is opposite. */
572-
if (offset > 0) {
573-
sign = '-';
574-
} else {
575-
offset = -offset;
576-
sign = '+';
556+
if (strftime(offset, 6, "%z", &localtm) != 5) {
557+
return strdup("GMT");
577558
}
578-
sprintf(buf, (const char *)"GMT%c%02d:%02d",
579-
sign, (int)(offset/3600), (int)((offset%3600)/60));
559+
560+
sprintf(buf, (const char *)"GMT%c%c%c:%c%c", offset[0], offset[1], offset[2],
561+
offset[3], offset[4]);
580562
return strdup(buf);
581563
}
582-
#endif /* MACOSX */
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright (c) 2022, 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 8285838
26+
* @library /test/lib
27+
* @summary This test will ensure that daylight savings rules are followed
28+
* appropriately when setting a custom timezone ID via the TZ env variable.
29+
* @requires os.family != "windows"
30+
* @run main/othervm CustomTzIDCheckDST
31+
*/
32+
import java.util.Calendar;
33+
import java.util.Date;
34+
import java.util.List;
35+
import java.util.SimpleTimeZone;
36+
import java.time.DayOfWeek;
37+
import java.time.ZonedDateTime;
38+
import java.time.temporal.TemporalAdjusters;
39+
import jdk.test.lib.process.ProcessTools;
40+
import jdk.test.lib.process.OutputAnalyzer;
41+
public class CustomTzIDCheckDST {
42+
private static String CUSTOM_TZ = "MEZ-1MESZ,M3.5.0,M10.5.0";
43+
public static void main(String args[]) throws Throwable {
44+
if (args.length == 0) {
45+
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(List.of("CustomTzIDCheckDST", "runTZTest"));
46+
pb.environment().put("TZ", CUSTOM_TZ);
47+
OutputAnalyzer output = ProcessTools.executeProcess(pb);
48+
output.shouldHaveExitValue(0);
49+
} else {
50+
runTZTest();
51+
}
52+
}
53+
54+
/* TZ code will always be set to "MEZ-1MESZ,M3.5.0,M10.5.0".
55+
* This ensures the transition periods for Daylights Savings should be at March's last
56+
* Sunday and October's last Sunday.
57+
*/
58+
private static void runTZTest() {
59+
Date time = new Date();
60+
if (new SimpleTimeZone(3600000, "MEZ-1MESZ", Calendar.MARCH, -1, Calendar.SUNDAY, 0,
61+
Calendar.OCTOBER, -1, Calendar.SUNDAY, 0).inDaylightTime(time)) {
62+
// We are in Daylight savings period.
63+
if (time.toString().endsWith("GMT+02:00 " + Integer.toString(time.getYear() + 1900)))
64+
return;
65+
} else {
66+
if (time.toString().endsWith("GMT+01:00 " + Integer.toString(time.getYear() + 1900)))
67+
return;
68+
}
69+
70+
// Reaching here means time zone did not match up as expected.
71+
throw new RuntimeException("Got unexpected timezone information: " + time);
72+
}
73+
74+
private static ZonedDateTime getLastSundayOfMonth(ZonedDateTime date) {
75+
return date.with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));
76+
}
77+
}

0 commit comments

Comments
 (0)