165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/* 265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project 365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License"); 565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License. 665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at 765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * http://www.apache.org/licenses/LICENSE-2.0 965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software 1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS, 1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and 1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License. 1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.widget.picker; 1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Bundle; 2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.view.View; 2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.ArrayList; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.Calendar; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.Date; 2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.GregorianCalendar; 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.widget.TextView; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepublic class DatePicker extends Picker { 2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 3065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_START_YEAR = "start_year"; 3165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_YEAR_RANGE = "year_range"; 3265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_DEFAULT_TO_CURRENT = "default_to_current"; 3365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_FORMAT = "date_format"; 3465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int DEFAULT_YEAR_RANGE = 24; 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int DEFAULT_START_YEAR = Calendar.getInstance().get(Calendar.YEAR); 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String[] mYears; 3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mStartYear; 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mYearRange; 3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String[] mDayString = null; 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mColMonthIndex = 0; 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mColDayIndex = 1; 4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mColYearIndex = 2; 4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private boolean mPendingDate = false; 4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mInitYear; 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mInitMonth; 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mInitDay; 4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private int mSelectedYear = DEFAULT_START_YEAR; 5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String mSelectedMonth; 5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static DatePicker newInstance() { 5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return newInstance(""); 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Creates a new instance of DatePicker 5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param format String containing a permutation of Y, M and D, indicating the order 6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * of the fields Year, Month and Day to be displayed in the DatePicker. 6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static DatePicker newInstance(String format) { 6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return newInstance(format, DEFAULT_START_YEAR); 6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Creates a new instance of DatePicker 6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param format String containing a permutation of Y, M and D, indicating the order 7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * of the fields Year, Month and Day to be displayed in the DatePicker. 7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param startYear The lowest number to be displayed in the Year selector. 7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static DatePicker newInstance(String format, int startYear) { 7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return newInstance(format, startYear, DEFAULT_YEAR_RANGE, true); 7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Creates a new instance of DatePicker 8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param format String containing a permutation of Y, M and D, indicating the order 8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * of the fields Year, Month and Day to be displayed in the DatePicker. 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param startYear The lowest number to be displayed in the Year selector. 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param yearRange Number of entries to be displayed in the Year selector. 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param startOnToday Indicates if the date should be set to the current date by default. 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public static DatePicker newInstance(String format, int startYear, int yearRange, 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean startOnToday) { 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane DatePicker datePicker = new DatePicker(); 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (startYear <= 0) { 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throw new IllegalArgumentException("The start year must be > 0. Got " + startYear); 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (yearRange <= 0) { 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane throw new IllegalArgumentException("The year range must be > 0. Got " + yearRange); 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle args = new Bundle(); 9765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putString(EXTRA_FORMAT, format); 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putInt(EXTRA_START_YEAR, startYear); 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putInt(EXTRA_YEAR_RANGE, yearRange); 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane args.putBoolean(EXTRA_DEFAULT_TO_CURRENT, startOnToday); 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane datePicker.setArguments(args); 10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return datePicker; 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void initYearsArray(int startYear, int yearRange) { 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mYears = new String[yearRange]; 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int i = 0; i < yearRange; i++) { 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mYears[i] = String.valueOf(startYear + i); 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onCreate(Bundle savedInstanceState) { 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onCreate(savedInstanceState); 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mStartYear = getArguments().getInt(EXTRA_START_YEAR, DEFAULT_START_YEAR); 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mYearRange = getArguments().getInt(EXTRA_YEAR_RANGE, DEFAULT_YEAR_RANGE); 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean startOnToday = getArguments().getBoolean(EXTRA_DEFAULT_TO_CURRENT, false); 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSelectedMonth = mConstant.months[0]; 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane initYearsArray(mStartYear, mYearRange); 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mDayString = mConstant.days30; 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String format = getArguments().getString(EXTRA_FORMAT); 12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (format != null && !format.isEmpty()) { 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane format = format.toUpperCase(); 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int yIndex = format.indexOf('Y'); 12865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int mIndex = format.indexOf('M'); 12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int dIndex = format.indexOf('D'); 13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (yIndex < 0 || mIndex < 0 || dIndex < 0 || yIndex > 2 || mIndex > 2 || dIndex > 2) { 13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Badly formatted input. Use default order. 13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mColMonthIndex = 0; 13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mColDayIndex = 1; 13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mColYearIndex = 2; 13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mColMonthIndex = mIndex; 13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mColDayIndex = dIndex; 13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mColYearIndex = yIndex; 13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (startOnToday) { 14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mPendingDate = true; 14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Calendar cal = Calendar.getInstance(); 14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mInitYear = cal.get(Calendar.YEAR); 14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mInitMonth = cal.get(Calendar.MONTH); 14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mInitDay = cal.get(Calendar.DATE); 14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 15165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 15265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onResume() { 15365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mPendingDate) { 15465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mPendingDate = false; 15565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane setDate(mInitYear, mInitMonth, mInitDay); 15665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane super.onResume(); 15865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected ArrayList<PickerColumn> getColumns() { 16265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayList<PickerColumn> ret = new ArrayList<PickerColumn>(); 16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // TODO orders of these columns might need to be localized 16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane PickerColumn months = new PickerColumn(mConstant.months); 16565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane PickerColumn days = new PickerColumn(mDayString); 16665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane PickerColumn years = new PickerColumn(mYears); 16765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int i = 0; i < 3; i++) { 16965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (i == mColYearIndex) { 17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ret.add(years); 17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (i == mColMonthIndex) { 17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ret.add(months); 17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (i == mColDayIndex) { 17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ret.add(days); 17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 17665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 17765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return ret; 17965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 18265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected String getSeparator() { 18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return mConstant.dateSeparator; 18465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane protected boolean setDate(int year, int month, int day) { 18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean isLeapYear = false; 18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (year < mStartYear || year > (mStartYear + mYearRange)) { 19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return false; 19165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Test to see if this is a valid date 19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane try { 19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane GregorianCalendar cal = new GregorianCalendar(year, month, day); 19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane cal.setLenient(false); 19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Date test = cal.getTime(); 19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } catch (IllegalArgumentException e) { 19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return false; 20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSelectedYear = year; 20365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSelectedMonth = mConstant.months[month]; 20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane updateSelection(mColYearIndex, year - mStartYear); 20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane updateSelection(mColMonthIndex, month); 20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] dayString = null; 20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // This is according to http://en.wikipedia.org/wiki/Leap_year#Algorithm 21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (year % 400 == 0) { 21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane isLeapYear = true; 21265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (year % 100 == 0) { 21365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane isLeapYear = false; 21465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (year % 4 == 0) { 21565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane isLeapYear = true; 21665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (month == 1) { 21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (isLeapYear) { 22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dayString = mConstant.days29; 22165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 22265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dayString = mConstant.days28; 22365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 22465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if ((month == 3) || (month == 5) || (month == 8) || (month == 10)) { 22565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dayString = mConstant.days30; 22665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 22765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dayString = mConstant.days31; 22865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 22965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 23065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mDayString != dayString) { 23165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mDayString = dayString; 23265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane updateAdapter(mColDayIndex, new PickerColumn(mDayString)); 23365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 23465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 23565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane updateSelection(mColDayIndex, day - 1); 23665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return true; 23765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 23865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 23965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 24065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onScroll(View v) { 24165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane int column = (Integer) v.getTag(); 24265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String text = ((TextView) v).getText().toString(); 24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (column == mColMonthIndex) { 24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSelectedMonth = text; 24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (column == mColYearIndex) { 24665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mSelectedYear = Integer.parseInt(text); 24765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 24865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return; 24965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 25165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] dayString = null; 25265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 25365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean isLeapYear = false; 25465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // This is according to http://en.wikipedia.org/wiki/Leap_year#Algorithm 25565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mSelectedYear % 400 == 0) { 25665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane isLeapYear = true; 25765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (mSelectedYear % 100 == 0) { 25865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane isLeapYear = false; 25965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (mSelectedYear % 4 == 0) { 26065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane isLeapYear = true; 26165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mSelectedMonth.equals(mConstant.months[1])) { 26365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (isLeapYear) { 26465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dayString = mConstant.days29; 26565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 26665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dayString = mConstant.days28; 26765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (mSelectedMonth.equals(mConstant.months[3]) 26965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane || mSelectedMonth.equals(mConstant.months[5]) 27065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane || mSelectedMonth.equals(mConstant.months[8]) 27165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane || mSelectedMonth.equals(mConstant.months[10])) { 27265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dayString = mConstant.days30; 27365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 27465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane dayString = mConstant.days31; 27565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 27665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (!mDayString.equals(dayString)) { 27765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mDayString = dayString; 27865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane updateAdapter(mColDayIndex, new PickerColumn(mDayString)); 27965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 28065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 28165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 282