Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8339644: Improve parsing of Day/Month in tzdata rules #64

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 29 additions & 20 deletions jdk/make/src/classes/build/tools/tzdb/TzdbZoneRulesCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,6 @@ private void outputFile(Path dstFile, String version,
}

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

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

private int parseMonth(Scanner s) {
if (s.hasNext(MONTH)) {
s.next(MONTH);
for (int moy = 1; moy < 13; moy++) {
if (s.match().group(moy) != null) {
return moy;
}
}
}
throw new IllegalArgumentException("Unknown month: " + s.next());
String mon = s.next();
int len = mon.length();

if (mon.regionMatches(true, 0, "January", 0, len)) return 1;
if (mon.regionMatches(true, 0, "February", 0, len)) return 2;
if (mon.regionMatches(true, 0, "March", 0, len)) return 3;
if (mon.regionMatches(true, 0, "April", 0, len)) return 4;
if (mon.regionMatches(true, 0, "May", 0, len)) return 5;
if (mon.regionMatches(true, 0, "June", 0, len)) return 6;
if (mon.regionMatches(true, 0, "July", 0, len)) return 7;
if (mon.regionMatches(true, 0, "August", 0, len)) return 8;
if (mon.regionMatches(true, 0, "September", 0, len)) return 9;
if (mon.regionMatches(true, 0, "October", 0, len)) return 10;
if (mon.regionMatches(true, 0, "November", 0, len)) return 11;
if (mon.regionMatches(true, 0, "December", 0, len)) return 12;

throw new IllegalArgumentException("Unknown month: " + mon);
}

private int parseDayOfWeek(String str) {
if (DOW.reset(str).matches()) {
for (int dow = 1; dow < 8; dow++) {
if (DOW.group(dow) != null) {
return dow;
}
}
}
throw new IllegalArgumentException("Unknown day-of-week: " + str);
private int parseDayOfWeek(String dow) {
int len = dow.length();

if (dow.regionMatches(true, 0, "Monday", 0, len)) return 1;
if (dow.regionMatches(true, 0, "Tuesday", 0, len)) return 2;
if (dow.regionMatches(true, 0, "Wednesday", 0, len)) return 3;
if (dow.regionMatches(true, 0, "Thursday", 0, len)) return 4;
if (dow.regionMatches(true, 0, "Friday", 0, len)) return 5;
if (dow.regionMatches(true, 0, "Saturday", 0, len)) return 6;
if (dow.regionMatches(true, 0, "Sunday", 0, len)) return 7;

throw new IllegalArgumentException("Unknown day-of-week: " + dow);
}

private String parseOptional(String str) {
Expand Down
37 changes: 17 additions & 20 deletions jdk/test/sun/util/calendar/zi/Month.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -23,11 +23,6 @@
* questions.
*/

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Month enum handles month related manipulation.
*
Expand All @@ -49,15 +44,6 @@ enum Month {

private final String abbr;

private static final Map<String,Month> abbreviations
= new HashMap<String,Month>(12);

static {
for (Month m : Month.values()) {
abbreviations.put(m.abbr, m);
}
}

private Month(String abbr) {
this.abbr = abbr;
}
Expand All @@ -72,11 +58,22 @@ int value() {
* @return the Month value
*/
static Month parse(String name) {
Month m = abbreviations.get(name);
if (m != null) {
return m;
}
return null;
int len = name.length();

if (name.regionMatches(true, 0, "January", 0, len)) return Month.JANUARY;
if (name.regionMatches(true, 0, "February", 0, len)) return Month.FEBRUARY;
if (name.regionMatches(true, 0, "March", 0, len)) return Month.MARCH;
if (name.regionMatches(true, 0, "April", 0, len)) return Month.APRIL;
if (name.regionMatches(true, 0, "May", 0, len)) return Month.MAY;
if (name.regionMatches(true, 0, "June", 0, len)) return Month.JUNE;
if (name.regionMatches(true, 0, "July", 0, len)) return Month.JULY;
if (name.regionMatches(true, 0, "August", 0, len)) return Month.AUGUST;
if (name.regionMatches(true, 0, "September", 0, len)) return Month.SEPTEMBER;
if (name.regionMatches(true, 0, "October", 0, len)) return Month.OCTOBER;
if (name.regionMatches(true, 0, "November", 0, len)) return Month.NOVEMBER;
if (name.regionMatches(true, 0, "December", 0, len)) return Month.DECEMBER;

throw new IllegalArgumentException("Unknown month: " + name);
}

/**
Expand Down
30 changes: 14 additions & 16 deletions jdk/test/sun/util/calendar/zi/RuleDay.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -23,11 +23,6 @@
* questions.
*/

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* RuleDay class represents the value of the "ON" field. The day of
* week values start from 1 following the {@link java.util.Calendar}
Expand All @@ -36,13 +31,6 @@
* @since 1.4
*/
class RuleDay {
private static final Map<String,DayOfWeek> abbreviations = new HashMap<String,DayOfWeek>(7);
static {
for (DayOfWeek day : DayOfWeek.values()) {
abbreviations.put(day.getAbbr(), day);
}
}

private String dayName = null;
private DayOfWeek dow;
private boolean lastOne = false;
Expand Down Expand Up @@ -168,13 +156,23 @@ String getDayOfWeekForSimpleTimeZone() {
return sign + toString(d);
}

private static DayOfWeek getDOW(String abbr) {
return abbreviations.get(abbr);
private static DayOfWeek getDOW(String name) {
int len = name.length();

if (name.regionMatches(true, 0, "Monday", 0, len)) return DayOfWeek.MONDAY;
if (name.regionMatches(true, 0, "Tuesday", 0, len)) return DayOfWeek.TUESDAY;
if (name.regionMatches(true, 0, "Wednesday", 0, len)) return DayOfWeek.WEDNESDAY;
if (name.regionMatches(true, 0, "Thursday", 0, len)) return DayOfWeek.THURSDAY;
if (name.regionMatches(true, 0, "Friday", 0, len)) return DayOfWeek.FRIDAY;
if (name.regionMatches(true, 0, "Saturday", 0, len)) return DayOfWeek.SATURDAY;
if (name.regionMatches(true, 0, "Sunday", 0, len)) return DayOfWeek.SUNDAY;

throw new IllegalArgumentException("Unknown day-of-week: " + name);
}

/**
* Converts the specified day of week value to the day-of-week
* name defined in {@link java.util.Calenda}.
* name defined in {@link java.util.Calendar}.
* @param dow 1-based day of week value
* @return the Calendar day of week name with "Calendar." prefix.
* @throws IllegalArgumentException if the specified dow value is out of range.
Expand Down