繁体   English   中英

计算Android中两个日期之间的周数

[英]Calculating the number of weeks between two dates in Android

如何计算 Android 中两个日期之间的周数? 我做过这样的事情

int week1 = calendar1.get(Calendar.WEEK_OF_YEAR);
int week2 = calendar2.get(Calendar.WEEK_OF_YEAR);
int calendarWeekDifference = week2 - week1;

但是,当两个日期在不同的年份时,这不起作用。 我怎样才能实现一个解决方案,使其能够在不同的年份发挥作用?

编辑

我尝试使用 Joda-Time 执行以下操作:

public static int weeksTouched(Calendar fromDate, Calendar toDate){
    DateTime fromDateTime = new DateTime(fromDate);
    DateTime toDateTime = new DateTime(toDate);
    DateTime epoch = new DateTime(0);
    Weeks fromWeeks = Weeks.weeksBetween(epoch, fromDateTime);
    Weeks toWeeks = Weeks.weeksBetween(epoch, toDateTime);
    int betweenWeeks = toWeeks.getWeeks() - fromWeeks.getWeeks();
    return betweenWeeks;
}

这几乎有效,但出于某种原因,它认为一周的开始是星期四。 我希望一周的开始是星期一,这样星期一到下一个星期六将返回 0(同一周),但星期六到第二天的星期日将返回 1(不同周)。

public int getWeekDifference(long fromDateInMills, long toDateInMills) {

    int weeks = Weeks.weeksBetween(new DateTime(fromDateInMills), new DateTime(toDateInMills)).getWeeks();

    // when we select any future date than week difference comes in negative so
    // just interchange millisecond You will get week difference in positive
    if (weeks < 0) {
        weeks = Weeks.weeksBetween(new DateTime(toDateInMills), new DateTime(fromDateInMills)).getWeeks();
    }

    return weeks;

}

这里的一些答案给出了错误的结果,有些需要额外的库。 我设法想出了一种使用标准日历API 计算周差的方法。

它可以正确处理2000-01-01 to 2000-12-31类的边缘情况(54 周意味着相差 53)。

getWeeksBetween() 使用日历 API

public static int getWeeksBetween(final Date start, final Date end) {
    final Calendar c1 = Calendar.getInstance(Locale.US);
    final Calendar c2 = Calendar.getInstance(Locale.US);

    // Skip time part! Not sure if this is needed, but I wanted clean dates.
    CalendarUtils.setDateWithNoTime(c1, start);
    CalendarUtils.setDateWithNoTime(c2, end);

    CalendarUtils.goToFirstDayOfWeek(c1);
    CalendarUtils.goToFirstDayOfWeek(c2);

    int weeks = 0;
    while (c1.compareTo(c2) < 0) {
        c1.add(Calendar.WEEK_OF_YEAR, 1);
        weeks++;
    }

    return weeks;
}

以及一些辅助方法:

public static int goToFirstDayOfWeek(final Calendar calendar) {
    final int firstDayOfWeek = calendar.getFirstDayOfWeek();
    calendar.set(Calendar.DAY_OF_WEEK, firstDayOfWeek);

    return firstDayOfWeek;
}

public static void setDateWithNoTime(final Calendar calendar, final Date date) {
    calendar.setTime(date);
    clearTime(calendar);
}

public static void clearTime(final Calendar calendar) {
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
}

在不使用 JodaTime 的情况下,我想出了这个计算周数的解决方案:

private fun calculateNumberOfWeeks() {
    val calendarFrom = Calendar.getInstance()
    calendarFrom.set(Calendar.HOUR_OF_DAY, 0)
    calendarFrom.set(Calendar.MINUTE, 0)
    calendarFrom.set(Calendar.SECOND, 0)
    calendarFrom.set(Calendar.MILLISECOND, 0)

    val calendarTo = Calendar.getInstance()
    calendarTo.add(Calendar.MONTH, months)
    calendarTo.set(Calendar.HOUR_OF_DAY, 0)
    calendarTo.set(Calendar.MINUTE, 0)
    calendarTo.set(Calendar.SECOND, 0)
    calendarTo.set(Calendar.MILLISECOND, 0)

    var weeks = -1
    while (calendarFrom.timeInMillis < calendarTo.timeInMillis) {
        calendarFrom.add(Calendar.DATE, 7)
        weeks++
        Log.d(Constants.LOG_TAG, "weeks $weeks")
    }
}

我建议您不要计算以周为单位的差异,而应尝试找出以天为单位的差异,然后将结果除以 7。

所以这将是周 = (daysBetweenDates / 7)

使用 Java 8

public void weeks_between_two_dates_in_java_with_java8 () {

    LocalDate startDate = LocalDate.of(2005, Month.JANUARY, 1);
    LocalDate endDate = LocalDate.of(2006, Month.JANUARY, 1);

    long weeksInYear = ChronoUnit.WEEKS.between(startDate, endDate);

   }

