Skip to content
This repository was archived by the owner on Sep 19, 2023. It is now read-only.

Commit a1cc5be

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

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
@@ -555,58 +555,39 @@ findJavaTZ_md(const char *java_home_dir)
555555
/**
556556
* Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00")
557557
*/
558-
559-
#if defined(MACOSX)
560-
561558
char *
562559
getGMTOffsetID()
563560
{
564-
time_t offset;
565-
char sign, buf[32];
566-
struct tm local_tm;
567-
time_t clock;
568-
569-
clock = time(NULL);
570-
if (localtime_r(&clock, &local_tm) == NULL) {
561+
char buf[32];
562+
char offset[6];
563+
struct tm localtm;
564+
time_t clock = time(NULL);
565+
if (localtime_r(&clock, &localtm) == NULL) {
571566
return strdup("GMT");
572567
}
573-
offset = (time_t)local_tm.tm_gmtoff;
574-
if (offset == 0) {
568+
569+
#if defined(MACOSX)
570+
time_t gmt_offset;
571+
gmt_offset = (time_t)localtm.tm_gmtoff;
572+
if (gmt_offset == 0) {
575573
return strdup("GMT");
576574
}
577-
if (offset > 0) {
578-
sign = '+';
579-
} else {
580-
offset = -offset;
581-
sign = '-';
582-
}
583-
sprintf(buf, (const char *)"GMT%c%02d:%02d",
584-
sign, (int)(offset/3600), (int)((offset%3600)/60));
585-
return strdup(buf);
586-
}
587-
588575
#else
576+
struct tm gmt;
577+
if (gmtime_r(&clock, &gmt) == NULL) {
578+
return strdup("GMT");
579+
}
589580

590-
char *
591-
getGMTOffsetID()
592-
{
593-
time_t offset;
594-
char sign, buf[32];
595-
offset = timezone;
596-
597-
if (offset == 0) {
581+
if(localtm.tm_hour == gmt.tm_hour && localtm.tm_min == gmt.tm_min) {
598582
return strdup("GMT");
599583
}
584+
#endif
600585

601-
/* Note that the time offset direction is opposite. */
602-
if (offset > 0) {
603-
sign = '-';
604-
} else {
605-
offset = -offset;
606-
sign = '+';
586+
if (strftime(offset, 6, "%z", &localtm) != 5) {
587+
return strdup("GMT");
607588
}
608-
sprintf(buf, (const char *)"GMT%c%02d:%02d",
609-
sign, (int)(offset/3600), (int)((offset%3600)/60));
589+
590+
sprintf(buf, (const char *)"GMT%c%c%c:%c%c", offset[0], offset[1], offset[2],
591+
offset[3], offset[4]);
610592
return strdup(buf);
611593
}
612-
#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)