Java:如何获得一个月中x天的日期(例如2012年2月的第三个星期一)

jjj*_*jjj 14 java calendar date

我有点挣扎于此.

我想设置我的日历让我们说:2012年2月的第三个星期一. 我没有找到任何使用Java的方法.

例如,如果我想设置2011年圣诞节的日历,我可以通过这种方式轻松完成:

Calendar when = Calendar.getInstance();
when.set (Calendar.MONTH, Calendar.DECEMBER);
when.set (Calendar.DAY_OF_MONTH, 25)
when.set (Calendar.YEAR, 2011);
Run Code Online (Sandbox Code Playgroud)

但我很遗憾如何设置它让我们说2012年阵亡将士纪念日,即5月的最后一个星期一.这是我的代码,但这显然是错误的,因为我根本无法假设5月的最后一个星期一将在当年5月的第4周:

Calendar when = Calendar.getInstance ();
when.set (Calendar.DAY_OF_WEEK,Calendar.MONDAY);
when.set (Calendar.MONTH, Calendar.MAY);
when.set (Calendar.WEEK_OF_MONTH, 4)
when.set (Calendar.YEAR, 2012);
Run Code Online (Sandbox Code Playgroud)

关于我如何以编程方式找出的任何建议,在2012年5月的哪个星期(例如上面的例子)是最后一个星期一?假设我可以获得该信息,我应该能够使我的代码在上面工作.

我需要一些基本上适用于任何其他例子的东西.可以为相同场景提供确切日期的东西.例子:

哪个日期是:

  • 2015年5月第3个星期四
  • 2050年6月1日星期一
  • 2012年12月4日星期二
  • 2000年7月2日星期三

我真的需要这个用于我的项目,我确信这很简单,但是我在这个没有任何实际结果的情况下突破了我的头脑:)并且在网上也找不到任何东西.


添加:

好的,这是我一个月的最后一个星期一的地方:

when.set (GregorianCalendar.MONTH, GregorianCalendar.MAY);
when.set (GregorianCalendar.DAY_OF_WEEK, Calendar.MONDAY);
when.set (GregorianCalendar.DAY_OF_WEEK_IN_MONTH, -1);
when.set (Calendar.YEAR, 2012);
Run Code Online (Sandbox Code Playgroud)

但我不知道我会在同一个月的星期一如何做这样的事情,就像这样?

when.set (GregorianCalendar.DAY_OF_WEEK_IN_MONTH, 2);
Run Code Online (Sandbox Code Playgroud)

有什么建议?

leo*_*loy 11

用Java做日期算术(一般来说,除了最琐碎的事情之外,用日期时间做任何事情)Joda-Time就是答案:

public static LocalDate getNDayOfMonth(int dayweek,int nthweek,int month,int year)  {
   LocalDate d = new LocalDate(year, month, 1).withDayOfWeek(dayweek);
   if(d.getMonthOfYear() != month) d = d.plusWeeks(1);
   return d.plusWeeks(nthweek-1);
}

public static LocalDate getLastWeekdayOfMonth(int dayweek,int month,int year) {
   LocalDate d = new LocalDate(year, month, 1).plusMonths(1).withDayOfWeek(dayweek);
   if(d.getMonthOfYear() != month) d = d.minusWeeks(1);
  return d;
}

public static void main(String[] args) {
   // second wednesday of oct-2011
   LocalDate d = getNDayOfMonth( DateTimeConstants.WEDNESDAY, 2, 10, 2011);
   System.out.println(d);
   // last wednesday of oct-2011
   LocalDate dlast = getLastWeekdayOfMonth( DateTimeConstants.WEDNESDAY,  10, 2011);
   System.out.println(dlast);
}
Run Code Online (Sandbox Code Playgroud)

编辑:自Java 8(2014)java.time以来,应该首选新的Date API(包),它受到Jodatime的启发/类似.


Ros*_*lls 7

以下代码已成功测试2013年和2014年的所有假期.我意识到这并没有真正回答原始问题,但我认为这对于遇到这篇文章的人来说可能是有用的,希望能找到如何使用假期使用日历.

