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 @android.ravenwood.annotation.RavenwoodKeepWholeClass 28 public class MonthDisplayHelper { 29 30 // display pref 31 private final int mWeekStartDay; 32 33 // holds current month, year, helps compute display 34 private Calendar mCalendar; 35 36 // cached computed stuff that helps with display 37 private int mNumDaysInMonth; 38 private int mNumDaysInPrevMonth; 39 private int mOffset; 40 41 42 /** 43 * @param year The year. 44 * @param month The month. 45 * @param weekStartDay What day of the week the week should start. 46 */ MonthDisplayHelper(int year, int month, int weekStartDay)47 public MonthDisplayHelper(int year, int month, int weekStartDay) { 48 49 if (weekStartDay < Calendar.SUNDAY || weekStartDay > Calendar.SATURDAY) { 50 throw new IllegalArgumentException(); 51 } 52 mWeekStartDay = weekStartDay; 53 54 mCalendar = Calendar.getInstance(); 55 mCalendar.set(Calendar.YEAR, year); 56 mCalendar.set(Calendar.MONTH, month); 57 mCalendar.set(Calendar.DAY_OF_MONTH, 1); 58 mCalendar.set(Calendar.HOUR_OF_DAY, 0); 59 mCalendar.set(Calendar.MINUTE, 0); 60 mCalendar.set(Calendar.SECOND, 0); 61 mCalendar.getTimeInMillis(); 62 63 recalculate(); 64 } 65 66 MonthDisplayHelper(int year, int month)67 public MonthDisplayHelper(int year, int month) { 68 this(year, month, Calendar.SUNDAY); 69 } 70 71 getYear()72 public int getYear() { 73 return mCalendar.get(Calendar.YEAR); 74 } 75 getMonth()76 public int getMonth() { 77 return mCalendar.get(Calendar.MONTH); 78 } 79 80 getWeekStartDay()81 public int getWeekStartDay() { 82 return mWeekStartDay; 83 } 84 85 /** 86 * @return The first day of the month using a constants such as 87 * {@link java.util.Calendar#SUNDAY}. 88 */ getFirstDayOfMonth()89 public int getFirstDayOfMonth() { 90 return mCalendar.get(Calendar.DAY_OF_WEEK); 91 } 92 93 /** 94 * @return The number of days in the month. 95 */ getNumberOfDaysInMonth()96 public int getNumberOfDaysInMonth() { 97 return mNumDaysInMonth; 98 } 99 100 101 /** 102 * @return The offset from displaying everything starting on the very first 103 * box. For example, if the calendar is set to display the first day of 104 * the week as Sunday, and the month starts on a Wednesday, the offset is 3. 105 */ getOffset()106 public int getOffset() { 107 return mOffset; 108 } 109 110 111 /** 112 * @param row Which row (0-5). 113 * @return the digits of the month to display in one 114 * of the 6 rows of a calendar month display. 115 */ getDigitsForRow(int row)116 public int[] getDigitsForRow(int row) { 117 if (row < 0 || row > 5) { 118 throw new IllegalArgumentException("row " + row 119 + " out of range (0-5)"); 120 } 121 122 int [] result = new int[7]; 123 for (int column = 0; column < 7; column++) { 124 result[column] = getDayAt(row, column); 125 } 126 127 return result; 128 } 129 130 /** 131 * @param row The row, 0-5, starting from the top. 132 * @param column The column, 0-6, starting from the left. 133 * @return The day at a particular row, column 134 */ getDayAt(int row, int column)135 public int getDayAt(int row, int column) { 136 137 if (row == 0 && column < mOffset) { 138 return mNumDaysInPrevMonth + column - mOffset + 1; 139 } 140 141 int day = 7 * row + column - mOffset + 1; 142 143 return (day > mNumDaysInMonth) ? 144 day - mNumDaysInMonth : day; 145 } 146 147 /** 148 * @return Which row day is in. 149 */ getRowOf(int day)150 public int getRowOf(int day) { 151 return (day + mOffset - 1) / 7; 152 } 153 154 /** 155 * @return Which column day is in. 156 */ getColumnOf(int day)157 public int getColumnOf(int day) { 158 return (day + mOffset - 1) % 7; 159 } 160 161 /** 162 * Decrement the month. 163 */ previousMonth()164 public void previousMonth() { 165 mCalendar.add(Calendar.MONTH, -1); 166 recalculate(); 167 } 168 169 /** 170 * Increment the month. 171 */ nextMonth()172 public void nextMonth() { 173 mCalendar.add(Calendar.MONTH, 1); 174 recalculate(); 175 } 176 177 /** 178 * @return Whether the row and column fall within the month. 179 */ isWithinCurrentMonth(int row, int column)180 public boolean isWithinCurrentMonth(int row, int column) { 181 182 if (row < 0 || column < 0 || row > 5 || column > 6) { 183 return false; 184 } 185 186 if (row == 0 && column < mOffset) { 187 return false; 188 } 189 190 int day = 7 * row + column - mOffset + 1; 191 if (day > mNumDaysInMonth) { 192 return false; 193 } 194 return true; 195 } 196 197 198 // helper method that recalculates cached values based on current month / year recalculate()199 private void recalculate() { 200 201 mNumDaysInMonth = mCalendar.getActualMaximum(Calendar.DAY_OF_MONTH); 202 203 mCalendar.add(Calendar.MONTH, -1); 204 mNumDaysInPrevMonth = mCalendar.getActualMaximum(Calendar.DAY_OF_MONTH); 205 mCalendar.add(Calendar.MONTH, 1); 206 207 int firstDayOfMonth = getFirstDayOfMonth(); 208 int offset = firstDayOfMonth - mWeekStartDay; 209 if (offset < 0) { 210 offset += 7; 211 } 212 mOffset = offset; 213 } 214 } 215