Home | History | Annotate | Download | only in util
      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