如何获得序平日一个月
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
这里有一个工具方法,这样做,使用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)
);
输出:
周四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
其他答案现在已过时。麻烦的旧日期时间类(Date
,Calendar
等)现在是legacy,由java.time类代替。
LocalDate
的LocalDate
类表示没有时间一天和不同时区的日期,唯一的价值。
时区对确定日期至关重要。对于任何特定的时刻,日期因地区而异。例如,Paris France午夜后几分钟是新的一天,而在Montréal Québec仍然是“昨天”。
在continent/region
的格式指定一个proper time zone name,如America/Montreal
,Africa/Casablanca
,或Pacific/Auckland
。切勿使用3-4字母缩写,如EST
或IST
,因为它们是而不是真正的时区,不是标准化的,甚至不是唯一的(!)。
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类?
-
Java SE 8和SE 9后来
- 内置。
- 带捆绑实现的标准Java API的一部分。
- Java 9增加了一些次要功能和修复。在ThreeTen-Backport
-
Java SE 6和SE 7
- 大部分的java.time功能后移植到Java 6 & 7。
-
Android
- 的ThreeTenABP项目适应ThreeTen-反向移植(上述)为Android特异性。
- 参见How to use ThreeTenABP…。
的ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,如Interval
,YearWeek
,YearQuarter
和more。
@MoinuddinQuadri我经常关闭问题作为重复,特别是日期时间问题。我邀请你也这样做。然而,这种情况*不是重复的。虽然这两个分享月份中序数的主题,但它们并不相同。另一个问题适用于Android。另一个问题涉及循环和收集一系列日期。另一个问题涉及'EnumSet','List'和'YearMonth',这里没有提到。本答案显示了多个TemporalAdjusters,另一个只有一个。我会复制粘贴一些样板文件,但不是完整的答案。 – 2017-01-31 21:44:15
我格式化了代码并修复了语法错误。但是仍然有一个巨大的bug,你应该修复(提示:只是尝试运行这个) – 2010-11-09 09:25:23
@seanizer谢谢,更新的代码。 – 2010-11-09 09:34:43
Joda时间不仅更好:JODA时间岩石日期/时间操作 – iirekm 2010-11-09 13:31:19