我希望在特定月份获得周数

时间:2013-01-22 08:56:57

标签: java android calendar

我希望获得当月的周数。包括上个月的上周和下个月的第一周。

这样的事情:

Simple Isnt it? http://i50.tinypic.com/5ml2de.png

我想在android上的某个gridview适配器中使用它,并且我试图操纵这个代码块:

            //FIRST_DAY_OF_WEEK =0;
    int lastDay = month.getActualMaximum(Calendar.DAY_OF_MONTH);
    int firstDay = (int) month.get(Calendar.DAY_OF_WEEK);
    int firstDayNextMonth = nextMonth.get(Calendar.DAY_OF_WEEK);
    int lastDayNextMonth=nextMonth.getActualMaximum(Calendar.DAY_OF_MONTH);
    int nextMonthdays=nextMonth.getMinimalDaysInFirstWeek();

    // figure size of the array
    if (firstDay == 1) {
        days = new String[lastDay + (FIRST_DAY_OF_WEEK * 6)];
    }

    else {
        days = new String[lastDay + firstDay - (FIRST_DAY_OF_WEEK + 1)];
    }

7 个答案:

答案 0 :(得分:10)

Calendar类的WEEK_OF_YEAR属性对您有用。参考:Calendar class

创建一个新日期,该日期将是某个月的第一天。得到这一天的一周,假设你有起始价值。

创建一个新日期,该日期将是给定月份的最后一天。得到这一天的一周,所以现在你有了最终价值。

现在结束 - 开始+ 1应该是你想要的。

当一周与另一年或类似的一周重叠时,您可能需要处理一些极端情况。但我认为一旦你做到了这一点,你就可以用简单的逻辑来做到这一点。

这是一个简单的示例代码。我认为你可以把它变成功能并传递你想要的任何东西。

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, 2013);
        cal.set(Calendar.MONTH, 1);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        int start = cal.get(Calendar.WEEK_OF_YEAR);
        Log.d("BLA BLA", "Value is " + start);
        cal.set(Calendar.YEAR, 2013);
        cal.set(Calendar.MONTH, 1);
        cal.set(Calendar.DAY_OF_MONTH, 28);
        int end = cal.get(Calendar.WEEK_OF_YEAR);
        //Above line will not work for December Month, use following line for this
        int end = isDecember?53:cal.get(Calendar.WEEK_OF_YEAR);
        Log.d("BLA BLA", "Value is " + end);
        Log.d("BLA BLA", "Num weeks:: " + (end - start +1 ));

对于角落案例:

角落案例仅发生在Januaray月份(例如2010年1月,2000年1月),在这些情况下,大多数日子都是上一年的最后一周的一部分,所以起始值将是52,结束值将是5.发生这种情况时,请检查是否,

          if(start > end) {
                numweeks = end + 1;
             }

P.S:把它放到你得到的不同测试输入上。让我知道如果你发现任何错误,我可以改进它。

甚至更简单的解决方案:

        Calendar cal = Calendar.getInstance();
        for(int i = 0 ; i < 11;i++){
            cal.set(Calendar.YEAR, 2013);
            cal.set(Calendar.DAY_OF_MONTH, 1);
            cal.set(Calendar.MONTH, i);
            int maxWeeknumber = cal.getActualMaximum(Calendar.WEEK_OF_MONTH);
            Log.d("LOG","max week number" + maxWeeknumber);
        }

        01-22 01:49:03.591: D/LOG(573): max week number5
        01-22 01:49:03.602: D/LOG(573): max week number5
        01-22 01:49:03.602: D/LOG(573): max week number6
        01-22 01:49:03.671: D/LOG(573): max week number5
        01-22 01:49:03.671: D/LOG(573): max week number5
        01-22 01:49:03.671: D/LOG(573): max week number6
        01-22 01:49:03.681: D/LOG(573): max week number5
        01-22 01:49:03.691: D/LOG(573): max week number5
        01-22 01:49:03.691: D/LOG(573): max week number5
        01-22 01:49:03.711: D/LOG(573): max week number5
        01-22 01:49:03.711: D/LOG(573): max week number5

简单解决方案适用于极端情况:

        Calendar cal = Calendar.getInstance();
        for(int i = 0 ; i < 11;i++){
            cal.set(Calendar.YEAR, 2010);
            cal.set(Calendar.DAY_OF_MONTH, 1);
            cal.set(Calendar.MONTH, i);
            int maxWeeknumber = cal.getActualMaximum(Calendar.WEEK_OF_MONTH);
            // Month value starts from 0 to 11 for Jan to Dec
            Log.d("LOG","For Month :: "+ i + " Num Week :: " + maxWeeknumber);
        }

日志:

        01-22 01:59:35.841: D/LOG(629): For Month :: 0 Num Week :: 6
        01-22 01:59:35.841: D/LOG(629): For Month :: 1 Num Week :: 5
        01-22 01:59:35.841: D/LOG(629): For Month :: 2 Num Week :: 5
        01-22 01:59:35.841: D/LOG(629): For Month :: 3 Num Week :: 5
        01-22 01:59:35.841: D/LOG(629): For Month :: 4 Num Week :: 6
        01-22 01:59:35.852: D/LOG(629): For Month :: 5 Num Week :: 5
        01-22 01:59:35.871: D/LOG(629): For Month :: 6 Num Week :: 5
        01-22 01:59:35.871: D/LOG(629): For Month :: 7 Num Week :: 5
        01-22 01:59:35.871: D/LOG(629): For Month :: 8 Num Week :: 5
        01-22 01:59:35.871: D/LOG(629): For Month :: 9 Num Week :: 6
        01-22 01:59:35.871: D/LOG(629): For Month :: 10 Num Week :: 5

