Java中的Calendar日历API用法完全解析

2023-10-27

第一部分 Calendar介绍

Calendar 定义:

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {}
Calendar 可以看作是一个抽象类。
它的实现,采用了设计模式中的工厂方法。表现在:当我们获取Calendar实例时,Calendar会根据传入的参数来返回相应的Calendar对象。获取Calendar实例,有以下两种方式:
(1) 当我们通过 Calendar.getInstance() 获取日历时,默认的是返回的一个GregorianCalendar对象。
     GregorianCalendar是Calendar的一个实现类,它提供了世界上大多数国家/地区使用的标准日历系统。
(2) 当我们通过 Calendar.getInstance(TimeZone timezone, Locale locale) 或 Calendar.getInstance(TimeZone timezone) 或 Calendar.getInstance(Locale locale)获取日历时,是返回“对应时区(zone) 或 地区(local)等所使用的日历”。
     例如,若是日本,则返回JapaneseImperialCalendar对象。

参考如下代码:

public static Calendar getInstance()
{
 // 调用createCalendar()创建日历
 Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault());
 cal.sharedZone = true;
 return cal;
}
 
 
public static Calendar getInstance(TimeZone zone)
{
 // 调用createCalendar()创建日历
 return createCalendar(zone, Locale.getDefault());
}
 
 
public static Calendar getInstance(Locale aLocale) {
 // 调用createCalendar()创建日历
 Calendar cal = createCalendar(TimeZone.getDefaultRef(), aLocale);
 cal.sharedZone = true;
 return cal;
}
 
public static Calendar getInstance(TimeZone zone,
   Locale aLocale)
{
 // 调用createCalendar()创建日历
 return createCalendar(zone, aLocale);
}
 
private static Calendar createCalendar(TimeZone zone,
   Locale aLocale)
{
 // (01) 若地区是“th”,则返回BuddhistCalendar对象
 // (02) 若地区是“JP”,则返回JapaneseImperialCalendar对象
 if ("th".equals(aLocale.getLanguage())
 && ("TH".equals(aLocale.getCountry()))) {
 return new sun.util.BuddhistCalendar(zone, aLocale);
 } else if ("JP".equals(aLocale.getVariant())
 && "JP".equals(aLocale.getCountry())
 && "ja".equals(aLocale.getLanguage())) {
 return new JapaneseImperialCalendar(zone, aLocale);
 } 
 
 // (03) 否则,返回GregorianCalendar对象
 return new GregorianCalendar(zone, aLocale); 
}

当我们获取Calendar实例之后,就可以通过Calendar提供的一些列方法来操作日历。

第二部分 Calendar的原理和思想
我们使用Calendar,无非是操作Calendar的“年、月、日、星期、时、分、秒”这些字段。下面,我们对这些字段的的来源、定义以及计算方法进行学习。
1. Calendar 各个字段值的来源

我们使用Calendar,无非是使用“年、月、日、星期、时、分、秒”等信息。那么它是如何做到的呢? 本质上,Calendar就是保存了一个时间。如下定义:

// time 是当前时间,单位是毫秒。
// 它是当前时间距离“January 1, 1970, 0:00:00 GMT”的差值。
protected long time;

Calendar就是根据 time 计算出 “Calendar的年、月、日、星期、时、分、秒”等等信息。

2. Calendar 各个字段的定义和初始化
Calendar 的“年、月、日、星期、时、分、秒”这些信息,一共是17个字段。
我们使用Calendar,无非是就是使用这17个字段。它们的定义如下:
(字段0) public final static int ERA = 0;
说明:纪元。
取值:只能为0 或 1。0表示BC(“before Christ”,即公元前),1表示AD(拉丁语“Anno Domini”,即公元)。
(字段1) public final static int YEAR = 1;
说明:年。
(字段2) public final static int MONTH = 2;
说明:月
取值:可以为,JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER, UNDECIMBER。
     其中第一个月是 JANUARY,它为 0。
(字段3) public final static int WEEK_OF_YEAR = 3;
说明:当前日期在本年中对应第几个星期。一年中第一个星期的值为 1。
(字段4) public final static int WEEK_OF_MONTH = 4;
说明:当前日期在本月中对应第几个星期。一个月中第一个星期的值为 1。
(字段5) public final static int DATE = 5;
说明:日。一个月中第一天的值为 1。
(字段5) public final static int DAY_OF_MONTH = 5;
说明:同“DATE”,表示“日”。
(字段6) public final static int DAY_OF_YEAR = 6;
说明:当前日期在本年中对应第几天。一年中第一天的值为 1。
(字段7) public final static int DAY_OF_WEEK = 7;
说明:星期几。
取值:可以为,SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY 和 SATURDAY。
     其中,SUNDAY为1,MONDAY为2,依次类推。
(字段8) public final static int DAY_OF_WEEK_IN_MONTH = 8;
说明:当前月中的第几个星期。
取值:DAY_OF_MONTH 1 到 7 总是对应于 DAY_OF_WEEK_IN_MONTH 1;8 到 14 总是对应于 DAY_OF_WEEK_IN_MONTH 2,依此类推。
(字段9) public final static int AM_PM = 9;
说明:上午 还是 下午
取值:可以是AM 或 PM。AM为0,表示上午;PM为1,表示下午。
(字段10) public final static int HOUR = 10;
说明:指示一天中的第几小时。
     HOUR 用于 12 小时制时钟 (0 - 11)。中午和午夜用 0 表示,不用 12 表示。
(字段11) public final static int HOUR_OF_DAY = 11;
说明:指示一天中的第几小时。
     HOUR_OF_DAY 用于 24 小时制时钟。例如,在 10:04:15.250 PM 这一时刻,HOUR_OF_DAY 为 22。
(字段12) public final static int MINUTE = 12;
说明:一小时中的第几分钟。
例如,在 10:04:15.250 PM这一时刻,MINUTE 为 4。
(字段13) public final static int SECOND = 13;
说明:一分钟中的第几秒。
例如,在 10:04:15.250 PM 这一时刻,SECOND 为 15。
(字段14) public final static int MILLISECOND = 14;
说明:一秒中的第几毫秒。
例如,在 10:04:15.250 PM 这一时刻,MILLISECOND 为 250。
(字段15) public final static int ZONE_OFFSET = 15;
说明:毫秒为单位指示距 GMT 的大致偏移量。
(字段16) public final static int DST_OFFSET = 16;
说明:毫秒为单位指示夏令时的偏移量。
public final static int FIELD_COUNT = 17;
这17个字段是保存在int数组中。定义如下:


// 保存这17个字段的数组
protected int  fields[];
// 数组的定义函数
protected Calendar(TimeZone zone, Locale aLocale)
{
 // 初始化“fields数组”
 fields = new int[FIELD_COUNT];
 isSet = new boolean[FIELD_COUNT];
 stamp = new int[FIELD_COUNT];
 
 this.zone = zone;
 setWeekCountData(aLocale);
}

