Skip to content

Commit 6e53ef2

Browse files
DeigueRealCLanger
authored andcommitted
8288377: [REDO] DST not applying properly with zone id offset set with TZ env variable
Reviewed-by: clanger Backport-of: 3c3256414f7df049cdd6c8519fbcea0d818a1a33
1 parent b5dbfef commit 6e53ef2

File tree

2 files changed

+95
-49
lines changed

2 files changed

+95
-49
lines changed

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

Lines changed: 18 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -853,70 +853,39 @@ findJavaTZ_md(const char *java_home_dir)
853853
/**
854854
* Returns a GMT-offset-based zone ID. (e.g., "GMT-08:00")
855855
*/
856-
857-
#if defined(MACOSX)
858-
859856
char *
860857
getGMTOffsetID()
861858
{
862-
time_t offset;
863-
char sign, buf[32];
864-
struct tm local_tm;
865-
time_t clock;
866-
867-
clock = time(NULL);
868-
if (localtime_r(&clock, &local_tm) == NULL) {
859+
char buf[32];
860+
char offset[6];
861+
struct tm localtm;
862+
time_t clock = time(NULL);
863+
if (localtime_r(&clock, &localtm) == NULL) {
869864
return strdup("GMT");
870865
}
871-
offset = (time_t)local_tm.tm_gmtoff;
872-
if (offset == 0) {
866+
867+
#if defined(MACOSX)
868+
time_t gmt_offset;
869+
gmt_offset = (time_t)localtm.tm_gmtoff;
870+
if (gmt_offset == 0) {
873871
return strdup("GMT");
874872
}
875-
if (offset > 0) {
876-
sign = '+';
877-
} else {
878-
offset = -offset;
879-
sign = '-';
880-
}
881-
sprintf(buf, (const char *)"GMT%c%02d:%02d",
882-
sign, (int)(offset/3600), (int)((offset%3600)/60));
883-
return strdup(buf);
884-
}
885-
886873
#else
887-
888-
char *
889-
getGMTOffsetID()
890-
{
891-
time_t offset;
892-
char sign, buf[32];
893-
#if defined(__solaris__)
894-
struct tm localtm;
895-
time_t currenttime;
896-
897-
currenttime = time(NULL);
898-
if (localtime_r(&currenttime, &localtm) == NULL) {
874+
struct tm gmt;
875+
if (gmtime_r(&clock, &gmt) == NULL) {
899876
return strdup("GMT");
900877
}
901878

902-
offset = localtm.tm_isdst ? altzone : timezone;
903-
#else
904-
offset = timezone;
879+
if(localtm.tm_hour == gmt.tm_hour && localtm.tm_min == gmt.tm_min) {
880+
return strdup("GMT");
881+
}
905882
#endif
906883

907-
if (offset == 0) {
884+
if (strftime(offset, 6, "%z", &localtm) != 5) {
908885
return strdup("GMT");
909886
}
910887

911-
/* Note that the time offset direction is opposite. */
912-
if (offset > 0) {
913-
sign = '-';
914-
} else {
915-
offset = -offset;
916-
sign = '+';
917-
}
918-
sprintf(buf, (const char *)"GMT%c%02d:%02d",
919-
sign, (int)(offset/3600), (int)((offset%3600)/60));
888+
sprintf(buf, (const char *)"GMT%c%c%c:%c%c", offset[0], offset[1], offset[2],
889+
offset[3], offset[4]);
920890
return strdup(buf);
921891
}
922-
#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("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)