Date
Date date = new Date(); //获取当前时间
System.out.println(date.getYear() + 1900); // 必须加上1900 System.out.println(date.getMonth() + 1); // 0~11,必须加上1 System.out.println(date.getDate()); // 1~31,不能加1
Calendar
可以用于获取并设置年、月、日、时、分、秒,它和Date比,主要多了一个可以做简单的日期和时间运算的功能。
// 获取当前时间:
Calendar c = Calendar.getInstance();
int y = c.get(Calendar.YEAR); i
nt m = 1 + c.get(Calendar.MONTH);
int d = c.get(Calendar.DAY_OF_MONTH);
int w = c.get(Calendar.DAY_OF_WEEK);
int hh = c.get(Calendar.HOUR_OF_DAY);
int mm = c.get(Calendar.MINUTE);
int ss = c.get(Calendar.SECOND);
int ms = c.get(Calendar.MILLISECOND);
System.out.println(y + "-" + m + "-" + d + " " + w + " " + hh + ":" + mm + ":" + ss + "." + ms);
TimeZone
Calendar和Date相比,它提供了时区转换的功能。
TimeZone tzDefault = TimeZone.getDefault(); // 当前时区
TimeZone tzGMT9 = TimeZone.getTimeZone("GMT+09:00"); // GMT+9:00时区
TimeZone tzNY = TimeZone.getTimeZone("America/New_York"); // 纽约时区 System.out.println(tzDefault.getID()); // Asia/Shanghai
时区的唯一标识是以字符串表示的ID,我们获取指定TimeZone对象也是以这个ID为参数获取,GMT+09:00、Asia/Shanghai都是有效的时区ID。要列出系统支持的所有ID,请使用TimeZone.getAvailableIDs()。
LocalDateTime
是java8,java.time提供新的API
LocalDate d = LocalDate.now(); // 当前日期
LocalTime t = LocalTime.now(); // 当前时间
LocalDateTime dt = LocalDateTime.now(); // 当前日期和时间
提供了对日期和时间进行加减的非常简单的链式调用
LocalDateTime dt = LocalDateTime.of(2019, 10, 26, 20, 30, 59);
System.out.println(dt);
// 加5天减3小时:
LocalDateTime dt2 = dt.plusDays(5).minusHours(3);
System.out.println(dt2); // 2019-10-31T17:30:59
// 减1月:
LocalDateTime dt3 = dt2.minusMonths(1);
System.out.println(dt3); // 2019-09-30T17:30:59
对时间和日期进行调整
LocalDateTime dt = LocalDateTime.of(2019, 10, 26, 20, 30, 59);
System.out.println(dt);
// 日期变为31日:
LocalDateTime dt2 = dt.withDayOfMonth(31);
System.out.println(dt2);
// 2019-10-31T20:30:59
// 月份变为9:
LocalDateTime dt3 = dt2.withMonth(9);
System.out.println(dt3); // 2019-09-30T20:30:59
LocalDateTime还有一个通用的with()方法允许我们做更复杂的运算
// 本月第一天0:00时刻:
LocalDateTime firstDay = LocalDate.now().withDayOfMonth(1).atStartOfDay(); System.out.println(firstDay);
// 本月最后1天:
LocalDate lastDay = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()); System.out.println(lastDay);
// 下月第1天:
LocalDate nextMonthFirstDay = LocalDate.now().with(TemporalAdjusters.firstDayOfNextMonth()); System.out.println(nextMonthFirstDay);
// 本月第1个周一:
LocalDate firstWeekday = LocalDate.now().with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); System.out.println(firstWeekday);
要判断两个LocalDateTime的先后,可以使用isBefore()、isAfter()方法,对于LocalDate和LocalTime
LocalDateTime now = LocalDateTime.now();
LocalDateTime target = LocalDateTime.of(2019, 11, 19, 8, 15, 0); System.out.println(now.isBefore(target)); System.out.println(LocalDate.now().isBefore(LocalDate.of(2019, 11, 19))); System.out.println(LocalTime.now().isAfter(LocalTime.parse("08:15:00")));
DateTimeFormatter
如果要自定义输出的格式,或者要把一个非ISO 8601格式的字符串解析成LocalDateTime
// 自定义格式化:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); System.out.println(dtf.format(LocalDateTime.now()));
// 用自定义格式解析:
LocalDateTime dt2 = LocalDateTime.parse("2019/11/30 15:16:17", dtf); System.out.println(dt2);
Duration
表示两个时刻得时间间隔
LocalDateTime start = LocalDateTime.of(2019, 11, 19, 8, 15, 0);
LocalDateTime end = LocalDateTime.of(2020, 1, 9, 19, 25, 30);
Duration d = Duration.between(start, end);
System.out.println(d); // PT1235H10M30S
Period
表示两个日期间隔的天数
Period p = LocalDate.of(2019, 11, 19).until(LocalDate.of(2020, 1, 9));
System.out.println(p); // P1M21D
ZonedDateTime
和LocalDateTime相比,增加了时区,可以理解为LocalDateTime+ZonedId
ZonedDateTime zbj = ZonedDateTime.now(); // 默认时区
ZonedDateTime zny = ZonedDateTime.now(ZoneId.of("America/New_York")); // 用指定时区获取当前时间
另一种方式是通过给一个LocalDateTime附加一个ZoneId,就可以变成ZonedDateTime
LocalDateTime ldt = LocalDateTime.of(2019, 9, 15, 15, 16, 17); ZonedDateTime zbj = ldt.atZone(ZoneId.systemDefault());
ZonedDateTime zny = ldt.atZone(ZoneId.of("America/New_York"));
要转换时区,首先我们需要有一个ZonedDateTime对象,然后,通过withZoneSameInstant()将关联时区转换到另一个时区,转换后日期和时间都会相应调整。
// 以中国时区获取当前时间:
ZonedDateTime zbj = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
// 转换为纽约时间:
ZonedDateTime zny = zbj.withZoneSameInstant(ZoneId.of("America/New_York"));
DateTimeFormatter
使用旧的Date对象时,我们用SimpleDateFormat进行格式化显示。使用新的LocalDateTime或ZonedDateTime时,我们要进行格式化显示,就要使用DateTimeFormatter。
和SimpleDateFormat不同的是,DateTimeFormatter不但是不变对象,它还是线程安全的。因为SimpleDateFormat不是线程安全的,使用的时候,只能在方法内部创建新的局部变量。而DateTimeFormatter可以只创建一个实例,到处引用。
创建DateTimeFormatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
另一种是加入时区
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm", Locale.US);
ZonedDateTime zdt = ZonedDateTime.now();
var formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm ZZZZ"); System.out.println(formatter.format(zdt));
var zhFormatter = DateTimeFormatter.ofPattern("yyyy MMM dd EE HH:mm", Locale.CHINA); System.out.println(zhFormatter.format(zdt));
var usFormatter = DateTimeFormatter.ofPattern("E, MMMM/dd/yyyy HH:mm", Locale.US); System.out.println(usFormatter.format(zdt));
输出结果为
2019-09-15T23:16 GMT+08:00
2019 9月 15 周日 23:16 Sun
September/15/2019 23:16