protected Calendar(TimeZone zone, Locale aLocale) 这是Calendar的构造函数。它会被它的子类的构造函数调用到,从而新建“保存Calendar的17个字段数据”的数组。

3. Calendar 各个字段值的计算
下面以get(int field)为例,简要的说明Calendar的17个字段的计算和操作。 get(int field)是获取“field”字段的值。它的定义如下:

protected void complete()
{
 if (!isTimeSet)
 updateTime();
 if (!areFieldsSet || !areAllFieldsSet) {
 computeFields(); // fills in unset fields
 areAllFieldsSet = areFieldsSet = true;
 }
}
private void updateTime() {
 computeTime();
 isTimeSet = true;
}
updateTime() 调用到的 computeTime() 定义在 Calendar.java的实现类中。下面,我列出GregorianCalendar.java中computeTime()的实现:
protected void computeTime() {
 // In non-lenient mode, perform brief checking of calendar
 // fields which have been set externally. Through this
 // checking, the field values are stored in originalFields[]
 // to see if any of them are normalized later.
 if (!isLenient()) {
 if (originalFields == null) {
  originalFields = new int[FIELD_COUNT];
 }
 for (int field = 0; field < FIELD_COUNT; field++) {
  int value = internalGet(field);
  if (isExternallySet(field)) {
  // Quick validation for any out of range values
  if (value < getMinimum(field) || value > getMaximum(field)) {
   throw new IllegalArgumentException(getFieldName(field));
  }
  }
  originalFields[field] = value;
 }
 }
 
 // Let the super class determine which calendar fields to be
 // used to calculate the time.
 int fieldMask = selectFields();
 
 // The year defaults to the epoch start. We don't check
 // fieldMask for YEAR because YEAR is a mandatory field to
 // determine the date.
 int year = isSet(YEAR) ? internalGet(YEAR) : EPOCH_YEAR;
 
 int era = internalGetEra();
 if (era == BCE) {
 year = 1 - year;
 } else if (era != CE) {
 // Even in lenient mode we disallow ERA values other than CE & BCE.
 // (The same normalization rule as add()/roll() could be
 // applied here in lenient mode. But this checking is kept
 // unchanged for compatibility as of 1.5.)
 throw new IllegalArgumentException("Invalid era");
 }
 
 // If year is 0 or negative, we need to set the ERA value later.
 if (year <= 0 && !isSet(ERA)) {
 fieldMask |= ERA_MASK;
 setFieldsComputed(ERA_MASK);
 }
 
 // Calculate the time of day. We rely on the convention that
 // an UNSET field has 0.
 long timeOfDay = 0;
 if (isFieldSet(fieldMask, HOUR_OF_DAY)) {
 timeOfDay += (long) internalGet(HOUR_OF_DAY);
 } else {
 timeOfDay += internalGet(HOUR);
 // The default value of AM_PM is 0 which designates AM.
 if (isFieldSet(fieldMask, AM_PM)) {
  timeOfDay += 12 * internalGet(AM_PM);
 }
 }
 timeOfDay *= 60;
 timeOfDay += internalGet(MINUTE);
 timeOfDay *= 60;
 timeOfDay += internalGet(SECOND);
 timeOfDay *= 1000;
 timeOfDay += internalGet(MILLISECOND);
 
 // Convert the time of day to the number of days and the
 // millisecond offset from midnight.
 long fixedDate = timeOfDay / ONE_DAY;
 timeOfDay %= ONE_DAY;
 while (timeOfDay < 0) {
 timeOfDay += ONE_DAY;
 --fixedDate;
 }
 
 // Calculate the fixed date since January 1, 1 (Gregorian).
 calculateFixedDate: {
 long gfd, jfd;
 if (year > gregorianCutoverYear && year > gregorianCutoverYearJulian) {
  gfd = fixedDate + getFixedDate(gcal, year, fieldMask);
  if (gfd >= gregorianCutoverDate) {
  fixedDate = gfd;
  break calculateFixedDate;
  }
  jfd = fixedDate + getFixedDate(getJulianCalendarSystem(), year, fieldMask);
 } else if (year < gregorianCutoverYear && year < gregorianCutoverYearJulian) {
  jfd = fixedDate + getFixedDate(getJulianCalendarSystem(), year, fieldMask);
  if (jfd < gregorianCutoverDate) {
  fixedDate = jfd;
  break calculateFixedDate;
  }
  gfd = fixedDate + getFixedDate(gcal, year, fieldMask);
 } else {
  gfd = fixedDate + getFixedDate(gcal, year, fieldMask);
  jfd = fixedDate + getFixedDate(getJulianCalendarSystem(), year, fieldMask);
 }
 // Now we have to determine which calendar date it is.
 if (gfd >= gregorianCutoverDate) {
  if (jfd >= gregorianCutoverDate) {
  fixedDate = gfd;
  } else {
  // The date is in an "overlapping" period. No way
  // to disambiguate it. Determine it using the
  // previous date calculation.
  if (calsys == gcal || calsys == null) {
   fixedDate = gfd;
  } else {
   fixedDate = jfd;
  }
  }
 } else {
  if (jfd < gregorianCutoverDate) {
  fixedDate = jfd;
  } else {
  // The date is in a "missing" period.
  if (!isLenient()) {
   throw new IllegalArgumentException("the specified date doesn't exist");
  }
  // Take the Julian date for compatibility, which
  // will produce a Gregorian date.
  fixedDate = jfd;
  }
 }
 }
 
 // millis represents local wall-clock time in milliseconds.
 long millis = (fixedDate - EPOCH_OFFSET) * ONE_DAY + timeOfDay;
 
 // Compute the time zone offset and DST offset. There are two potential
 // ambiguities here. We'll assume a 2:00 am (wall time) switchover time
 // for discussion purposes here.
 // 1. The transition into DST. Here, a designated time of 2:00 am - 2:59 am
 // can be in standard or in DST depending. However, 2:00 am is an invalid
 // representation (the representation jumps from 1:59:59 am Std to 3:00:00 am DST).
 // We assume standard time.
 // 2. The transition out of DST. Here, a designated time of 1:00 am - 1:59 am
 // can be in standard or DST. Both are valid representations (the rep
 // jumps from 1:59:59 DST to 1:00:00 Std).
 // Again, we assume standard time.
 // We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET
 // or DST_OFFSET fields; then we use those fields.
 TimeZone zone = getZone();
 if (zoneOffsets == null) {
 zoneOffsets = new int[2];
 }
 int tzMask = fieldMask & (ZONE_OFFSET_MASK|DST_OFFSET_MASK);
 if (tzMask != (ZONE_OFFSET_MASK|DST_OFFSET_MASK)) {
 if (zone instanceof ZoneInfo) {
  ((ZoneInfo)zone).getOffsetsByWall(millis, zoneOffsets);
 } else {
  int gmtOffset = isFieldSet(fieldMask, ZONE_OFFSET) ?
  internalGet(ZONE_OFFSET) : zone.getRawOffset();
  zone.getOffsets(millis - gmtOffset, zoneOffsets);
 }
 }
 if (tzMask != 0) {
 if (isFieldSet(tzMask, ZONE_OFFSET)) {
  zoneOffsets[0] = internalGet(ZONE_OFFSET);
 }
 if (isFieldSet(tzMask, DST_OFFSET)) {
  zoneOffsets[1] = internalGet(DST_OFFSET);
 }
 }
 
 // Adjust the time zone offset values to get the UTC time.
 millis -= zoneOffsets[0] + zoneOffsets[1];
 
 // Set this calendar's time in milliseconds
 time = millis;
 
 int mask = computeFields(fieldMask | getSetStateFields(), tzMask);
 
 if (!isLenient()) {
 for (int field = 0; field < FIELD_COUNT; field++) {
  if (!isExternallySet(field)) {
  continue;
  }
  if (originalFields[field] != internalGet(field)) {
  // Restore the original field values
  System.arraycopy(originalFields, 0, fields, 0, fields.length);
  throw new IllegalArgumentException(getFieldName(field));
  }
 }
 }
 setFieldsNormalized(mask);
}

