Android java.util.Calendar - Time Difference

前端 未结 3 423
再見小時候
再見小時候 2021-01-22 09:07

I want to make calendar view in order to support touch interaction. So I\'d like to build new custom calendar view. I tried to make mapping function between view offset and rea

相关标签:
3条回答
  • 2021-01-22 09:26

    tl;dr

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

    Avoid count-from-epoch

    Do not work in a count-since-epoch such as milliseconds. Confusing, cloaks bugs, and ignores issues such as time zones.

    Let a good date-time library do the heavy-lifting in these calculations.

    java.time

    You are using troublesome old date-time classes such as java.util.Calendar. These poorly-designed classes have been supplanted by the java.time framework built into Java 8 and later. See Oracle Tutorial. Much of the java.time functionality has been back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.

    ChronoUnit

    The ChronoUnit class calculates elapsed time such as number of whole weeks between a pair of LocalDate (date-only, no time-of-day nor time zone) values.

        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 );
    

    Dump to console.

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

    start: 2016-01-01 | stop: 2016-01-18 | weeks: 2

    If you want a number of weeks since 1989-12-31, use that as the start object seen above.

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

    Half-Open

    But I notice your base date is the last day of the year. Tip: spans of time are generally best handled with the Half-Open approach where the beginning is inclusive while the ending is exclusive. So you may want to use 1990-01-01 as your base date (I do not know your business logic, so just a guess on my part).

    So you first two weeks would be this (1st - 15th):

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

    …rather than this (31st - 14th):

    long firstTwoWeeks = ChronoUnit.WEEKS.between ( LocalDate.of ( 1989 , 12 , 31 ) , LocalDate.of ( 1990 , 1 , 14 ) );
    
    0 讨论(0)
  • 2021-01-22 09:40

    This is because you need to use the "equals" method to compare different objects. Using operator "==" will tell you if the objects are identical (do they reside in the exact same memory location), while the "equals" comparison function will tell you if the two objects are logically equivalent.

    0 讨论(0)
  • 2021-01-22 09:44

    This statement confuses me:

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

    Are you actually trying to check for equality by doing the comparison: if (mBaseDate == mAnotherDate) { System.out.println("They are the same"); }

    If so, your issue is that you are misunderstanding how the "==" operator works in Java. It compares references, rather than comparing the underlying object data, and since these are different objects (with the same values) that will always be false. For a lot more details, see the Java Notes on comparison operators.

    Also, these lines look really suspicious to me:

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

    I would really be surprised if Android had a bug requiring you to do this, but I guess anything is possible. What kind of problems do you have without this call?

    0 讨论(0)
提交回复
热议问题