第一代日期类
类结构

代码演示
java
public class Date_ {
public static void main(String[] args) throws ParseException {
//构造方法1
Date now = new Date();
System.out.println(now);
System.out.println(now.toString());
//构造方法2 参数表示的是 从 1970-01-01 00:00:00 UTC 开始经过的毫秒数
Date d2 = new Date(1792581127826);
System.out.println(d2);
//可以配合SimpleDataFormat类,转换成自己想要的格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(now));
System.out.println(sdf.format(d2));
/*
* parse 将字符串转化成对应的date对象
* 字符串的格式需要和new SimpleDateFormat时候的格式相同
*/
String s = "2222-02-22 22:22:22 星期三";
Date d = sdf.parse(s);
System.out.println(d.getTime());
//getTime() 和currentTimeMillis() 得到一个long型的整数,表示当前时间戳
//不过由于机器性能的原因,可能会相差几十毫秒,毕竟每执行一行代码,都是需要时间的
System.out.println(now.getTime());
System.out.println(System.currentTimeMillis());
System.out.printf("1995年这一年种的一个随机时间 %s ", sdf.format(getRandomDateTime("1995", "1995")));
System.out.println();
//练习
String[] dates = new String[9];
for (int i = 0; i < dates.length; i++) {
dates[i] = sdf.format(getRandomDateTime("1970", "2000"));
}
System.out.println("init dates:" + Arrays.toString(dates));
Arrays.sort(dates, (sd1, sd2)->{
try {
Date p1 = sdf.parse(sd1);
Date p2 = sdf.parse(sd2);
return p2.compareTo(p1);
} catch (ParseException e) {
throw new RuntimeException(e);
}
});
System.out.println(Arrays.toString(dates));
}
public static Date getRandomDateTime(String startYear, String endYear) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String start = startYear + "-01-01 00:00:00";
String end = endYear + "-12-31 23:59:59";
Date ps = sdf.parse(start);
Date pd = sdf.parse(end);
long yearMs = pd.getTime() - ps.getTime();
long rl = (long)(Math.random() * yearMs);
return new Date(ps.getTime() + rl);
}
}
SimpleDateFormat类定义了以下模式字母(所有其他字符 'A' 到 'Z' 和 'a' 到 'z' 都被保留):

第二代日期类
类结构

类特性:
- Calendar是一个抽象类(不能被实例化),构造器都是protected类型的,所以java.util包之外的类无法通过Calendar的构造器创建对象。
- 可以通过getInstance方法获取实例
- 提供了大量的方法和属性。
- 没有提供对应的格式化类。需要自己类组合。
代码示例
java
public class Calendar_ {
public static void main(String[] args) {
//类似于单例,通过getInstance()创建对象
Calendar c = Calendar.getInstance();
System.out.println(c);
//获取日历对象的某个日历字段
System.out.println("年:" + c.get(Calendar.YEAR));
//这里的月份是从0开始的,所以要加1
System.out.println("月:" + (c.get(Calendar.MONTH) + 1));
System.out.println("日:" + c.get(Calendar.DAY_OF_MONTH));
System.out.println("小时:" + c.get(Calendar.HOUR));
System.out.println("分钟:" + c.get(Calendar.MINUTE));
System.out.println("秒:" + c.get(Calendar.SECOND));
//Calender 没有专门的格式化方法,所以需要程序员自己来组合显示
System.out.println(c.get(Calendar.YEAR) + " 年" + (c.get(Calendar.MONTH) + 1)
+ " 月 " + c.get(Calendar.DAY_OF_MONTH) + "日");
}
}
Calendar也存在问题:
-
可变性:像日期和时间这样的类应该是不可变的。
-
偏移性:Date中的年份是从1900开始的,而月份都从0开始。
-
格式化:格式化只对Date有用,Calendar则不行。
-
此外,它们也不是线程安全的;不能处理闰秒等(什么是瑞年?每隔2天,多出1s)。
第三代日期类(jdk8后增加)
类结构


代码示例
java
public class LocalDate_ {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now(); //年月日时分秒
LocalDate date = LocalDate.now(); //只需要年月日
LocalTime time = LocalTime.now();//只需要时间
System.out.println(now);
System.out.println(date);
System.out.println(time);
//常用方法
System.out.println("年:" + now.getYear());
System.out.println("月:" + now.getMonthValue());
System.out.println("月:" + now.getMonth());
System.out.println("日:" + now.getDayOfMonth());
System.out.println("时:" + now.getHour());
System.out.println("分:" + now.getMinute());
System.out.println("秒:" + now.getSecond());
//时间格式化 DateTimeFormatter类(类似于SimpleDateFormat类)
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时 mm分 ss秒");
System.out.println(dtf.format(now));
}
}
All letters 'A' to 'Z' and 'a' to 'z' are reserved as pattern letters. The following pattern letters are defined

Instant 时间戳类
类似于Date类,并且提供了一系列与Date转换的方式
java
public class Instant_ {
public static void main(String[] args) {
//获取当前时间戳对象
Instant now = Instant.now();
System.out.println(now);
//Instant ---> Date
Date date = Date.from(now);
System.out.println(date);
//Date--->instant
Instant instant = date.toInstant();
System.out.println(instant);
}
}
第三代日期类更多方法
LocalDateTime类MonthDay类: 检查重复事件- 是否是闰年
- 增加日期的某个部分
- 使用
plus方法测试增加时间的某个部分 - 使用
minus方法测试查看一年前和一年后的日期
java
public class LocalDate_ {
public static void main(String[] args) {
//plus、minus系列方法可以对当前时间进行增加和减少
LocalDateTime plus = now.plusDays(300);
System.out.println("300天之后的日期:" + dtf.format(plus));
LocalDateTime minus = now.minusDays(100);
System.out.println("100天之前的日期:" + dtf.format(minus));
LocalDateTime lastMinMinus = now.minusMinutes(30);
System.out.println("30分钟之前的日期:" + dtf.format(lastMinMinus));
LocalDateTime addYearPlus = now.plusYears(20);
System.out.println("20年之后的日期:" + dtf.format(addYearPlus));
}
}
开发中尽量使用第三代日期类