下面,我们看看internalGet(field)的定义。如下:

// 获取Calendar实例
Calendar cal = Calendar.getInstance();
// 获取MONTH的最大值
int max = cal.getMaximum(Calendar.MONTH);
若要获取其它字段的最大值,只需要将示例中的MONTH相应的替换成其它字段名即可。
(2) getActualMaximum(int field)
作用:获取“当前日期下,该字段的最大值”。 示例:以“MONTH”字段来说。使用方法为:
// 获取Calendar实例
Calendar cal = Calendar.getInstance();
// 获取当前MONTH的最大值
int max = cal.getActualMaximum(Calendar.MONTH);
若要获取其它字段的最大值,只需要将示例中的MONTH相应的替换成其它字段名即可。
注意:对比getActualMaximum() 和 getMaximum() 的区别。参考下面的对比示例,
A、 getMaximum() 获取的“字段最大值”,是指在综合所有的日期,在所有这些日期中得出的“字段最大值”。
     例如,getMaximum(Calendar.DATE)的目的是“获取‘日的最大值'”。综合所有的日期,得出一个月最多有31天。因此,getMaximum(Calendar.DATE)的返回值是“31”!
B、 getActualMaximum() 获取的“当前日期时,该字段的最大值”。
     例如,当日期为2013-09-01时,getActualMaximum(Calendar.DATE)是获取“日的最大值”是“30”。当前日期是9月份,而9月只有30天。因此,getActualMaximum(Calendar.DATE)的返回值是“30”!
(3) getMinimum(int field)
作用:获取“字段的最小值”。注意“对比它和 getActualMinimum() 的区别”。 示例:以“MONTH”字段来说。使用方法为:
// 获取Calendar实例
Calendar cal = Calendar.getInstance();
// 获取MONTH的最小值
int min = cal.getMinimum(Calendar.MONTH);

(4) getActualMinimum(int field)

//作用:获取“当前日期下,该字段的最小值”。 示例:以“MONTH”字段来说。使用方法为:
// 获取Calendar实例
Calendar cal = Calendar.getInstance();
// 获取MONTH的最小值
int min = cal.getMinimum(Calendar.MONTH);
若要获取其它字段的最小值,只需要将示例中的MONTH相应的替换成其它字段名即可。
注意:在Java默认的Calendar中,虽然 getMinimum() 和 getActualMinimum() 的含义不同;但是,它们的返回值是一样的。因为Calendar的默认是返回GregorianCalendar对象,而在GregorianCalendar.java中,getMinimum() 和 getActualMinimum() 返回值一样。
(5) get(int field)
作用:获取“字段的当前值”。获取field字段的当前值。 示例:以“MONTH”字段来说。“获取MONTH的当前值”的方法为:
// 获取Calendar实例
Calendar cal = Calendar.getInstance();
// 获取“cal日历”的当前MONTH值
int MONTH = cal.get(Calendar.MONTH);
若要获取其它字段的当前值,只需要将示例中的MONTH相应的替换成其它字段名即可。
(6) set(int field, int value)

作用:设置“字段的当前值”。设置field字段的当前值为value 示例:以“MONTH”字段来说。“设置MONTH的当前值”的方法为:

// 获取Calendar实例
Calendar cal = Calendar.getInstance();
// 设置“cal日历”的当前MONTH值为 1988年
cal.set(Calendar.MONTH, 1988);
说明:
A、1988 是想要设置的MONTH的当前值。这个设置值必须是整数。
B、若要设置其它字段的当前值,只需要将示例中的MONTH相应的替换成其它字段名即可。
(7) add(int field, int value)

作用:给“字段的当前值”添加值。给field字段的当前值添加value。 示例:以“MONTH”字段来说。方法如下:

// 获取Calendar实例,并设置日期为“2013-09-01”
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2013);
cal.set(Calendar.MONTH, 8);
cal.set(Calendar.DATE, 1);
// 给“cal日历”的当前MONTH值 “添加-10”
cal.add(Calendar.MONTH, -10);
说明:
A、 -10 是添加值。
     添加值可以为正数,也可以是负数。
     正数表示将日期增加,负数表示将日期减少。
     假设:现在cal的值是“2013-09-01”,现在我们将MONTH字段值增加-10。得到的结果是:“2012-10-01”。
     为什么会这样呢?“2013-09-01”增加-10,也就是将日期向前减少10个月;得到的结果就是“2012-10-01”。
B、 Calendar的17个字段中:除了回滚Calendar.ZONE_OFFSET时,会抛出IllegalArgumentException异常;其它的字段都支持该操作。
C、 若要设置其它字段的当前值,只需要将示例中的MONTH相应的替换成其它字段名即可。
(8) roll(int field, int value)

作用:回滚“字段的当前值” 示例:以“MONTH”字段来说。“回滚MONTH的当前值”的方法为:

// 获取Calendar实例,并设置日期为“2013-09-01”
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2013);
cal.set(Calendar.MONTH, 8);
cal.set(Calendar.DATE, 1);
// 将“cal日历”的当前MONTH值 “向前滚动10”
cal.roll(Calendar.MONTH, -10);
说明:
A、 -10 是回滚值。
     当回滚值是负数时,表示将当前字段向前滚;
     当回滚值是正数时,表示将当前字段向后滚。
     回滚Calendar中某一字段时,不更改更大的字段!
     这是roll()与add()的根据区别!add()可能会更改更大字段,比如“使用add()修改‘MONTH'字段,可能会引起‘YEAR'字段的改变”;但是roll()不会更改更大的字段,例如“使用roll()修改‘MONTH'字段,不回引起‘YEAR'字段的改变。”
     假设:现在cal的值是“2013-09-01”,现在我们将MONTH字段值增加-10。得到的结果是:“2013-10-01”。
     为什么会这样呢?这就是因为“回滚”就是“在最小值和最大值之间来回滚动”。本例中,MONTH是9月,前回滚10,得到的值是10月,但是roll()不会改变“比MONTH”更大的字段,所以YEAR字段不会改变。所以结果是“2013-10-01”。
