1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file. 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccipackage org.chromium.ui.picker; 6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 7eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochimport android.content.Context; 8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciimport org.chromium.ui.R; 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)import java.util.Calendar; 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)import java.util.TimeZone; 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// This class is heavily based on android.widget.DatePicker. 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochpublic class WeekPicker extends TwoFieldDatePicker { 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public WeekPicker(Context context, double minValue, double maxValue) { 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch super(context, minValue, maxValue); 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch getPositionInYearSpinner().setContentDescription( 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch getResources().getString(R.string.accessibility_date_picker_week)); 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // initialize to current date 24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cal.setFirstDayOfWeek(Calendar.MONDAY); 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cal.setMinimalDaysInFirstWeek(4); 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch cal.setTimeInMillis(System.currentTimeMillis()); 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch init(getISOWeekYearForDate(cal), getWeekForDate(cal), null); 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) /** 32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * Creates a date object from the |year| and |week|. 33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */ 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public static Calendar createDateFromWeek(int year, int week) { 35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Calendar date = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch date.clear(); 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch date.setFirstDayOfWeek(Calendar.MONDAY); 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch date.setMinimalDaysInFirstWeek(4); 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch date.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch date.set(Calendar.YEAR, year); 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch date.set(Calendar.WEEK_OF_YEAR, week); 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return date; 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) /** 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * Creates a date object from the |value| which is milliseconds since epoch. 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */ 48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public static Calendar createDateFromValue(double value) { 49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) Calendar date = Calendar.getInstance(TimeZone.getTimeZone("UTC")); 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch date.clear(); 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch date.setFirstDayOfWeek(Calendar.MONDAY); 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch date.setMinimalDaysInFirstWeek(4); 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) date.setTimeInMillis((long) value); 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return date; 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) @Override 58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) protected Calendar getDateForValue(double value) { 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return WeekPicker.createDateFromValue(value); 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public static int getISOWeekYearForDate(Calendar date) { 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int year = date.get(Calendar.YEAR); 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int month = date.get(Calendar.MONTH); 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int week = date.get(Calendar.WEEK_OF_YEAR); 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (month == 0 && week > 51) { 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch year--; 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (month == 11 && week == 1) { 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch year++; 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return year; 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public static int getWeekForDate(Calendar date) { 75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return date.get(Calendar.WEEK_OF_YEAR); 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch @Override 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protected void setCurrentDate(int year, int week) { 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch Calendar date = createDateFromWeek(year, week); 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (date.before(getMinDate())) { 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch setCurrentDate(getMinDate()); 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (date.after(getMaxDate())) { 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch setCurrentDate(getMaxDate()); 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch setCurrentDate(date); 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private int getNumberOfWeeks(int year) { 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Create a date in the middle of the year, where the week year matches the year. 9258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) Calendar date = createDateFromWeek(year, 20); 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return date.getActualMaximum(Calendar.WEEK_OF_YEAR); 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /** 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * @return The selected year. 98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch @Override 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public int getYear() { 101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return getISOWeekYearForDate(getCurrentDate()); 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /** 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * @return The selected week. 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public int getWeek() { 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return getWeekForDate(getCurrentDate()); 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch @Override 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public int getPositionInYear() { 113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return getWeek(); 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch @Override 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protected int getMaxYear() { 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return getISOWeekYearForDate(getMaxDate()); 119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch @Override 122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protected int getMinYear() { 123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return getISOWeekYearForDate(getMinDate()); 124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch @Override 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) protected int getMaxPositionInYear(int year) { 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (year == getISOWeekYearForDate(getMaxDate())) { 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return getWeekForDate(getMaxDate()); 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return getNumberOfWeeks(year); 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch @Override 13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) protected int getMinPositionInYear(int year) { 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (year == getISOWeekYearForDate(getMinDate())) { 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return getWeekForDate(getMinDate()); 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 1; 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 142