Skip to content

Commit 88a7829

Browse files
author
Dmitry Cherepanov
committed
8339644: Improve parsing of Day/Month in tzdata rules
Reviewed-by: andrew Backport-of: 86a2f9c7dcb6585cabf03c0940511d11560e85b7
1 parent 4c50940 commit 88a7829

File tree

3 files changed

+60
-56
lines changed

3 files changed

+60
-56
lines changed

jdk/make/src/classes/build/tools/tzdb/TzdbZoneRulesCompiler.java

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,6 @@ private void outputFile(Path dstFile, String version,
270270
}
271271

272272
private static final Pattern YEAR = Pattern.compile("(?i)(?<min>min)|(?<max>max)|(?<only>only)|(?<year>[0-9]+)");
273-
private static final Pattern MONTH = Pattern.compile("(?i)(jan)|(feb)|(mar)|(apr)|(may)|(jun)|(jul)|(aug)|(sep)|(oct)|(nov)|(dec)");
274-
private static final Matcher DOW = Pattern.compile("(?i)(mon)|(tue)|(wed)|(thu)|(fri)|(sat)|(sun)").matcher("");
275273
private static final Matcher TIME = Pattern.compile("(?<neg>-)?+(?<hour>[0-9]{1,2})(:(?<minute>[0-5][0-9]))?+(:(?<second>[0-5][0-9]))?+").matcher("");
276274

277275
/** The TZDB rules. */
@@ -495,26 +493,37 @@ private int parseYear(Scanner s, int defaultYear) {
495493
}
496494

497495
private int parseMonth(Scanner s) {
498-
if (s.hasNext(MONTH)) {
499-
s.next(MONTH);
500-
for (int moy = 1; moy < 13; moy++) {
501-
if (s.match().group(moy) != null) {
502-
return moy;
503-
}
504-
}
505-
}
506-
throw new IllegalArgumentException("Unknown month: " + s.next());
496+
String mon = s.next();
497+
int len = mon.length();
498+
499+
if (mon.regionMatches(true, 0, "January", 0, len)) return 1;
500+
if (mon.regionMatches(true, 0, "February", 0, len)) return 2;
501+
if (mon.regionMatches(true, 0, "March", 0, len)) return 3;
502+
if (mon.regionMatches(true, 0, "April", 0, len)) return 4;
503+
if (mon.regionMatches(true, 0, "May", 0, len)) return 5;
504+
if (mon.regionMatches(true, 0, "June", 0, len)) return 6;
505+
if (mon.regionMatches(true, 0, "July", 0, len)) return 7;
506+
if (mon.regionMatches(true, 0, "August", 0, len)) return 8;
507+
if (mon.regionMatches(true, 0, "September", 0, len)) return 9;
508+
if (mon.regionMatches(true, 0, "October", 0, len)) return 10;
509+
if (mon.regionMatches(true, 0, "November", 0, len)) return 11;
510+
if (mon.regionMatches(true, 0, "December", 0, len)) return 12;
511+
512+
throw new IllegalArgumentException("Unknown month: " + mon);
507513
}
508514