B、 Calendar的17个字段中:除了回滚Calendar.ZONE_OFFSET时,会抛出IllegalArgumentException异常;其它的字段都支持该操作。
C、 若要设置其它字段的当前值,只需要将示例中的MONTH相应的替换成其它字段名即可。
(9) clear(int field)

作用:清空“字段的当前值”。所谓清空,实际上是将“field”的值设置为0;若field最小值为1,则设置为1。 示例:以“MONTH”字段来说。“清空MONTH”的方法为:

// 获取Calendar实例,并设置日期为“9月”
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, 9);
// 清空MONTH
cal.clear(Calendar.MONTH);

若要判断其它字段,只需要将示例中的MONTH相应的替换成其它字段名即可。

2. Calendar的其它函数
(1) 日期比较函数

Calendar的比较函数,主要有以下几个:

boolean equals(Object object)
// 当前Calendar对象 是否 早于calendar
boolean before(Object calendar)
// 当前Calendar对象 是否 晚于calendar
boolean after(Object calendar)
// 比较“当前Calendar对象”和“calendar”。
// 若 早于 “calendar” 则,返回-1
// 若 相等, 则,返回0
// 若 晚于 “calendar” 则,返回1
int compareTo(Calendar anotherCalendar) 

(2) “宽容”函数

// 设置“Calendar的宽容度”
void setLenient(boolean value)
// 获取“Calendar的宽容度”
boolean isLenient()
这些函数的使用示例,请参考CalendarTest.java示例中的 testLenientAPIs() 函数。
说明:
Calendar 有两种解释日历字段的模式,即 lenient 和 non-lenient。
A、 当 Calendar 处于 lenient 模式时,它可接受比它所生成的日历字段范围更大范围内的值。当 Calendar 重新计算日历字段值,以便由 get() 返回这些值时,所有日历字段都被标准化。
     例如,lenient 模式下的 GregorianCalendar 将 MONTH == JANUARY、DAY_OF_MONTH == 32 解释为 February 1。
B、 当 Calendar 处于 non-lenient 模式时,如果其日历字段中存在任何不一致性,它都会抛出一个异常。
     例如,GregorianCalendar 总是在 1 与月份的长度之间生成 DAY_OF_MONTH 值。如果已经设置了任何超出范围的字段值,那么在计算时间或日历字段值时,处于 non-lenient 模式下的 GregorianCalendar 会抛出一个异常。
注意:在(02)步骤中的异常,在使用set()时不会抛出,而需要在使用get()、getTimeInMillis()、getTime()、add() 和 roll() 等函数中才抛出。因为set()只是设置了一个修改标志,而get()等方法才会引起时间的重新计算,此时才会抛出异常!

(3) "年月日(时分秒)"、Date、TimeZone、MilliSecond函数

// 设置“年月日”
final void set(int year, int month, int day)
// 设置“年月日时分”
final void set(int year, int month, int day, int hourOfDay, int minute, int second)
// 设置“年月日时分秒”
final void set(int year, int month, int day, int hourOfDay, int minute)
// 获取Calendar对应的日期
final Date getTime()
// 设置Calendar为date
final void setTime(Date date)
// 获取Calendar对应的时区
TimeZone getTimeZone()
// 设置Calendar对应的时区
void setTimeZone(TimeZone timezone)
// 获取Calendar对应的milliscondes值,就是“Calendar当前日期”距离“1970-01-01 0:00:00 GMT”的毫秒数
long getTimeInMillis()
// 设置Calendar对应的milliscondes值
void setTimeInMillis(long milliseconds)
这些函数的使用示例,请参考CalendarTest.java示例中的 testTimeAPIs() 函数。

(4) 其它操作

// 克隆Calendar
Object clone()
// 获取“每周的第一天是星期几”。例如,在美国,这一天是 SUNDAY,而在法国,这一天是 MONDAY。
int getFirstDayOfWeek()
// 设置“每周的第一天是星期几”。例如,在美国,这一天是 SUNDAY,而在法国,这一天是 MONDAY。
void setFirstDayOfWeek(int value)
// 获取一年中第一个星期所需的最少天数,例如,如果定义第一个星期包含一年第一个月的第一天,则此方法将返回 1。如果最少天数必须是一整个星期,则此方法将返回 7。
int getMinimalDaysInFirstWeek()
// 设置一年中第一个星期所需的最少天数,例如,如果定义第一个星期包含一年第一个月的第一天,则使用值 1 调用此方法。如果最少天数必须是一整个星期,则使用值 7 调用此方法。
void setMinimalDaysInFirstWeek(int value)

这些函数的使用示例,请参考CalendarTest.java示例中的 testOtherAPIs() 函数。

第四部分 Calendar使用示例
下面,我们通过示例学习使用Calendar的API。CalendarTest.java的源码如下:


import java.util.Date;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.Random;
 
public class CalendarTest {
 
 public static void main(String[] args) {
 
 // 测试Calendar的“17个字段的公共函数接口”
 testAllCalendarSections() ;
 
 // 测试Calendar的“比较接口”
 testComparatorAPIs() ;
 
 // 测试Calendar的“比较接口”
 testLenientAPIs() ;
 
 // 测试Calendar的Date、TimeZone、MilliSecond等相关函数
 testTimeAPIs() ;
 
 // 测试Calendar的clone(),getFirstDayOfWeek()等接口
 testOtherAPIs() ;
 
 }
 
 
 /**
 * 测试“Calendar的字段”
 *
 * @param cal -- Calendar对象
 * @param field -- 要测试的“Calendar字段”。可以为以下值:
 * Calendar.YEAR, Calendar.MONTH, Calendar.DATE, ... 等等
 * @param title -- 标题
 */
 private static void testSection(Calendar cal, int field, String title) {
 final Random random = new Random();
 final Date date = cal.getTime();
 
 final int min = cal.getMinimum(field); // 获取"字段最小值"
 final int max = cal.getMaximum(field); // 获取“字段最大值”
 
 final int actualMin = cal.getActualMinimum(field); // 获取"当前日期下,该字段最小值"
 final int actualMax = cal.getActualMaximum(field); // 获取“当前日期下,该字段的最大值”
 
 // 获取“字段的当前值”
 final int ori = cal.get(field);  
 
 // 设置“字段的当前值”, 并获取“设置之后的值”
 final int r1 = random.nextInt(max);
 cal.set(field, r1);  
 final int set = cal.get(field);  
 try {
  // 回滚“字段的当前值”:在“字段最小值”和“字段最大值”之间回滚。
  // “回滚值”可以为正,也可以为负。
  cal.roll(field, -max);  
 } catch (IllegalArgumentException e) {
  // 当field == Calendar.ZONE_OFFSET时,会抛出该异常!
  e.printStackTrace();
 }
 final int roll = cal.get(field);  
 
 // 获取一个随机值
 final int sign = ( random.nextInt(2) == 1) ? 1 : -1;
 final int r2 = sign * random.nextInt(max);
 try {
  // 增加“字段的当前值” ,并获取“新的当前字段值”
  // add的“参数值”可以为正,也可以为负。
  cal.add(field, r2);  
 } catch (IllegalArgumentException e) {
  // 当field == Calendar.ZONE_OFFSET时,会抛出该异常!
  e.printStackTrace();
 }
 final int add = cal.get(field);
 
 
 
 // 打印字段信息
 System.out.printf("%s:\n\trange is [%d - %d] actualRange is [%d - %d]. original=%d, set(%d)=%d, roll(%d)=%d, add(%d)=%d\n",
  title, min, max, actualMin, actualMax, ori, r1, set, -max, roll, r2, add);
 }
 
