JodaTime有没有办法 轻松 确定哪个星期属于哪个月?
给出月份数字的东西会返回与之相关的一周中的几周。如果一个星期的4天以上,则应与特定月份相关联。
In 2014 for month = 1 then weeks = [1, 2, 3, 4, 5] (note 5 weeks because of 4 days rule)
In 2014 for month = 3 then weeks = [10, 11, 12, 13] (note 4 weeks because of same rule)
我不想计算'手动'......
答案 0 :(得分:6)
您必须为指定的周数实例化DateTime
对象,然后只需阅读其month property(使用Joda-Time和Google Guava)。
DateTime dateTime = new DateTime().withWeekOfWeekyear(i).withDayOfWeek(DateTimeConstants.MONDAY);
if (dateTime.dayOfMonth().getMaximumValue() - dateTime.dayOfMonth().get() < 3) {
dateTime = dateTime.plusMonths(1);
}
int month = dateTime.monthOfYear().get();
我们还可以使用以下功能打印属于他们的所有月份:
public static void main(String[] args) {
Multimap<Integer, Integer> monthsWithWeeks = LinkedListMultimap.create();
int weeksInYear = new DateTime().withYear(2014).weekOfWeekyear().getMaximumValue();
for (int i = 1; i <= weeksInYear; i++) {
DateTime weekDate = new DateTime().withWeekOfWeekyear(i).withDayOfWeek(DateTimeConstants.MONDAY);
if (weekDate.dayOfMonth().getMaximumValue() - weekDate.dayOfMonth().get() < 3) {
weekDate = weekDate.plusMonths(1);
}
int month = weekDate.monthOfYear().get();
monthsWithWeeks.put(month, i);
}
for (Integer month : monthsWithWeeks.keySet()) {
System.out.println(String.format("%d => [%s]", month, Joiner.on(',').join(monthsWithWeeks.get(month))));
}
}
答案 1 :(得分:0)
有趣的问题,虽然我对Joda的经验较少。我试图用jata.util解决它,只需要简单的计算,我想这可以解决你的问题 - 只有没有Joda。
累积一年中一个月的所有周数的方法:
public static Integer[] getWeeksInMonth(int month, int year) {
List<Integer> list = new ArrayList<Integer>();
SimpleDateFormat format = new SimpleDateFormat("w");
Calendar startDate = Calendar.getInstance();
Calendar endDate = Calendar.getInstance();
startDate.set(year, month - 1, 1);
startDate.setMinimalDaysInFirstWeek(4);
endDate.set(year, month, 0);
// Iterate between the start and stop days
while (startDate.getTimeInMillis() <= endDate.getTimeInMillis()) {
Calendar cal = Calendar.getInstance();
cal.setTime(startDate.getTime());
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
// System.out.println("Here here " +
// cal.get(Calendar.DAY_OF_MONTH));
// Start of the week is Monday - check if dates 1, 2, 3 fall after
// Wednesday (specified 4 day rule)
if ((startDate.get(Calendar.DAY_OF_WEEK) > Calendar.THURSDAY)
&& (startDate.get(Calendar.DAY_OF_MONTH) < 4)) {
// If they do, move the dates to next immediate start of the
// week - making it to 4th
startDate.add(Calendar.DAY_OF_MONTH,
(4 - startDate.get(Calendar.DAY_OF_MONTH)));
// Similarly - check if last dates of the month make less than 4
// for that month
} else if ((startDate.get(Calendar.DAY_OF_MONTH) > 25)
&& ((startDate.getActualMaximum(Calendar.DAY_OF_MONTH) - (cal
.get(Calendar.DAY_OF_MONTH))) + 1) < 4) {
// If they do, move the dates to next immediate start of the
// week - making it to next month
startDate
.add(Calendar.DAY_OF_MONTH,
(startDate
.getActualMaximum(Calendar.DAY_OF_MONTH) - startDate
.get(Calendar.DAY_OF_MONTH)) + 1);
} else {
// Get the number of the week
// System.out.println(startDate.getTime());
int week = Integer.parseInt(format.format(startDate.getTime()));
// If December, check if the next year's 1st week falls under
// the 4 day rule, if it does then ignore
if (!(startDate.get(Calendar.MONTH) == Calendar.DECEMBER && week == 1))
list.add(week);
startDate.add(Calendar.WEEK_OF_MONTH, 1);
}
}
return list.toArray(new Integer[list.size()]);
}
调用主要方法:
public static void main(String... args) {
int year = 2014;
System.out.println(":::: YEAR " + year + " ::::");
for (int j = 1; j <= 12; j++) {
Integer[] array = getWeeksInMonth(j, year);
System.out.print("For month : " + j);
System.out.print(" [ ");
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.print("]");
System.out.println();
}
}
输出(可能的测试用例):
:::: YEAR 2014 ::::
For month : 1 [ 1 2 3 4 5 ]
For month : 2 [ 6 7 8 9 ]
For month : 3 [ 10 11 12 13 ]
For month : 4 [ 14 15 16 17 ]
For month : 5 [ 18 19 20 21 22 ]
For month : 6 [ 23 24 25 26 ]
For month : 7 [ 27 28 29 30 31 ]
For month : 8 [ 32 33 34 35 ]
For month : 9 [ 36 37 38 39 ]
For month : 10 [ 40 41 42 43 44 ]
For month : 11 [ 45 46 47 48 ]
For month : 12 [ 49 50 51 52 ]
您可以验证其他测试用例,如果有任何问题,请告诉我。我知道很多计算,但它对要求很灵活。
答案 2 :(得分:0)
使用JodaTime时非常简单:
/** returns first and last week in a month (must have at least 4 days of that week)
* Warning: The first week might be week 53
*/
public static int[] firstAndLastWeeksInMonth(int year, int month) {
int firstweek = new LocalDate(year, month, 4).getWeekOfWeekyear();
int lastweek = new LocalDate(year, month, 1).plusMonths(1).minusDays(4).getWeekOfWeekyear();
return new int[] { firstweek, lastweek };
}
public static List<Integer> weeksInMonth(int year, int month) {
int[] fl = firstAndLastWeeksInMonth(year, month);
ArrayList<Integer> weeks = new ArrayList<Integer>(4);
weeks.add(fl[0]);
for( int w = fl[0] > fl[1] ? 1 : fl[0] + 1; w <= fl[1]; w++ )
weeks.add(w);
return weeks;
}
一些帮助代码,要测试:
static void testWeeksInMonth(int year, int month, boolean printdetail) {
List<Integer> weeks = weeksInMonth(year, month);
System.out.printf("weeks for %d/%d: [%s]\n", year, month, weeks);
LinkedHashMap<Integer, Integer> whist = new LinkedHashMap<Integer, Integer>();
LocalDate d1 = new LocalDate(year, month, 1);
LocalDate d2 = d1.plusMonths(1);
for( LocalDate d = d1; d.isBefore(d2); d = d.plusDays(1) ) {
int wd = d.getWeekOfWeekyear();
if( !whist.containsKey(wd) ) whist.put(wd, 0);
whist.put(wd, whist.get(wd) + 1);
}
List<Integer> weeks2 = new ArrayList<Integer>();
for( Integer wd : whist.keySet() ) {
if( printdetail ) System.out.printf(" ( %d: %d) ", wd, whist.get(wd));
if( whist.get(wd) >= 4 ) weeks2.add(wd);
}
if( printdetail ) System.out.println("");
if( !weeks.equals(weeks2) ) { throw new RuntimeException("bad values"); }
}
public static void main(String[] args) {
LocalDate d = new LocalDate(2010, 1, 1);
for( int i = 0; i < 60; i++ ) {
testWeeksInMonth(d.getYear(), d.getMonthOfYear(), true);
d = d.plusMonths(1);
}
}