Java基础——Date和Calendar类超详细讲解
在Java编程里,对日期和时间的处理是非常常见的操作。Date
类和Calendar
类便是Java提供的处理日期和时间的重要工具。虽然从Java 8开始引入了新的日期时间API,如LocalDate
、LocalTime
、LocalDateTime
等,但Date
类和Calendar
类在旧代码中仍广泛存在,理解它们的用法对Java开发者来说依旧十分必要。
一、Date类
(一)概述
java.util.Date
类用于表示特定的时间点,精确到毫秒。它记录的是自1970年1月1日00:00:00 GMT(格林威治标准时间)以来的毫秒偏移量,这个时间点也被称作“纪元时间”。不过,Date
类的大部分方法已被弃用,原因在于其API设计不够直观,并且对国际化支持不足。即便如此,在一些需要快速表示日期和时间戳的场景中,Date
类仍被频繁使用。
(二)构造函数
- 无参构造函数:
Date()
,使用当前日期和时间来初始化对象。例如:
Date now = new Date();
System.out.println("当前时间:" + now);
- 带参构造函数:
Date(long millisec)
,接收一个参数,该参数是从1970年1月1日起的毫秒数。比如:
long milliseconds = 1690000000000L;
Date specificDate = new Date(milliseconds);
System.out.println("指定毫秒数对应的时间:" + specificDate);
(三)常用方法
虽然许多方法已弃用,但仍有部分常用方法在使用:
getTime()
:返回自1970年1月1日0点0分0秒(UTC)以来的毫秒数。例如:
Date date = new Date();
long time = date.getTime();
System.out.println("当前时间的毫秒数:" + time);
equals(Object obj)
:比较调用此方法的Date
对象和指定对象是否相等,相等返回true
,否则返回false
。
Date date1 = new Date();
Date date2 = new Date();
boolean isEqual = date1.equals(date2);
System.out.println("两个日期是否相等:" + isEqual);
before(Date when)
:判断调用此方法的Date
对象是否在指定日期之前,是则返回true
,否则返回false
。
Date earlierDate = new Date(1690000000000L);
Date laterDate = new Date(1690000001000L);
boolean isBefore = earlierDate.before(laterDate);
System.out.println("earlierDate是否在laterDate之前:" + isBefore);
after(Date when)
:判断调用此方法的Date
对象是否在指定日期之后,是则返回true
,否则返回false
。
(四)格式化与解析
Date
类本身没有提供很好的日期格式化和解析功能,通常借助SimpleDateFormat
类来实现。SimpleDateFormat
是一个以语言环境敏感的方式来格式化和分析日期的类。
- 格式化日期:确立转换格式,例如
SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
,其中yyyy
是完整的公元年,MM
是月份,dd
是日期,HH:mm:ss
是时、分、秒。注意大小写,如MM
是月份,mm
是分;HH
是24小时制,hh
是12小时制。示例如下:
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateFormatExample {
public static void main(String[] args) {
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EEE a");
String formattedDate = sdf.format(now);
System.out.println("格式化后的日期:" + formattedDate);
}
}
- 解析日期:将符合特定格式的字符串解析为
Date
对象,例如:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateParseExample {
public static void main(String[] args) {
String dateString = "2024-08-10 12:30:00";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
Date date = sdf.parse(dateString);
System.out.println("解析后的日期:" + date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
二、Calendar类
(一)概述
java.util.Calendar
类是一个抽象类,用于表示特定时区内的日历日期和时间。它提供了丰富的方法来操作日期和时间字段,比如年、月、日、小时、分钟、秒等,并且支持国际化。通常使用其静态方法getInstance()
来获取Calendar
的实例,返回的是默认时区和语言环境的Calendar
对象,一般是GregorianCalendar
(格里高利历,目前世界广泛使用的日历系统)的实例。
(二)字段
Calendar
类定义了一系列int
类型的常量字段来表示时间的各个组成部分:
YEAR
:年份。MONTH
:月份(从0开始,0代表1月,11代表12月)。DAY_OF_MONTH
:一个月中的第几天。HOUR_OF_DAY
:一天中的小时数(24小时制)。MINUTE
:分钟。SECOND
:秒。
(三)常用方法
getInstance()
:获取默认时区和语言环境的Calendar
实例。
Calendar calendar = Calendar.getInstance();
set(int field, int value)
:设置日历字段的值。例如设置年份为2024,月份为8月(注意月份从0开始,7代表8月),日期为10日:
calendar.set(Calendar.YEAR, 2024);
calendar.set(Calendar.MONTH, 7);
calendar.set(Calendar.DAY_OF_MONTH, 10);
get(int field)
:获取日历字段的值。比如获取当前年份:
int year = calendar.get(Calendar.YEAR);
add(int field, int amount)
:根据日历规则,将指定的时间量添加到指定的日历字段中。例如将日期增加3天:
calendar.add(Calendar.DAY_OF_MONTH, 3);
setTime(Date date)
:使用给定的Date
设置此Calendar
的时间。
Date date = new Date();
calendar.setTime(date);
getTime()
:返回一个表示此Calendar
时间值的Date
对象。
Date resultDate = calendar.getTime();
getTimeInMillis()
:返回此Calendar
的时间值,以毫秒为单位。
long millis = calendar.getTimeInMillis();
(四)示例代码
import java.util.Calendar;
import java.util.Date;
public class CalendarExample {
public static void main(String[] args) {
// 获取默认时区和语言环境的Calendar实例
Calendar calendar = Calendar.getInstance();
// 打印当前时间
System.out.println("当前时间: " + calendar.getTime());
// 设置日期为2024年8月10日
calendar.set(Calendar.YEAR, 2024);
calendar.set(Calendar.MONTH, Calendar.AUGUST);
calendar.set(Calendar.DAY_OF_MONTH, 10);
// 打印设置后的日期
System.out.println("设置后的日期: " + calendar.getTime());
// 获取年份、月份和日
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1; // 转换为常规月份表示
int day = calendar.get(Calendar.DAY_OF_MONTH);
// 打印年份、月份和日
System.out.printf("年: %d, 月: %d, 日: %d\n", year, month, day);
// 将时间向前推进3天
calendar.add(Calendar.DAY_OF_MONTH, 3);
// 打印调整后的日期
System.out.println("调整后的日期: " + calendar.getTime());
// 获取当前时间的毫秒表示
long currentTimeMillis = calendar.getTimeInMillis();
System.out.println("当前时间的毫秒表示: " + currentTimeMillis);
// 假设我们有一个特定的Date对象
Date specificDate = new Date(currentTimeMillis - 1000 * 60 * 60 * 24); // 一天前
// 使用这个Date对象来设置Calendar的时间
calendar.setTime(specificDate);
// 打印一天前的日期
System.out.println("一天前的日期: " + calendar.getTime());
}
}
三、Date类和Calendar类的区别
- 可变性:
Date
类是不可变的,一旦创建了Date
对象,就无法更改它所表示的时间。而Calendar
类是可变的,可以使用其方法来修改日期和时间的各个组成部分。 - 国际化:
Calendar
类支持国际化,考虑了时区信息,能处理不同时区中的日期和时间。Date
类没有此功能。 - 易用性:
Calendar
类提供了更多处理日期和时间的方法,包括获取和设置日期和时间的各个组成部分,比Date
类更易用。 - API设计:
Date
类的许多方法已被弃用,API设计不够直观。Calendar
类的API设计更直观和易于使用。 - 时间戳:若只需要时间戳(自1970年1月1日以来的毫秒偏移量),
Date
类是更好选择。若需要处理日期和时间的各个组成部分,或者考虑时区信息和国际化,Calendar
类则更合适。
理解并熟练运用Date
类和Calendar
类,能帮助开发者更好地处理Java编程中的日期和时间相关问题。如果你还想了解在实际项目中如何优化日期时间处理,或者在特定场景下如何选择使用Date
类和Calendar
类 ,欢迎随时交流。