 /**
 * 测试Calendar的“17个字段的公共函数接口”
 */
 private static void testAllCalendarSections() {
 // 00. ERA 字段
 testSection(Calendar.getInstance(), Calendar.ERA, "Calendar.ERA");
 // 01. YEAR 字段
 testSection(Calendar.getInstance(), Calendar.YEAR, "Calendar.YEAR");
 // 02. MONTH 字段
 testSection(Calendar.getInstance(), Calendar.MONTH, "Calendar.MONTH");
 // 03. WEEK_OF_YEAR 字段
 testSection(Calendar.getInstance(), Calendar.WEEK_OF_YEAR, "Calendar.WEEK_OF_YEAR");
 // 04. WEEK_OF_MONTH 字段
 testSection(Calendar.getInstance(), Calendar.WEEK_OF_MONTH, "Calendar.WEEK_OF_MONTH");
 // 05. DATE 字段
 testSection(Calendar.getInstance(), Calendar.DATE, "Calendar.DATE");
 // 06. DAY_OF_MONTH 字段
 testSection(Calendar.getInstance(), Calendar.DAY_OF_MONTH, "Calendar.DAY_OF_MONTH");
 // 07. DAY_OF_YEAR 字段
 testSection(Calendar.getInstance(), Calendar.DAY_OF_YEAR, "Calendar.DAY_OF_YEAR");
 // 08. DAY_OF_WEEK 字段
 testSection(Calendar.getInstance(), Calendar.DAY_OF_WEEK, "Calendar.DAY_OF_WEEK");
 // 09. DAY_OF_WEEK_IN_MONTH 字段
 testSection(Calendar.getInstance(), Calendar.DAY_OF_WEEK_IN_MONTH, "Calendar.DAY_OF_WEEK_IN_MONTH");
 // 10. AM_PM 字段
 testSection(Calendar.getInstance(), Calendar.AM_PM, "Calendar.AM_PM");
 // 11. HOUR 字段
 testSection(Calendar.getInstance(), Calendar.HOUR, "Calendar.HOUR");
 // 12. HOUR_OF_DAY 字段
 testSection(Calendar.getInstance(), Calendar.HOUR_OF_DAY, "Calendar.HOUR_OF_DAY");
 // 13. MINUTE 字段
 testSection(Calendar.getInstance(), Calendar.MINUTE, "Calendar.MINUTE");
 // 14. SECOND 字段
 testSection(Calendar.getInstance(), Calendar.SECOND, "Calendar.SECOND");
 // 15. MILLISECOND 字段
 testSection(Calendar.getInstance(), Calendar.MILLISECOND, "Calendar.MILLISECOND");
 // 16. ZONE_OFFSET 字段
 testSection(Calendar.getInstance(), Calendar.ZONE_OFFSET, "Calendar.ZONE_OFFSET");
 }
 
 /**
 * 测试Calendar的“比较接口”
 */
 private static void testComparatorAPIs() {
 // 新建cal1 ,且时间为1988年
 Calendar cal1 = Calendar.getInstance();
 cal1.set(Calendar.YEAR, 1988);
 // 新建cal2 ,且时间为2000年
 Calendar cal2 = Calendar.getInstance();
 cal2.set(Calendar.YEAR, 2000);
 // 新建cal3, 为cal1的克隆对象
 Calendar cal3 = (Calendar)cal1.clone();
 
 // equals 判断 cal1和cal2的“时间、时区等”内容是否相等
 boolean isEqual12 = cal1.equals(cal2);
 // equals 判断 cal1和cal3的“时间、时区等”内容是否相等
 boolean isEqual13 = cal1.equals(cal3);
 // cal1是否比cal2早
 boolean isBefore = cal1.before(cal2);
 // cal1是否比cal2晚
 boolean isAfter = cal1.after(cal2);
 // 比较cal1和cal2
 // (01) 若cal1 早于 cal2,返回-1
 // (02) 若cal1 等于 cal2,返回0
 // (03) 若cal1 晚于 cal2,返回1
 int icompare = cal1.compareTo(cal2);
 
 System.out.printf("\ntestComparatorAPIs: isEuqal12=%s, isEqual13=%s, isBefore=%s, isAfter=%s, icompare=%s\n",
  isEqual12, isEqual13, isBefore, isAfter, icompare);
 }
 
 /**
 * 测试Calendar的“比较接口”
 */
 private static void testLenientAPIs() {
  Calendar cal = Calendar.getInstance();
 
  // 获取默认的“宽容度”。返回true
  boolean oriLenient = cal.isLenient();
  // MONTH值只能是“0-11”,这里越界。但是由于当前cal是宽容的,所以不会抛出异常
  cal.set(Calendar.MONTH, 50); 
 
  // 设置“宽容度”为false。
  cal.setLenient(false);
  // 获取设置后的“宽容度”
  boolean curLenient = cal.isLenient();
  try {
  // MONTH值只能是“0-11”,这里越界。而且当前cal是不宽容的,所以会产生异常。
  // 但是,异常到下次计算日期时才会抛出。即,set()中不回抛出异常,而要等到get()中才会抛出异常
  cal.set(Calendar.MONTH, 50);
  // 此时,对cal进行读取。读取会导致重新计算cal的值,所以此时抛出异常!
  int m2 = cal.get(Calendar.MONTH); 
 } catch (IllegalArgumentException e) {
  e.printStackTrace();
 }
 
 System.out.printf("\ntestLenientAPIs: oriLenient=%s, curLenient=%s\n",
  oriLenient, curLenient);
 }
 
