001 /*
002 * Copyleft notice: This is public-domain software and documentation
003 * with no restrictions of any kind.
004 * Please feel free to use any of it in any way you want.
005 * This work is distributed in the hope that it will be useful,
006 * but WITHOUT ANY WARRANTY; without even the implied warranty of
007 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
008 */
009
010
011 package time;
012
013 import java.util.*;
014
015 /**
016 * Definition a day of the week.
017 *
018 * <p>Unlike month, this class is not an <tt>Enum</tt>, because <tt>DayOfWeek</tt> does not
019 * have a <i>natural order</i>. More precisely, even if everyone agrees on the
020 * order of weekdays, the first day of the week depends on the local usage.
021 *
022 * <p>This class provides also static method to have several appropriate
023 * <tt>Comparator</tt> or <tt>SortedSet</tt> where the first conventionnal day of the
024 * week has been set.
025 *
026 *
027 * @author Arnaud Roques
028 */
029 public final class DayOfWeek
030 {
031 private final static WeekDayComparator[] COMPARATOR;
032 private final static SortedSet<DayOfWeek>[] SORTED_SET;
033 private final static Map<String, DayOfWeek> valueOfMap = new HashMap<String, DayOfWeek>(7);
034
035 public static final DayOfWeek SUNDAY = new DayOfWeek(GregorianCalendar.SUNDAY, "SUNDAY");
036 public static final DayOfWeek MONDAY = new DayOfWeek(GregorianCalendar.MONDAY, "MONDAY");
037 public static final DayOfWeek TUESDAY = new DayOfWeek(GregorianCalendar.TUESDAY, "TUESDAY");
038 public static final DayOfWeek WEDNESDAY = new DayOfWeek(GregorianCalendar.WEDNESDAY, "WEDNESDAY");
039 public static final DayOfWeek THURSDAY = new DayOfWeek(GregorianCalendar.THURSDAY, "THURSDAY");
040 public static final DayOfWeek FRIDAY = new DayOfWeek(GregorianCalendar.FRIDAY, "FRIDAY");
041 public static final DayOfWeek SATURDAY = new DayOfWeek(GregorianCalendar.SATURDAY, "SATURDAY");
042
043 private final int gcValue;
044 private final String name;
045
046 static class WeekDayComparator implements Comparator<DayOfWeek>
047 {
048 private final int modulo;
049
050 WeekDayComparator(int modulo)
051 {
052 this.modulo = modulo;
053 }
054
055 public int compare(DayOfWeek d1, DayOfWeek d2)
056 {
057 return modulo(d1.gcValue) - modulo(d2.gcValue);
058 }
059
060 private int modulo(int i)
061 {
062 return (i-1-modulo+7)%7;
063 }
064 }
065
066
067 static
068 {
069 COMPARATOR = new WeekDayComparator[7];
070 for (int i=0; i<COMPARATOR.length; i++) COMPARATOR[i] = new WeekDayComparator(i);
071 SORTED_SET = new SortedSet[7];
072 List<DayOfWeek> all = Arrays.asList(SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
073 THURSDAY, FRIDAY, SATURDAY);
074 for (int i=0; i<SORTED_SET.length; i++)
075 {
076 SORTED_SET[i] = new TreeSet<DayOfWeek>(COMPARATOR[i]);
077 SORTED_SET[i].addAll(all);
078 SORTED_SET[i] = Collections.unmodifiableSortedSet(SORTED_SET[i]);
079 }
080 }
081
082 /**
083 * Return a <tt>Comparator</tt> for sorting <tt>DayOfWeek</tt>.
084 *
085 * <p>
086 * The conventionnal first week of the day must be provided,
087 * so that the <tt>Comparator</tt>
088 * can do his job.
089 *
090 * @param firstWeekDay conventionnal first day of week
091 *
092 * @return a <tt>Comparator</tt> that compare <tt>DayOfWeek</tt> objects
093 * using a precise first day of week
094 */
095 static public Comparator<DayOfWeek> specialComparator(DayOfWeek firstWeekDay)
096 {
097 return COMPARATOR[firstWeekDay.gcValue-1];
098 }
099
100 /**
101 * Return a immutable <tt>SortedSet</tt> with all seven <tt>DayOfWeek</tt>.
102 *
103 * <p>
104 * The conventionnal first week of the day must be provided.
105 *
106 * @param firstWeekDay conventionnal first day of week
107 *
108 * @return a <tt>SortedSet</tt> with all seven <tt>DayOfWeek</tt>, starting with
109 * <tt>firstWeekDay</tt>
110 */
111 static public SortedSet<DayOfWeek> specialSet(DayOfWeek firstWeekDay)
112 {
113 return SORTED_SET[firstWeekDay.gcValue-1];
114 }
115
116 private DayOfWeek(int gcValue, String name)
117 {
118 this.gcValue = gcValue;
119 this.name = name;
120 valueOfMap.put(name, this);
121 }
122
123 /**
124 * Return the <tt>java.util.Calendar</tt> integer constant corresponding to
125 * this <tt>DayWeek</tt> object.
126 *
127 * <p>
128 * This method should be use only for compatibility with <tt>java.util.Calendar</tt>.
129 *
130 * @return the <tt>java.util.Calendar</tt> integer constant corresponding to
131 * this <tt>DayWeek</tt> object.
132 */
133 public int getGcValue()
134 {
135 return gcValue;
136 }
137
138 /**
139 * Return a <tt>String</tt> describing the <tt>DayOfWeek</tt>
140 *
141 * @return a <tt>String</tt> describing the <tt>DayOfWeek</tt>
142 * @hidden
143 */
144 @Override
145 public String toString()
146 {
147 return name;
148 }
149
150 /**
151 * Returns the <tt>DayOfWeek</tt> object with the specified name.
152 *
153 * @param name the name of the weekday to be returned
154 *
155 * @return the <tt>DayOfWeek</tt> object with the specified name.
156 *
157 * @throws IllegalArgumentException if <tt>name</tt> is not a valid weekday name.
158 */
159 public static DayOfWeek valueOf(String name)
160 {
161 DayOfWeek result = valueOfMap.get(name);
162 if (result==null) throw new IllegalArgumentException();
163 return result;
164 }
165
166
167 /**
168 * Returns the <tt>DayOfWeek</tt> object with the specified <tt>java.util.Calendar</tt>
169 * integer constant.
170 *
171 * @param gc a integer from <tt>java.util.Calendar</tt> weekday constants.
172 *
173 * @return the <tt>DayOfWeek</tt> object with the specified <tt>java.util.Calendar</tt>
174 * integer constant.
175 *
176 * @throws IllegalArgumentException if <tt>gc</tt> is not a valid integer constant.
177 */
178 public static DayOfWeek fromGcValue(int gc)
179 {
180 for (DayOfWeek d : valueOfMap.values())
181 if (d.gcValue==gc) return d;
182 throw new IllegalArgumentException();
183 }
184
185 /*
186 public static void main(String arg[])
187 {
188 System.err.println(specialSet(DayOfWeek.SUNDAY));
189 System.err.println(specialSet(DayOfWeek.MONDAY));
190 System.err.println(specialSet(DayOfWeek.TUESDAY));
191 System.err.println(specialSet(DayOfWeek.WEDNESDAY));
192 System.err.println(specialSet(DayOfWeek.THURSDAY));
193 System.err.println(specialSet(DayOfWeek.FRIDAY));
194 System.err.println(specialSet(DayOfWeek.SATURDAY));
195 }*/
196
197 }
198