public static boolean isMajorHoliday(java.util.Date date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);

    // check if New Year's Day
    if (cal.get(Calendar.MONTH) == Calendar.JANUARY
        && cal.get(Calendar.DAY_OF_MONTH) == 1) {
        return true;
    }

    // check if Christmas
    if (cal.get(Calendar.MONTH) == Calendar.DECEMBER
        && cal.get(Calendar.DAY_OF_MONTH) == 25) {
        return true;
    }

    // check if 4th of July
    if (cal.get(Calendar.MONTH) == Calendar.JULY
        && cal.get(Calendar.DAY_OF_MONTH) == 4) {
        return true;
    }

    // check Thanksgiving (4th Thursday of November)
    if (cal.get(Calendar.MONTH) == Calendar.NOVEMBER
        && cal.get(Calendar.DAY_OF_WEEK_IN_MONTH) == 4
        && cal.get(Calendar.DAY_OF_WEEK) == Calendar.THURSDAY) {
        return true;
    }

    // check Memorial Day (last Monday of May)
    if (cal.get(Calendar.MONTH) == Calendar.MAY
        && cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY
        && cal.get(Calendar.DAY_OF_MONTH) > (31 - 7) ) {
        return true;
    }

    // check Labor Day (1st Monday of September)
    if (cal.get(Calendar.MONTH) == Calendar.SEPTEMBER
        && cal.get(Calendar.DAY_OF_WEEK_IN_MONTH) == 1
        && cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {
        return true;
    }

    // check President's Day (3rd Monday of February)
    if (cal.get(Calendar.MONTH) == Calendar.FEBRUARY
        && cal.get(Calendar.DAY_OF_WEEK_IN_MONTH) == 3
        && cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {
        return true;
    }

    // check Veterans Day (November 11)
    if (cal.get(Calendar.MONTH) == Calendar.NOVEMBER
        && cal.get(Calendar.DAY_OF_MONTH) == 11) {
        return true;
    }

    // check MLK Day (3rd Monday of January)
    if (cal.get(Calendar.MONTH) == Calendar.JANUARY
        && cal.get(Calendar.DAY_OF_WEEK_IN_MONTH) == 3
        && cal.get(Calendar.DAY_OF_WEEK) == Calendar.MONDAY) {
        return true;
    }

    return false;

}
Run Code Online (Sandbox Code Playgroud)


Bas*_*que 5

太长了;博士

\n\n
LocalDate thirdMondayInFebruary2012 = \n    YearMonth.of( 2012 , Month.FEBRUARY )\n             .atDay( 1 )\n             .with( TemporalAdjusters.dayOfWeekInMonth( 3 , DayOfWeek.MONDAY ) );\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xe2\x80\xa6 和 \xe2\x80\xa6

\n\n
LocalDate lastMondayInMay2012 = \n    YearMonth.of( 2012 , Month.MAY )\n             .atDay( 1 );\n             .with( TemporalAdjusters.lastInMonth( DayOfWeek.MONDAY ) );\n
Run Code Online (Sandbox Code Playgroud)\n\n

java.time

\n\n

使用 java.time 类非常容易做到,这些类现在取代了 Joda-Time 和与最早版本的 Java 捆绑在一起的麻烦的旧日期时间类。

\n\n

首先我们需要指定所需的月份。班级YearMonth可以做到这一点。从那里我们得到一个LocalDate,一个没有时间和时区的日期。

\n\n
YearMonth ym = YearMonth.of( 2012 , Month.FEBRUARY ); // Or pass \'2\' for \'February\'.\nLocalDate ld = ym.atDay( 1 );\n
Run Code Online (Sandbox Code Playgroud)\n\n

TemporalAdjuster接口提供将日期时间值调整为另一个日期时间值的功能。类提供的实现TemporalAdjusters(注意复数\'s\')。使用方便的DayOfWeek枚举指定一周中的某一天。

\n\n
int ordinal = 3 ; // Use \'3\' for \'third occurrence in month\' such as \'3rd Monday\'.\nLocalDate thirdMondayInFebruary2012 = ld.with( TemporalAdjusters.dayOfWeekInMonth( ordinal , DayOfWeek.MONDAY ) );\n
Run Code Online (Sandbox Code Playgroud)\n\n

提示:不要在代码库中仅传递年份和月份的整数,而是传递诸如YearMonthYearMonth和 之类的对象DayOfWeek。这样做可以消除歧义,使您的代码更加自我记录,提供类型安全并确保有效值。

\n\n
\n\n

关于java.time

\n\n

java.time框架内置于 Java 8 及更高版本中这些类取代了麻烦的旧遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

\n\n

Joda -Time项目现在处于维护模式,建议迁移到java.time类。

\n\n

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

\n\n

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

\n\n

从哪里获取 java.time 类?

\n\n\n\n

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

\n