 /**
 * 测试Calendar的Date、TimeZone、MilliSecond等相关函数
 */
 private static void testTimeAPIs() {
 Calendar cal = Calendar.getInstance();
 
 // 设置cal的时区为“GMT+8”
 cal.setTimeZone(TimeZone.getTimeZone("GMT+8"));
 // 获取当前的cal时区
 TimeZone timezone = cal.getTimeZone();
 
 // 设置 milliseconds
 cal.setTimeInMillis(1279419645742l);
 // 获取 milliseconds
 long millis = cal.getTimeInMillis();
 // 设置 milliseconds之后,时间也改变了。
 // 获取cal对应的日期
 Date date = cal.getTime();
 
 // 设置时间为“1988-08-08”
 cal.set(1988, 08, 08);
 // 设置时间为“1999-09-09 09:09”
 cal.set(1999, 09, 09, 9, 9);
 // 设置时间为“2000-10-10 10:10:10”
 cal.set(2000, 10, 10, 10, 10, 10);
 
 System.out.printf("\ntestTimeAPIs: date=%s, timezone=%s, millis=%s\n",
  date, timezone, millis);
 }
 
 /**
 * 测试Calendar的clone(),getFirstDayOfWeek()等接口
 */
 private static void testOtherAPIs() {
 Calendar cal = Calendar.getInstance();
 // 克隆cal
 Calendar clone = (Calendar)cal.clone();
 
 // 设置 为 2013-01-10。 
 // 注:2013-01-01 为“星期二”,2013-01-06为“星期天”,
 clone.set(Calendar.YEAR, 2013);
 clone.set(Calendar.MONTH, 0);
 clone.set(Calendar.DATE, 10);
 // 设置“本年的第一个星期最少包含1天”。
 // 则2013-01-10属于第2个星期
 clone.setMinimalDaysInFirstWeek(1);
 int m1 = clone.getMinimalDaysInFirstWeek();
 int index1 = clone.get(Calendar.WEEK_OF_YEAR);
 
 // 设置“本年的第一个星期最少包含7天”。
 // 则2013-01-10属于第1个星期
 clone.setMinimalDaysInFirstWeek(7);
 int m2 = clone.getMinimalDaysInFirstWeek();
 int index2 = clone.get(Calendar.WEEK_OF_YEAR);
 
 // 设置“每周的第一天是星期几”。
 clone.setFirstDayOfWeek(Calendar.WEDNESDAY);
 // 获取“每周的第一天是星期几”。
 int firstdayOfWeek = clone.getFirstDayOfWeek();
 
 System.out.printf("\ntestOtherAPIs: firstdayOfWeek=%s, [minimalDay, WeekOfYear]={(%s, %s), (%s, %s)} %s\n",
  firstdayOfWeek, m1, index1, m2, index2, clone.getTime());
 }
}
第五部分 自定义的Calendar接口示例
这些接口在写日历程序时可能会用到。

源代码如下(CalendarSelfDefineTest.java):

import java.util.Calendar;
 
/**
 * 根据Calendar的API封装的一些常用函数
 */
public class CalendarSelfDefineTest {
 
 public static void main(String[] args) {
 Calendar cal = Calendar.getInstance();
 
 // 设置日期为“2013-09-18”
 cal.set(2013, Calendar.SEPTEMBER, 18);
 
 // 获取“年”
 System.out.printf("year: %s\n", getYear(cal) );
 // 获取“月”
 System.out.printf("month: %s\n", getMonth(cal) );
 // 获取“上月”
 System.out.printf("previcou month: %s\n", getLastMonth(cal) );
 // 获取“下月”
 System.out.printf("next month: %s\n", getNextMonth(cal) );
 // 获取“日”
 System.out.printf("day: %s\n", getDay(cal) );
 // 获取Cal对应星期几
 System.out.printf("weekday: %s\n", getWeekDay(cal) );
 // 本月天数
 System.out.printf("Current Month days: %s\n", getMonthDays(cal) );
 // 上月天数
 System.out.printf("Previcous Month days: %s\n", getPrevMonthDays(cal) );
 // 下月天数
 System.out.printf("Next Month days: %s\n", getNextMonthDays(cal) );
 // 获取当月第一天的星期几
 System.out.printf("First day' weekday : %s\n", getFirstDayWeekday(cal) );
 // 获取当前月最后一天的星期几
 System.out.printf("Last day' weekday : %s\n", getLastDayWeekday(cal) );
 // 获取上月最后一天的星期几
 System.out.printf("PrevMonth Last day' weekday: %s\n", getLastDayWeekdayOfPrevMonth(cal) );
 // 获取下月第一天的星期几
 System.out.printf("NextMonth First day' weekday: %s\n", getFirstDayWeekdayOfNextMonth(cal) );
 }
 
 /**
 * 获取“年”
 * 
 * @return 例如,2013-09-18,则返回2013
 */
 public static int getYear(Calendar cal) {
 return cal.get(Calendar.YEAR);
 } 
 
 /**
 * 获取“月”
 * 
 * @return 返回值可以为以下值:
 * JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER, UNDECIMBER。
 * 其中第一个月是 JANUARY,它为 0。
 *
 * 例如,2013-09-18,则返回8
 */
 public static int getMonth(Calendar cal) {
 return cal.get(Calendar.MONTH);
 } 
 
 /**
 * 获取“上一个月”
 * 
 * @return 返回值可以为以下值:
 * JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER, UNDECIMBER。
 * 其中第一个月是 JANUARY,它为 0。
 *
 * 例如,2012-01-12的上一个月是“11”(即DECEMBER)。
 */
 public static int getLastMonth(Calendar cal) {
 return (cal.get(Calendar.MONTH) + 11) % 12;
 } 
 
 /**
 * 获取“下一个月”
 * 
 * @return 返回值可以为以下值:
 * JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER, UNDECIMBER。
 * 其中第一个月是 JANUARY,它为 0。
 *
 * 例如,2013-12-12的下一个月是“1”(即DECEMBER)。
 */
 public static int getNextMonth(Calendar cal) {
 return (cal.get(Calendar.MONTH) + 13) % 12;
 } 
 
 /**
 * 获取“日”
 *
 * @return 例如,2013-09-18,则返回18
 *
 */
 public static int getDay(Calendar cal) {
 return cal.get(Calendar.DATE);
 } 
 
 /**
 * 获取“本月的天数”
 *
 * @return 例如,2013-09-18,则返回30
 *
 */
 public static int getMonthDays(Calendar cal) {
 return cal.getActualMaximum(Calendar.DATE); 
 } 
 
 /**
 * 获取“上一个月的天数”
 *
 * @return 例如,2013-01-18,则返回31 (因为2012-12有31天)
 *
 */
 public static int getPrevMonthDays(Calendar cal) {
 Calendar tmpCal = (Calendar)cal.clone(); // 克隆cal。后面对tmpCal操作,就不会改变cal
 tmpCal.add(Calendar.MONTH, -1);   // 设为“上一个月”
 return tmpCal.getActualMaximum(Calendar.DATE); 
 } 
 
