如何在一个月内获得序数平日

时间:2010-11-09 08:06:21

标签: java date ordinal localdate

嗨我想在java中创建一个程序,其中days,weekNo是参数..类似于月的第一个星期五或月的第二个星期一..它返回日期

4 个答案:

答案 0 :(得分:5)

以下是使用DateUtils中的Apache Commons / Lang执行此操作的实用程序方法:

/**
 * Get the n-th x-day of the month in which the specified date lies.  
 * @param input the specified date
 * @param weeks 1-based offset (e.g. 1 means 1st week)
 * @param targetWeekDay (the weekday we're looking for, e.g. Calendar.MONDAY
 * @return the target date
 */
public static Date getNthXdayInMonth(final Date input,
    final int weeks,
    final int targetWeekDay){

    // strip all date fields below month
    final Date startOfMonth = DateUtils.truncate(input, Calendar.MONTH);
    final Calendar cal = Calendar.getInstance();
    cal.setTime(startOfMonth);
    final int weekDay = cal.get(Calendar.DAY_OF_WEEK);
    final int modifier = (weeks - 1) * 7 + (targetWeekDay - weekDay);
    return modifier > 0
        ? DateUtils.addDays(startOfMonth, modifier)
        : startOfMonth;
}

测试代码:

// Get this month's third thursday
System.out.println(getNthXdayInMonth(new Date(), 3, Calendar.THURSDAY));

// Get next month's second wednesday:
System.out.println(getNthXdayInMonth(DateUtils.addMonths(new Date(), 1),
    2,
    Calendar.WEDNESDAY)
);

<强>输出:

  

2010年11月18日星期四00:00:00 CET 2010年   2010年12月8日星期三00:00:00 CET 2010


这是相同代码的JodaTime版本(之前我从未使用过JodaTime,所以可能有一种更简单的方法):

/**
 * Get the n-th x-day of the month in which the specified date lies.
 * 
 * @param input
 *            the specified date
 * @param weeks
 *            1-based offset (e.g. 1 means 1st week)
 * @param targetWeekDay
 *            (the weekday we're looking for, e.g. DateTimeConstants.MONDAY
 * @return the target date
 */
public static DateTime getNthXdayInMonthUsingJodaTime(final DateTime input,
    final int weeks,
    final int targetWeekDay){

    final DateTime startOfMonth =
        input.withDayOfMonth(1).withMillisOfDay(0);
    final int weekDay = startOfMonth.getDayOfWeek();
    final int modifier = (weeks - 1) * 7 + (targetWeekDay - weekDay);
    return modifier > 0 ? startOfMonth.plusDays(modifier) : startOfMonth;
}

测试代码:

// Get this month's third thursday
System.out.println(getNthXdayInMonthUsingJodaTime(new DateTime(),
    3,
    DateTimeConstants.THURSDAY));

// Get next month's second wednesday:
System.out.println(getNthXdayInMonthUsingJodaTime(new DateTime().plusMonths(1),
    2,
    DateTimeConstants.WEDNESDAY));

<强>输出:

  

2010-11-18T00:00:00.000 + 01:00
  2010-12-08T00:00:00.000 + 01:00

答案 1 :(得分:1)

  public static Date getDate(int day, int weekNo, int month, int year) {
    Calendar cal = Calendar.getInstance();
    cal.set(Calendar.DATE,1);
    cal.set(Calendar.YEAR, year);
    cal.set(Calendar.MONTH, month);
    for (int i = 0; i < 31; i++) {
        if (cal.get(Calendar.WEEK_OF_MONTH) == weekNo
                && cal.get(Calendar.DAY_OF_WEEK) == day) {
            return cal.getTime();
        }
        cal.add(Calendar.DATE,1);
    }
    return null;
  }

致电代码

System.out.println(""+getDate(Calendar.MONDAY, 2, Calendar.DECEMBER,2010));

输出

Mon Dec 06 15:09:00 IST 2010

答案 2 :(得分:0)

TL;博士

LocalDate firstFridayThisMonth =
    LocalDate.now( ZoneId.of( "America/Montreal" ) )
             .with( TemporalAdjusters.firstInMonth( DayOfWeek.FRIDAY ) )

使用java.time

其他答案现已过时。麻烦的旧日期时间类(DateCalendar等)现在是legacy,取而代之的是java.time类。

LocalDate

LocalDate类表示没有时间且没有时区的仅限日期的值。

时区对于确定日期至关重要。对于任何给定的时刻,日期在全球范围内因地区而异。例如,在Paris France午夜后的几分钟是新的一天,而Montréal Québec中仍然是“昨天”。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4字母缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

TemporalAdjuster

TemporalAdjuster接口提供了操作日期时间值的功能。 java.time类使用不可变对象,因此结果始终是一个全新的对象,其值基于原始值。

TemporalAdjusters类(注释复数名称)提供了几个方便的实现。其中包括在一个月内获得序数的星期几:firstInMonth()lastInMonth()dayOfWeekInMonth()。所有这些都采用DayOfWeek枚举对象的参数。

LocalDate firstFridayOfThisMonth = 
    today.with(
        TemporalAdjusters.firstInMonth( DayOfWeek.FRIDAY ) 
    )
;

...和...

LocalDate secondMondayOfThisMonth = 
    today.with(
        TemporalAdjusters.dayOfWeekInMonth( 2 , DayOfWeek.MONDAY ) 
    )
;

...和...

LocalDate thirdWednesdayOfNextMonth = 
    today.plusMonths( 1 )
         .with(  
             TemporalAdjusters.dayOfWeekInMonth( 3 , DayOfWeek.WEDNESDAY )  
         )
;

关于java.time

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

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

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 3 :(得分:-1)

Calendar cal = Calendar.getInstance();
int dayofweek = cal.get(Calendar.DAY_OF_WEEK);

这应该做你想要的。
修改: 通过一些更多的计算步骤,你可能有结果:)(抱歉混淆你的标题)