或使用 joda time api

public void weeks_between_two_dates_in_java_with_joda () {

    DateTime start = new DateTime(2005, 1, 1, 0, 0, 0, 0);
    DateTime end = new DateTime(2006, 1, 1, 0, 0, 0, 0);

    Weeks weeks = Weeks.weeksBetween(start, end);

    int weeksInYear = weeks.getWeeks();

    }

一种仅使用数学的低技术解决方案怎么样?

您有每个日期的 Week_OF_YEAR。 还有每个的年份编号。 将每个 Year 数字乘以 52,将其添加到 WEEK_OF_YEAR 中,然后减去这两个数字。 例如.... 2018 年第 50 周到 2019 年第 2 周

2018*52 = 104936 + 50 周 = 104986
2019*52 = 104988 + 2 周 = 104990

104990 - 104986 = 4 周

另一种替代解决方案。 我的基本概念是:

  1. 将给定的日期修剪为相应的星期一 00:00:00.000
  2. 计算这些修剪日期之间的毫秒数,然后将其除以一周的毫秒数。

Java 中的示例:

public class Main {
    
    public static void main(String[] args) {
        Calendar Monday = Calendar.getInstance();
        Monday.set(2020, 11, 28, 12, 34, 56); // 2020-12-28T12:34:56
        Calendar Saturday = Calendar.getInstance();
        Saturday.set(2021, 0, 2, 21, 43, 57); // 2021-01-02T21:43:57
        Calendar Sunday = Calendar.getInstance();
        Sunday.set(2021, 0, 3, 0, 1, 2); // 2021-01-03T00:01:02
        Calendar NextMonday = Calendar.getInstance();
        NextMonday.set(2021, 0, 4, 1, 23, 45); // 2021-01-04T01:23:45
        
        System.out.println(String.format(": %d week(s)", weeksTouched(Monday, Sunday)));
        System.out.println(String.format(": %d week(s)", weeksTouched(Saturday, Sunday)));
        System.out.println(String.format(": %d week(s)", weeksTouched(Sunday, NextMonday)));
    }
    
    public static int weeksTouched(Calendar fromDate, Calendar toDate){
        System.out.print(String.format("%s -> %s", fromDate.getTime(), toDate.getTime()));
        return (int) (
                (trimToMonday(toDate).getTimeInMillis() - trimToMonday(fromDate).getTimeInMillis())
                / (1000 * 60 * 60 * 24 * 7)
                );
    }
    
    private static Calendar trimToMonday(Calendar input) {
        Calendar output = (Calendar) input.clone();
        
        switch (output.get(Calendar.DAY_OF_WEEK)) {
        case Calendar.TUESDAY:
            output.add(Calendar.DAY_OF_MONTH, -1);
            break;
        case Calendar.WEDNESDAY:
            output.add(Calendar.DAY_OF_MONTH, -2);
            break;
        case Calendar.THURSDAY:
            output.add(Calendar.DAY_OF_MONTH, -3);
            break;
        case Calendar.FRIDAY:
            output.add(Calendar.DAY_OF_MONTH, -4);
            break;
        case Calendar.SATURDAY:
            output.add(Calendar.DAY_OF_MONTH, -5);
            break;
        case Calendar.SUNDAY:
            output.add(Calendar.DAY_OF_MONTH, -6);
            break;
        }
        
        output.set(Calendar.HOUR_OF_DAY, 0);
        output.set(Calendar.MINUTE, 0);
        output.set(Calendar.SECOND, 0);
        output.set(Calendar.MILLISECOND, 0);
        
        return output;
    }
}

输出:

Mon Dec 28 12:34:56 JST 2020 -> Sun Jan 03 00:01:02 JST 2021: 0 week(s)
Sat Jan 02 21:43:57 JST 2021 -> Sun Jan 03 00:01:02 JST 2021: 0 week(s)
Sun Jan 03 00:01:02 JST 2021 -> Mon Jan 04 01:23:45 JST 2021: 1 week(s)

这将为您提供两个日期的周数 b/w。

  public void getNoOfWeek()
    {

        Calendar date1 = Calendar.getInstance();
        Calendar date2 = Calendar.getInstance();

        date1.clear();
        date1.set(2015, 12, 29); // set date 1 (yyyy,mm,dd)
        date2.clear();
        date2.set(2016, 02, 7); //set date 2 (yyyy,mm,dd)

        long diff = date2.getTimeInMillis() - date1.getTimeInMillis();

        float dayCount = (float) diff / (24 * 60 * 60 * 1000);

        int week = (int) (dayCount / 7);
        System.out.println(week);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM