用过Outlook的同学都知道在Inbox中如果选择"Arranged By: Date",所有的邮件会按照日期进行排序或者分组。
这样分组后对邮件的大概接收日期范围就比较清晰了。
以下是类似的实现:
import java.util.ArrayList;
import java.util.Calendar;
public class DateGroup {
public static final int GROUP_INVALID = 0;
public static final int GROUP_BEYOND_NEXT_MONTH = GROUP_INVALID + 1;
public static final int GROUP_NEXT_MONTH = GROUP_BEYOND_NEXT_MONTH + 1;
public static final int GROUP_LATER_THIS_MONTH = GROUP_NEXT_MONTH + 1;
public static final int GROUP_3_WEEKS_AWAY = GROUP_LATER_THIS_MONTH + 1;
public static final int GROUP_2_WEEKS_AWAY = GROUP_3_WEEKS_AWAY + 1;
public static final int GROUP_NEXT_WEEK = GROUP_2_WEEKS_AWAY + 1;
public static final int GROUP_THIS_WEEK_AFTER_TOMORROW = GROUP_NEXT_WEEK + 1;
public static final int GROUP_TOMORROW = GROUP_THIS_WEEK_AFTER_TOMORROW + 1;
public static final int GROUP_TODAY = GROUP_TOMORROW + 1;
public static final int GROUP_YESTERDAY = GROUP_TODAY + 1;
public static final int GROUP_THIS_WEEK_BEFORE_YESTERDAY = GROUP_YESTERDAY + 1;
public static final int GROUP_LAST_WEEK = GROUP_THIS_WEEK_BEFORE_YESTERDAY + 1;
public static final int GROUP_2_WEEKS_AGO = GROUP_LAST_WEEK + 1;
public static final int GROUP_3_WEEKS_AGO = GROUP_2_WEEKS_AGO + 1;
public static final int GROUP_EARLIER_THIS_MONTH = GROUP_3_WEEKS_AGO + 1;
public static final int GROUP_LAST_MONTH = GROUP_EARLIER_THIS_MONTH + 1;
public static final int GROUP_OLDER = GROUP_LAST_MONTH + 1;
/**
* Get the date group for a sorted date list (like outlook inbox):
*
* <pre>
* Groups:
* beyond next month: yyyy/MM/dd
* next month: yyyy/MM/dd
* later this month: yyyy/MM/dd
* three weeks away: yyyy/MM/dd
* two weeks away: yyyy/MM/dd
* next week: MM/dd (week)
* this week after tomorrow: HH:mm
* tomorrow: HH:mm
* today: HH:mm
* yesterday: HH:mm
* this week before yesterday: HH:mm
* last week: MM/dd (week)
* two weeks ago: yyyy/MM/dd
* three weeks ago: yyyy/MM/dd
* earlier this month: yyyy/MM/dd
* last month: yyyy/MM/dd
* older: yyyy/MM/dd
* </pre>
*
* @param dateList
* - the sorted date list (ASC or DESC)
* @return
*/
public static int[] getDateGroup(ArrayList<Calendar> dateList) {
return getDateGroup(getToday(), dateList);
}
public static int[] getDateGroup(Calendar today, ArrayList<Calendar> dateList) {
int size = dateList.size();
int[] groupArray = new int[size];
for (int i = 0; i < size; i++) {
groupArray[i] = getGroupOfDate(dateList.get(i), today);
}
return groupArray;
}
public static int getGroupOfDate(Calendar date, Calendar today) {
if (isToday(date, today))
return DateGroup.GROUP_TODAY;
if (date.after(today)) {
if (isBeyondNextMonth(date, today))
return DateGroup.GROUP_BEYOND_NEXT_MONTH;
if (isTomorrow(date, today))
return DateGroup.GROUP_TOMORROW;
if (isSameWeek(date, today))
return DateGroup.GROUP_THIS_WEEK_AFTER_TOMORROW;
if (isNextWeek(date, today))
return DateGroup.GROUP_NEXT_WEEK;
if (isTwoWeeksAway(date, today))
return DateGroup.GROUP_2_WEEKS_AWAY;
if (isThreeWeeksAway(date, today))
return DateGroup.GROUP_3_WEEKS_AWAY;
if (isSameMonth(date, today))
return DateGroup.GROUP_LATER_THIS_MONTH;
if (isNextMonth(date, today))
return DateGroup.GROUP_NEXT_MONTH;
} else {
if (isOlder(date, today))
return DateGroup.GROUP_OLDER;
if (isYesterday(date, today))
return DateGroup.GROUP_YESTERDAY;
if (isSameWeek(date, today))
return DateGroup.GROUP_THIS_WEEK_BEFORE_YESTERDAY;
if (isLastWeek(date, today))
return DateGroup.GROUP_LAST_WEEK;
if (isTwoWeeksAgo(date, today))
return DateGroup.GROUP_2_WEEKS_AGO;
if (isThreeWeeksAgo(date, today))
return DateGroup.GROUP_3_WEEKS_AGO;
if (isSameMonth(date, today))
return DateGroup.GROUP_EARLIER_THIS_MONTH;
if (isLastMonth(date, today))
return DateGroup.GROUP_LAST_MONTH;
}
return DateGroup.GROUP_INVALID;
}
public static Calendar getToday() {
return Calendar.getInstance();
}
private static Calendar getDate(Calendar date) {
Calendar c = Calendar.getInstance();
c.setTime(date.getTime());
return c;
}
private static Calendar getDate(long date) {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(date);
return c;
}
private static Calendar getYesterday(Calendar today) {
Calendar date = getDate(today);
date.add(Calendar.DATE, -1);
return date;
}
private static Calendar getTommorow(Calendar today) {
Calendar date = getDate(today);
date.add(Calendar.DATE, 1);
return date;
}
private static Calendar getNextNWeek(int weeksAway, Calendar today) {
Calendar date = getDate(today);
date.add(Calendar.WEEK_OF_YEAR, weeksAway);
return date;
}
private static Calendar getNextNMonth(int monthsAway, Calendar today) {
Calendar date = getDate(today);
date.add(Calendar.MONTH, monthsAway);
return date;
}
private static boolean isSameDay(Calendar date1, Calendar date2) {
return date1.get(Calendar.YEAR) == date2.get(Calendar.YEAR)
&& date1.get(Calendar.MONTH) == date2.get(Calendar.MONTH)
&& date1.get(Calendar.DATE) == date2.get(Calendar.DATE);
}
private static boolean isSameMonth(Calendar date1, Calendar date2) {
return date1.get(Calendar.YEAR) == date2.get(Calendar.YEAR)
&& date1.get(Calendar.MONTH) == date2.get(Calendar.MONTH);
}
private static boolean isSameWeek(Calendar date1, Calendar date2) {
return date1.get(Calendar.WEEK_OF_YEAR) == date2.get(Calendar.WEEK_OF_YEAR);
}
private static boolean isBeyondNextMonth(Calendar date, Calendar today) {
Calendar nextMonth = getNextNMonth(1, today);
int nextMonthYear = nextMonth.get(Calendar.YEAR);
int dateYear = date.get(Calendar.YEAR);
if (nextMonthYear == dateYear) {
return date.get(Calendar.MONTH) > nextMonth.get(Calendar.MONTH);
}
return dateYear > nextMonthYear;
}
private static boolean isNextMonth(Calendar date, Calendar today) {
return isSameMonth(getNextNMonth(1, today), date);
}
private static boolean isThreeWeeksAway(Calendar date, Calendar today) {
return isSameWeek(date, getNextNWeek(3, today));
}
private static boolean isTwoWeeksAway(Calendar date, Calendar today) {
return isSameWeek(date, getNextNWeek(2, today));
}
private static boolean isNextWeek(Calendar date, Calendar today) {
return isSameWeek(date, getNextNWeek(1, today));
}
private static boolean isTomorrow(Calendar date, Calendar today) {
return isSameDay(getTommorow(today), date);
}
private static boolean isToday(Calendar date, Calendar today) {
return isSameDay(today, date);
}
private static boolean isYesterday(Calendar date, Calendar today) {
return isSameDay(getYesterday(today), date);
}
private static boolean isLastWeek(Calendar date, Calendar today) {
return isSameWeek(date, getNextNWeek(-1, today));
}
private static boolean isTwoWeeksAgo(Calendar date, Calendar today) {
return isSameWeek(date, getNextNWeek(-2, today));
}
private static boolean isThreeWeeksAgo(Calendar date, Calendar today) {
return isSameWeek(date, getNextNWeek(-3, today));
}
private static boolean isLastMonth(Calendar date, Calendar today) {
return isSameMonth(getNextNMonth(-1, today), date);
}
private static boolean isOlder(Calendar date, Calendar today) {
Calendar nextMonth = getNextNMonth(-1, today);
int nextMonthYear = nextMonth.get(Calendar.YEAR);
int dateYear = date.get(Calendar.YEAR);
if (nextMonthYear == dateYear) {
return date.get(Calendar.MONTH) < nextMonth.get(Calendar.MONTH);
}
return dateYear < nextMonthYear;
}
}