【问题标题】:In Java, get all weekend dates in a given month在 Java 中,获取给定月份的所有周末日期
【发布时间】:2011-03-17 09:25:23
【问题描述】:

我需要找到给定月份和给定年份的所有周末日期。

例如:对于 01(月)、2010(年),输出应为:2、3、9、10、16、17、23、24、30、31,所有周末日期。

【问题讨论】:

    标签: java date weekend


    【解决方案1】:

    这是一个粗略的版本,带有描述步骤的 cmets:

    // create a Calendar for the 1st of the required month
    int year = 2010;
    int month = Calendar.JANUARY;
    Calendar cal = new GregorianCalendar(year, month, 1);
    do {
        // get the day of the week for the current day
        int day = cal.get(Calendar.DAY_OF_WEEK);
        // check if it is a Saturday or Sunday
        if (day == Calendar.SATURDAY || day == Calendar.SUNDAY) {
            // print the day - but you could add them to a list or whatever
            System.out.println(cal.get(Calendar.DAY_OF_MONTH));
        }
        // advance to the next day
        cal.add(Calendar.DAY_OF_YEAR, 1);
    }  while (cal.get(Calendar.MONTH) == month);
    // stop when we reach the start of the next month
    

    【讨论】:

    • 样本无法正常工作,它给出的输出:2、3、9、10、16、17、23、24、30,但对于 2010 年 1 月,周末列表是 2、3、9、10 ,16,17,23,24,30,31 。请告诉我专业人士在哪里
    • while 条件中存在一个错误,即错过了该月的最后一天。我现在已经修好了。
    • 仅供参考,非常麻烦的旧日期时间类,如 java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 现在是 legacy,被 Java 8 中内置的 java.time 类所取代,之后。见Tutorial by Oracle
    • 这段代码在许多语言环境中完全是错误的;并非所有地区都将“周六和周日”视为周末!
    【解决方案2】:

    java.time

    您可以使用Java 8 streamjava.time package。这里生成了一个从1 到给定月份的天数的IntStream。此流在给定月份映射到LocalDate 流,然后过滤以保留周六和周日。

    import java.time.DayOfWeek;
    import java.time.DayOfWeek;
    import java.time.LocalDate;
    import java.time.Month;
    import java.time.YearMonth;
    import java.util.stream.IntStream;
    
    class Stackoverflow{
        public static void main(String args[]){
    
            int year    = 2010;
            Month month = Month.JANUARY;
    
            IntStream.rangeClosed(1,YearMonth.of(year, month).lengthOfMonth())
                     .mapToObj(day -> LocalDate.of(year, month, day))
                     .filter(date -> date.getDayOfWeek() == DayOfWeek.SATURDAY ||
                                     date.getDayOfWeek() == DayOfWeek.SUNDAY)
                     .forEach(date -> System.out.print(date.getDayOfMonth() + " "));
        }
    }
    

    我们发现与第一个答案相同的结果 (2 3 9 10 16 17 23 24 30 31)。

    【讨论】:

      【解决方案3】:

      你可以这样尝试:

      int year=2016;
      int month=10;
      calendar.set(year, 10- 1, 1);
      int daysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
      ArrayList<Date> sundays = new ArrayList<Date>();>
      
      for (int d = 1;  d <= daysInMonth;  d++) {
            calendar.set(Calendar.DAY_OF_MONTH, d);
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
            if (dayOfWeek==Calendar.SUNDAY) {
                  calendar.add(Calendar.DATE, d);
                  sundays.add(calendar.getTime());
            }
      }
      

      【讨论】:

      • 仅供参考,这些臭名昭著的麻烦和令人困惑的旧日期时间类现在已被 java.time 类所取代。避免使用旧课程。
      • 仍然适用于 Android 开发者。
      【解决方案4】:

      Answer by Lokni 似乎是正确的,使用 Streams 可以获得奖励积分。

      EnumSet

      我的改进建议:EnumSet。这个类是Set 的一个非常有效的实现。在内部以位向量表示,它们执行速度快且占用内存极少。

      使用EnumSet,您可以通过传入Set&lt;DayOfWeek&gt;soft-code 定义周末。

      Set<DayOfWeek> dows = EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY );
      

      演示使用不带 Streams 的老式语法。您可以以类似的方式调整 Lokni’s answer’s code 以使用 EnumSet

      YearMonth ym = YearMonth.of( 2016 , Month.JANUARY ) ;
      int initialCapacity = ( ( ym.lengthOfMonth() / 7 ) + 1 ) * dows.size() ;  // Maximum possible weeks * number of days per week.
      List<LocalDate> dates = new ArrayList<>(  initialCapacity  );
      for (int dayOfMonth = 1;  dayOfMonth <= ym.lengthOfMonth() ;  dayOfMonth ++) {
          LocalDate ld =  ym.atDay( dayOfMonth ) ;
          DayOfWeek dow = ld.getDayOfWeek() ;
          if( dows.contains( dow ) ) {  
              // Is this date *is* one of the days we care about, collect it.
              dates.add( ld );
          }
      }
      

      TemporalAdjuster

      您还可以使用TemporalAdjuster 接口,该接口提供了用于操作日期时间值的类。 TemporalAdjusters 类(注意复数 s)提供了几个方便的实现。

      ThreeTen-Extra 项目提供了使用 java.time 的类。这包括 TemporalAdjuster 实现,Temporals.nextWorkingDay()

      您可以编写自己的实现来做相反的事情,nextWeekendDay 时间调整器。


      关于java.time

      java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧 legacy 日期时间类,例如 java.util.DateCalendarSimpleDateFormat

      Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

      要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

      您可以直接与您的数据库交换 java.time 对象。使用符合JDBC 4.2 或更高版本的JDBC driver。不需要字符串,不需要java.sql.* 类。

      从哪里获得 java.time 类?

      ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

      【讨论】:

        猜你喜欢
        • 2014-07-09
        • 2013-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-08
        • 1970-01-01
        • 2018-12-15
        相关资源
        最近更新 更多