 /**
 * 获取“下一个月的天数”
 *
 * @return 例如,2013-12-18,则返回31 (因为2014-01有31天)
 *
 */
 public static int getNextMonthDays(Calendar cal) {
 Calendar tmpCal = (Calendar)cal.clone(); // 克隆cal。后面对tmpCal操作,就不会改变cal
 tmpCal.add(Calendar.MONTH, 1);   // 设为“下一个月”
 return tmpCal.getActualMaximum(Calendar.DATE); 
 } 
 
 /**
 * 获取Cal对应星期几
 *
 * @return 返回“星期几”,可以为以下值:
 * SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY 和 SATURDAY。
 * SUNDAY为1,MONDAY为2,依次类推。
 * 例如,2013-09-18(星期三),则返回4
 */
 public static int getWeekDay(Calendar cal) {
 return cal.get(Calendar.DAY_OF_WEEK);
 } 
 
 
 /**
 * 获取当月第一天对应星期几
 *
 * @return SUNDAY为1,MONDAY为2,依次类推。
 */
 public static int getFirstDayWeekday(Calendar cal) {
 
 Calendar tmpCal = (Calendar)cal.clone(); // 克隆cal。后面对tmpCal操作,就不会改变cal
 tmpCal.set(Calendar.DATE, 1);   // 把日期设置为当月第一天 
 return tmpCal.get(Calendar.DAY_OF_WEEK);
 } 
 
 /**
 * 获取当前月最后一天对应星期几
 * 
 * @return SUNDAY为1,MONDAY为2,依次类推。
 */
 public static int getLastDayWeekday(Calendar cal) {
 Calendar tmpCal = (Calendar)cal.clone(); // 克隆cal。后面对tmpCal操作,就不会改变cal
 tmpCal.set(Calendar.DATE, 1);   // 把日期设置为当月第一天 
 tmpCal.roll(Calendar.DATE, -1);   // 把日期设置为当月最后一天 
 return tmpCal.get(Calendar.DAY_OF_WEEK);
 } 
 
 
 /**
 * 获取上月最后一天的星期几
 * 
 * @return SUNDAY为1,MONDAY为2,依次类推。
 */
 public static int getLastDayWeekdayOfPrevMonth(Calendar cal) {
 
 Calendar tmpCal = (Calendar)cal.clone(); // 克隆cal。后面对tmpCal操作,就不会改变cal
 tmpCal.set(Calendar.DATE, 1);   // 把日期设置为当月第一天 
 tmpCal.add(Calendar.DATE, -1);   // 把日期设置为上一个月最后一天 
 return tmpCal.get(Calendar.DAY_OF_WEEK);
 } 
 
 /**
 * 获取下月第一天的星期偏移
 * 
 * @return SUNDAY为1,MONDAY为2,依次类推。
 */
 public static int getFirstDayWeekdayOfNextMonth(Calendar cal) {
 
 Calendar tmpCal = (Calendar)cal.clone(); // 克隆cal。后面对tmpCal操作,就不会改变cal
 tmpCal.add(Calendar.MONTH, 1);   // 设为“下一个月”
 tmpCal.set(Calendar.DATE, 1);   // 设为“第一天” 
 return tmpCal.get(Calendar.DAY_OF_WEEK);
 } 
}





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中的Calendar日历API用法完全解析 的相关文章

  • Java RSA加密解密及签名验证

    一 简介 RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥 在公开密钥密码体制中 加密密钥 即公开密钥 PK是公开信息 而解密密钥 即秘密密钥 SK是需要保密的 加密算法E和解密算法D也都是公开的 虽然解密密钥SK是由公开密钥PK决
  • 腾讯云短信Java调用示例(SDK3.0)

    腾讯云短信Java调用示例 SDK3 0 1 pom xml 添加以下依赖 2 需要引入的包 3 程序实例 1 pom xml 添加以下依赖
  • PageHelper 分页排序使用记录

    PageHelper 分页使用 PageHelper startPage pageNum pageSize orderBy 其中最后一个参数是数据库字段名称 按传入的字段进行排序 场景 如果有接口参数中有排序字段 则按参数中的排序字段来排序
  • JAVA代码规范

    一 MyBatis 不要为了多个查询条件而写 1 1 二 迭代entrySet 获取Map 的key 和value 三 使用Collection isEmpty 检测空 四 初始化集合时尽量指定其大小 五 若需频繁调用Collection
  • java解析邮件并下载附件

    package com testspring mailserver mail parsemail import com sun mail pop3 POP3Folder import org springframework web bind
  • AES加密解密

    import javax crypto Cipher import javax crypto spec SecretKeySpec 功能 加密解密工具类 日期 2022 5 5 author lf public class AesUtil2
  • feign的加解密封装

    功能描述 通过覆盖 feign codec Encoder 和 feign codec Decoder 实现 feign 请求的加解密操作 采用动态的 feignClient 调用 平台统一的通信加解密策略 同一个服务节点可以同时使用非加密
  • Java 开发工具类Pager

    import java util ArrayList import java util List 分页工具类 author user public class Pager private static final int DEFAULT P
  • 生成UUID

    import java util UUID author lf Description date 2022 5 5 public class IdUtils 根据字符串生成固定UUID param name public static sy
  • Java判断两个ListMap值是否相等(包括数据长度、存储的值)超实用工具类(亲测)

    一 功能描述 比较两个list中存储的map数据 比较的list的数据类型需一致 就能比较出存储的数据是否一致 二 实现步骤 1 比较两个list的长度大小 2 统计出每个list中存储的map值的个数及重复的 进行比较 3 具体比较值 三
  • mybatis-generator结合freemarker生成简单的service

    首先附上项目的github地址 点击打开链接 第一步 在generatorConfig xml里添加标签 点击进入xml文件对应的dtd文件 在contex那添加需要的标签
  • Object类型数据转化为json字符串工具类

    Object类型数据转json字符串 package com xxxxx emis base util import com fasterxml jackson annotation JsonFilter import com faster
  • Java实现通过证书访问Https请求

    创建证书管理器类 import java io FileInputStream import java security KeyStore import java security cert CertificateException imp
  • Java基础篇--工具类操作之敏感词过滤

    编写敏感词过滤程序 说明 在网络程序中 如聊天室 聊天软件等 经常需要对一些用户所提交的聊天内容中的敏感性词语进行过滤 如 性 色情 爆炸 恐怖 枪 军火 等 这些都不可以在网上进行传播 需要过滤掉或者用其他词语替换掉 提示 将用户的聊天内
  • Java 校验规则

    import java util regex Matcher import java util regex Pattern import static jodd util StringUtil isEmpty 数据校验 author lf
  • idea插件 restfulTool使用

    1 首先进行下载 两种方式 一个idea工具在插件直接下载 另一个是去官网把插件的包下载下来 官网地址 https plugins jetbrains com idea 然后搜索插件 2 里面有对应的版本 适合自己idea版本 可自行下载
  • MD5加密解密

    import java security MessageDigest import org apache commons codec digest DigestUtils import java math BigInteger Descri
  • 回调函数使用

    https www cnblogs com shenwen p 9046482 html
  • SpringBoot生成二维码

    目录 Zxing原生方式 添加依赖 二维码生成工具类 添加Controller 添加测试页面 使用postman测试效果 Hutool的方式 添加依赖 创建QRCodeService 添加Controller 效果测试 我们使用两种方式 去
  • Java将数字金额转换为中文大写

    import java math BigDecimal import java util regex Matcher import java util regex Pattern 2022 5 5 author lf public clas

