1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.util; 18 19 import java.util.Calendar; 20 21 /** 22 * Helps answer common questions that come up when displaying a month in a 23 * 6 row calendar grid format. 24 * 25 * Not thread safe. 26 */ 27 public class MonthDisplayHelper { 28 29 // display pref 30 private final int mWeekStartDay; 31 32 // holds current month, year, helps compute display 33 private Calendar mCalendar; 34 35 // cached computed stuff that helps with display 36 private int mNumDaysInMonth; 37 private int mNumDaysInPrevMonth; 38 private int mOffset; 39 40 41 /** 42 * @param year The year. 43 * @param month The month. 44 * @param weekStartDay What day of the week the week should start. 45 */ 46 public MonthDisplayHelper(int year, int month, int weekStartDay) { 47 48 if (weekStartDay < Calendar.SUNDAY || weekStartDay > Calendar.SATURDAY) { 49 throw new IllegalArgumentException(); 50 } 51 mWeekStartDay = weekStartDay; 52 53 mCalendar = Calendar.getInstance(); 54 mCalendar.set(Calendar.YEAR, year); 55 mCalendar.set(Calendar.MONTH, month); 56 mCalendar.set(Calendar.DAY_OF_MONTH, 1); 57 mCalendar.set(Calendar.HOUR_OF_DAY, 0); 58 mCalendar.set(Calendar.MINUTE, 0); 59 mCalendar.set(Calendar.SECOND, 0); 60 mCalendar.getTimeInMillis(); 61 62 recalculate(); 63 } 64 65 66 public MonthDisplayHelper(int year, int month) { 67 this(year, month, Calendar.SUNDAY); 68 } 69 70 71 public int getYear() { 72 return mCalendar.get(Calendar.YEAR); 73 } 74 75 public int getMonth() { 76 return mCalendar.get(Calendar.MONTH); 77 } 78 79 80 public int getWeekStartDay() { 81 return mWeekStartDay; 82 } 83 84 /** 85 * @return The first day of the month using a constants such as 86 * {@link java.util.Calendar#SUNDAY}. 87 */ 88 public int getFirstDayOfMonth() { 89 return mCalendar.get(Calendar.DAY_OF_WEEK); 90 } 91 92 /** 93 * @return The number of days in the month. 94 */ 95 public int getNumberOfDaysInMonth() { 96 return mNumDaysInMonth; 97 } 98 99 100 /** 101 * @return The offset from displaying everything starting on the very first 102 * box. For example, if the calendar is set to display the first day of 103 * the week as Sunday, and the month starts on a Wednesday, the offset is 3. 104 */ 105 public int getOffset() { 106 return mOffset; 107 } 108 109 110 /** 111 * @param row Which row (0-5). 112 * @return the digits of the month to display in one 113 * of the 6 rows of a calendar month display. 114 */ 115 public int[] getDigitsForRow(int row) { 116 if (row < 0 || row > 5) { 117 throw new IllegalArgumentException("row " + row 118 + " out of range (0-5)"); 119 } 120 121 int [] result = new int[7]; 122 for (int column = 0; column < 7; column++) { 123 result[column] = getDayAt(row, column); 124 } 125 126 return result; 127 } 128 129 /** 130 * @param row The row, 0-5, starting from the top. 131 * @param column The column, 0-6, starting from the left. 132 * @return The day at a particular row, column 133 */ 134 public int getDayAt(int row, int column) { 135 136 if (row == 0 && column < mOffset) { 137 return mNumDaysInPrevMonth + column - mOffset + 1; 138 } 139 140 int day = 7 * row + column - mOffset + 1; 141 142 return (day > mNumDaysInMonth) ? 143 day - mNumDaysInMonth : day; 144 } 145 146 /** 147 * @return Which row day is in. 148 */ 149 public int getRowOf(int day) { 150 return (day + mOffset - 1) / 7; 151 } 152 153 /** 154 * @return Which column day is in. 155 */ 156 public int getColumnOf(int day) { 157 return (day + mOffset - 1) % 7; 158 } 159 160 /** 161 * Decrement the month. 162 */ 163 public void previousMonth() { 164 mCalendar.add(Calendar.MONTH, -1); 165 recalculate(); 166 } 167 168 /** 169 * Increment the month. 170 */ 171 public void nextMonth() { 172 mCalendar.add(Calendar.MONTH, 1); 173 recalculate(); 174 } 175 176 /** 177 * @return Whether the row and column fall within the month. 178 */ 179 public boolean isWithinCurrentMonth(int row, int column) { 180 181 if (row < 0 || column < 0 || row > 5 || column > 6) { 182 return false; 183 } 184 185 if (row == 0 && column < mOffset) { 186 return false; 187 } 188 189 int day = 7 * row + column - mOffset + 1; 190 if (day > mNumDaysInMonth) { 191 return false; 192 } 193 return true; 194 } 195 196 197 // helper method that recalculates cached values based on current month / year 198 private void recalculate() { 199 200 mNumDaysInMonth = mCalendar.getActualMaximum(Calendar.DAY_OF_MONTH); 201 202 mCalendar.add(Calendar.MONTH, -1); 203 mNumDaysInPrevMonth = mCalendar.getActualMaximum(Calendar.DAY_OF_MONTH); 204 mCalendar.add(Calendar.MONTH, 1); 205 206 int firstDayOfMonth = getFirstDayOfMonth(); 207 int offset = firstDayOfMonth - mWeekStartDay; 208 if (offset < 0) { 209 offset += 7; 210 } 211 mOffset = offset; 212 } 213 } 214