答案 1 :(得分:7)

使用WEEK_OF_MONTH会更好,没有跨年问题。

public static void main(String[] args) throws Exception {
  for (String m : new String[] { "2012-11", "2012-12", "2013-01", "2013-02", "2013-03",
              "2013-04", "2013-05", "2013-06" }) {
      SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
      Date date = format.parse(m);
      Calendar c = Calendar.getInstance();
      c.setTime(date);

      int start = c.get(Calendar.WEEK_OF_MONTH);

      c.add(Calendar.MONTH, 1);
      c.add(Calendar.DATE, -1);
      int end = c.get(Calendar.WEEK_OF_MONTH);
      System.out.println(" # of weeks in " + format.format(c.getTime())
              + ": " + (end - start + 1));
  }
}

结果:

# of weeks in 2012-11: 5
# of weeks in 2012-12: 6
# of weeks in 2013-01: 5
# of weeks in 2013-02: 5
# of weeks in 2013-03: 6
# of weeks in 2013-04: 5
# of weeks in 2013-05: 5
# of weeks in 2013-06: 6

答案 2 :(得分:5)

我们可以使用日历类,然后执行类似

的操作
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getActualMaximum(Calendar.WEEK_OF_MONTH));

这将返回当月的周数

答案 3 :(得分:1)

java.time

我建议您使用 java.time,现代 Java 日期和时间 API,用于您的日期工作(坦率地说,我很惊讶地看到到目前为止没有任何答案建议这样做)。

public static int getTotalNumberOfWeeks(WeekFields wf, Temporal month) {
    YearMonth ym = YearMonth.from(month);
    int firstWeekNumber = ym.atDay(1).get(wf.weekOfMonth());
    int lastWeekNumber = ym.atEndOfMonth().get(wf.weekOfMonth());
    return lastWeekNumber - firstWeekNumber + 1; // Both weeks inclusive
}

让我们先用您问题中的示例月份 2013 年 1 月来尝试一下,这样我们就知道预期结果是 5。由于您的星期从星期日开始,我们也在电话会议中指定了这一点:

    System.out.println(getTotalNumberOfWeeks(
            WeekFields.SUNDAY_START, YearMonth.of(2013, Month.JANUARY)));

输出是预期的:

<块引用>

5

对于较新的示例,我将采用 2021 年 5 月(撰写本文时的下个月)。因为我住的地方我们使用 ISO 周(从星期一开始),让我们也试试:

    System.out.println(getTotalNumberOfWeeks(
            WeekFields.ISO, YearMonth.of(2021, Month.MAY)));
<块引用>

6

如果您希望在 JVM 的默认语言环境中使用周数,请使用 WeekFields.of(Locale.getDefault()) 作为第一个参数。如果您想要当前月份,您可以通过 YearMonth.now(ZoneId.systemDefault()) 作为第二个。为方便起见,我将第二个参数声明为 Temporal。这允许您传递 LocalDateYearMonthZonedDateTime、任何定义月份和年份的 java.time 类。

ISO 8601(可能在世界大部分地区使用的国际标准)将每月的第 1 周定义为每月至少包含 4 天的第一周。这意味着月初最多三天可能在第 0 周。这就是为什么只看月份中断的最大周数的答案。相反,我从最大值中减去最小周数并加 1,因为我们希望这两个周都包含在计数中。

链接

Oracle tutorial: Date Time 解释如何使用 java.time。

答案 4 :(得分:0)

我们假设我们知道一个月的第一天(周六,周日等)。

  • 如果该月的第一天是Sunday并且它不是闰年,那么(更正修改)February个月将只有4周。否则,在所有情况下,它应至少有5周,最多6周。
  • 现在,如果您的月份从Saturday开始,那么您将总是有6个星期(如果是2月份,那么将会有5个星期)
  • 现在,如果您的月份从Friday开始,那么您将有6个星期的工作时间为31天,其余为5个星期。
  • 对于其他情况,它总是5周。

找出本月的第一天并不困难,您可以使用Calendar或其他日期/时间实用程序库类。但是,我想可以采用更清晰的解决方案来消除极端情况和不必要的复杂性。

答案 5 :(得分:0)

如果你想通过“手”来做到这一点

使用它:

Date.prototype.getMonthWeek = function(monthAdjustement)
{    

    var firstDay = new Date(this.getFullYear(), this.getMonth(), 1).getDay();

    var returnMessage = (Math.ceil(this.getDate()/7) + Math.floor(((7-firstDay)/7)));

    return returnMessage;

}

monthAdjustement只是一个整数,用于调整您寻找的月份与今天的日期相比。

答案 6 :(得分:0)

Java 的日历 API 对于这种用例非常有用。 参考链接:Calendar docs

我假设您有一个月的开始日期。

  1. 我们需要使用 setTime() 来设置 Time(java.util.Date obj) 因为当您创建 Calendar 类的实例时,它默认将时间设置为机器的当前时间和日期

    如果您不需要计算特定月份的总周数,那么您可以简单地避免第一步。

  2. 我们只需要为一个名为的字段名调用 getActualMaximum() 日历。WEEK_OF_MONTH。

    public static int getTotalNumberOfWeeks() throws ParseException {
    
        Calendar calendar = Calendar.getInstance();
    
        Date monthStartingDate = new SimpleDateFormat("yyyy-MM- dd").parse("2021-04-01");
    
        calendar.setTime(monthStartingDate);
    
        return calendar.getActualMaximum(Calendar.WEEK_OF_MONTH);
    }
    

您也可以通过打印日历对象在控制台中查看给定日期的更多详细信息。