随机推荐

  • Linux提权(mysql UDF提权)

    靶机为vulhub靶场中的Raven2 攻击机kali2021 192 168 61 128 靶机Raven2 192 168 61 148 1 信息收集 masscan nmap masscan扫描内网存活主机 快 nmap扫描端口开放情
  • 哪些软件 限制 服务器操作系统,配置服务器操作系统和软件准则_服务器知识学堂-中关村在线...

    如果你购买的服务器已经预装了操作系统 那么这将为您节省大约一个小时左右的时间 如果没有 那么你就要自行安装 下面是用户配置新服务器操作系统和软件的一些准则 1 只安装你使用的程序 如果你只想搭建一个文件服务器 那么你就不需要安装Web服务器
  • python测试3_Python小测试_3

    第二周 A 1 用 simpleguitk 创建的应用程序框架是由哪三部分组成的 标题 控制区域 鼠标 边框 画布 键盘 状态区域 背景区域 选择区域 2 假设在程序中已经导入 simpleguitk 下列哪项对 create frame
  • electron-builder打包白屏,报错:Not allowed to load local resource: file:///index.html解决方法

    报错如下 还有的是控制台弹窗报错 先看看项目目录结构 dist index html 打包好的主入口文件 main bundle js 打包好的main js文件 src main main js文件在里面 main js electron
  • hdf5文件读取

    深度学习中 数据集的特征文件通常以hdf5文件形式存储 读取方式如下 import h5py 读取文件 路径需要自己修改下 f h5py File home xdu yys MIGCN main data raw data charades
  • 【事件驱动】【数码管识别】 封装成DLL的函数的梳理

    要封装成动态链接库 首先要知道哪些函数需要封装起来 所以今天主要是把程序的结构梳理了一下 看看用到了哪些函数 因为后来识别的方法修改了 所以之前采用的很多函数没有再用到 所以就没有必要把所有的函数都封装起来了 程序主干部分的结构如下 这个流
  • 【regression】分位数回归 quantile regression

    quantile regression python实现 前言 分位数回归可调用的库 1 scikit learn 2 statsmodels quantile loss function python实现 1 在neural networ
  • 区块链在医疗行业能做些什么?

    千金难买一个健康的身体 健康是每个人成长和实现幸福生活的基础 也是促进人的全面发展的必然条件 当今时代 社会压力巨大 很多人处于亚健康的状态 这是一个亟需重视的问题 众所周知 很多疾病早发现就能实现早治疗 实现及时治疗 才能最大程度上挽回生
  • 腾讯云2核4G服务器5M带宽轻量CPU性能、流量和系统盘测试

    腾讯云轻量应用服务器2核4G5M配置 自带5M公网带宽 5M带宽下载速度峰值可达640KB 秒 系统盘为60GB SSD盘 每月500GB流量包 折合每天16GB流量 腾讯云百科来详细说下腾讯云轻量应用服务器2核4G5M配置 CPU型号处理
  • 「速通Shell」建楼先搬砖,Shell变量四大分类

    目录 Shell变量 什么是变量 shell变量定义 shell变量分类 环境变量 常见变量 变量引用 变量赋值 本地变量 变量定义 变量引用 变量赋值 变量删除 位置参数变量 变量定义 变量引用 特殊变量 变量定义 变量引用 总结 上一篇
  • POJ--1328:Radar Installation (贪心)

    1 题目源地址 http poj org problem id 1328 2 解题思路 该题题意是为了求出能够覆盖所有岛屿的最小雷达数目 每个小岛对应x轴上的一个区间 在这个区间内的任何一个点放置雷达 则可以覆盖该小岛 区间范围的计算用 x
  • MySQL数据库命令行详解

    MySQL数据库命令行详解 基础操作 进入数据库 mysql u root p databaseName root是只用管理员账户 后面括号是自己想连接的数据库名称 可不写 进入mysql后在通过use databaseName来连接对应数
  • 小样本学习--学习记录

    之前在做课题的时候 把数据不均衡和小样本的概念混淆了 昨天看了一篇论文 面向小样本数据的机器学习方法研究综述 陈良臣 傅德印 这篇论文写的非常清晰 推荐阅读 网上的一些综述整理都是根据 小样本学习研究综述 赵凯琳 这篇论文 知乎上的一篇笔记
  • 哪些应用适合服务器虚拟化,哪些服务器和应用适合虚拟化?

    虚拟化如今很流行 你可能也想把你所有的物理机进行虚拟化 考虑到可移植性 部署和硬件利用等方面的好处 虚拟化的确是非常诱人的 不过 这并不意味着虚拟化是任何服务器或应用的最好解决方案 至少现在还不是 其挑战是如何判断到底哪些服务器和应用适合于
  • 优秀英语教材

    优秀英语教材的选择 本人是个学生 依照自己学习英语的经历发表一些浅见 请各位不要将以下内容做商业用途 误区 1 在我看来 简单地评判一本英语教材是否优秀 可以观察以下几点 1 有无CEFR欧洲标准评级 2 是否是近10年出版 3 是否是英美
  • 【磕盐随记】C++ CUDA编程的环境配置

    一 前言 最近写了个又臭又长的代码来验证idea 效果还行但速度太慢 原因是代码中包含了一个很耗时的模块 这个模块需要连续执行百次以上才能得到最终结果 经过实测模块每次执行消耗约20ms 而且两次执行之间没有先后关系 为了保证系统的实时性
  • VUE3 + TS + 父子组件传值

    VUE3 TS 父子组件传值 父组件 传入几个变量 并且有接受子组件函数 changeaddress
  • 【主席树启发式合并】【P3302】[SDOI2013]森林

    Description 给定一个 n 个节点的森林 有 Q 次操作 每次要么将森林中某两点联通 保证操作后还是个森林 要么查询两点间权值第 k 小 保证两点联通 强制在线 Limitation 1 leq n Q leq 80000 Sol
  • SpringBoot核心配置全面总结

    Spring Boot的核心配置文件用于配置Spring Boot程序 文件名字必须以application开始 这个既是底层源码的强制要求 也是SpringBoot的一种代码规约 有助于在开发层面利于代码规范管理 说明 以下内容接着i前面
  • Java中的Calendar日历API用法完全解析

    第一部分 Calendar介绍 Calendar 定义 public abstract class Calendar implements Serializable Cloneable Comparable