最近在做日历相关的需求的时候,会经常需要获取当前日期的 月份第一天,上个月,的日期,接触最多的就是set() add()方法,
1. 先看看set()方法的使用
获取当前日期所处的月份的第一天
public static String getThisMothFirstDayFormat(Calendar calendar, String format) {
//拷贝传过来的日期,避免会同时修改原有日期
Calendar calendarNow = (Calendar) calendar.clone();
//调用set方法把当前月份设为第一天
calendarNow.set(Calendar.DAY_OF_MONTH, 1);
return new SimpleDateFormat(format).format(calendarNow);
}
设置当前月份为第一个月
public static String getThisMothFirstDayFormat(Calendar calendar, String format) {
//拷贝原有日期
Calendar calendarNow = (Calendar) calendar.clone();
calendarNow.set(Calendar.DAY_OF_MONTH, 1);
return new SimpleDateFormat(format).format(calendarNow);
}
2. 再看看add()方法的使用
获取当前日期日期的后一天
public static String getNowBeforeDays(Calendar calendar, String formatString) {
Calendar nowCalendar = (Calendar) calendar.clone();
//调用add()第一个参数传日,第二个传-1
nowCalendar.add(Calendar.DAY_OF_MONTH, -1);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formatString);
return simpleDateFormat.format(nowCalendar.getTime());
}
获取当前日期的后一个月
public static String getNowBeforeDays(Calendar calendar, String formatString) {
Calendar nowCalendar = (Calendar) calendar.clone();
//调用add()第一个参数传月,第二个传1
nowCalendar.add(Calendar.MONTH, 1);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formatString);
return simpleDateFormat.format(nowCalendar.getTime());
}
3.源码解析
public void set(int field, int value)
{
// If the fields are partially normalized, calculate all the
// fields before changing any fields.
if (areFieldsSet && !areAllFieldsSet) {
computeFields();
}
//1 .调用interSet()
internalSet(field, value);
isTimeSet = false;
areFieldsSet = false;
isSet[field] = true;
stamp[field] = nextStamp++;
if (nextStamp == Integer.MAX_VALUE) {
adjustStamp();
}
}
final void internalSet(int field, int value)
{
//fieleds是数组,根据field下标去修改值
fields[field] = value;
}
由此可见当我们调用set()方法时,就是修改它的值
Calendar.java
abstract public void add(int field, int amount);
//点进去看是抽象方法,所以去他的实现类中找
GregorianCalendar.java
//因代码过长我们只看核心部分
public void add(int field, int amount) {
...
//当field是年的时候
if (field == YEAR) {
int year = internalGet(YEAR);
if (internalGetEra() == CE) {
//year加上amount
year += amount;
if (year > 0) {
把上面加减的结果在设置到YEAR中,设置的流程就是上面分析的set()方法
set(YEAR, year);
} else { // year <= 0
set(YEAR, 1 - year);
// if year == 0, you get 1 BCE.
set(ERA, BCE);
}
}
else { // era == BCE
year -= amount;
if (year > 0) {
set(YEAR, year);
} else { // year <= 0
set(YEAR, 1 - year);
// if year == 0, you get 1 CE
set(ERA, CE);
}
}
pinDayOfMonth();
}
//Month同year
else if (field == MONTH) {
int month = internalGet(MONTH) + amount;
int year = internalGet(YEAR);
int y_amount;
if (month >= 0) {
y_amount = month/12;
} else {
y_amount = (month+1)/12 - 1;
}
if (y_amount != 0) {
if (internalGetEra() == CE) {
year += y_amount;
if (year > 0) {
set(YEAR, year);
} else { // year <= 0
set(YEAR, 1 - year);
// if year == 0, you get 1 BCE
set(ERA, BCE);
}
}
else { // era == BCE
year -= y_amount;
if (year > 0) {
set(YEAR, year);
} else { // year <= 0
set(YEAR, 1 - year);
// if year == 0, you get 1 CE
set(ERA, CE);
}
}
}
if (month >= 0) {
set(MONTH, month % 12);
} else {
// month < 0
month %= 12;
if (month < 0) {
month += 12;
}
set(MONTH, JANUARY + month);
}
pinDayOfMonth();
} else if (field == ERA) {
int era = internalGet(ERA) + amount;
if (era < 0) {
era = 0;
}
if (era > 1) {
era = 1;
}
set(ERA, era);
} else {
long delta = amount;
long timeOfDay = 0;
switch (field) {
// Handle the time fields here. Convert the given
// amount to milliseconds and call setTimeInMillis.
case HOUR:
case HOUR_OF_DAY:
delta *= 60 * 60 * 1000; // hours to minutes
break;
case MINUTE:
delta *= 60 * 1000; // minutes to seconds
break;
case SECOND:
delta *= 1000; // seconds to milliseconds
break;
case MILLISECOND:
break;
// Handle week, day and AM_PM fields which involves
// time zone offset change adjustment. Convert the
// given amount to the number of days.
case WEEK_OF_YEAR:
case WEEK_OF_MONTH:
case DAY_OF_WEEK_IN_MONTH:
delta *= 7;
break;
case DAY_OF_MONTH: // synonym of DATE
case DAY_OF_YEAR:
case DAY_OF_WEEK:
break;
case AM_PM:
// Convert the amount to the number of days (delta)
// and +12 or -12 hours (timeOfDay).
delta = amount / 2;
timeOfDay = 12 * (amount % 2);
break;
}
// The time fields don't require time zone offset change
// adjustment.
if (field >= HOUR) {
setTimeInMillis(time + delta);
return;
}
// The rest of the fields (week, day or AM_PM fields)
// require time zone offset (both GMT and DST) change
// adjustment.
// Translate the current time to the fixed date and time
// of the day.
long fd = getCurrentFixedDate();
timeOfDay += internalGet(HOUR_OF_DAY);
timeOfDay *= 60;
timeOfDay += internalGet(MINUTE);
timeOfDay *= 60;
timeOfDay += internalGet(SECOND);
timeOfDay *= 1000;
timeOfDay += internalGet(MILLISECOND);
if (timeOfDay >= ONE_DAY) {
fd++;
timeOfDay -= ONE_DAY;
} else if (timeOfDay < 0) {
fd--;
timeOfDay += ONE_DAY;
}
fd += delta; // fd is the expected fixed date after the calculation
// BEGIN Android-changed: time zone related calculation via helper methods
// Calculate the time in the UTC time zone.
long utcTime = (fd - EPOCH_OFFSET) * ONE_DAY + timeOfDay;
// Neither of the time zone related fields are relevant because they have not been
// set since the call to complete() above.
int tzMask = 0;
// Adjust the time to account for zone and daylight savings time offset.
long millis = adjustForZoneAndDaylightSavingsTime(tzMask, utcTime, getZone());
// Update the time and recompute the fields.
setTimeInMillis(millis);
// END Android-changed: time zone related calculation via helper methods
}
}
总结
set() 方法就是直接修改
add() 方法就是被当前值就行加减