【问题标题】:Getting full "monday to sunday" weeks between two dates [duplicate]在两个日期之间获得完整的“周一至周日”周[重复]
【发布时间】:2014-09-18 22:47:20
【问题描述】:

让我们看看你是否可以帮助我。我想获得两个日期 d1 和 d2 之间的周数(从星期一开始到星期日结束)。假设 d2 早于 d1。这部分代码已经编程并可以工作。我现在的问题是我无法正确编写周程序。这是我现在做的:

public static void getFullWeeks(Calendar d1, Calendar d2){
    int Weeks = 0;
    Calendar date2 = d2;
    Calendar addWeek = GregorianCalendar.getInstance();
    addWeek.setTime(date2.getTime());
    addWeek.add(Calendar.DATE, 6);

    while(addWeek.before(d1) || addWeek.equals(d1)){
        if(date2.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY){
            Weeks++;
        }
        date2.add(Calendar.DATE,1);
    }

    System.out.println(
        "The number of weeks (from monday to sunday) between both dates are: " 
        + Weeks);
}

但输出为“0 周”,因此程序无法运行。怎么了?我没有遇到该错误,也无法找到解决此问题的有效解决方案。

谢谢!!

【问题讨论】:

  • 我们需要知道什么是suma7。
  • 使用joda!
  • @Jean-FrançoisSavard 对不起,代码是西班牙语,我把它翻译成英语忘记了。现在已经修好了。
  • @hd1 Joda 非常擅长处理时间和日期,但我不允许在这项工作中使用外部库
  • 啊...你知道 SO 不喜欢家庭作业问题吗?

标签: java


【解决方案1】:

在没有外部库的 Java 8 中,您可以执行以下操作:

*编辑以说明从星期一开始的一周

// TechTrip - ASSUMPTION d1 is earlier than d2
// leave that for exercise
public static long getFullWeeks(Calendar d1, Calendar d2){
    // In Java the week starts on Sunday from an integral perspective
    //  public final static int SUNDAY = 1;
    // SEQUENTIAL UP TO
    // public final static int SATURDAY = 7;

    // make the starting date relative to the Monday we need to calculate from
    int dayOfStartWeek = d1.get(Calendar.DAY_OF_WEEK);

    // IF we have a partial week we should add an offset that moves the start
    // date UP TO the next Monday to simulate a week starting on Monday
    // eliminating partial weeks from the calculation
    // NOTE THIS METHOD WILL RETURN NEGATIVES IF D1 < D2 after adjusting for 
    // offset
    if (dayOfStartWeek == Calendar.SUNDAY) {
        // add an offset of 1 day because this is a partial week
        d1.add(Calendar.DAY_OF_WEEK, 1);
    } else if (dayOfStartWeek != Calendar.MONDAY){
        // add an offset for the partial week
        // Hence subtract from 9 accounting for shift by 1
        // and start at 1
        // ex if WEDNESDAY we need to add 9-4 (WED Int Val) = 5 days
        d1.add(Calendar.DAY_OF_WEEK, 9 - dayOfStartWeek);
    }

    Instant d1i = Instant.ofEpochMilli(d1.getTimeInMillis());
    Instant d2i = Instant.ofEpochMilli(d2.getTimeInMillis());

    LocalDateTime startDate = LocalDateTime.ofInstant(d1i, ZoneId.systemDefault());
    LocalDateTime endDate = LocalDateTime.ofInstant(d2i, ZoneId.systemDefault());

    return ChronoUnit.WEEKS.between(startDate, endDate);
}

这里是主要的:

public static void main(String[] args) {
    Calendar d1 = Calendar.getInstance();
    Calendar d2 = Calendar.getInstance();
    d2.add(Calendar.WEEK_OF_YEAR, 6);
    System.out.println(
            "The number of weeks (from monday to sunday) between both dates are: " 
            + getFullWeeks(d1, d2));
}

如果开始日期是星期一,则输出如下:

两个日期之间的周数(从星期一到星期日)为:6

注意,我没有将日期 d2 分配给 d1,使其成为相同的参考。在这种情况下,你会得到 0。

*ChronoUnit 采用一个 Temporal,它只是一个日期、时间或偏移量。它们必须属于同一类型。可以用加号和减号来操纵时间。

【讨论】:

  • 查看 ChronoUnit 时,重要的是要了解计算是相对于绝对开始日期的。计算返回一个整数,表示两个时间之间的完整单元数。例如,时间 11:30 和 13:29 之间的小时数将只有一小时,因为它比两小时短一分钟
【解决方案2】:

在我看来你犯了几个小错误:

1.) 您的输出为 0 周,因为在代码的其他地方,您必须使用第一个参数 d1 调用此方法,早于第二个参数,而在方法主体中,您假设 d2 更早比d1。使用有意义的参数名称可以轻松避免此类错误。在这种情况下,适当的参数名称例如是 startend

2) 如果您使用d2 早于d1 的参数执行此方法,您的方法将陷入无限循环。在我看来,添加到 date2 并不会更改 addWeek 中的日期。

3) 您的方法计算从周二到周一的周数,而不是从周一到周日。要解决此问题,请将 7 天添加到 addWeek 而不是 6 天,或者更改 while 循环以仅检查 addWeek 是否在 d1 之前并在星期日增加 weeks

把所有这些放在一起,我相信这会给你想要的东西:

public static void getFullWeeks(Calendar start, Calendar end)
{
    System.out.println("The number of weeks (from monday to sunday) between both dates are: " + getNrWeeksBetween(start, end));
}

private static int getNrWeeksBetween(Calendar start, Calendar end)
{
    int weeks = 0;

    Calendar counter = new GregorianCalendar();
    counter.setTime( start.getTime() );
    counter.add(Calendar.DATE, 6);

    while( counter.before(end) )
    {
        if(counter.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) weeks++;
        counter.add(Calendar.DATE, 1);
    }

    return weeks;
}

【讨论】:

  • 简单但有效
【解决方案3】:

你的算法错了;您的 while 循环需要比较您正在修改的同一个 Calendar 对象,但您不这样做,因此您要么有一个无限循环,要么立即退出并返回值为 0,具体取决于 addDate 是之前还是在 d1 之后(因为两者都没有改变)。你的代码应该是:

public static void getFullWeeks(Calendar d1, Calendar d2){
    int Weeks = 0;
    Calendar addWeek = GregorianCalendar.getInstance();
    addWeek.setTime(d2.getTime());
    addWeek.add(Calendar.DATE, 6);

    while(addWeek.before(d1) || addWeek.equals(d1)){
        if(addWeek.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY){
            Weeks++;
        }
        addWeek.add(Calendar.DATE,1);
    }

    System.out.println(
        "The number of weeks (from monday to sunday) between both dates are: " 
        + Weeks);
}

【讨论】:

  • 一旦我意识到这是一个家庭作业问题,我几乎删除了我的答案。我将离开它,但我也将给出我几乎将其替换为的答案:当您使用调试器逐步完成它时,问题是非常明显。所以这应该是你作为 Java 学生的第一课:学习如何在一行上设置断点,然后使用调试器在该行处停止,逐行通过你的方法,检查变量等。调试器将为您节省 小时 的猜测问题的时间;它应该始终是您解决任何问题的第一步。
猜你喜欢
  • 2021-12-31
  • 1970-01-01
  • 2017-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多