文章目录
1. 前言
学习时间无非就是下面内容:
- 时间怎么创建
- 时间怎么加减
- 时间怎么格式化
- 时间怎么比大小
- 时间怎么求之间差值
2. 时间的创建
先总结:
// 创建时间方法 有两种
// 1. 创建当前时间 now方法
LocalDate.now();
LocalTime.now();
LocalDateTime.now();
Year.now();
YearMonth.now();
MonthDay.now();
// 2. 创建具体指定的时间 of方法
LocalDate.of();
LocalTime.of();
LocalDateTime.of();
Year.of();
YearMonth.of();
MonthDay.of();
1. now方法
now方法:创建当前时间
public class createNowTime {
public static void main(String[] args) {
System.out.println(LocalDate.now());
System.out.println(LocalTime.now());
System.out.println(LocalDateTime.now());
System.out.println("-----");
System.out.println(Year.now());
System.out.println(YearMonth.now());
System.out.println(MonthDay.now());
}
}
2. of方法
of方法:指定创建需求时间
public class createNowTime {
public static void main(String[] args) {
System.out.println(LocalTime.of(22, 0, 20, 12));
System.out.println(LocalDate.of(2021, 1, 20));
System.out.println("----");
System.out.println(LocalDateTime.of(2021, 1, 20, 22, 11, 3));
// 也可以LocalDateTime.of(LocalDateTime,LocalTime)
System.out.println(LocalDateTime.of(LocalDate.now(), LocalTime.now()));
System.out.println("---");
System.out.println(Year.of(1658));
System.out.println(YearMonth.of(2121, 5));
System.out.println(MonthDay.of(1, 21));
}
}
3. 时间的加减(plus、minus)
直接总结:
这种固定时间加减自己去试一下就懂了,就不代码演示了
1. 加法
plusNanos()
plusSeconds()
plusMinutes()
plusHours()
plusDays()
plusWeeks()
plusMonths()
plusYears()
2. 减法
就是将上面的plus改成minus
或者再加法的时候传入参数为负数:如plusDays(-2) 等于减两天
时间的加减还有一点知识点:请跳到 其他知识点的Period类、ChronoUnit类查看
4. plus()使用Period类(一段时间)
- LocalDateTime.plus(TemporalAmount amountToAdd)
Period类 代表一段时间的值。public class demo { public static void main(String[] args) { LocalDateTime now = LocalDateTime.now(); // 求当前时间 过了1年2个月15天之后的值 // 固然下面的方法可以,但是太过于啰嗦了 System.out.println(now.plusYears(1).plusMonths(2).plusDays(15)); // 因此产生了Period类,代表一段时间 // 下面则表示1年2个月15天的一段时间 Period period = Period.of(1, 2, 15); // 直接加一段时间,简单明了 System.out.println(now.plus(period)); } }
5. plus()方法使用ChronoUnit类(枚举类 时间单位)
-
LocalDateTime.plus(long amountToAdd, TemporalUnit unit)
jdk8为了让时间操作更加方便,还定义了ChronoUnit枚举:
public class demo { public static void main(String[] args) { LocalDateTime now = LocalDateTime.now(); // 当前时间 System.out.println(now); // 直接加一星期 System.out.println(now.plus(1, ChronoUnit.WEEKS)); // 直接加10年 System.out.println(now.plus(1, ChronoUnit.DECADES)); } }
6. 直接修改时间(不是加减方式)(with方法)
-
解释:比如我获取到当前时间是某月某号,但是我想直接获取这个月1号,如果是加减则需要知道到底现在几号,然后减,有点麻烦,因此产生了 直接修改时间方法(with方法)
-
代码例子:
public class demo { public static void main(String[] args) { LocalDateTime now = LocalDateTime.now(); // 当前时间 System.out.println(now); // 直接修改 当前月15号 System.out.println(now.withDayOfMonth(15)); // 直接修改 今天8点 System.out.println(now.withHour(8)); // 直接修改 今年6月 System.out.println(now.withMonth(Month.JUNE.getValue())); } }
7. with()方法使用chronoField类(枚举类)
-
其代表 就是 月中的天数,一周的天数等等类似枚举
-
LocalDateTime.with(TemporalField field, long newValue)(使用枚举类,修改时间)
public class demo { public static void main(String[] args) { LocalDateTime now = LocalDateTime.now(); // 当前时间 星期四 System.out.println(now); // 直接修改时间为:这周星期二 System.out.println(now.with(ChronoField.DAY_OF_WEEK, 2)); // 直接修改时间为:今年第10天 System.out.println(now.with(ChronoField.DAY_OF_YEAR, 10)); } }
8. with()方法配合使用调节器TemporalAdjuster
-
有时候我们还需要更加复杂的改变当前时间,比如改为当前时间的下个月,下个星期什么什么,针对的是下一月,而不是当前月,
-
上面的with方法已经无法满足这个需求了,除非先让当前时间plus到下个月,然后再使用with方法,这样子你还要判到底是加30天还是31天,实在繁琐,因此出现了调节器TemporalAdjuster。
-
with中有个方法是with(TemporalAdjuster temporalAdjuster),而jdk本身就自带了一些返回调节器的方法,在TemporalAdjusters中。
-
代码:
public class demo { public static void main(String[] args) { final LocalDateTime nowTime = LocalDateTime.now(); System.out.println("当前时间:" + nowTime); System.out.println("-----previous/next方法"); // previous(DayOfWeek) :上个星期几 System.out.println("上个星期天的时间: " + nowTime.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY))); // next(DayOfWeek) :下个星期几 System.out.println("下个星期天的时间: " + nowTime.with(TemporalAdjusters.next(DayOfWeek.SUNDAY))); // nextOrSame(DayOfWeek.SUNDAY) // 今天是星期六,而这周的星期天还没有过,因此会返回这周的星期天 // 若这周星期天已经过了,则会直接返回下个星期天的时间 System.out.println("下个星期天的时间: " + nowTime.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY))); System.out.println("----"); System.out.println("下个月第一天的时间: " + nowTime.with(TemporalAdjusters.firstDayOfNextMonth())); System.out.println("下一年第一天的时间: " + nowTime.with(TemporalAdjusters.firstDayOfNextYear())); System.out.println("这个月最后一天的时间: " + nowTime.with(TemporalAdjusters.lastDayOfMonth())); System.out.println("今年最后一天: " + nowTime.with(TemporalAdjusters.lastDayOfYear())); } }
9. with()使用自定义的调节器TemporalAdjuster
-
需求:每个月15号下午5点发工资,若15号是周六周日,则星期五发工资,现求输入指定时间,求当月实际发工资时间。
-
这个时候jdk自带的调节器无法帮助我们完成该任务,则需要我们自己定义调节器:
public class demo { public static void main(String[] args) { final LocalDateTime nowTime = LocalDateTime.now(); System.out.println(nowTime.with(new TemporalAdjuster() { @Override public Temporal adjustInto(Temporal temporal) { LocalDate localDate = LocalDate.from(temporal); LocalDateTime localDateTime = LocalDateTime.of(localDate, LocalTime.of(17, 0, 0)); localDateTime = localDateTime.with(ChronoField.DAY_OF_MONTH, 15); // localDateTime = localDateTime.withDayOfMonth(15); if(localDateTime.getDayOfWeek() == DayOfWeek.SUNDAY || localDateTime.getDayOfWeek() == DayOfWeek.SATURDAY){ localDateTime = localDateTime.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY)); } return localDateTime; } })); } }
10. 两个时间怎么比较大小以及求差值
1. 比较大小(isAfter()、isBefore())
-
A.isAfter(B):判断A是否在B的后面,即A时间是否比B时间晚
-
A.isBefore(B):判断A是否在B的前面,即A时间是否比B时间早
-
代码:
public class demo { public static void main(String[] args) { final LocalDateTime nowTime = LocalDateTime.now(); // 模拟 两周前的时间 final LocalDateTime oldTime = nowTime.plus(-2, ChronoUnit.WEEKS); System.out.println("nowTime: " + nowTime); System.out.println("oldTime: " + oldTime); // 当前时间 是否在oldTime 后面 System.out.println("isAfter: " + nowTime.isAfter(oldTime)); // 当前时间 是否在oldTime 前面 System.out.println("isBefore: " + nowTime.isBefore(oldTime)); } }
2. 两个时间之间求差值(ChronoUnit的between()方法)
-
ChronoUnit是个时间单位枚举类:
-
但是每个枚举后面都可以跟方法 between(A,B),表示A到B两个时间之间的差值时间戳(有正负之分),并转化为枚举的时间单位:
public class demo { public static void main(String[] args) { final LocalDateTime nowTime = LocalDateTime.now(); // 模拟 两周前的时间 final LocalDateTime oldTime = nowTime.plus(-2, ChronoUnit.WEEKS); System.out.println("nowTime: " + nowTime); System.out.println("oldTime: " + oldTime); System.out.println("--"); System.out.println("nowTime到oldTime之间相差的多少天: " + ChronoUnit.DAYS.between(nowTime, oldTime)); System.out.println("oldTime到nowTime之间相差的多少天: " + ChronoUnit.DAYS.between(oldTime, nowTime)); System.out.println("---"); System.out.println("oldTime到nowTime之间相差的多少周: " + ChronoUnit.WEEKS.between(oldTime, nowTime)); System.out.println("oldTime到nowTime之间相差的多少秒: " + ChronoUnit.SECONDS.between(oldTime, nowTime)); System.out.println("oldTime到nowTime之间相差的多少分钟: " + ChronoUnit.MINUTES.between(oldTime, nowTime)); System.out.println("oldTime到nowTime之间相差的多少小时: " + ChronoUnit.HOURS.between(oldTime, nowTime)); } }
3. 使用query(TemporalAccessor)计算时间差
-
需求:计算到5月1号还有多久?
-
TemporalAccessor 是个接口,方法queryFrom
-
代码:
public class demo { public static void main(String[] args) { final LocalDateTime nowTime = LocalDateTime.of(2021,10,1, 0,0 , 0); System.out.println("当前时间:" + nowTime + " ,距离5月1号还有:" + nowTime.query(new TemporalQuery<Object>() { @Override public Object queryFrom(TemporalAccessor temporal) { LocalDate nowLocalDate = LocalDate.from(temporal); // 获取当前时间的今年的 5.1 号 LocalDate laborDay = LocalDate.of(nowLocalDate.getYear(), Month.MAY, 1); // 判断nowLocalDate是否过了今年的5月1号 // 若过了,则需要判断它到下一年的5月1号的时间差 // 因此需要在laborDay 加一年 if (nowLocalDate.isAfter(laborDay)) { laborDay = laborDay.plusYears(1); } return ChronoUnit.DAYS.between(nowLocalDate, laborDay); } })); } }
11. DateTimeFormatter 时间格式化(重点)
1. TimeToString(时间转String格式)
public class demo {
private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss.SSS");
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
// 当前时间
System.out.println(now);
final String format = now.format(DATETIME_FORMATTER);
System.out.println(format);
}
}
2. StringToTime(String转时间)
public class demo {
private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss.SSS");
public static void main(String[] args) {
String time = "2022-01-20 23-26-54.540";
System.out.println(LocalDateTime.parse(time, DATETIME_FORMATTER));
}
}
2. jdk自带格式转化模式
1. DateTimeFormatter自带枚举属性
public class demo {
public static void main(String[] args) {
final LocalDateTime now = LocalDateTime.now();
System.out.println("当前时间:" + now);
System.out.println("格式化时间:");
final String date_format = now.format(DateTimeFormatter.ISO_DATE);
System.out.println(date_format);
final String data_time_format2 = now.format(DateTimeFormatter.ISO_DATE_TIME);
System.out.println(data_time_format2);
System.out.println("恢复:");
System.out.println(LocalDate.parse(date_format));
System.out.println(LocalDateTime.parse(data_time_format2));
}
}
2. FormatStyle类,格式化风格(jdk8自带)
- FULL:全显示(年月日+星期)
- LONG:全显示(年月日)
- MEDIUM:缩略显示(没有年月日汉字)
- SHORT:精简显示(精简年+月日)
public class demo {
public static void main(String[] args) {
final LocalDateTime now = LocalDateTime.now();
System.out.println("当前时间:" + now);
System.out.println("格式化时间:");
System.out.println(now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)));
System.out.println(now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG)));
System.out.println(now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)));
System.out.println(now.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT)));
}
}
12. 时区
-
先总结:
1. 时区相关类: ZonedDateTime:带时区的时间类 ZoneId:时区类 2. 获取所有时区信息:ZoneId.getAvailableZoneIds() 3. 获取该系统的时区:ZoneId.systemDefault() 4. 给不带时区的时间对象设置时区:time.atZone(ZoneId zoneId)
-
获取所有时区信息
public class demo { public static void main(String[] args) { final Set<String> availableZoneIds = ZoneId.getAvailableZoneIds(); for (String availableZoneId : availableZoneIds) { System.out.println(availableZoneId); } } }
-
获取该系统使用的时区
public class demo { public static void main(String[] args) { System.out.println(ZoneId.systemDefault()); } }
-
给 不带时区的时间对象设置时区
public class demo { public static void main(String[] args) { LocalDateTime now = LocalDateTime.now(); // 带上时区的时间对象 ZonedDateTime zonedDateTime = now.atZone(ZoneId.systemDefault()); System.out.println(zonedDateTime); // 获取使用相同时间内其他时区的时间对象 ZonedDateTime zonedDateTime2 = zonedDateTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo")); System.out.println(zonedDateTime2); } }
13. 方法总结
1. 时间的常见类
LocalTime: 时分秒
LocalDate: 年月日
LocalDateTime: 年月日 时分秒
Year: 年
YearMonth: 年月
MonthDay: 月日
Month 月份 枚举
DayofWeek 星期几 枚举
plus: Period 一段时间/chronoUnit 枚举单位
with:chronoField 枚举,如:今年的天数/TemporalAccessor 调节器
2. 时间的创建方法:
now():创建当前时间对象
of(): 创建指定的时间 的对象
3. 时间怎么加减:
plus/minus:直接加减
plus(Period period): 加一段时间方法
plus(amountToAdd,chronoUnit) 枚举时间单位加
4. 时间直接修改
with方法
with(ChronoField, value): 使用ChronoField枚举 方式 修改时间
with使用调节器
5. 时间之间比大小,求差值
isAfter()
isBefore()
between()
query()
6. 时间格式化
DateTimeFormatter 有自带枚举
自带格式风格:
FormatStyle.FULL:全显示(年月日+星期)
FormatStyle.LONG:全显示(年月日)
FormatStyle.MEDIUM:缩略显示(没有年月日汉字)
FormatStyle.SHORT:精简显示(精简年+月日)
DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
自定义格式化:
DateTimeFormatter.ofPattern()