How to get number of days between two calendar instance?

后端 未结 11 1091
孤城傲影
孤城傲影 2020-12-05 01:58

I want to find the difference between two Calendar objects in number of days if there is date change like If clock ticked from 23:59-0:00 there should be a day

11条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-05 02:33

    If your project doesn't support new Java 8 classes (as selected answer), you can add this method to calculate the days without being influenced by timezones or other facts.

    It is not as fast (greater time complexity) as other methods but it's reliable, anyways date comparisons are rarely larger than hundreds or thousands of years.

    (Kotlin)

    /**
         * Returns the number of DAYS between two dates. Days are counted as calendar days
         * so that tomorrow (from today date reference) will be 1 ,  the day after 2 and so on
         * independent on the hour of the day.
         *
         * @param date - reference date, normally Today
         * @param selectedDate - date on the future
         */
    fun getDaysBetween(date: Date, selectedDate: Date): Int {
    
                val d = initCalendar(date)
                val s = initCalendar(selectedDate)
                val yd = d.get(Calendar.YEAR)
                val ys = s.get(Calendar.YEAR)
    
                if (ys == yd) {
                    return s.get(Calendar.DAY_OF_YEAR) - d.get(Calendar.DAY_OF_YEAR)
                }
    
                //greater year
                if (ys > yd) {
                    val endOfYear = Calendar.getInstance()
                    endOfYear.set(yd, Calendar.DECEMBER, 31)
                    var daysToFinish = endOfYear.get(Calendar.DAY_OF_YEAR) - d.get(Calendar.DAY_OF_YEAR)
                    while (endOfYear.get(Calendar.YEAR) < s.get(Calendar.YEAR)-1) {
                        endOfYear.add(Calendar.YEAR, 1)
                        daysToFinish += endOfYear.get(Calendar.DAY_OF_YEAR)
                    }
                    return daysToFinish + s.get(Calendar.DAY_OF_YEAR)
                }
    
                //past year
                else {
                    val endOfYear = Calendar.getInstance()
                    endOfYear.set(ys, Calendar.DECEMBER, 31)
                    var daysToFinish = endOfYear.get(Calendar.DAY_OF_YEAR) - s.get(Calendar.DAY_OF_YEAR)
                    while (endOfYear.get(Calendar.YEAR) < d.get(Calendar.YEAR)-1) {
                        endOfYear.add(Calendar.YEAR, 1)
                        daysToFinish += endOfYear.get(Calendar.DAY_OF_YEAR)
                    }
                    return daysToFinish + d.get(Calendar.DAY_OF_YEAR)
                }
            }
    

    Unit Tests, you can improve them I didn't need the negative days so I didn't test that as much:

    @Test
        fun `Test days between on today and following days`() {
            val future = Calendar.getInstance()
            calendar.set(2019, Calendar.AUGUST, 26)
    
            future.set(2019, Calendar.AUGUST, 26)
            Assert.assertEquals(0, manager.getDaysBetween(calendar.time, future.time))
    
            future.set(2019, Calendar.AUGUST, 27)
            Assert.assertEquals(1, manager.getDaysBetween(calendar.time, future.time))
    
            future.set(2019, Calendar.SEPTEMBER, 1)
            Assert.assertEquals(6, manager.getDaysBetween(calendar.time, future.time))
    
            future.set(2020, Calendar.AUGUST, 26)
            Assert.assertEquals(366, manager.getDaysBetween(calendar.time, future.time)) //leap year
    
            future.set(2022, Calendar.AUGUST, 26)
            Assert.assertEquals(1096, manager.getDaysBetween(calendar.time, future.time))
    
            calendar.set(2019, Calendar.DECEMBER, 31)
            future.set(2020, Calendar.JANUARY, 1)
            Assert.assertEquals(1, manager.getDaysBetween(calendar.time, future.time))
        }
    
        @Test
        fun `Test days between on previous days`() {
            val future = Calendar.getInstance()
            calendar.set(2019, Calendar.AUGUST, 26)
    
            future.set(2019,Calendar.AUGUST,25)
            Assert.assertEquals(-1, manager.getDaysBetween(calendar.time, future.time))
        }
    
        @Test
        fun `Test days between hour doesn't matter`() {
            val future = Calendar.getInstance()
            calendar.set(2019, Calendar.AUGUST, 26,9,31,15)
    
            future.set(2019,Calendar.AUGUST,28, 7,0,0)
            Assert.assertEquals(2, manager.getDaysBetween(calendar.time, future.time))
    
            future.set(2019,Calendar.AUGUST,28, 9,31,15)
            Assert.assertEquals(2, manager.getDaysBetween(calendar.time, future.time))
    
            future.set(2019,Calendar.AUGUST,28, 23,59,59)
            Assert.assertEquals(2, manager.getDaysBetween(calendar.time, future.time))
        }
    
        @Test
        fun `Test days between with time saving change`() {
            val future = Calendar.getInstance()
            calendar.set(2019, Calendar.OCTOBER, 28)
    
            future.set(2019, Calendar.OCTOBER,29)
            Assert.assertEquals(1, manager.getDaysBetween(calendar.time, future.time))
    
            future.set(2019, Calendar.OCTOBER,30)
            Assert.assertEquals(2, manager.getDaysBetween(calendar.time, future.time))
        }
    

提交回复
热议问题