1 /* 2 * Copyright (c) 2000, 2018, 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 import java.util.ArrayList; 25 import java.util.HashMap; 26 import java.util.List; 27 import java.util.Map; 28 29 /** 30 * RuleDay class represents the value of the "ON" field. The day of 31 * week values start from 1 following the {@link java.util.Calendar} 32 * convention. 33 * 34 * @since 1.4 35 */ 36 class RuleDay { 37 private static final Map<String,DayOfWeek> abbreviations = new HashMap<String,DayOfWeek>(7); 38 static { 39 for (DayOfWeek day : DayOfWeek.values()) { 40 abbreviations.put(day.getAbbr(), day); 41 } 42 } 43 44 private String dayName = null; 45 private DayOfWeek dow; 46 private boolean lastOne = false; 47 private int soonerOrLater = 0; 48 private int thanDayOfMonth; // day of month (e.g., 8 for "Sun>=8") 49 50 RuleDay() { 51 } 52 53 RuleDay(int day) { 54 thanDayOfMonth = day; 55 } 56 57 int getDay() { 58 return thanDayOfMonth; 59 } 60 61 /** 62 * @return the day of week value (1-based) 63 */ 64 int getDayOfWeekNum() { 65 return dow.value(); 66 } 67 68 /** 69 * @return true if this rule day represents the last day of 70 * week. (e.g., lastSun). 71 */ 72 boolean isLast() { 73 return lastOne; 74 } 75 76 /** 77 * @return true if this rule day represents the day of week on or 78 * later than (after) the {@link #getDay}. (e.g., Sun>=1) 79 */ 80 boolean isLater() { 81 return soonerOrLater > 0; 82 } 83 84 /** 85 * @return true if this rule day represents the day of week on or 86 * earlier than (before) the {@link #getDay}. (e.g., Sun<=15) 87 */ 88 boolean isEarlier() { 89 return soonerOrLater < 0; 90 } 91 92 /** 93 * @return true if this rule day represents an exact day. 94 */ 95 boolean isExact() { 96 return soonerOrLater == 0; 97 } 98 99 /** 100 * Parses the "ON" field and constructs a RuleDay. 101 * @param day an "ON" field string (e.g., "Sun>=1") 102 * @return a RuleDay representing the given "ON" field 103 */ 104 static RuleDay parse(String day) { 105 RuleDay d = new RuleDay(); 106 if (day.startsWith("last")) { 107 d.lastOne = true; 108 d.dayName = day.substring(4); 109 d.dow = getDOW(d.dayName); 110 } else { 111 int index; 112 if ((index = day.indexOf(">=")) != -1) { 113 d.dayName = day.substring(0, index); 114 d.dow = getDOW(d.dayName); 115 d.soonerOrLater = 1; // greater or equal 116 d.thanDayOfMonth = Integer.parseInt(day.substring(index+2)); 117 } else if ((index = day.indexOf("<=")) != -1) { 118 d.dayName = day.substring(0, index); 119 d.dow = getDOW(d.dayName); 120 d.soonerOrLater = -1; // less or equal 121 d.thanDayOfMonth = Integer.parseInt(day.substring(index+2)); 122 } else { 123 // it should be an integer value. 124 d.thanDayOfMonth = Integer.parseInt(day); 125 } 126 } 127 return d; 128 } 129 130 /** 131 * Converts this RuleDay to the SimpleTimeZone day rule. 132 * @return the converted SimpleTimeZone day rule 133 */ 134 int getDayForSimpleTimeZone() { 135 if (isLast()) { 136 return -1; 137 } 138 return isEarlier() ? -getDay() : getDay(); 139 } 140 141 /** 142 * Converts this RuleDay to the SimpleTimeZone day-of-week rule. 143 * @return the SimpleTimeZone day-of-week rule value 144 */ 145 int getDayOfWeekForSimpleTimeZoneInt() { 146 if (isEarlier() || isLater()) { 147 return -getDayOfWeekNum(); 148 } 149 return isLast() ? getDayOfWeekNum() : 0; 150 } 151 152 /** 153 * @return the string representation of the {@link 154 * #getDayOfWeekForSimpleTimeZoneInt} value 155 */ 156 String getDayOfWeekForSimpleTimeZone() { 157 int d = getDayOfWeekForSimpleTimeZoneInt(); 158 if (d == 0) { 159 return "0"; 160 } 161 String sign = ""; 162 if (d < 0) { 163 sign = "-"; 164 d = -d; 165 } 166 return sign + toString(d); 167 } 168 169 private static DayOfWeek getDOW(String abbr) { 170 return abbreviations.get(abbr); 171 } 172 173 /** 174 * Converts the specified day of week value to the day-of-week 175 * name defined in {@link java.util.Calenda}. 176 * @param dow 1-based day of week value 177 * @return the Calendar day of week name with "Calendar." prefix. 178 * @throws IllegalArgumentException if the specified dow value is out of range. 179 */ 180 static String toString(int dow) { 181 if (dow >= DayOfWeek.SUNDAY.value() && dow <= DayOfWeek.SATURDAY.value()) { 182 return "Calendar." + DayOfWeek.values()[dow - 1]; 183 } 184 throw new IllegalArgumentException("wrong Day_of_Week number: " + dow); 185 } 186 }