2009-07-29 7 views
2

Я хочу сделать вид календаря, чтобы поддерживать сенсорное взаимодействие. Итак, я хотел бы создать новый пользовательский вид календаря. Я попытался сделать функцию отображения между смещением вида и значением реальной даты.Android java.util.Calendar - Разница во времени

вот моя идея: Если я могу вычислить количество недель с базы (в моем случае, 1989-12-31), , то легко узнать смещение. HEIGHT_FOR_WEEK * NUM_OF_WEEK - очень простое вычисление , чтобы узнать точное смещение.

Моя проблема заключается в следующем: Сначала я получил значение в миллисекундах от базовой даты. И я установил миллисекунды для другого объекта календаря. Я ожидал такую ​​же дату с этого объекта. Но на самом деле была другая дата.

mBaseDateInMillis = mBaseDate.getTimeInMillis(); 
mAnotherDate.setTimeInMillis(mBaseDateInMillis); 
/* I expect mBaseDate == mAnotherDate. 
* but it was different. 
*/ 

Вот мой код:

public class CalendarCoordinate { 
    public static final long ONEWEEK_IN_MILLISECONDS = 60 * 60 * 24 * 7 * 1000; 
    public Calendar mBaseDate = new GregorianCalendar(TimeZone.getTimeZone("GMT")); 
    public long mBaseDateInMillis = 0; 
    public Calendar mDate = new GregorianCalendar(TimeZone.getTimeZone("GMT")); 
    public int mWeekHeight = 30; 

    /** 
    * CTOR 
    */ 
    public CalendarCoordinate() { 
     /* Base date is 1989-12-31 0, 0, 0 
     * It was Sunday and offset 0 will be mapped onto this day. 
     */ 
     mBaseDate.set(Calendar.MILLISECOND, 0); 
     mBaseDate.set(1989, 12, 31, 0, 0, 0); 
     mBaseDateInMillis = mBaseDate.getTimeInMillis(); 
     Log.v(TAG, "BaseDate:" + mBaseDate.toString()); 
    } 

    /** 
    * Compute DATE from Y-Offset 
    * @param yOffset 
    * @return 
    */ 
    public Calendar dateFromYOffset(int yOffset) { 
     long nthWeeks = yOffset/mWeekHeight; 
     long millsSinceBaseDate = nthWeeks * ONEWEEK_IN_MILLISECONDS; 
     mDate.clear(); 
     mDate.set(Calendar.MILLISECOND, 0); 
     mDate.setTimeInMillis(mBaseDateInMillis + millsSinceBaseDate); 

     /* We SHOULD call to update mDate internal data structure. 
     * Java is really strange for this thing 
     **/ 
     mDate.getTimeInMillis(); 
     return mDate; 
    } 

    /** 
    * Compute Y-Offset from DATE 
    * @param date 
    * @return 
    */ 
    public long yOffsetFromDate(Calendar cal) { 
     long mills = cal.getTimeInMillis(); 
     long nthWeeks = (mills - mBaseDateInMillis)/ONEWEEK_IN_MILLISECONDS; 
     return nthWeeks * mWeekHeight; 
    } 
} 

Кто-нибудь может мне помочь? Я не хороший программист на Java.

ответ

5

Это заявление меня смущает:

/* I expect mBaseDate == mAnotherDate. 
* but it was different. 
*/ 

ли вы на самом деле пытаетесь проверить равенство, делая сравнение: если (mBaseDate == mAnotherDate) {System.out.println ("Они же"); }

Если да, то проблема заключается в том, что вы неправильно понимаете, как работает оператор «==» на Java. Он сравнивает ссылки, а не сравнивает базовые данные объекта, и поскольку это разные объекты (с одинаковыми значениями), которые всегда будут ложными. Для получения более подробной информации см. Java Notes on comparison operators.

Кроме того, эти линии выглядят очень подозрительно ко мне:

/* We SHOULD call to update mDate internal data structure. 
* Java is really strange for this thing 
**/ 
mDate.getTimeInMillis(); 

Я бы очень удивлен, если Android была ошибка, требующий, чтобы вы это сделать, но я предполагаю, что все возможно. Какие проблемы у вас есть без этого звонка?

3

Это потому, что вам нужно использовать метод «equals» для сравнения разных объектов. Использование оператора «==» скажет вам, идентичны ли объекты (они находятся в том же месте памяти), в то время как функция сравнения «равно» скажет вам, являются ли эти два объекта логически эквивалентными.

0

Т.Л., д-р

long weeks = ChronoUnit.WEEKS.between (LocalDate.of (1989 , 12 , 31) , LocalDate.of (1990 , 1 , 14)); // Results: 2 

Избегайте отсчет из-эпох

Не работать в эпохе отсчет с момента, такие как миллисекунды. Сбивает с толку, маскирует ошибки и игнорирует такие проблемы, как часовые пояса.

Позвольте хорошей библиотеке времени провести тяжелый подъем в этих расчетах.

java.time

Вы используете хлопотно старые классы даты и времени, такие как java.util.Calendar. Эти плохо разработанные классы были вытеснены картой java.time, встроенной в Java 8 и более поздние версии. См. Oracle Tutorial. Большая часть java.временная функциональность была перенесена на Java 6 & 7 в ThreeTen-Backport и далее адаптирована для Android в ThreeTenABP.

ChronoUnit

ChronoUnit класса вычисляет время, прошедшее такие как количество целых недель между парой LocalDate (дата-только, без времени в день, ни временной зоне) значений.

LocalDate start = LocalDate.of (2016 , 1 , 1); 
    LocalDate stop = start.plusDays (17); // Ex: 13 days = 1 week. 14 days = 2 weeks. 

    long weeks = ChronoUnit.WEEKS.between (start , stop); 

Дамп для консоли.

System.out.println ("start: " + start + " | stop: " + stop + " | weeks: " + weeks); 

старт: 2016-01-01 | остановка: 2016-01-18 | недель: 2

Если вы хотите несколько недель после 1989-12-31, используйте, что, как показано выше start объекта.

LocalDate start = LocalDate.of(1989 , 12 , 31); 

Half-Open

Но я заметил, ваша дата база в последний день года. Совет: промежутки времени обычно лучше всего обрабатываются с помощью метода Half-Open, где начало включительно, в то время как окончание исключение. Итак, вы можете хотите использовать 1990-01-01 в качестве вашей базовой даты (я не знаю вашу бизнес-логику, так что просто догадаться с моей стороны).

Таким образом, вы первые две недели будет это (первый - пятнадцатый):

long firstTwoWeeks = ChronoUnit.WEEKS.between (LocalDate.of (1990 , 1 , 1) , LocalDate.of (1990 , 1 , 15)); 

... вместо этого (31 - 14):

long firstTwoWeeks = ChronoUnit.WEEKS.between (LocalDate.of (1989 , 12 , 31) , LocalDate.of (1990 , 1 , 14)); 
Смежные вопросы