【问题标题】:Joda-Time: Get first/second/last sunday of monthJoda-Time:获取每月的第一个/第二个/最后一个星期日
【发布时间】:2012-09-11 12:34:37
【问题描述】:

在纯 Java 中,我有这段代码来获取该月的最后一个星期日。

Calendar getNthOfMonth(int n, int day_of_week, int month, int year) {
    Calendar compareDate = Date(1, month, year);
    compareDate.set(DAY_OF_WEEK, day_of_week);
    compareDate.set(DAY_OF_WEEK_IN_MONTH, n);
    return compareDate;
}
// Usage
Calendar lastSundayOfNovember = getNthOfMonth(-1, SUNDAY, NOVEMBER, 2012)

使用Joda-Time 实现相同结果的简洁优雅方法是什么?

【问题讨论】:

    标签: java date datetime jodatime


    【解决方案1】:

    这是一篇相当老的帖子,但可能这个答案会对某人有所帮助。使用替换 Joda-Time 的 java.time 类。

    private static LocalDate getNthOfMonth(int type, DayOfWeek dayOfWeek, int month, int year){
        return LocalDate.now().withMonth(month).withYear(year).with(TemporalAdjusters.dayOfWeekInMonth(type, dayOfWeek));
    }
    

    【讨论】:

      【解决方案2】:

      使用 Java-8 java.time API 的解决方案

      获取指定年月最后一个星期日的本地日期:

      为了使用 Java 的 modern date-time API 实现这一点,您可以将 TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY) 作为参数传递给指定年份和月份的任何 LocalDate

      import java.time.DayOfWeek;
      import java.time.LocalDate;
      import java.time.YearMonth;
      import java.time.temporal.TemporalAdjusters;
      
      public class Main {
          public static void main(String[] args) {
              // Test
              System.out.println(getLastSundayOfMonth(2020, 12));
          }
      
          public static LocalDate getLastSundayOfMonth(int year, int month) {
              return YearMonth.of(year, month)
                      .atEndOfMonth() //Returns a LocalDate at the end of the month
                      .with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));
          }
      }
      

      输出:

      2020-12-27
      

      我使用YearMonth#atEndOfMonth 来获取LocalDate。除了这个,YearMonth#atDay 也可以使用。

      获取指定年份和月份的第 n 周(例如第 2 周四)的本地日期:

      您可以将TemporalAdjusters#dayOfWeekInMonth 作为参数传递给指定年份和月份的任何LocalDate

      import java.time.DayOfWeek;
      import java.time.LocalDate;
      import java.time.YearMonth;
      import java.time.temporal.TemporalAdjusters;
      
      public class Main {
          public static void main(String[] args) {
              // Test
              System.out.println(localDateOnNthDayOfWeekOfMonth(DayOfWeek.THURSDAY, 2, 2020, 12));
          }
      
          public static LocalDate localDateOnNthDayOfWeekOfMonth(DayOfWeek dayOfWeek, int ordinal, int year, int month) {
              return YearMonth.of(year, month)
                      .atEndOfMonth() // Returns a LocalDate at the end of the month
                      .with(TemporalAdjusters.dayOfWeekInMonth(ordinal, dayOfWeek));
          }
      }
      

      输出:

      2020-12-10
      

      Trail: Date Time 了解 Java-8 日期时间 API。

      Java 6 或 7 用户注意事项:

      无论出于何种原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7。如果您是为 Android 项目工作,而您的 Android API 级别仍不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

      【讨论】:

        【解决方案3】:

        与乔达

        假设我们有个约会:

        DateTime date = new DateTime(2017, 6, 1, 0, 0, 0);
        

        `首先我们需要知道该月是否有 31、30、28 或 29 天:

        int lastofMonth = date.dayOfMonth().getMaximumValue();
        

        由此我们创建一个新日期:

        DateTime endOfMonth = new DateTime(2017, 6, lastOfMonth, 0, 0, 0);
        

        我们找出最后一天是星期几:

        int whatDayIsLast = endOfMonth.getDayOfWeek();
        

        现在我们可以创建一个日期,这将是该月最后一个星期日的日期:

        DateTime lastSunday = new DateTime(2017, 6, lastOfMonth - whatDayIsLast, 0, 0, 0);
        

        对于我的示例(2017 年 6 月),结果将是:

        DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyy-MM-dd");
        System.out.println(dtf.print(lastSunday);
        

        2017-06-25

        【讨论】:

        • 很好的解释
        【解决方案4】:

        你可以试试这样的:

        public class Foo {
        
          public static LocalDate getNthSundayOfMonth(final int n, final int month, final int year) {
            final LocalDate firstSunday = new LocalDate(year, month, 1).withDayOfWeek(DateTimeConstants.SUNDAY);
            if (n > 1) {
              final LocalDate nThSunday = firstSunday.plusWeeks(n - 1);
              final LocalDate lastDayInMonth = firstSunday.dayOfMonth().withMaximumValue();
              if (nThSunday.isAfter(lastDayInMonth)) {
                throw new IllegalArgumentException("There is no " + n + "th Sunday in this month!");
              }
              return nThSunday;
            }
            return firstSunday;
          }
        
        
          public static void main(final String[] args) {
            System.out.println(getNthSundayOfMonth(1, DateTimeConstants.SEPTEMBER, 2012));
            System.out.println(getNthSundayOfMonth(2, DateTimeConstants.SEPTEMBER, 2012));
            System.out.println(getNthSundayOfMonth(3, DateTimeConstants.SEPTEMBER, 2012));
            System.out.println(getNthSundayOfMonth(4, DateTimeConstants.SEPTEMBER, 2012));
            System.out.println(getNthSundayOfMonth(5, DateTimeConstants.SEPTEMBER, 2012));
          }
        }
        

        输出:

        2012-09-02
        2012-09-09
        2012-09-16
        2012-09-23
        2012-09-30
        

        【讨论】:

        • 使用 java.time 类和 TemporalAdjuster 来缩短此代码。见this Answer
        【解决方案5】:
        public class Time {
        public static void main(String[] args) {
            System.out.println(getNthOfMonth(DateTimeConstants.SUNDAY, DateTimeConstants.SEP, 2012));
        }
        
        
        public static LocalDate getNthOfMonth(int day_of_week, int month, int year) {
            LocalDate date = new LocalDate(year, month, 1).dayOfMonth()  
                     .withMaximumValue()
                     .dayOfWeek()
                     .setCopy(day_of_week);
            if(date.getMonthOfYear() != month) {
                return date.dayOfWeek().addToCopy(-7);
            }
            return date;
        }
        }
        

        【讨论】:

        • 不,该代码将给出该月最后一周的星期日。例如。对于 2012 年 10 月,它将在 11 月 4 日返回。
        • 对。我添加了 if 语句。现在应该没问题了。
        【解决方案6】:
           static LocalDate getNthOfMonth(int n, int day_of_week, int month, int year)
           {
              if (n == -1)
              {
                 return getNthOfMonth(0, day_of_week, month + 1, year);
              }
              final LocalDate compareDate = new LocalDate(year, month, 1);
              if (compareDate.getDayOfWeek() > day_of_week)
              {
                 return compareDate.withDayOfWeek(day_of_week).plusDays(7 * n);   
              }
              else
              {
                 return compareDate.withDayOfWeek(day_of_week).plusDays(7 * (n - 1));    
              }
           }  
        

        【讨论】:

        • 使用 java.time 类和 TemporalAdjuster 来缩短此代码。见this Answer
        【解决方案7】:

        // 以下方法将给出给定月份和年份的最后一个星期日

        public Date getLastSunday(int month, int year) {
            Calendar cal = Calendar.getInstance();
            cal.set(year, month + 1, 1);
            int dayOftheWeek = cal.get(Calendar.DAY_OF_WEEK);
            int val = dayOftheWeek == Calendar.SUNDAY ? -7: -(dayOftheWeek-1);
            cal.add(Calendar.DAY_OF_MONTH, val);
            return cal.getTime();
        }
        

        //obj.getLastSunday(Calendar.OCTOBER, 2014);

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-29
          • 2020-06-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多