Java 常用时间API:时间类,日期类
JDK8 之前
Date类 : 表示日期时间的类
构造方法 :
| 构造器 |
说明 |
| public Date() |
创建一个Date对象,代表的是系统当前此刻日期时间。 |
| public Date(long time) |
把时间毫秒值转换成Date日期对象。 |
1 2 3 4
| Date d1 = new Date(0L); System.out.println(d1); Date d2 = new Date(1000L); System.out.println(d2);
|
常见方法 :
| 常见方法 |
说明 |
| public long getTime() |
返回从1970年1月1日 00:00:00走到此刻的总的毫秒数 |
| public void setTime(long time) |
设置日期对象的时间为当前时间毫秒值对应的时间 |
1.构造方法 :
| 构造器 |
说明 |
| public SimpleDateFormat() |
构造一个SimpleDateFormat日期格式化对象,使用默认格式 |
| public SimpleDateFormat(String pattern) |
构造一个SimpleDateFormat日期格式化对象,使用指定的格式 |
2.常见方法 :
| 格式化方法 |
说明 |
| public final String format(Date date) |
将日期对象格式化成日期时间字符串 |
| public final Date parse(String source) |
将日期字符串解析为日期类型 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public static void main(String[] args) throws ParseException { SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat(); SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy年MM月dd日"); Date date = new Date(); String time = simpleDateFormat1.format(date); String time = simpleDateFormat2.format(date);
String today = "2023年1月1日"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日"); Date date = simpleDateFormat.parse(today); System.out.println(date); }
private static void method() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
Date date = new Date();
String result = simpleDateFormat.format(date);
System.out.println(result); }
|
Calendar 类:系统此刻时间对应的日历,用于单独获取、修改时间中的年、月、日、时、分、秒
创建对象
注: Calendar是一个抽象类,不能直接创建对象,使用静态方法创建
| 方法名 |
说明 |
| public static Calendar getInstance() |
获取当前时间的日历对象 |
常用方法
| 方法名 |
说明 |
| public int get(int field) |
获取日历中的某个字段信息 |
| public void set(int field,int value) |
修改日历的某个字段信息 |
| public void add(int field,int amount) |
为某个字段增加/减少指定的值 |
| public final Date getTime() |
获取日期对象 |
| public final setTime(Date date) |
给日历设置日期对象 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| private static void getMethod() { Calendar c = Calendar.getInstance(); int year = c.get(Calendar.YEAR); System.out.println(year);
int month = c.get(Calendar.MONTH); System.out.println(month + 1);
int day = c.get(Calendar.DAY_OF_MONTH); System.out.println(day);
char[] weeks = {' ', '日', '一', '二', '三', '四', '五', '六'};
int weekIndex = c.get(Calendar.DAY_OF_WEEK); System.out.println(weeks[weekIndex]);
int dayOfYear = c.get(Calendar.DAY_OF_YEAR); System.out.println(dayOfYear); }
private static void setMethod() { Calendar c = Calendar.getInstance(); c.set(Calendar.YEAR, 2022); c.set(2000,1,1); }
private static void addMethod() { Calendar c = Calendar.getInstance(); c.add(Calendar.YEAR, -1); }
|
注:get方法的参数为Calendar类中的静态常量
Calendar.YEAR : 获取年
Calendar.MONTH : 月份是0~11, 常规日期要+1
Calendar.DAY_OF_MONTH : 获取日
Calendar.DAY_OF_WEEK : 获取星期, 但是1代表周日,7代表周六
Calendar.DAY_OF_YEAR : 获取一年中的第几天
实例
1.判断 2030年3月3日 周几
1 2 3 4
| Calendar c = Calendar.getInstance(); c.set(2030, 2, 3); char[] weeks = {' ', '日', '一', '二', '三', '四', '五', '六'}; int weekIndex = c.get(Calendar.DAY_OF_WEEK);
|
2.键盘录入一个日期字符串, 判断是一年的第几天
分析:
- 使用SimpleDateFormat, 将日期字符串转换为日期对象
- 将日期对象, 转换为Calendar对象
- 调用get方法, 获取是一年中的第几天
1 2 3 4 5 6 7 8
| Scanner sc = new Scanner(System.in); System.out.println("请输入:"); String dateContent = sc.nextLine(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日"); Date date = dateFormat.parse(dateContent); Calendar c = Calendar.getInstance(); c.setTime(date); int dayOfYear = c.get(Calendar.DAY_OF_YEAR);
|
前后对比
JDK8之前的传统的时间API
- 设计欠妥,使用不方便,部分已经淘汰
- 都是可变对象,修改后会丢失最开始的时间信息 覆盖之前的时间信息
- 线程不安全
- 只能精确到毫秒
JDK8开始之后新增的时间API
- 设计更合理,功能丰富,使用更方便
- 都是不可变对象,修改后会返回新的时间对象,不会丢失最开始的时间 每一次修改都返回一个新的对象
- 线程安全
- 能精确到毫秒、纳秒
JDK8 之后
日历类
LocalDate:代表本地日期(年、月、日、星期)
LocalTime:代表本地时间(时、分、秒、纳秒)
LocalDateTime:代表本地日期、时间(年、月、日、星期、时、分、秒、纳秒)
获取对象
| 方法名 |
示例 |
| public static Xxxx now(): 获取系统当前时间对应的该对象 |
LocaDate ld = LocalDate.now();LocalTime lt = LocalTime.now(); LocalDateTime ldt = LocalDateTime.now(); |
| public static Xxxx of(…):获取指定时间的对象 |
LocalDate localDate1 = LocalDate.of(2099 , 11,11); LocalTime localTime1 = LocalTime.of(9, 8, 59);LocalDateTime localDateTime1 = LocalDateTime.of(2025, 11, 16, 14, 30, 01); |
获取对象中的年月日时分秒
| 方法名 |
功能 |
| int getYear() |
获取年 字段 |
| Month getMonth() |
使用 Month 枚举获取年份字段 |
| int getMonthValue() |
获取1到12之间的月份字段 |
| int getDayOfMonth() |
获取日 |
| DayOfWeek getDayOfWeek() |
获取星期 字段,即枚举 DayOfWeek |
| int getHour() |
获取时 |
| int getMinute() |
获取分 |
| int getSecond() |
获取秒 |
1 2 3 4 5 6 7 8 9 10 11
| LocalDateTime now = LocalDateTime.now(); System.out.println(now); LocalDateTime time = LocalDateTime.of(2000, 1, 1, 1, 1); System.out.println(now.getYear() + "年"); System.out.println(now.getMonth() + "月"); System.out.println(now.getMonthValue() + "月"); System.out.println(nowDateTime.getMonth().getValue()); System.out.println(now.getDayOfMonth() + "日"); System.out.println("dayOfYear:" + nowDateTime.getDayOfYear()); System.out.println(nowDateTime.getDayOfWeek()); System.out.println(nowDateTime.getDayOfWeek().getValue());
|
修改年月日时分秒相关
LocalDateTime 、LocalDate 、LocalTime 都是不可变的, 方法返回的是一个新对象
| 方法名 |
说明 |
| withHour、withMinute、withSecond、withNano |
修改时间,返回新时间对象 |
| plusHours、plusMinutes、plusSeconds、plusNanos |
把某个信息加多少,返回新时间对象 |
| minusHours、minusMinutes、minusSeconds、minusNanos |
把某个信息减多少,返回新时间对象 |
| equals / isBefore / isAfter |
判断2个时间对象,是否相等,在前还是在后 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| LocalDateTime nowTime = LocalDateTime.now();
System.out.println(nowTime.withYear(2000)); System.out.println(nowTime.withMonth(1)); System.out.println(nowTime.withDayOfMonth(1)); System.out.println(nowTime.withHour(1)); System.out.println(nowTime.withNano(1));
nowTime = LocalDate.of(2008, 8, 8);
System.out.println(nowTime.minusHours(1)); System.out.println(nowTime.minusSeconds(1));
System.out.println(nowTime.plusMinutes(1));
System.out.println(date1.isBefore(date2)); System.out.println(date1.isAfter(date2)); System.out.println(date1.equals(date2));
|
LocalDateTime 转 LocalDate 和 Local Time
| 方法名 |
说明 |
| public LocalDate toLocalDate() |
转换成一个LocalDate对象 |
| public LocalTime toLocalTime() |
转换成一个LocalTime对象 |
——-> LocalDateTime拆分两块功能给LocalDate, LocalTime
日期格式化类
格式化时间
| 方法名 |
说明 |
| static DateTimeFormatter ofPattern(格式) |
获取格式对象 |
| String format(时间对象) |
按照指定方式格式化 |
解析时间 :
LocalDateTime.parse(“解析字符串”, 格式化对象);
LocalDate.parse(“解析字符串”, 格式化对象);
LocalTime.parse(“解析字符串”, 格式化对象);
1 2 3 4 5 6
| LocalDateTime nowTime = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年M月d日"); String gsltime = formatter.format(nowTime);
String time = "2000年01月01日"; LocalDate parse = LocalDate.parse(time, formatter);
|
DateTimeFormatter.ofPattern("yyyy年MM月dd日"); :不能解析2000-1-1
DateTimeFormatter.ofPattern("yyyy年M月d日"); :可以解析2000-1-1,也可以解析2000-01-01
时间类
Instant 时间戳:表示时间的类,类似Date类
| 方法名 |
说明 |
| static Instant now() |
获取当前时间的Instant对象(标准时间) |
| static Instant ofXxxx(long epochMilli) |
根据(秒/毫秒/纳秒)获取Instant对象 |
| ZonedDateTime atZone(ZoneId zone) |
指定时区 |
| boolean isXxx(Instant otherInstant) |
判断系列的方法 |
| Instant minusXxx(long millisToSubtract) |
减少时间系列的方法 |
| Instant plusXxx(long millisToSubtract) |
增加时间系列的方法 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| Instant now = Instant.now(); System.out.println("当前时间为(世界标准时间):" + now); System.out.println("------------------");
Instant instant1 = Instant.ofEpochMilli(1000); Instant instant2 = Instant.ofEpochSecond(5);
System.out.println(instant1); System.out.println(instant2); System.out.println("------------------");
ZonedDateTime zonedDateTime = Instant.now().atZone(ZoneId.systemDefault()); System.out.println("带时区的时间:" + zonedDateTime); System.out.println("------------------");
System.out.println(now.isBefore(instant1)); System.out.println(now.isAfter(instant1)); System.out.println("------------------");
System.out.println("减1000毫秒:" + now.minusMillis(1000)); System.out.println("减5秒钟:" + now.minusSeconds(5)); System.out.println("------------------");
System.out.println("加1000毫秒:" + now.plusMillis(1000)); System.out.println("加5秒钟:" + now.plusSeconds(5)); System.out.println("------------------");
|
ZonedDateTime:带时区的时间类
1 2 3 4 5
| Instant now = Instant.now(); System.out.println(now);
ZonedDateTime zonedDateTime = Instant.now().atZone(ZoneId.of("Asia/Shanghai")); System.out.println(zonedDateTime);
|
| 方法名 |
说明 |
| static ZonedDateTime now() |
获取当前时间的ZonedDateTime对象 |
| static ZonedDateTime ofXxxx(…) |
获取指定时间的ZonedDateTime对象 |
| ZonedDateTime withXxx(时间) |
修改时间系列的方法 |
| ZonedDateTime minusXxx(时间) |
减少时间系列的方法 |
| ZonedDateTime plusXxx(时间) |
增加时间系列的方法 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| ZonedDateTime now = ZonedDateTime.now(); System.out.println(now); System.out.println("--------------------------");
ZonedDateTime of = ZonedDateTime.of (2008, 8, 8, 8, 8, 8, 8, ZoneId.systemDefault()); System.out.println(of); System.out.println("--------------------------");
System.out.println(now.withYear(2008)); System.out.println(now.withMonth(8)); System.out.println(now.withDayOfMonth(8)); System.out.println("--------------------------");
System.out.println(now.minusYears(1)); System.out.println(now.minusMonths(1)); System.out.println(now.minusDays(1)); System.out.println("--------------------------");
System.out.println(now.plusYears(1)); System.out.println(now.plusMonths(1)); System.out.println(now.plusDays(1));
|
ZoneId 类:有关时区设置的类
| 方法名 |
说明 |
| static Set getAvailableZoneIds() |
获取Java中支持的所有时区 |
| static ZoneId systemDefault() |
获取系统默认时区 |
| static ZoneId of(String zoneId) |
获取一个指定时区 |
1 2 3 4 5 6 7 8 9 10 11 12
| Set<String> set = ZoneId.getAvailableZoneIds(); System.out.println(set); System.out.println(set.size());
ZoneId zoneId = ZoneId.systemDefault();
ZoneId of = ZoneId.of("Africa/Nairobi"); ZonedDateTime zonedDateTime = Instant.now().atZone(of); System.out.println(zonedDateTime);
|
工具类
Duration类:计算两个“时间”间隔
1 2 3 4 5 6 7
| LocalDateTime对象:data1,data2 Duration duration = Duration.between(data1, data2); System.out.println(duration.toDays()); System.out.println(duration.toHours()); System.out.println(duration.toMinutes()); System.out.println(duration.toMillis()); System.out.println(duration.toNanos());
|
Period类:计算两个“日期”间隔
1 2 3 4 5 6
| LocalDate对象:day1, day2 Period period = Period.between(day1, day2); System.out.println(period.getYears()); System.out.println(period.getMonths()); System.out.println(period.getDays()); System.out.println(period.toTotalMonths());
|
ChronoUnit类:计算两个“日期”间隔
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| LocalDateTime对象:data1,data2 System.out.println("相差的年数:" + ChronoUnit.YEARS.between(data1, data2)); System.out.println("相差的月数:" + ChronoUnit.MONTHS.between(data1,data2)); System.out.println("相差的周数:" + ChronoUnit.WEEKS.between(data1,data2)); System.out.println("相差的天数:" + ChronoUnit.DAYS.between(data1,data2)); System.out.println("相差的时数:" + ChronoUnit.HOURS.between(data1,data2)); System.out.println("相差的分数:" + ChronoUnit.MINUTES.between(data1,data2)); System.out.println("相差的秒数:" + ChronoUnit.SECONDS.between(data1,data2)); System.out.println("相差的毫秒数:" + ChronoUnit.MILLIS.between(data1,data2)); System.out.println("相差的微秒数:" + ChronoUnit.MICROS.between(data1,data2)); System.out.println("相差的纳秒数:" + ChronoUnit.NANOS.between(data1,data2)); System.out.println("相差的半天数:" + ChronoUnit.HALF_DAYS.between(data1,data2)); System.out.println("相差的十年数:" + ChronoUnit.DECADES.between(data1,data2)); System.out.println("相差的世纪(百年)数:" + ChronoUnit.CENTURIES.between(data1,data2)); System.out.println("相差的千年数:" + ChronoUnit.MILLENNIA.between(data1,data2)); System.out.println("相差的纪元数:" + ChronoUnit.ERAS.between(data1,data2));
|
实例: 生日→计算年龄
1 2 3 4 5 6 7 8 9 10 11 12
| Scanner sc = new Scanner(System.in); System.out.println("输入生日: "); String birthday = sc.nextLine();
LocalDate birthdayDate = LocalDate.parse(birthday, DateTimeFormatter.ofPattern("yyyy年M月d日"));
LocalDate now = LocalDate.now();
long age = ChronoUnit.YEARS.between(birthdayDate, now);
|