509-
private int parseDayOfWeek(String str) {
510-
if (DOW.reset(str).matches()) {
511-
for (int dow = 1; dow < 8; dow++) {
512-
if (DOW.group(dow) != null) {
513-
return dow;
514-
}
515-
}
516-
}
517-
throw new IllegalArgumentException("Unknown day-of-week: " + str);
515+
private int parseDayOfWeek(String dow) {
516+
int len = dow.length();
517+
518+
if (dow.regionMatches(true, 0, "Monday", 0, len)) return 1;
519+
if (dow.regionMatches(true, 0, "Tuesday", 0, len)) return 2;
520+
if (dow.regionMatches(true, 0, "Wednesday", 0, len)) return 3;
521+
if (dow.regionMatches(true, 0, "Thursday", 0, len)) return 4;
522+
if (dow.regionMatches(true, 0, "Friday", 0, len)) return 5;
523+
if (dow.regionMatches(true, 0, "Saturday", 0, len)) return 6;
524+
if (dow.regionMatches(true, 0, "Sunday", 0, len)) return 7;
525+
526+
throw new IllegalArgumentException("Unknown day-of-week: " + dow);
518527
}
519528

520529
private String parseOptional(String str) {

jdk/test/sun/util/calendar/zi/Month.java

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2000, 2024, 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
@@ -23,11 +23,6 @@
2323
* questions.
2424
*/
2525

26-
import java.util.ArrayList;
27-
import java.util.HashMap;
28-
import java.util.List;
29-
import java.util.Map;
30-
3126
/**
3227
* Month enum handles month related manipulation.
3328
*
@@ -49,15 +44,6 @@ enum Month {
4944

5045
private final String abbr;
5146

52-
private static final Map<String,Month> abbreviations
53-
= new HashMap<String,Month>(12);
54-
55-
static {
56-
for (Month m : Month.values()) {
57-
abbreviations.put(m.abbr, m);
58-
}
59-
}
60-
6147
private Month(String abbr) {
6248
this.abbr = abbr;
6349
}
@@ -72,11 +58,22 @@ int value() {
7258
* @return the Month value
7359
*/
7460
static Month parse(String name) {
75-
Month m = abbreviations.get(name);
76-
if (m != null) {
77-
return m;
78-
}
79-
return null;
61+
int len = name.length();
62+
63+
if (name.regionMatches(true, 0, "January", 0, len)) return Month.JANUARY;
64+
if (name.regionMatches(true, 0, "February", 0, len)) return Month.FEBRUARY;
65+
if (name.regionMatches(true, 0, "March", 0, len)) return Month.MARCH;
66+
if (name.regionMatches(true, 0, "April", 0, len)) return Month.APRIL;
67+
if (name.regionMatches(true, 0, "May", 0, len)) return Month.MAY;
68+
if (name.regionMatches(true, 0, "June", 0, len)) return Month.JUNE;
69+
if (name.regionMatches(true, 0, "July", 0, len)) return Month.JULY;
70+
if (name.regionMatches(true, 0, "August", 0, len)) return Month.AUGUST;
71+
if (name.regionMatches(true, 0, "September", 0, len)) return Month.SEPTEMBER;
72+
if (name.regionMatches(true, 0, "October", 0, len)) return Month.OCTOBER;
73+
if (name.regionMatches(true, 0, "November", 0, len)) return Month.NOVEMBER;
74+
if (name.regionMatches(true, 0, "December", 0, len)) return Month.DECEMBER;
75+
76+
throw new IllegalArgumentException("Unknown month: " + name);
8077
}
8178

8279
/**

jdk/test/sun/util/calendar/zi/RuleDay.java

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2000, 2024, 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
@@ -23,11 +23,6 @@
2323
* questions.
2424
*/
2525

26-
import java.util.ArrayList;
27-
import java.util.HashMap;
28-
import java.util.List;
29-
import java.util.Map;
30-
3126
/**
3227
* RuleDay class represents the value of the "ON" field. The day of
3328
* week values start from 1 following the {@link java.util.Calendar}
@@ -36,13 +31,6 @@
3631
* @since 1.4
3732
*/
3833
class RuleDay {
39-
private static final Map<String,DayOfWeek> abbreviations = new HashMap<String,DayOfWeek>(7);
40-
static {
41-
for (DayOfWeek day : DayOfWeek.values()) {
42-
abbreviations.put(day.getAbbr(), day);
43-
}
44-
}
45-
4634
private String dayName = null;
4735
private DayOfWeek dow;
4836
private boolean lastOne = false;
@@ -168,13 +156,23 @@ String getDayOfWeekForSimpleTimeZone() {
168156
return sign + toString(d);
169157
}
170158

171-
private static DayOfWeek getDOW(String abbr) {
172-
return abbreviations.get(abbr);
159+
private static DayOfWeek getDOW(String name) {
160+
int len = name.length();
161+
162+
if (name.regionMatches(true, 0, "Monday", 0, len)) return DayOfWeek.MONDAY;
163+
if (name.regionMatches(true, 0, "Tuesday", 0, len)) return DayOfWeek.TUESDAY;
164+
if (name.regionMatches(true, 0, "Wednesday", 0, len)) return DayOfWeek.WEDNESDAY;
165+
if (name.regionMatches(true, 0, "Thursday", 0, len)) return DayOfWeek.THURSDAY;
166+
if (name.regionMatches(true, 0, "Friday", 0, len)) return DayOfWeek.FRIDAY;
167+
if (name.regionMatches(true, 0, "Saturday", 0, len)) return DayOfWeek.SATURDAY;
168+
if (name.regionMatches(true, 0, "Sunday", 0, len)) return DayOfWeek.SUNDAY;
169+
170+
throw new IllegalArgumentException("Unknown day-of-week: " + name);
173171
}
174172

175173
/**
176174
* Converts the specified day of week value to the day-of-week
177-
* name defined in {@link java.util.Calenda}.
175+
* name defined in {@link java.util.Calendar}.
178176
* @param dow 1-based day of week value
179177
* @return the Calendar day of week name with "Calendar." prefix.
180178
* @throws IllegalArgumentException if the specified dow value is out of range.

0 commit comments

Comments
 (0)