一、Date
1.1 获取当前时间
Date date = new Date();
1.2 时间戳和Date格式互相转换
// 时间戳转Date
Date date = new Date(long date);
// Date转时间戳
Long time = date.getTime();
1.3 自定义时间
通过SimpleDateFormat类的构造函数,定义一个格式化的实例。构造函数传入一个格式化模板的参数。
DateFormat类的parse(String source)方法需捕获异常,使用parse(String source, ParsePosition pos)方法可不用捕获异常。
// 指定格式
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
// 字符串转Date日期
Date date = dateFormat.parse("2022-09-17 18:00:00.000");
System.out.println(date); // Sat Sep 17 18:00:00 CST 2022
// Date日期转字符串
String dateStr = dateFormat.format(date);
System.out.println(dateStr); // 2022-09-17 18:00:00.000
1.4 指定格式的String字符串和Date格式互相转换
// String 转 Date
String dateStr = "2022-07-08 15:22:00";
Date date = dateFormat.parse(dateStr);
System.out.println(date);
// Date 转 String
String dateStr1 = dateFormat.format(date);
System.out.println(dateStr1);
1.5 两个Date格式时间比较大小、判断是否相等
方式1:通过before()、after()的方式比较大小
方式2:将Date格式转成时间戳比较大小
// 定义格式并创建Date格式对象
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr1 = "2022-07-08 15:22:00";
String dateStr2 = "2022-07-08 16:00:00";
Date date1 = dateFormat.parse(dateStr1, new ParsePosition(0));
Date date2 = dateFormat.parse(dateStr2, new ParsePosition(0));
// date1是否在date2之前,也就是date1是否小于date2 // 返回true
System.out.println(date1.before(date2));
System.out.println(date1.getTime() < date2.getTime());
// date1是否在date2之后,也就是date1是否大于date2 // 返回false
System.out.println(date1.after(date2));
System.out.println(date1.getTime() > date2.getTime());
// date1是否等于date2 // 返回false
System.out.println(date1.equals(date2));
1.6 Date时间加1天或减1天
将Date格式转换成Calendar格式进行的加减运算,参考下节Calendar使用
二、Calendar
2.1 Calendar常用的常量 - 时间属性
常量 | 描述 |
---|---|
Calendar.YEAR | 年份 |
Calendar.MONTH | 月份,月份从0开始,011表示1月12月 |
Calendar.DATE | 日期在年月日中的日 |
Calendar.WEEK_OF_MONTH | 本月的第几个周 |
Calendar.DAY_OF_WEEK | 本周的第几天,周日开始算第一天 |
Calendar.DAY_OF_MONTH | 本月的第几天,和常量Calendar.DATE差不多 |
Calendar.DAY_OF_YEAR | 当前年度的第多少天 |
Calendar.HOUR | 小时(12小时格式) |
Calendar.HOUR_OF_DAY | 小时(24小时格式) |
Calendar.MINUTE | 分钟 |
Calendar.SECOND | 秒 |
Calendar.MILLISECOND | 毫秒 |
Calendar.JANUARY | 一月,值等于0 |
Calendar.FEBRUARY | 二月,值等于1 |
Calendar.MARCH | 三月,值等于2 |
Calendar.APRIL | 四月,值等于3 |
Calendar.MAY | 五月,值等于4 |
Calendar.JUNE | 六月,值等于5 |
Calendar.JULY | 七月,值等于6 |
Calendar.AUGUST | 八月,值等于7 |
Calendar.SEPTEMBER | 九月,值等于8 |
Calendar.OCTOBER | 十月,值等于9 |
Calendar.NOVEMBER | 十一月,值等于10 |
Calendar.DECEMBER | 十二月,值等于11 |
2.2 获取当前时间
Calendar calendar = Calendar.getInstance();
2.3 设置时间、自定义时间
直接根据Date日期 或 时间戳设置Calendar时间
Calendar calendar = Calendar.getInstance();
// 设置Date时间格式
calendar.setTime(new Date());
// 设置时间戳格式
calendar.setTimeInMillis(System.currentTimeMillis());
根据某个时间属性设置对应的值
下面例子打印的年、月、日是设置后的日期,时间(时、分、秒)没有设置会因打印当前时间
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2021); // 设置年
calendar.set(Calendar.MONTH, 10); // 设置月
calendar.set(Calendar.DATE, 15); // 设置日
System.out.println("输出:" + dateFormat.format(calendar.getTime())); // 输出:2021-11-15 11:20:43.451
2.4 获取时间属性
将Calendar转成Date日期格式 或 时间戳格式
Calendar calendar = Calendar.getInstance();
// Calendar格式修改为Date格式
Date date = calendar.getTime();
// Calendar格式修改为时间戳格式
Long time = calendar.getTimeInMillis();
获取Calendar日期的某个时间属性的值,calendar.get()方法的返回值均是int类型
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.get(Calendar.YEAR)); // 当前年份
System.out.println(calendar.get(Calendar.MONTH)); // 当前月份,月份从0开始,0~11表示1月~12月
System.out.println(calendar.get(Calendar.DATE)); // 当前日期在年月日中的日
System.out.println(calendar.get(Calendar.HOUR)); // 当前小时数(12小时格式)
System.out.println(calendar.get(Calendar.HOUR_OF_DAY)); // 当前小时数(24小时格式)
System.out.println(calendar.get(Calendar.MINUTE)); // 分钟数
System.out.println(calendar.get(Calendar.SECOND)); // 秒数
System.out.println(calendar.get(Calendar.MILLISECOND)); // 毫秒数
2.5 提前 或 延后指定的时间(时间推移)
通过Calendar类的add()方法或roll()方法进行时间推移.
- add(int field, int amount)
add方法,顾名思义就是对某个时间增加多少时间。
该方法接收两个参数——“field”表示时间属性,可传入Calendar的常量属性;“amount”表示要增加的时间值,正数表示时间属性对应的日期延后,负数表示提前。如下:
// 定义日期格式
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
// 先打印当前时间
System.out.println(dateFormat.format(new Date())); // 2022-09-17
// 通过Calendar 对日期进行推移,年份加一年,日提前5天
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, 1);
calendar.add(Calendar.DATE, -5);
// 打印推移后的日期
System.out.println(dateFormat.format(calendar.getTime())); // 2023-09-12
- roll(int field, boolean up)
该方法接收两个参数——“field”表示时间属性,可传入Calendar的常量属性;“up”为一个布尔值,true表示“field”对应的时间属性值加1,false表示“field”对应的时间属性值加减1。如下
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(dateFormat.format(new Date())); //2022-09-17
Calendar calendar = Calendar.getInstance();
// 年份减 1
calendar.roll(Calendar.YEAR, false);
// 日加 1
calendar.roll(Calendar.DATE, true);
System.out.println(dateFormat.format(calendar.getTime())); // 2021-09-18
- roll(int field, int amount)
该方法同样接收两个参数——“field”表示时间属性,可传入Calendar的常量属性;“amount”表示要增加的时间值,正数表示时间属性对应的日期延后,负数表示提前。
该方法名和上面的roll()方法名看似相同,但用法不同,上面第二个参数接收的布尔值,只能对前一个日期属性值进行加1或减1;而该方法可通过“amount”参数推移多个日期属性值。
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println(dateFormat.format(new Date())); // 2022-09-17
// 通过Calendar 对日期进行推移,年份加一年,日提前5天
Calendar calendar = Calendar.getInstance();
calendar.roll(Calendar.YEAR, 1);
calendar.roll(Calendar.DATE, -5);
// 打印推移后的日期
System.out.println(dateFormat.format(calendar.getTime())); // 2023-09-12
- 注意add()方法和roll()方法的本质区别:
- 通过add()对日期属性推移的量,超出该属性的最大或最小范围时,会对它的上一级属性产生影响。例如9月28日增加3天,会变成10月1日。
- 通过roll()对日期属性推移的量,超出该属性的最大或最小范围时,会对它的上一级属性产生影响。例如9月28日增加3天,会变成9月1日。
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
// 先打印当前日期
System.out.println(dateFormat.format(new Date())); // 2022-09-17
// 通过add()方法对当前日期增加5个月,超出月份最大值后,年份会增加
Calendar calendar1 = Calendar.getInstance();
calendar1.add(Calendar.MONTH, 5);
System.out.println(dateFormat.format(calendar1.getTime())); // 2023-02-17
// 通过roll()方法对当前日期增加5个月,超出月份最大值后,年份不会增加
Calendar calendar2 = Calendar.getInstance();
calendar2.roll(Calendar.MONTH, 5);
System.out.println(dateFormat.format(calendar2.getTime())); // 2022-02-17
三、LocalDateTime、LocalDate、LocalTime
LocalDateTime、LocalDate、LocalTime是Java1.8版本的新特性。
- 三者区别
- LocalDateTime:表示包含年、月、日、时、分、秒、毫秒的对象
- LocalDate:表示包含年、月、日的对象
- LocalTime:表示包含时、分、秒、毫秒的对象
3.1 获取当前时间
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime); // 2022-09-17T21:22:29.036
LocalDate localDate = LocalDate.now();
System.out.println(localDate); // 2022-09-17
LocalTime localTime = LocalTime.now();
System.out.println(localTime); // 21:22:29.036
3.2 获取时间属性
LocalDateTime、LocalDate、LocalTime均可通过实例对象的getXxx()方法获取出对应的年份、月份、日期、时、分、秒、毫秒等属性的值,如下:
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime.getDayOfYear()); // 260(表示今天是本年度的第260天)
LocalDate localDate = LocalDate.now();
System.out.println(localDate.getMonthValue()); // 9(表示当前月份时9月份)
LocalTime localTime = LocalTime.now();
System.out.println(localTime.getHour()); // 21 (表示当前时间的小时值是21)
3.3 常用的自定义日期与时间
// 自定义LocalDateTime日期,可传入年、月、日、时、分、秒参数。如需毫秒数可追加一个参数,下方的500000000为纳秒单位
LocalDateTime localDateTime = LocalDateTime.of(2022, 9, 17, 22, 5, 5);
LocalDateTime localDateTime1 = LocalDateTime.of(2022, 9, 17, 22, 5, 5, 500000000);
// 自定义LocalDate日期,可传入年、月、日参数
LocalDate localDate = LocalDate.of(2022, 9, 17);
// 自定义LocalTime日期,可传入时、分、秒参数。如需毫秒数可追加一个参数,下方的200000000为纳秒单位
LocalTime localTime = LocalTime.of(22, 10, 10);
LocalTime localTime1 = LocalTime.of(22, 10, 10, 200000000);
3.4 Date日期与LocalDateTime、LocalDate、LocalTime的互相转换
- Date日期与这三中时间类型的对象进行转换时,都需要结合java.time包下ZoneId和Instant两个工具类进行转换。
- java.time.ZoneId:时区类
- java.time.Instant:距离时间差。也就是表示了时间线上一个确切的点,距离初始时间的时间差(初始时间为GMT 1970年1月1日00:00)
// Date日期转LocalDateTime
Date date = new Date();
Instant instant = date.toInstant();
LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
// LocalDateTime转Date日期
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
Date date1 = Date.from(zonedDateTime.toInstant());
System.out.println(date1);
// Date日期转LocalDate
Date date = new Date();
Instant instant = date.toInstant();
LocalDate localDate = instant.atZone(ZoneId.systemDefault()).toLocalDate();
// LocalDate转Date日期
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zonedDateTime = localDate.atStartOfDay(zoneId);
Date date1 = Date.from(zonedDateTime.toInstant());
// Date日期转LocalTime
Date date = new Date();
Instant instant = date.toInstant();
LocalTime localTime = instant.atZone(ZoneId.systemDefault()).toLocalTime();
// LocalTime转日期格式需将LocalTime结合LocalDate转成LocalDateTime,再将LocalDateTime转成Date日期
LocalDate localDate = LocalDate.now();
LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
Date date1 = Date.from(zonedDateTime.toInstant());
3.5 比较大小
LocalDateTime、LocalDate、LocalTime使用各自实例的"a.compareTo(b)"方法比较大小,该方法接收同类型的实例对象,返回一个int类型的结果——返回结果有3种,-1表示a小于b,0表示a=b,1表示a大于b。
// 两个LocalDateTime实例比较大小
LocalDateTime localDateTime = LocalDateTime.of(2022, 9, 17, 23, 5, 5);
LocalDateTime localDateTime1 = LocalDateTime.of(2022, 9, 17, 22, 5, 5, 0);
System.out.println(localDateTime.compareTo(localDateTime1)); // 1
// 两个相同的LocalDate实例比较大小
System.out.println(LocalDate.now().compareTo(LocalDate.now())); // 0
// 两个LocalTime实例比较大小
LocalTime localTime = LocalTime.of(22, 10, 10);
LocalTime localTime1 = LocalTime.of(22, 10, 10, 200000000);
System.out.println(localTime.compareTo(localTime1)); // -1
3.6 提前 或 延后指定的时间(时间推移)
方式一:可通过LocalDateTime、LocalDate、LocalTime实例对象的plusXxx()方法提前或延后指定的日期时间属性,plusXxx()接收一个long类型的参数,正数表示延后时间,负数表示提前时间。
LocalDateTime localDateTime = LocalDateTime.now();
// 当前时间,控制台输出:2022-09-18T18:24:29.875
System.out.println(localDateTime);
// 当前时间延后1天,控制台输出:2022-09-19T18:24:29.875
System.out.println(localDateTime.plusDays(1));
// 当前时间提前5个小时,控制台输出:2022-09-18T13:24:29.875
System.out.println(localDateTime.plusHours(-5));
LocalDate localDate = LocalDate.now();
// 当前日期,控制台输出:2022-09-18
System.out.println(localDate);
// 当前日期延后2周,控制台输出:2022-10-02
System.out.println(localDate.plusWeeks(2));
// 当前日期提前5天,控制台输出:2022-09-13
System.out.println(localDate.plusDays(-5));
LocalTime localTime = LocalTime.now();
// 当前时间,控制台输出:18:24:29.875
System.out.println(localTime);
// 当前时间延后300毫秒,控制台输出:18:24:30.175
System.out.println(localTime.plusNanos(300000000));
// 当前时间提前5个小时,控制台输出:13:24:29.875
System.out.println(localTime.plusHours(-5));
方式二:还可以通过各实例对象的plus(TemporalAmount amount)或plus(long amountToAdd, TemporalUnit unit)方法进行时间推移
- plus(TemporalAmount amount)
- 推移日期用TemporalAmount 的实现类Period
- 推移时间用TemporalAmount 的实现类Duration
- plus(long amountToAdd, TemporalUnit unit),该方法接收两个参数
- 第一个参数正数表示延后,负数表示提前
- 第二个参数,推移日期和时间均可用TemporalUnit的实现类ChronoUnit
LocalDateTime localDateTime = LocalDateTime.now();
// 当前时间,控制台输出:2022-09-18T18:39:11.832
System.out.println(localDateTime);
// 当前时间延后5天,控制台输出:2022-09-23T18:39:11.832
System.out.println(localDateTime.plus(Period.ofDays(5)));
// 当前时间提前5个小时,控制台输出:2022-09-18T13:39:11.832
System.out.println(localDateTime.plus(-5, ChronoUnit.HOURS));
LocalTime localTime = LocalTime.now();
// 当前时间,控制台输出:18:39:11.832
System.out.println(localTime);
// 当前时间延后30秒,控制台输出:18:39:41.832
System.out.println(localTime.plus(Duration.ofSeconds(30)));
// 当前时间提前10分钟,控制台输出:18:29:11.832
System.out.println(localTime.plus(10, ChronoUnit.MINUTES));