Code example for Calendar

Methods: get, getActualMaximum, set, setTimeInMillis

0
 
    public class OnValueChangeListener implements NumberPicker.OnValueChangeListener {
        @Override 
        public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
            updateInputState(); 
            mTempDate.setTimeInMillis(mCurrentDate.getTimeInMillis());
            boolean newBehavior = (Build.VERSION.SDK_INT > 10);
            if (newBehavior) {
                if (DEBUG) Log.d(LOGTAG, "Sdk version > 10, using new behavior");
                //The native date picker widget on these sdks increment 
                //the next field when one field reach the maximum 
                if (picker == mDaySpinner && mDayEnabled) {
                    int maxDayOfMonth = mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH);
                    int old = mTempDate.get(Calendar.DAY_OF_MONTH);
                    setTempDate(Calendar.DAY_OF_MONTH, old, newVal, 1, maxDayOfMonth);
                } else if (picker == mMonthSpinner && mMonthEnabled) {
                    int old = mTempDate.get(Calendar.MONTH);
                    setTempDate(Calendar.MONTH, old, newVal, Calendar.JANUARY, Calendar.DECEMBER);
                } else if (picker == mWeekSpinner) {
                    int old = mTempDate.get(Calendar.WEEK_OF_YEAR);
                    int maxWeekOfYear = mTempDate.getActualMaximum(Calendar.WEEK_OF_YEAR);
                    setTempDate(Calendar.WEEK_OF_YEAR, old, newVal, 0, maxWeekOfYear);
                } else if (picker == mYearSpinner && mYearEnabled) {
                    int month = mTempDate.get(Calendar.MONTH);
                    mTempDate.set(Calendar.YEAR,newVal);
                    // Changing the year shouldn't change the month. (in case of non-leap year a Feb 29) 
                    // change the day instead; 
                    if (month != mTempDate.get(Calendar.MONTH)){
                        mTempDate.set(Calendar.MONTH, month);
                        mTempDate.set(Calendar.DAY_OF_MONTH,
                        mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH));
                    } 
                } else if (picker == mHourSpinner && mHourEnabled) {
                    if (mIs12HourMode) {
                        setTempDate(Calendar.HOUR, oldVal, newVal, 1, 12);
                    } else { 
                        setTempDate(Calendar.HOUR_OF_DAY, oldVal, newVal, 0, 23);
                    } 
                } else if (picker == mMinuteSpinner && mMinuteEnabled) {
                    setTempDate(Calendar.MINUTE, oldVal, newVal, 0, 59);
                } else if (picker == mAMPMSpinner && mHourEnabled) {
                    mTempDate.set(Calendar.AM_PM,newVal);
                } else { 
                    throw new IllegalArgumentException();
                } 
            } else { 
                if (DEBUG) Log.d(LOGTAG,"Sdk version < 10, using old behavior");
                if (picker == mDaySpinner && mDayEnabled){
                    mTempDate.set(Calendar.DAY_OF_MONTH, newVal);
                } else if (picker == mMonthSpinner && mMonthEnabled){
                    mTempDate.set(Calendar.MONTH, newVal);
                    if (mTempDate.get(Calendar.MONTH) == newVal+1){
                        mTempDate.set(Calendar.MONTH, newVal);
                        mTempDate.set(Calendar.DAY_OF_MONTH,
                        mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH));
                    } 
                } else if (picker == mWeekSpinner){
                    mTempDate.set(Calendar.WEEK_OF_YEAR, newVal);
                } else if (picker == mYearSpinner && mYearEnabled){
                    int month = mTempDate.get(Calendar.MONTH);
                    mTempDate.set(Calendar.YEAR, newVal);
                    if (month != mTempDate.get(Calendar.MONTH)) {
                        mTempDate.set(Calendar.MONTH, month);
                        mTempDate.set(Calendar.DAY_OF_MONTH,
                        mTempDate.getActualMaximum(Calendar.DAY_OF_MONTH));
                    } 
                } else if (picker == mHourSpinner && mHourEnabled){
                    if (mIs12HourMode) {
                        mTempDate.set(Calendar.HOUR, newVal);
                    } else { 
                        mTempDate.set(Calendar.HOUR_OF_DAY, newVal);
                    } 
                } else if (picker == mMinuteSpinner && mMinuteEnabled){
                    mTempDate.set(Calendar.MINUTE, newVal);
                } else if (picker == mAMPMSpinner && mHourEnabled) {
                    mTempDate.set(Calendar.AM_PM, newVal);
                } else { 
                    throw new IllegalArgumentException();
                } 
            } 
            setDate(mTempDate);
            if (mDayEnabled) {
                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
            } 
            if(mWeekEnabled) {
                mWeekSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.WEEK_OF_YEAR));
            } 
            updateCalendar(); 
            updateSpinners(); 
            notifyDateChanged(); 
        } 
 
        private void setTempDate(int field, int oldVal, int newVal, int min, int max) {
            if (oldVal == max && newVal == min ) {
                mTempDate.add(field, 1);
            } else if (oldVal == min && newVal == max) {
                mTempDate.add(field, -1);
            } else { 
                mTempDate.add(field, newVal - oldVal);
            } 
        } 
    } 
 
    private static final NumberPicker.Formatter TWO_DIGIT_FORMATTER = new NumberPicker.Formatter() {
        final StringBuilder mBuilder = new StringBuilder(); 
 
        final java.util.Formatter mFmt = new java.util.Formatter(mBuilder, java.util.Locale.US); 
 
        final Object[] mArgs = new Object[1]; 
 
        @Override 
        public String format(int value) { 
            mArgs[0] = value; 
            mBuilder.delete(0, mBuilder.length()); 
            mFmt.format("%02d", mArgs); 
            return mFmt.toString(); 
        } 
    }; 
 
    private void displayPickers() { 
        setWeekShown(false); 
        set12HourShown(mIs12HourMode);
        if (mState == PickersState.DATETIME) {
            return; 
        } 
        setHourShown(false); 
        setMinuteShown(false); 
        if (mState == PickersState.WEEK) {
            setDayShown(false); 
            setMonthShown(false); 
            setWeekShown(true); 
        } else if (mState == PickersState.MONTH) {
            setDayShown(false); 
        } 
    } 
 
    public DateTimePicker(Context context) {
        this(context, "", "", PickersState.DATE);
    } 
 
    public DateTimePicker(Context context, String dateFormat, String dateTimeValue, PickersState state) {
        super(context);
        if (Build.VERSION.SDK_INT < 11) {
            throw new UnsupportedOperationException("Custom DateTimePicker is only available for SDK > 10");
        } 
        setCurrentLocale(Locale.getDefault());
        mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1);
        mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31);
        mState = state;
        LayoutInflater inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.datetime_picker, this, true);
 
        mOnChangeListener = new OnValueChangeListener();
 
        mDateSpinners = (LinearLayout)findViewById(R.id.date_spinners);
        mTimeSpinners = (LinearLayout)findViewById(R.id.time_spinners);
        mSpinners = (LinearLayout)findViewById(R.id.spinners);
        mPickers = (LinearLayout)findViewById(R.id.datetime_picker);
 
        // We will display differently according to the screen size width. 
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        display.getMetrics(dm);
        mScreenWidth = display.getWidth() / dm.densityDpi;
        mScreenHeight = display.getHeight() / dm.densityDpi;
        if (DEBUG) Log.d(LOGTAG, "screen width: " + mScreenWidth + " screen height: " + mScreenHeight);
 
        // If we're displaying a date, the screen is wide enought (and if we're using a sdk where the calendar view exists) 
        // then display a calendar. 
        if ((mState == PickersState.DATE || mState == PickersState.DATETIME) &&
            Build.VERSION.SDK_INT > 10 && mScreenWidth >= SCREEN_SIZE_THRESHOLD) {
            if (DEBUG) Log.d(LOGTAG,"SDK > 10 and screen wide enough, displaying calendar");
            mCalendar = new CalendarView(context);
            mCalendar.setVisibility(GONE);
 
            LayoutParams layoutParams = new LayoutParams(250,280);
            mCalendar.setLayoutParams(layoutParams);
            mCalendar.setFocusable(true);
            mCalendar.setFocusableInTouchMode(true);
            mCalendar.setMaxDate(mMaxDate.getTimeInMillis());
            mCalendar.setMinDate(mMinDate.getTimeInMillis());
 
            mCalendar.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
                @Override 
                public void onSelectedDayChange( 
                    CalendarView view, int year, int month, int monthDay) {
                    mTempDate.set(year, month, monthDay);
                    setDate(mTempDate);
                    notifyDateChanged(); 
                } 
            }); 
 
            mPickers.addView(mCalendar);
        } else { 
          // If the screen is more wide than high, we are displaying daye and time spinners, 
          // and if there is no calendar displayed, 
          // we should display the fields in one row. 
            if (mScreenWidth > mScreenHeight && mState == PickersState.DATETIME) {
                mSpinners.setOrientation(LinearLayout.HORIZONTAL);
            } 
            mCalendar = null;
        } 
 
        // Find the initial date from the constructor arguments. 
        try { 
            if (!dateTimeValue.equals("")) {
                mTempDate.setTime(new SimpleDateFormat(dateFormat).parse(dateTimeValue));
            } else { 
                mTempDate.setTimeInMillis(System.currentTimeMillis());
            } 
        } catch (Exception ex) {
            Log.e(LOGTAG, "Error parsing format string: " + ex);
            mTempDate.setTimeInMillis(System.currentTimeMillis());
        } 
 
        // Initialize all spinners. 
        mDaySpinner = setupSpinner(R.id.day, 1,
                                   mTempDate.get(Calendar.DAY_OF_MONTH));
        mDaySpinner.setFormatter(TWO_DIGIT_FORMATTER);
        mDaySpinnerInput = (EditText) mDaySpinner.getChildAt(1);
 
        mMonthSpinner = setupSpinner(R.id.month, 1,
                                     mTempDate.get(Calendar.MONTH));
        mMonthSpinner.setFormatter(TWO_DIGIT_FORMATTER);
        mMonthSpinner.setDisplayedValues(mShortMonths);
        mMonthSpinnerInput = (EditText) mMonthSpinner.getChildAt(1);
 
        mWeekSpinner = setupSpinner(R.id.week, 1,
                                    mTempDate.get(Calendar.WEEK_OF_YEAR));
        mWeekSpinner.setFormatter(TWO_DIGIT_FORMATTER);
        mWeekSpinnerInput = (EditText) mWeekSpinner.getChildAt(1);
 
        mYearSpinner = setupSpinner(R.id.year, DEFAULT_START_YEAR,
                                    DEFAULT_END_YEAR);
        mYearSpinnerInput = (EditText) mYearSpinner.getChildAt(1);
 
        mAMPMSpinner = setupSpinner(R.id.ampm, 0, 1);
        mAMPMSpinner.setFormatter(TWO_DIGIT_FORMATTER);
 
        if (mIs12HourMode) {
            mHourSpinner = setupSpinner(R.id.hour, 1, 12);
            mAMPMSpinnerInput = (EditText) mAMPMSpinner.getChildAt(1);
            mAMPMSpinner.setDisplayedValues(mShortAMPMs); 
        } else { 
            mHourSpinner = setupSpinner(R.id.hour, 0, 23);
            mAMPMSpinnerInput = null;
        } 
 
        mHourSpinner.setFormatter(TWO_DIGIT_FORMATTER);
        mHourSpinnerInput = (EditText) mHourSpinner.getChildAt(1);
 
        mMinuteSpinner = setupSpinner(R.id.minute, 0, 59);
        mMinuteSpinner.setFormatter(TWO_DIGIT_FORMATTER);
        mMinuteSpinnerInput = (EditText) mMinuteSpinner.getChildAt(1);
 
        // The order in which the spinners are displayed are locale-dependent 
        reorderDateSpinners(); 
        // Set the date to the initial date. Since this date can come from the user, 
        // it can fire an exception (out-of-bound date) 
        try { 
          updateDate(mTempDate);
        } catch (Exception ex) { }
 
        // Display only the pickers needed for the current state. 
        displayPickers(); 
    } 
 
    public NumberPicker setupSpinner(int id, int min, int max) {
        NumberPicker mSpinner = (NumberPicker) findViewById(id);
        mSpinner.setMinValue(min);
        mSpinner.setMaxValue(max);
        mSpinner.setOnValueChangedListener(mOnChangeListener);
        mSpinner.setOnLongPressUpdateInterval(100);
        return mSpinner;
    } 
 
    public long getTimeInMillis(){ 
        return mCurrentDate.getTimeInMillis();
    } 
 
    private void reorderDateSpinners() { 
        mDateSpinners.removeAllViews();
        char[] order = DateFormat.getDateFormatOrder(getContext());
        final int spinnerCount = order.length;
        for (int i = 0; i < spinnerCount; i++) {
            switch (order[i]) {
                case DateFormat.DATE:
                    mDateSpinners.addView(mDaySpinner);
                    break; 
                case DateFormat.MONTH:
                    mDateSpinners.addView(mMonthSpinner);
                    break; 
                case DateFormat.YEAR:
                    mDateSpinners.addView(mYearSpinner);
                    break; 
                default: 
                    throw new IllegalArgumentException();
            } 
        } 
        mDateSpinners.addView(mWeekSpinner);
    } 
 
    private void setDate(Calendar calendar){
        mCurrentDate = mTempDate;
        if (mCurrentDate.before(mMinDate)) {
            mCurrentDate.setTimeInMillis(mMinDate.getTimeInMillis());
        } else if (mCurrentDate.after(mMaxDate)) {
            mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());
        } 
    } 
 
    private void updateInputState() { 
        InputMethodManager inputMethodManager = (InputMethodManager)
          getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (mYearEnabled && inputMethodManager.isActive(mYearSpinnerInput)) {
            mYearSpinnerInput.clearFocus();
            inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
        } else if (mMonthEnabled && inputMethodManager.isActive(mMonthSpinnerInput)) {
            mMonthSpinnerInput.clearFocus();
            inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
        } else if (mDayEnabled && inputMethodManager.isActive(mDaySpinnerInput)) {
            mDaySpinnerInput.clearFocus();
            inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
        } else if (mHourEnabled && inputMethodManager.isActive(mHourSpinnerInput)) {
            mHourSpinnerInput.clearFocus();
            inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
        } else if (mMinuteEnabled && inputMethodManager.isActive(mMinuteSpinnerInput)) {
            mMinuteSpinnerInput.clearFocus();
            inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
        } 
    } 
 
    private void updateSpinners() { 
        if (mDayEnabled) {
            if (mCurrentDate.equals(mMinDate)) {
                mDaySpinner.setMinValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
            } else if (mCurrentDate.equals(mMaxDate)) {
                mDaySpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.DAY_OF_MONTH));
                mDaySpinner.setMaxValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
            } else { 
                mDaySpinner.setMinValue(1);
                mDaySpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.DAY_OF_MONTH));
            } 
            mDaySpinner.setValue(mCurrentDate.get(Calendar.DAY_OF_MONTH));
        } 
 
        if (mWeekEnabled) {
            mWeekSpinner.setMinValue(1);
            mWeekSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.WEEK_OF_YEAR));
            mWeekSpinner.setValue(mCurrentDate.get(Calendar.WEEK_OF_YEAR));
        } 
 
        if (mMonthEnabled) {
            mMonthSpinner.setDisplayedValues(null);
            if (mCurrentDate.equals(mMinDate)) {
                mMonthSpinner.setMinValue(mCurrentDate.get(Calendar.MONTH));
                mMonthSpinner.setMaxValue(mCurrentDate.getActualMaximum(Calendar.MONTH));
            } else if (mCurrentDate.equals(mMaxDate)) {
                mMonthSpinner.setMinValue(mCurrentDate.getActualMinimum(Calendar.MONTH));
                mMonthSpinner.setMaxValue(mCurrentDate.get(Calendar.MONTH));
            } else { 
                mMonthSpinner.setMinValue(Calendar.JANUARY);
                mMonthSpinner.setMaxValue(Calendar.DECEMBER);
            } 
 
            String[] displayedValues = Arrays.copyOfRange(mShortMonths,
                    mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);
            mMonthSpinner.setDisplayedValues(displayedValues);
            mMonthSpinner.setValue(mCurrentDate.get(Calendar.MONTH));
        } 
 
        if (mYearEnabled) {
            mYearSpinner.setMinValue(mMinDate.get(Calendar.YEAR));
            mYearSpinner.setMaxValue(mMaxDate.get(Calendar.YEAR));