java.util.Calendar类是一个抽象类,它提供了在特定的时间戳和一组Calendar字段之间进行转换的方法,例如年,月,日,小时等等,以及用于操作日历字段的方法,比如下星期的日期。时间的戳可以用毫秒值表示,该值是从1970年1月1日格林尼治标准时间00:00:00.000(公历)开始的偏移量。该类还提供了用于在包外实现具体日历系统的其他字段和方法。这些字段和方法被定义为protected。
Calendar对象可以生成实现特定语言和日历样式的日期时间格式所需的所有日历字段值。Calendar定义某些日历字段返回的值的范围及其含义。例如,对于所有日历,日历系统的第一个月都有值month==JANUARY。其他值由具体的子类定义。可以通过调用set方法设置日历字段值。在需要计算其时间值(从纪元开始的毫秒数)或日历字段的值之前,在日历中设置的任何字段值都不会被解释。
Calendar有两种解释日历字段的模式,容错和非容错。当日历处于容错模式时,它接受的日历字段值范围比它产生的值范围更广。当日历重新计算日历字段值以通过get()返回时,所有日历字段都将规范化。例如,容错的GregorianCalendar将MONTH=一月,DAY=32解释为二月一日。
当日历处于非容错模式时,如果日历字段中存在任何不一致,它将引发异常。例如,GregorianCalendar总是生成介于1和月长之间的DAY_OF_MONTH。如果设置了任何超出范围的字段值,则非容错的GregorianCalendar在计算其时间或日历字段值时引发异常。
类名
public abstract class Calendar
implements Serializable, Cloneable, Comparable<Calendar>
变量
/**
* 此日历当前设置时间的日历字段值.
*/
@SuppressWarnings("ProtectedField")
protected int fields[];
/**
* 指示是否设置了日历的指定日历字段的标志。
* 新对象没有设置字段。在第一次调用生成字段的方法之后,
* 这些字段都保持设置不变
*/
@SuppressWarnings("ProtectedField")
protected boolean isSet[];
/**
* 指定每个字段设置时间的伪时间戳。
* 有两个特殊值,UNSET和COMPUTED。
* 从MINIMUM_USER_SET到Integer.MAX_VALUE的值是合法的用户设置值。
*/
transient private int stamp[];
/**
* 此日历的当前设置时间,
* 以1970年1月1日0:00:00 GMT之后的毫秒为单位。
*/
@SuppressWarnings("ProtectedField")
protected long time;
/**
* 如果time的值有效,则为True
*/
@SuppressWarnings("ProtectedField")
protected boolean isTimeSet;
/**
* 如果fields[]与当前设置的时间同步,则为True。
* 如果为false,则下一次尝试获取字段值时将强制从当前值time重新计算所有字段。
*/
@SuppressWarnings("ProtectedField")
protected boolean areFieldsSet;
/**
* 如果已设置所有fields,则为True。
*/
transient boolean areAllFieldsSet;
/**
* 如果此日历允许在从fields[]计算时间期间字段值超出范围,则为True。
*/
private boolean lenient = true;
除了上面这些变量,Calendar还提供了很多时间相关的静态变量,如YEAR、MONTH、WEEK_OF_YEAR ...
实例
Calendar calendar = Calendar.getInstance();
由于Calendar是抽象类,不能使用new关键字。在getInstance()方法中会根据TimeZone时区类型和Locale地区类型创建Calendar对象。
getInstance()
public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(),
Locale.getDefault(Locale.Category.FORMAT));
}
createCalendar(TimeZone zone, Locale aLocale)
private static Calendar createCalendar(TimeZone zone,
Locale aLocale)
{
CalendarProvider provider =
LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
.getCalendarProvider();
if (provider != null) {
try {
//使用Builder创建Calendar
return provider.getInstance(zone, aLocale);
} catch (IllegalArgumentException iae) {
}
}
Calendar cal = null;
if (aLocale.hasExtensions()) {
String caltype = aLocale.getUnicodeLocaleType("ca");
if (caltype != null) {
switch (caltype) {
case "buddhist":
//佛历
cal = new BuddhistCalendar(zone, aLocale);
break;
case "japanese":
//日本历
cal = new JapaneseImperialCalendar(zone, aLocale);
break;
case "gregory":
//公历
cal = new GregorianCalendar(zone, aLocale);
break;
}
}
}
if (cal == null) {
// 如果没有显式指定已知的日历类型,请执行创建日历的传统方法
if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
cal = new BuddhistCalendar(zone, aLocale);
} else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
&& aLocale.getCountry() == "JP") {
cal = new JapaneseImperialCalendar(zone, aLocale);
} else {
cal = new GregorianCalendar(zone, aLocale);
}
}
return cal;
}
获取日期
set(int field, int value)
public void set(int field, int value)
{
// 如果字段部分规范化,请在更改任何字段之前计算所有字段.
if (areFieldsSet && !areAllFieldsSet) {
computeFields();
}
//设置时间属性值
internalSet(field, value);
isTimeSet = false;
areFieldsSet = false;
isSet[field] = true;
//指定每个字段设置时间的伪时间戳
stamp[field] = nextStamp++;
if (nextStamp == Integer.MAX_VALUE) {
//在nextStamp溢出之前调整stamp[]值。
adjustStamp();
}
}
set方法是将给定的日历字段设置为给定值,internalSet方法中只有一句,fields[field] = value;将value值赋值到fields[]属性中。例如set(Calendar.YEAR, 2019)则表示将年份设置成2019年。
get(int field)
public int get(int field)
{
//填写日历字段中任何未设置的字段
complete();
//返回field数组中的值
return internalGet(field);
}
get方法用来获取实例化的Calendar对象储存的年月日时分秒星期等等信息,complete方法主要是对所有日期字段的值进行计算并赋值给相应变量。方法的参数通过Calendar.XXXX的形式填写,比如要想获取年份信息就用Calendar.YEAR、月份Calendar.MONTH、日期Calendar.Date、时Calendar.HOUR、分Calendar.MINUTE、秒Calendar.SECOND等等。
add(int field, int amount)
abstract public void add(int field, int amount);
add方法根据日历的规则,向给定日历字段添加或减去指定的时间量。此方法是抽象方法,调用的时候根据生成的Calendar对象调用对应的add方法。
前一天
Calendar calendar = Calendar.getInstance();
Date time = calendar.getTime();
System.out.println(time);// Fri Feb 28 20:39:10 CST 2020
//昨天
calendar.add(Calendar.DAY_OF_MONTH, -1);
System.out.println(calendar.getTime());
更多精彩内容请关注微信公众号: