如何获得序平日一个月

问题描述:

您好我想用Java做一个程序,其中天,weekNo是本月或参数..Like第一个星期五每月的第二个星期一..和返回日期如何获得序平日一个月

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

这应该做你想做的。
编辑: 多带些计算步骤,你可以有结果:)(对不起,迷惑你的标题)

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 
+0

我格式化了代码并修复了语法错误。但是仍然有一个巨大的bug,你应该修复(提示:只是尝试运行这个) – 2010-11-09 09:25:23

+0

@seanizer谢谢,更新的代码。 – 2010-11-09 09:34:43

+0

Joda时间不仅更好:JODA时间岩石日期/时间操作 – iirekm 2010-11-09 13:31:19

这里有一个工具方法,这样做,使用DateUtilsApache 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) 
); 

输出:

周四11月18日00:00:00 CET 2010
周三08年12月CET 00:00:00 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

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/Casablanca,或Pacific/Auckland。切勿使用3-4字母缩写,如ESTIST,因为它们是而不是真正的时区,不是标准化的,甚至不是唯一的(!)。

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.Date,Calendar,& SimpleDateFormat

Joda-Time项目现在位于maintenance mode,建议迁移到java.time类。请参阅Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。规格是JSR 310

从何处获取java.time类?

ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,如Interval,YearWeek,YearQuartermore

+0

@MoinuddinQuadri我经常关闭问题作为重复,特别是日期时间问题。我邀请你也这样做。然而,这种情况*不是重复的。虽然这两个分享月份中序数的主题,但它们并不相同。另一个问题适用于Android。另一个问题涉及循环和收集一系列日期。另一个问题涉及'EnumSet','List'和'YearMonth',这里没有提到。本答案显示了多个TemporalAdjusters,另一个只有一个。我会复制粘贴一些样板文件,但不是完整的答案。 – 2017-01-31 21:44:15