文章目录
- Java旧时间类关系图![在这里插入图片描述](https://img-blog.csdnimg.cn/e2c2c26c841e40bdb9cc85d0fc4bc1df.png)
- GMT、时间戳、统一标准时间、时区
- Java时间类
- 创建时间类示例
- java.text.DateFormat时间格式转换
- java.util.Calendar
- 总结Java时间类
- Java8新时间类
- Instant
- Clock
- LocalDate
- LocalTime
- LocalDateTime
- 时区篇
- java.time.ZoneId
- java.time.ZoneOffset
- java.time.OffsetDateTime
- java.time.ZonedDateTime
- 时间间隔
- java.time.Duration(时间值)
- java.time.Period(日期值)
- TemporalAdjuster 矫正器
参考文章:Java时间类汇总
Java旧时间类关系图
GMT、时间戳、统一标准时间、时区
- GMT:格林尼治标准时间,是计算机中时间原点:1970年1月1日 00:00:00
- 时间戳:自1970年1月1日(00:00:00 GMT)至当前时间的总秒数
- UTC:统一的标准时间
- 时区:CST可视为中国、美国、澳大利亚或古巴的标准时间
美国:Central Standard Time UT-6:00
澳大利亚:Central Standard Time UT+9:30
中国:China Standard Time UT+8:00
古巴:Cuba Standard Time UT-4:00
Java时间类
创建时间类示例
public class JavaDateTest {
public static void main(String[] args) {
//public Date()构造器
//public Date(long date)构造器
java.util.Date utilDate1 = new java.util.Date();
java.util.Date utilDate2 = new java.util.Date(System.currentTimeMillis());
//public Date(long date)构造器
java.sql.Date sqlDate1 = new java.sql.Date(System.currentTimeMillis());
//public Time(long date)构造器
java.sql.Date time = new java.sql.Time(System.currentTimeMillis());
//public Timestamp(long date)构造器
java.sql.Timestamp timestamp = new java.sql.Timestamp(System.currentTimeMillis());
System.out.println(utilDate1); // Fri Feb 11 13:00:14 CST 2022
System.out.println(utilDate2); // Fri Feb 11 13:00:14 CST 2022
System.out.println(sqlDate2); // 2022-02-11
System.out.println(time); // 17:53:45
System.out.println(timestamp); //2022-02-11 16:56:00.171
}
}
java.text.DateFormat时间格式转换
1. 该类方法如下
public final String format(Date date):将日期格式化字符串
public Date parse(String source):将字符串转为日期
public void applyPattern(String pattern):设置指定格式化字符串
public SimpleDateFormat(String pattern):设置指定格式化的SimpleDateFormat对象
2. 示例
public class JavaDateTest {
public static void main(String[] args) throws ParseException {
//默认实例化
SimpleDateFormat sdf1 = new SimpleDateFormat();
String format1 = sdf1.format(new Date()); //将日期格式化字符串
System.out.println(format1); // 2021/12/18 下午6:19
Date parse1 = sdf1.parse("2021/11/15 下午3:41"); //将字符串转为日期
System.out.println(parse1); // Mon Nov 15 15:41:00 CST 2021
// 带参数实例化
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format2 = sdf2.format(date); // 将日期格式化字符串
System.out.println(format2); // 2021-11-15 15:41:00
Date parse2 = sdf2.parse("2021-11-15 16:11:27"); //将字符串转为日期
System.out.println(parse2); // Mon Nov 15 16:11:27 CST 2021
}
}
3. SimpleDateFormat正确使用
方法一:在需要执行格式化的地方都新建SimpleDateFormat实例,使用局部变量来存放SimpleDateFormat实例。这种方法可能会导致短期内创建大量的SimpleDateFormat实例,如解析一个excel表格里的字符串日期。同一个线程内的所有SimpleDateFormat都不同
public static String formatDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(date);
}
方法二:为了避免创建大量的SimpleDateFormat实例,往往会考虑把SimpleDateFormat实例设为静态成员变量,共享SimpleDateFormat对象。这种情况下就得对SimpleDateFormat添加同步。这种方法的缺点也很明显,就是在高并发的环境下会导致解析被阻塞。只有一个SimpleDateFormat,所有用户都使用这个
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static String formatDate(Date date) {
synchronized (sdf) {
return sdf.format(date);
}
}
方法三:要在高并发环境下能有比较好的体验,可以使用ThreadLocal来限制SimpleDateFormat只能在线程内共享,这样就避免了多线程导致的线程安全问题。
private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};
public static String formatDate(Date date) {
return threadLocal.get().format(date);
}
java.util.Calendar
Calendar的常用属性
import java.util.Calendar;
import java.util.GregorianCalendar;
public class JavaDateTest {
public static void main(String[] args) {
Calendar gregorianCalendar = new GregorianCalendar(); //创建其子类的实例化
Calendar calendar = Calendar.getInstance(); //调用其静态方法getInstance实例化
// 获得年份:2022
System.out.println("现在是:" + calendar.get(Calendar.YEAR) + "年");
// 获得月份:2
System.out.println("现在是:" + (calendar.get(Calendar.MONTH)+1) + "月");
//获得日期(本月的第几天):13
System.out.println("现在是:" + calendar.get(Calendar.DATE) + "号");
System.out.println("现在是:" + calendar.get(Calendar.DAY_OF_MONTH) + "号");
// 获得这是今年的第几天:44
System.out.println("现在是今年第" + calendar.get(Calendar.DAY_OF_YEAR) + "天");
// 获得今天周几:0(星期天天)
System.out.println("现在是星期:" + (calendar.get(Calendar.DAY_OF_WEEK)-1) );
// 获得今天是这个月的第几周:2
System.out.println("现在是第:" + calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH) + "周" );
// 12小时制的时间:9
System.out.println("现在是:" + calendar.get(Calendar.HOUR) + "点");
// 24小时制的时间:21
System.out.println("现在是:" + calendar.get(Calendar.HOUR_OF_DAY) + "点");
// 分钟数:30
System.out.println("现在是:" + calendar.get(Calendar.MINUTE) + "分");
// 秒数:21
System.out.println("现在是:" + calendar.get(Calendar.SECOND) + "秒");
// 毫秒:338
System.out.println("现在是:" + calendar.get(Calendar.MILLISECOND) + "毫秒");
// 设置当前时间为本年度的第10天
calendar.set(Calendar.DAY_OF_YEAR,10);
// 再次调用get()方法后返回的是更改后的值
System.out.println(calendar.get(Calendar.DAY_OF_YEAR)); // 10
// 给当前日期上加上本年度的3天(现在是本年度的第10天)
calendar.add(Calendar.DAY_OF_YEAR,3);
System.out.println(calendar.get(Calendar.DAY_OF_YEAR)); // 13
// getTime()方法实现 calendar 类 -> Date类
// 得到的Date类型变量是Calendar对象经过修改后的时间
java.util.Date time = calendar.getTime();
System.out.println(time); // Thu Jan 13 21:12:50 CST 2022
//setTime()方法实现 Date类 -> Calendar 类
calendar.setTime(new java.util.Date());
// 通过该Calendar实例对象调用get方法得知传入Date类型变量是一年中的第几天等信息
System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); // 13
}
}
总结Java时间类
- 创建时间对象
- new java.util.Date(System.currentTimeMillis())、new java.util.Date()
- new java.sql.Date(System.currentTimeMillis())
- new java.sql.Time(System.currentTimeMillis())
- new java.sql.Timestamp(System.currentTimeMillis())
- new GregorianCalendar();
- Calender.getInstance();
- 对象规范化
SimpleDateFormat sdf1 = new SimpleDateFormat();
String format1 = sdf1.format(new Date()); //将日期格式化字符串
System.out.println(format1); // 2021/12/18 下午6:19
Date parse1 = sdf1.parse(“2021/11/15 下午3:41”); //将字符串转为日期
System.out.println(parse1); // Mon Nov 15 15:41:00 CST 2021
Java8新时间类
Instant
- public static Instant now():返回时间戳
- public static Instant ofEpochMilli(long epochMilli):通过给定毫秒数,获取Instance实例
- public static Instant ofEpochSecond(long epochSecond):通过给定秒数,获取Instance实例
- public static Instant parse(final CharSequence text):字符串转换成Instance实例
- public OffsetDateTime atOffset(ZoneOffset offset):根据时区修正偏移量,北京时间应该+8
- public ZonedDateTime atZone(ZoneId zone):获取系统默认时区时间
- public long getEpochSecond():获取从1970-01-01 00:00:00到当前时间的秒值
- public long toEpochMilli():获取从1970-01-01 00:00:00到当前时间的毫秒值
- public int getNano():把获取到的当前时间的秒数换算成纳秒
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.Date;
public class JavaDateTest {
public static void main(String[] args) {
/**
* 实例方式一:通过静态方法now(),获得UTC(本初子午线)的此刻瞬时时间的实例对象
* 输出内容(默认时间比北京时间相差8小时):2022-02-16T07:22:12.266171900Z(Z表示本初子午线)
* 注:不建议使用Instant查看当前时间点
*/
Instant instant1 = Instant.now();
System.out.println(instant1); // 2022-02-16T07:22:12.266Z
/**
* 实例化方式二:通过给定毫秒数或秒数,获取Instant实例
*/
System.out.println(Instant.ofEpochMilli(Clock.systemDefaultZone().millis())); // 2022-02-16T07:22:12.266Z
System.out.println(Instant.ofEpochMilli(Clock.systemUTC().millis())); // 2022-02-16T07:22:12.266Z
System.out.println(Instant.ofEpochMilli(new Date().getTime())); // 2022-02-16T07:22:12.266Z
System.out.println(Instant.ofEpochMilli(System.currentTimeMillis())); // 2022-02-16T07:22:12.266Z
System.out.println(Instant.ofEpochSecond(System.currentTimeMillis() / 1000)); // 2022-02-16T07:22:12Z
/**
* 实例化方式三:将字符串转换成Instant
*/
System.out.println(Instant.parse("2022-02-16T07:22:12.266Z")); // 2022-02-16T07:22:12.266Z
/**
* long getEpochSecond():获取当前时间戳的秒数:
* long toEpochMilli():获取当前时间戳的毫秒:
* int getNano():获取当前时间点(抛开整数秒不算)的纳秒数
* 如: 12345.12秒,抛开整数秒不算,则为0.12秒,那么instant.getNano()的结果为 0.12 * 1000_000_000 = 120_000_000
*/
System.out.println("秒数 -> " + Instant.now().getEpochSecond()); // 秒数 -> 1644997084
System.out.println("毫秒数 -> " + Instant.now().toEpochMilli()); // 毫秒数 -> 1644997084046
System.out.println("纳秒数 -> " + Instant.now().getNano()); // 纳秒数 -> 46179600
/**
* Instant 与 时间偏移量 的相互转换, 注:从1970-01-01 00:00:00开始计算偏移
*/
System.out.println(Instant.now()); // 2022-02-16T07:44:36.084408900Z
// 对时间进行时区偏移修正,北京时间应+8,输出内容可以发现->(Z变为+8:00)
System.out.println(Instant.now().atOffset(ZoneOffset.ofHours(8))); // 2022-02-16T15:44:36.084408900+08:00
// 设置时区后,显示时间为北京时间了->(可以发现后面带上了时区)
System.out.println(Instant.now().atZone(ZoneId.systemDefault())); // 2022-02-16T15:44:36.084408900+08:00[Asia/Shanghai]
/**
* Instant的时间加、减:
* 由于北京时间比UTC时间晚8小时,所以我们需要得出北京的瞬时时间,需要加8小时
*/
Instant instant3 = Instant.now().plus(8, ChronoUnit.HOURS);
// 原(北京瞬时)instant -> 2022-02-16T15:22:12.266653300Z
System.out.println("原(北京瞬时)instant -> " + instant3);
Instant plusRes = instant3.plus(1, ChronoUnit.HOURS); // + 1 小时
// 原(北京瞬时)instant + 1小时,结果是 -> 2022-02-16T16:22:12.266653300Z
System.out.println("原(北京瞬时)instant + 1小时,结果是 -> " + plusRes);
Instant minusRes = instant3.minus(2, ChronoUnit.HOURS); // - 2 小时
// 原(北京瞬时)instant - 2小时,结果是 -> 2022-02-16T13:22:12.266653300Z
System.out.println("原(北京瞬时)instant - 2小时,结果是 -> " + minusRes);
/**
* 判断两个Instant之间谁早谁晚
*/
// 将Clock转换成Instant
Instant instantOne = Instant.now(Clock.systemDefaultZone());
// 对时间进行时区偏移修正,北京时间应+8
Instant instantTwo = instantOne.plus(8, ChronoUnit.HOURS);
boolean isAfterResult = instantOne.isAfter(instantTwo);
// 瞬时时间点instantOne晚于instantTwo ? --- false
System.out.println("瞬时时间点instantOne晚于instantTwo ? --- " + isAfterResult);
// 瞬时时间点instantOne早于instantTwo ? --- true
boolean isBeforeResult = instantOne.isBefore(instantTwo);
System.out.println("瞬时时间点instantOne早于instantTwo ? --- " + isBeforeResult);
}
}
Clock
import java.time.Clock;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
public class JavaDateTest {
public static void main(String[] args) {
// 系统时区默认时间, 通过clock.instant()方法获取当前时刻
Clock clock = Clock.systemDefaultZone();
System.out.println(clock); // SystemClock[Asia/Shanghai]
System.out.println(clock.getZone()); // Asia/Shanghai
System.out.println("当前时刻为:" + clock.instant()); // 当前时刻为:2022-02-18T08:25:12.954071700Z
// 世界协调时UTC
Clock clockUTC = Clock.systemUTC();
System.out.println(clockUTC); // SystemClock[Z]
System.out.println(clockUTC.getZone()); // Z
System.out.println("当前时刻为:" + clockUTC.instant()); // 当前时刻为:2022-02-18T08:25:12.973084700Z
// 获取Clock对应的毫秒数,与System.currentTimeMillis()输出相同
System.out.println(Clock.systemDefaultZone().millis()); // 1645172712973
System.out.println(Clock.systemUTC().millis()); // 1645172712973
System.out.println(System.currentTimeMillis()); // 1645172712973
// 在clock基础上增加6000秒,返回新的Clock
Clock clockSet = Clock.offset(clockUTC, Duration.ofSeconds(6000));
System.out.println(clockSet); // OffsetClock[SystemClock[Z],PT1H40M]
System.out.println(clockSet.getZone()); // Z
System.out.println("当前时刻为:" + clockSet.instant()); // 当前时刻为:2022-02-18T10:05:12.974077200Z
// 纽约时间
Clock clockNewYork = Clock.system(ZoneId.of("America/New_York"));
// Current DateTime with NewYork clock: 2022-02-18T03:25:12.975086200
System.out.println("Current DateTime with NewYork clock: " + LocalDateTime.now(clockNewYork));
System.out.println(clockNewYork.millis()); // 1645172712977
// 返回具有不同时区的此时钟的副本, withZone(ZoneId zoneId)
Clock systemDefaultZone = Clock.systemDefaultZone();
Clock withZone = systemDefaultZone.withZone(ZoneId.of("America/New_York"));
System.out.println(systemDefaultZone); // SystemClock[Asia/Shanghai]
System.out.println(withZone); // SystemClock[America/New_York]
/**
* Clock tick(Clock baseClock, Duration tickDuration):此方法获得一个时钟,该时钟返回从指定时钟被截断到指定持续时间的最接近值的瞬间
* Clock tickMinutes(ZoneId zone):此方法获得一个时钟,该时钟使用最佳的可用系统时钟返回整分钟的当前即时滴答
* Clock tickSeconds(ZoneId zone) 此方法获得一个时钟,该时钟使用最佳可用系统时钟返回整秒的当前即时滴答。
*/
Clock clock1 = Clock.systemDefaultZone();
Clock clock2 = Clock.tick(clock1, Duration.ofDays(1));
System.out.println("Clock1 : " + clock1.instant()); // Clock1 : 2022-02-18T08:25:12.977085300Z
System.out.println("Clock2 : " + clock2.instant()); // Clock2 : 2022-02-18T00:00:00Z
Clock clock3 = Clock.systemDefaultZone();
Clock clock4 = Clock.tickMinutes(ZoneId.systemDefault());
System.out.println("Clock3 : " + clock3.instant()); // Clock3 : 2022-02-18T08:25:12.977085300Z
System.out.println("Clock4 : " + clock4.instant()); // Clock4 : 2022-02-18T08:25:00Z
Clock clock5 = Clock.systemDefaultZone();
Clock clock6 = Clock.tickSeconds(ZoneId.systemDefault());
System.out.println("Clock5 : " + clock5.instant()); // Clock5 : 2022-02-18T08:25:12.978077500Z
System.out.println("Clock6 : " + clock6.instant()); // Clock6 : 2022-02-18T08:25:12Z
}
}
LocalDate
import java.time.LocalDate;
public class JavaDateTest {
public static void main(String[] args) {
/**
* 常用的两种实例化方式:
* 1.通过静态方法, 获取系统的当前时间:LocalDate.now()
* 2.通过静态方法, 获取自定义指定时间:LocalDate.of(2022, 02, 28)
*/
LocalDate today = LocalDate.now(); // 获取当前日期(年/月/日) 2020-6-14 周天
LocalDate of = LocalDate.of(2022, 02, 28);
/**
* 常用的getXxx()系列操作,获得日期:
* int getYear() 获取当前⽇期的年份
* Month getMonth() 获取当前⽇期的⽉份对象(返回一个 Month 枚举值)
* int getMonthValue() 获取当前⽇期是第⼏⽉(1-12)
* int getDayOfMonth() 表示该对象表示的⽇期是这个⽉第⼏天(1-31)
* DayOfWeek getDayOfWeek() 表示该对象表示的⽇期是星期⼏(返回一个 DayOfWeek枚举值)
* int getDayOfYear() 表示该对象表示的⽇期是今年第⼏天(1-366)
*/
System.out.println("今天的⽇期:" + today); // 今天的⽇期:2020-06-14
System.out.println("指定的⽇期:" + of); // 指定的⽇期:2022-02-28
System.out.println("现在是哪年:" + today.getYear()); // 现在是哪年:2020
System.out.println("现在是哪⽉(英文):" + today.getMonth()); // 现在是哪⽉(英文):JUNE
System.out.println("现在是哪⽉(数字):" + today.getMonthValue()); // 现在是哪⽉(数字):6
System.out.println("现在是⼏号:" + today.getDayOfMonth()); // 现在是⼏号:14
System.out.println("现在是周⼏:" + today.getDayOfWeek()); // 现在是周⼏:SUNDAY
System.out.println("现在是今年的第几天:" + today.getDayOfYear()); // 现在是今年的第几天:166
/**
* 常用的setXxx()系列操作,设置日期:
* LocalDate withYear(int year) 修改当前对象的年份
* LocalDate withMonth(int month) 修改当前对象的⽉份
* LocalDate withDayOfMonth(int dayOfMonth) 修改当前对象在当⽉的⽇期
* LocalDate withDayOfYear(int dayOfYear) 修改当前对象在当年的⽇期
*/
LocalDate withLocalDate = LocalDate.of(2022, 01, 01);
System.out.println("常用的setXxx()系列操作:" + withLocalDate); // 此刻时间:2022-01-01(用作对比参考)
System.out.println(withLocalDate.withYear(2030));// 2030-01-01
System.out.println(withLocalDate.withMonth(2)); // 2022-02-01
System.out.println(withLocalDate.withDayOfMonth(8)); // 2022-01-08
System.out.println(withLocalDate.withDayOfYear(10)); // 2022-01-10
/**
* 常用的plusXxx()系列操作,增加时间的方法:
* LocalDate plusYears(long yearsToAdd) 增加指定年份数
* LocalDate plusMonths(long monthsToAdd) 增加指定⽉份数
* LocalDate plusDays(long daysToAdd) 增加指定天数
* LocalDate plusWeeks(long weeksToAdd) 增加指定周数
*/
LocalDate plusLocalDate = LocalDate.of(2022, 01, 01);
System.out.println("常用的plusXxx()系列操作:" + plusLocalDate); // 此刻时间:2022-01-01(用作对比参考)
System.out.println(plusLocalDate.plusYears(1)); // 2023-01-01
System.out.println(plusLocalDate.plusMonths(1)); // 2022-02-01
System.out.println(plusLocalDate.plusWeeks(1)); // 2022-01-08
System.out.println(plusLocalDate.plusDays(6)); // 2022-01-07
/**
* 常用的minusXxx()系列操作,减少时间的方法:
* LocalDate minusYears(long yearsToSubtract) 减去指定年数
* LocalDate minusMonths(long monthsToSubtract) 减去注定⽉数
* LocalDate minusDays(long daysToSubtract) 减去指定天数
* LocalDate minusWeeks(long weeksToSubtract) 减去指定周数
*/
LocalDate minusLocalDate = LocalDate.of(2022, 01, 01);
System.out.println("常用的minusXxx()系列操作:" + minusLocalDate); // 此刻时间:2022-01-01(用作对比参考)
System.out.println(minusLocalDate.minusYears(5)); // 2017-01-01
System.out.println(minusLocalDate.minusMonths(60)); // 2017-01-01
System.out.println(minusLocalDate.minusWeeks(260)); // 2017-01-07
System.out.println(minusLocalDate.minusDays(1826)); // 2017-01-01
/**
* 常用日期对比方法:
* int compareTo(ChronoLocalDate other) ⽐较当前对象和other对象在时间上的⼤⼩,返回值如果为正,则当前对象时间较晚
* boolean isBefore(ChronoLocalDate other) ⽐较当前对象⽇期是否在other对象⽇期之前
* boolean isAfter(ChronoLocalDate other) ⽐较当前对象⽇期是否在other对象⽇期之后
* boolean isEqual(ChronoLocalDate other) ⽐较两个⽇期对象是否相等
* boolean isLeapYear() 判断是否是闰年(注意是LocalDate类 和 LocalDateTime类特有的方法)
*/
LocalDate localDateOne = LocalDate.of(2022, 01, 01);
LocalDate localDateTwo = LocalDate.of(2000, 01, 01);
System.out.println("compareTo: " + localDateOne.compareTo(localDateTwo)); // compareTo: 22
System.out.println("isBefore: " + localDateOne.isBefore(localDateTwo)); // isBefore: false
System.out.println("isAfter: " + localDateOne.isAfter(localDateTwo)); // isAfter: true
System.out.println("isEqual: " + localDateOne.isEqual(localDateTwo)); // isEqual: false
System.out.println("isLeapYear: " + localDateTwo.isLeapYear()); // isLeapYear: true
}
}
LocalTime
import java.time.LocalTime;
public class JavaDateTest {
public static void main(String[] args) {
/**
* 常用的两种实例化方式:
* 1.通过静态方法, 获取系统的当前时间:LocalTime.now()
* 2.通过静态方法, 获取自定义指定时间:LocalTime.of(21, 30, 59, 11001);
*/
LocalTime today = LocalTime.now();
LocalTime of = LocalTime.of(21, 30, 59, 11001);
System.out.println("指定的时间:" + of); // 指定的时间:18:24:31.761102500
/**
* 常用的getXxx()系列操作,获得日期:
* int getHour() 获取当前时间小时数
* int getMinute() 获取当前时间分钟数
* int getSecond() 获取当前时间秒值
* int getNano() 把获取到的当前时间的秒数换算成纳秒
*/
System.out.println("今天的时间:" + today); // 今天的时间:18:24:31.761102500
System.out.println("现在是几时:" + today.getHour()); // 现在是几时:18
System.out.println("现在是几分:" + today.getMinute()); // 现在是几分:24
System.out.println("现在是几秒:" + today.getSecond()); // 现在是几秒:31
System.out.println("现在是⼏纳秒:" + today.getNano()); // 现在是⼏纳秒:761102500
/**
* 常用的setXxx()系列操作,设置日期:
* LocalTime withHour(int hour) 修改当前对象的小时数
* LocalTime withMinute(int minute) 修改当前对象的分钟数
* LocalTime withSecond(int second) 修改当前对象在当⽉的秒数
* LocalTime withNano(int nanoOfSecond) 修改当前对象在当年的纳秒数
*/
LocalTime withLocalTime = LocalTime.of(13, 8, 20, 123456789);
System.out.println("常用的setXxx()系列操作:" + withLocalTime); // 此刻时间:13:08:20.123456789(用作对比参考)
System.out.println(withLocalTime.withHour(5)); // 05:08:20.123456789
System.out.println(withLocalTime.withMinute(10)); // 13:10:20.123456789
System.out.println(withLocalTime.withSecond(8)); // 13:08:08.123456789
System.out.println(withLocalTime.withNano(100000001)); // 13:08:20.100000001
/**
* 常用的plusXxx()系列操作,增加时间的方法:
* LocalTime plusHours(long hoursToAdd) 增加指定小时
* LocalTime plusMinutes(long minutesToAdd) 增加指定分钟
* LocalTime plusSeconds(long secondstoAdd) 增加指定秒
* LocalTime plusNanos(long nanosToAdd) 增加指定纳秒
*/
LocalTime plusLocalTime = LocalTime.of(13, 8, 20, 123456789);
System.out.println("常用的plusXxx()系列操作:" + plusLocalTime); // 此刻时间:13:08:20.123456789(用作对比参考)
System.out.println(plusLocalTime.plusHours(1)); // 14:08:20.123456789
System.out.println(plusLocalTime.plusMinutes(1)); // 13:09:20.123456789
System.out.println(plusLocalTime.plusSeconds(1)); // 13:08:21.123456789
System.out.println(plusLocalTime.plusNanos(6)); // 13:08:20.123456795
/**
* 常用的minusXxx()系列操作,减少时间的方法:
* LocalTime minusHours(long hoursToSubtract) 减去指定年数
* LocalTime minusMinutes(long minutesToSubtract) 减去注定⽉数
* LocalTime minusSeconds(long secondsToSubtract) 减去指定天数
* LocalTime minusNanos(long nanosToSubtract) 减去指定周数
*/
LocalTime minusLocalTime = LocalTime.of(13, 8, 20, 123456789);
System.out.println("常用的minusXxx()系列操作:" + minusLocalTime); // 此刻时间:13:08:20.123456789(用作对比参考)
System.out.println(minusLocalTime.minusHours(1)); // 12:08:20.123456789
System.out.println(minusLocalTime.minusMinutes(60)); // 12:08:20.123456789
System.out.println(minusLocalTime.minusSeconds(3600)); // 12:08:20.123456789
System.out.println(minusLocalTime.minusNanos(9)); // 13:08:20.123456780
/**
* 常用日期对比方法:
* int compareTo(LocalTime other) ⽐较当前对象和other对象在时间上的⼤⼩,返回值如果为正,则当前对象时间较晚
* boolean isBefore(LocalTime other) ⽐较当前对象时间是否在other对象时间之前
* boolean isAfter(LocalTime other) ⽐较当前对象时间是否在other对象时间之后
*/
LocalTime localTimeOne = LocalTime.of(13, 8, 20, 123456789);
LocalTime localTimeTwo = LocalTime.of(10, 8, 20, 123456789);
System.out.println("compareTo: " + localTimeOne.compareTo(localTimeTwo)); // compareTo: 1
System.out.println("isBefore: " + localTimeOne.isBefore(localTimeTwo)); // isBefore: false
System.out.println("isAfter: " + localTimeOne.isAfter(localTimeTwo)); // isAfter: true
}
}
LocalDateTime
import java.time.*;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
public class JavaDateTest {
public static void main(String[] args) {
/**
* 常用的两种实例化方式:
* 1.通过静态方法, 获取系统的当前时间:LocalTime.now()
* 2.通过静态方法, 获取自定义指定时间:
* 1.LocalDateTime.of(LocalDate.now(), LocalTime.now())
* 2.LocalDateTime.of(2020,02,8,21, 30, 59, 11001)
* 3.通过LocalDateTime转换LocalDate、LocalTime
*/
LocalDateTime today = LocalDateTime.now();
LocalDateTime of1 = LocalDateTime.of(LocalDate.now(), LocalTime.now());
LocalDateTime of2 = LocalDateTime.of(2020,02,8,21, 30, 59, 11001);
/**
* 转换的方法:
* LocalDate toLocalDate():将LocalDateTime转换为相应的LocalDate对象
* LocalTime toLocalTime():将LocalDateTime转换为相应的LocalTime对象
*/
LocalDate localDate = today.toLocalDate();
LocalTime localTime = today.toLocalTime();
/**
* 常用的getXxx()系列操作,获得日期:
* int getYear() 获取当前日期的年份
* Month getMonth() 获取当前日期的月份对象(返回一个Month枚举值)
* int getMonthValue() 获取当前日期是第几月(1-12)
* int getDayOfMonth() 表示该对象表示的⽇期是这个⽉第⼏天(1-31)
* DayOfWeek getDayOfWeek() 表示该对象表示的日期是星期几(返回一个DayOfWeek枚举值)
* int getDayOfYear() 表示该对象表示的日期是今年第几天(1-366)
* int getHour() 获取当前时间小时数
* int getMinute() 获取当前时间分钟数
* int getSecond() 获取当前时间秒值
* int getNano() 把获取到的当前时间的秒数换算成纳秒
* int get(TemporalField field) 获取指定字段的日期时间,通过ChronoField枚举类
*/
System.out.println("今天的时间:" + today); // 今天的时间:2022-02-17T19:13:38.682102600
System.out.println("现在是哪年:" + today.getYear()); // 现在是哪年:2022
System.out.println("现在是哪⽉(英文):" + today.getMonth()); // 现在是哪⽉(英文):FEBRUARY
System.out.println("现在是哪⽉(数字):" + today.getMonthValue()); // 现在是哪⽉(数字):2
System.out.println("现在是⼏号:" + today.getDayOfMonth()); // 现在是⼏号:17
System.out.println("现在是周⼏:" + today.getDayOfWeek()); // 现在是周⼏:THURSDAY
System.out.println("现在是该年的第几天:" + today.getDayOfYear()); // 现在是该年的第几天:48
System.out.println("现在是几时:" + today.getHour()); // 现在是几时:19
System.out.println("现在是几分:" + today.getMinute()); // 现在是几分:13
System.out.println("现在是几秒:" + today.getSecond()); // 现在是几秒:38
System.out.println("现在是⼏纳秒:" + today.getNano()); // 现在是⼏纳秒:682102600
System.out.println("现在是⼏号:" + today.get(ChronoField.DAY_OF_MONTH)); // 现在是⼏号:19
/**
* 常用的setXxx()系列操作,设置日期:
* LocalDateTime withYear(int year) 指定对象的年份
* LocalDateTime withMonth(int month) 指定对象的月份
* LocalDateTime withDayOfMonth(int dayOfMonth) 指定对象在当月的日期
* LocalDateTime withDayOfYear(int dayOfYear) 指定对象在当年的日期
* LocalDateTime withHour(int hour) 指定对象的小时数
* LocalDateTime withMinute(int minute) 指定对象的分钟数
* LocalDateTime withSecond(int second) 指定对象在当⽉的秒数
* LocalDateTime withNano(int nanoOfSecond) 指定对象在当年的纳秒数
* LocalDateTime with(TemporalField field, long newValue) 指定对象的日期时间,通过ChronoField枚举类
*/
LocalDateTime withLocalDateTime = LocalDateTime.of(2020,02,8,21, 30, 59, 123456789);
System.out.println("常用的setXxx()系列操作:" + withLocalDateTime); // 常用的setXxx()系列操作:2020-02-08T21:30:59.123456789
System.out.println(withLocalDateTime.withYear(2030));// 2030-02-08T21:30:59.123456789
System.out.println(withLocalDateTime.withMonth(2)); // 2020-02-08T21:30:59.123456789
System.out.println(withLocalDateTime.withDayOfMonth(8)); // 2020-02-08T21:30:59.123456789
System.out.println(withLocalDateTime.withDayOfYear(10)); // 2020-01-10T21:30:59.123456789
System.out.println(withLocalDateTime.withHour(5)); // 2020-02-08T05:30:59.123456789
System.out.println(withLocalDateTime.withMinute(10)); // 2020-02-08T21:10:59.123456789
System.out.println(withLocalDateTime.withSecond(8)); // 2020-02-08T21:30:08.123456789
System.out.println(withLocalDateTime.withNano(100000001)); // 2020-02-08T21:30:59.100000001
System.out.println(withLocalDateTime.with(ChronoField.DAY_OF_MONTH, 1)); // 2020-02-01T21:30:59.123456789
/**
* 常用的plusXxx()系列操作,增加时间的方法:
* LocalDateTime plusYears(long years) 增加指定年份数
* LocalDateTime plusMonths(long months) 增加指定⽉份数
* LocalDateTime plusDays(long days) 增加指定天数
* LocalDateTime plusWeeks(long weeks) 增加指定周数
* LocalDateTime plusHours(long hours) 增加指定小时
* LocalDateTime plusMinutes(long minutes) 增加指定分钟
* LocalDateTime plusSeconds(long seconds) 增加指定秒
* LocalDateTime plusNanos(long nanos) 增加指定纳秒
* plus(long amountToAdd, TemporalUnit unit) 指定增加的字段的日期时间
*/
LocalDateTime plusLocalDateTime = LocalDateTime.of(2020,02,8,21, 30, 59, 123456789);
System.out.println("常用的plusXxx()系列操作:" + plusLocalDateTime); // 常用的plusXxx()系列操作:2020-02-08T21:30:59.123456789
System.out.println(plusLocalDateTime.plusYears(1)); // 2021-02-08T21:30:59.123456789
System.out.println(plusLocalDateTime.plusMonths(1)); // 2020-03-08T21:30:59.123456789
System.out.println(plusLocalDateTime.plusDays(6)); // 2020-02-14T21:30:59.123456789
System.out.println(plusLocalDateTime.plusWeeks(1)); // 2020-02-15T21:30:59.123456789
System.out.println(plusLocalDateTime.plusHours(1)); // 2020-02-08T22:30:59.123456789
System.out.println(plusLocalDateTime.plusMinutes(1)); // 2020-02-08T21:31:59.123456789
System.out.println(plusLocalDateTime.plusSeconds(1)); // 2020-02-08T21:31:00.123456789
System.out.println(plusLocalDateTime.plusNanos(6)); // 2020-02-08T21:30:59.123456795
System.out.println(plusLocalDateTime.plus(1, ChronoUnit.DAYS)); // 2020-02-09T21:30:59.123456789
/**
* 常用的minusXxx()系列操作,减少时间的方法:
* LocalDateTime minusYears(long years) 减去指定年份
* LocalDateTime minusMonths(long months) 减去指定月份
* LocalDateTime minusDays(long days) 减去指定天数
* LocalDateTime minusWeeks(long weeks) 减去指定周数
* LocalDateTime minusHours(long hours) 减去指定小时
* LocalDateTime minusMinutes(long minutes) 减去指定分钟
* LocalDateTime minusSeconds(long seconds) 减去指定秒
* LocalDateTime minusNanos(long nanos) 减去指定纳秒
* LocalDateTime minus(long amountToSubtract, TemporalUnit unit) 减少指定字段的日期时间
*/
LocalDateTime minusLocalDateTime = LocalDateTime.of(2020,02,8,21, 30, 59, 123456789);
System.out.println("常用的minusXxx()系列操作:" + minusLocalDateTime); // 常用的minusXxx()系列操作:2020-02-08T21:30:59.123456789
System.out.println(minusLocalDateTime.minusYears(5)); // 2015-02-08T21:30:59.123456789
System.out.println(minusLocalDateTime.minusMonths(60)); // 2015-02-08T21:30:59.123456789
System.out.println(minusLocalDateTime.minusDays(1826)); // 2015-02-08T21:30:59.123456789
System.out.println(minusLocalDateTime.minusWeeks(260)); // 2015-02-14T21:30:59.123456789
System.out.println(minusLocalDateTime.minusHours(1)); // 2020-02-08T20:30:59.123456789
System.out.println(minusLocalDateTime.minusMinutes(60)); // 2020-02-08T20:30:59.123456789
System.out.println(minusLocalDateTime.minusSeconds(3600)); // 2020-02-08T20:30:59.123456789
System.out.println(minusLocalDateTime.minusNanos(9)); // 2020-02-08T21:30:59.123456780
System.out.println(minusLocalDateTime.minus(1, ChronoUnit.HOURS)); // 2020-02-08T20:30:59.123456789
/**
* 常用日期对比方法:
* int compareTo(localDateTimeOne other) 比较当前对象和other对象在时间上的大小,返回值如果为正,则当前对象时间较晚
* boolean isBefore(localDateTimeOne other) 比较当前对象时间是否在other对象时间之前
* boolean isAfter(localDateTimeOne other) 比较当前对象时间是否在other对象时间之后
* boolean isEqual(ChronoLocalDateTime other) 比较两个日期对象是否相等
*/
LocalDateTime localDateTimeOne = LocalDateTime.of(2022,02,8,21, 30, 59, 123456789);
LocalDateTime localDateTimeTwo = LocalDateTime.of(2020,02,8,21, 30, 59, 123456789);
System.out.println("compareTo: " + localDateTimeOne.compareTo(localDateTimeTwo)); // compareTo: 2
System.out.println("isBefore: " + localDateTimeOne.isBefore(localDateTimeTwo)); // isBefore: false
System.out.println("isAfter: " + localDateTimeOne.isAfter(localDateTimeTwo)); // isAfter: true
System.out.println("isEqual: " + localDateTimeOne.isEqual(localDateTimeTwo)); // isEqual: false
/**
* 从LocalDateTime实例获取时间戳
* 从LocalDateTime获取时间戳稍微有点麻烦,需先把LocalDateTime实例转为Instant实例,再调用Instant实例的toEpochMilli方法获得对应的时间戳。
* 下面示例从本地日期时间实例获取对应的时间戳
*/
LocalDateTime now = LocalDateTime.now();
Instant instant1 = now.toInstant(ZoneOffset.ofHours(8));
System.out.println("timeFromLocal1 = " + instant1.toEpochMilli()); // timeFromLocal1 = 1645272488866
/**
* 上面获取代码基于北京时间,所以转为Instant实例时使用了东八区。
* 倘若在东八区以外的其他地区运行上述代码,就无法得到正确的当地时间戳,此时要先设置当地的默认时区,再将LocalDateTime实例转为Instant实例
*/
Instant instant2 = now.atZone(ZoneId.systemDefault()).toInstant();
System.out.println("timeFromLocal2 = " + instant2.toEpochMilli()); // timeFromLocal2 = 1645272488866
/**
* 当前日期时间替换成指定的日期时间, 这里会用到一个方法adjustInto()
* Temporal adjustInto(Temporal temporal) 将指定的时间对象调整为具有与此对象相同的日期和时间
* 不常用(该方法不学也罢)
*/
// 获取当前时间
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("转换前的时间:" + localDateTime); // 转换前的时间:2022-02-19T22:25:20.859059200
// 使用adjustInto()方法后
LocalDateTime localDateTimeOf = LocalDateTime.of(2020,12,12,12,00,01);
localDateTime = (LocalDateTime)localDateTimeOf.adjustInto(localDateTime);
System.out.println("转换后的时间:" + localDateTime); // 转换后的时间:2020-12-12T12:00:01
}
}
时区篇
首先介绍:LocalDateTime、OffsetDateTime 和 ZoneDateTime 之间的关系,且与 ZoneOffset(偏移量)和 ZoneId(时区) 的概念。
┌─────────────┐─────────────┐────────────┐────────────┐
│ LocalDate │ LocalTime │ ZoneOffset │ ZoneId │
└─────────────┘─────────────┘────────────┘────────────┘
┌───────────────────────────┐
│ LocalDateTime │
└───────────────────────────┘
┌────────────────────────────────────────┐
│ OffsetDateTime │
└────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ ZonedDateTime │
└─────────────────────────────────────────────────────┘
分割时间(ZonedDateTime):2022-02-18T20:41:14.164538200+08:00[Asia/Shanghai]
LocalDate:2022-02-18
LocalTime:T20:41:14.164538200
ZoneOffset:+08:00
ZoneId:[Asia/Shanghai]
import java.time.*;
public class JavaDateTest {
public static void main(String[] args) {
System.out.println(LocalDate.now()); // 2022-02-19
System.out.println(LocalTime.now()); // 18:52:15.279221600
System.out.println(LocalDateTime.now()); // 2022-02-19T18:52:15.279221600
System.out.println(ZoneOffset.ofHours(8)); // +08:00
System.out.println(ZoneId.systemDefault()); // Asia/Shanghai
System.out.println(OffsetDateTime.now()); // 2022-02-19T18:52:15.279221600+08:00
System.out.println(ZonedDateTime.now()); // 2022-02-19T18:52:15.279221600+08:00[Asia/Shanghai]
}
}
java.time.ZoneId
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Set;
public class JavaDateTest {
public static void main(String[] args) {
/**
* 常用API:
* systemDefault():获取系统默认时区的ID
* of(String zoneName):根据各个地区的时区ID名创建对象
* getAvailableZoneIds():获取世界各个地方的时区的集合
*/
System.out.println(ZoneId.systemDefault()); // Asia/Shanghai
System.out.println(ZoneId.of("Asia/Kolkata")); // Asia/Kolkata
System.out.println(ZoneId.of("Asia/Tokyo")); // Asia/Tokyo
System.out.println(LocalDateTime.now(ZoneId.of("Asia/Kolkata"))); // 2022-02-19T17:24:39.643968100
System.out.println(LocalDateTime.now(ZoneId.of("Asia/Kolkata"))); // 2022-02-19T17:24:39.643968100
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
// [Asia/Aden, America/Cuiaba, Etc/GMT+9, Etc/GMT+8, ...省略后面输出
System.out.println(availableZoneIds);
}
}
java.time.ZoneOffset
import java.time.*;
import java.time.temporal.Temporal;
public class JavaDateTest {
public static void main(String[] args) {
System.out.println(ZoneOffset.MAX); // +18:00
System.out.println(ZoneOffset.MIN); // -18:00
ZoneOffset zone = ZoneOffset.UTC;
System.out.println(zone); // Z
Temporal temp = zone.adjustInto(ZonedDateTime.now());
System.out.println(temp); // 2022-02-19T18:55:40.567526+08:00[Asia/Shanghai]
// 获取5小时偏移量的ZoneOffset对象
System.out.println(ZoneOffset.ofHours(5)); // +05:00
}
}
java.time.OffsetDateTime
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
public class JavaDateTest {
public static void main(String[] args) {
/**
* 最大/最小值
* 偏移量的最大值是+18,最小值是-18,这是由ZoneOffset内部的限制决定的。
*/
OffsetDateTime min = OffsetDateTime.MIN;
OffsetDateTime max = OffsetDateTime.MAX;
// OffsetDateTime最小值:-999999999-01-01T00:00+18:00
System.out.println("OffsetDateTime最小值:" + min);
// OffsetDateTime最大值:+999999999-12-31T23:59:59.999999999-18:00
System.out.println("OffsetDateTime最大值:" + max);
// +18:00:-999999999-1-1
System.out.println(min.getOffset() + ":" + min.getYear() + "-" + min.getMonthValue() + "-" + min.getDayOfMonth());
// -18:00:999999999-12-31
System.out.println(max.getOffset() + ":" + max.getYear() + "-" + max.getMonthValue() + "-" + max.getDayOfMonth());
/**
* ZoneOffset的实例化
*/
// 当前位置偏移量的本地时间:2022-02-19T22:31:13.539368500+08:00
System.out.println("当前位置偏移量的本地时间:" + OffsetDateTime.now());
// 偏移量-4(纽约)的本地时间::2022-02-19T22:31:13.539368500-04:00
System.out.println("偏移量-4(纽约)的本地时间::" + OffsetDateTime.of(LocalDateTime.now(), ZoneOffset.of("-4")));
// 纽约时区的本地时间:2022-02-19T09:31:13.539368500-05:00
System.out.println("纽约时区的本地时间:" + OffsetDateTime.now(ZoneId.of("America/New_York")));
/**
* 转换:LocalDateTime -> OffsetDateTime
* 通过此例值得注意的是:LocalDateTime#atOffset()/atZone()只是增加了偏移量/时区,本地时间是并没有改变的。
* 若想实现本地时间到其它偏移量的对应的时间只能通过其ofInstant()系列构造方法。
*/
LocalDateTime localDateTime = LocalDateTime.of(2021, 12, 12, 18, 00, 00);
// 当前时区(北京)时间为:2021-12-12T18:00
System.out.println("当前时区(北京)时间为:" + localDateTime);
// 转换为偏移量为 -4的OffsetDateTime时间:(-4地方的晚上18点)
// -4偏移量地方的晚上18点(方式一):2021-12-12T18:00-04:00
System.out.println("-4偏移量地方的晚上18点(方式一):" + OffsetDateTime.of(localDateTime, ZoneOffset.ofHours(-4)));
// -4偏移量地方的晚上18点(方式二):2021-12-12T18:00-04:00
System.out.println("-4偏移量地方的晚上18点(方式二):" + localDateTime.atOffset(ZoneOffset.ofHours(-4)));
// 转换为偏移量为 -4的OffsetDateTime时间:(北京时间晚上18:00 对应的-4地方的时间点)
// 当前地区对应的-4地方的时间:2021-12-12T06:00-04:00
System.out.println("当前地区对应的-4地方的时间:" + OffsetDateTime.ofInstant(localDateTime.toInstant(ZoneOffset.ofHours(8)), ZoneOffset.ofHours(-4)));
/**
* 转换:OffsetDateTime -> LocalDateTime
*/
OffsetDateTime offsetDateTime = OffsetDateTime.of(LocalDateTime.now(), ZoneOffset.ofHours(-4));
// -4偏移量时间为:2022-02-19T22:39:14.442577-04:00
System.out.println("-4偏移量时间为:" + offsetDateTime);
// 转为LocalDateTime 注意:时间还是未变的哦
// LocalDateTime的表示形式:2022-02-19T22:39:14.442577
System.out.println("LocalDateTime的表示形式:" + offsetDateTime.toLocalDateTime());
}
}
java.time.ZonedDateTime
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class JavaDateTest {
public static void main(String[] args) {
// 获取系统的默认时区编号
System.out.println(ZoneId.systemDefault());
// 获取本地默认时区国家的的日期
System.out.println("本地时区的日期时间:" + LocalDateTime.now()); // 本地时区的日期时间:2022-02-18T19:17:37.416345200
/**
* 实例化ZonedDateTime对象:
* 一种是通过now()方法返回当前时间,一种是通过of()方法放回指定时间。对会带上时区ZoneId对象
* ZonedDateTime now()
* ZonedDateTime now(ZoneId zone)
* ZonedDateTime now(Clock clock)
* ZonedDateTime of(LocalDate date, LocalTime time, ZoneId zone)
* ZonedDateTime of(LocalDateTime localDateTime, ZoneId zone)
* ZonedDateTime of(int year, int month, int dayOfMonth,int hour, int minute, int second, int nanoOfSecond, ZoneId zone)
*/
ZonedDateTime zbj1 = ZonedDateTime.now(); // 默认时区
ZonedDateTime zny1 = ZonedDateTime.now(ZoneId.of("America/New_York")); // 用指定时区获取当前时间
System.out.println(zbj1); // 2022-02-18T20:41:14.164538200+08:00[Asia/Shanghai]
System.out.println(zny1); // 2022-02-18T07:41:14.164538200-05:00[America/New_York]
/**
* 另一种方式是通过给一个LocalDateTime附加一个ZoneId,就可以变成ZonedDateTime:
*/
LocalDateTime ldt = LocalDateTime.of(2019, 9, 15, 15, 16, 17);
ZonedDateTime zbj2 = ldt.atZone(ZoneId.systemDefault());
ZonedDateTime zny2 = ldt.atZone(ZoneId.of("America/New_York"));
// 以这种方式创建的ZonedDateTime,它的日期和时间与LocalDateTime相同,但附加的时区不同,因此是两个不同的时刻:
System.out.println(zbj2); // 2019-09-15T15:16:17+08:00[Asia/Shanghai]
System.out.println(zny2); // 2019-09-15T15:16:17-04:00[America/New_York]
/**
* 对比LocalDateTime和ZonedDateTime都设置时区的情况
*/
// 根据时区,获得指定时区的当前时间(可以理解为还是本地时区,所以输出不显示时区)
LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("America/Phoenix"));
System.out.println(localDateTime); // 2022-02-18T04:17:37.431349500
// 获取指定时区,获得指定时区的当前时间(这个是把当前时间指定到固定的时区)
ZonedDateTime zonedDateTime = LocalDateTime.now().atZone(ZoneId.of("Europe/Monaco"));
System.out.println(zonedDateTime); // 2022-02-18T19:17:37.416345200+01:00[Europe/Monaco]
/**
* 时区转换:
* 要转换时区,通过ZonedDateTime的withZoneSameInstant()将关联时区转换到另一个时区,转换后日期和时间都会相应调整。
* 下面的代码演示了如何将北京时间转换为纽约时间:
* 要特别注意,时区转换的时候,由于夏令时的存在,不同的日期转换的结果很可能是不同的。这是北京时间9月15日的转换结果:
* 下面两次转换后的纽约时间有1小时的夏令时时差( 涉及到时区时,千万不要自己计算时差,否则难以正确处理夏令时)
*/
// 设置中国时区时间9月15日:
ZonedDateTime zbj3 = ZonedDateTime.of(2020, 9, 15, 15, 16, 17, 00, ZoneId.of("Asia/Shanghai"));
// 转换为纽约时间:
ZonedDateTime zny3 = zbj3.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println(zbj3); // 2020-09-15T15:16:17+08:00[Asia/Shanghai]
System.out.println(zny3); // 2020-09-15T03:16:17-04:00[America/New_York]
// 设置中国时区时间11月15日:
ZonedDateTime zbj4 = ZonedDateTime.of(2020, 11, 15, 15, 16, 17, 00, ZoneId.of("Asia/Shanghai"));
// 转换为纽约时间:
ZonedDateTime zny4 = zbj4.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println(zbj4); // 2020-11-15T15:16:17+08:00[Asia/Shanghai]
System.out.println(zny4); // 2020-11-15T02:16:17-05:00[America/New_York]
/**
* 访问与设置ZonedDateTime对象的时间(与LocalDateTime用法基本一致, 案例直接参考LocalDateTime)
*
* 1.常用的getXxx()系列操作,获得日期:
* int getYear() 获取当前日期的年份
* Month getMonth() 获取当前日期的月份对象(返回一个Month枚举值)
* int getMonthValue() 获取当前日期是第几月(1-12)
* int getDayOfMonth() 表示该对象表示的⽇期是这个⽉第⼏天(1-31)
* DayOfWeek getDayOfWeek() 表示该对象表示的日期是星期几(返回一个DayOfWeek枚举值)
* int getDayOfYear() 表示该对象表示的日期是今年第几天(1-366)
* int getHour() 获取当前时间小时数
* int getMinute() 获取当前时间分钟数
* int getSecond() 获取当前时间秒值
* int getNano() 把获取到的当前时间的秒数换算成纳秒
*
* 2.常用的setXxx()系列操作,设置日期:
* ZonedDateTime withYear(int year) 指定对象的年份
* ZonedDateTime withMonth(int month) 指定对象的月份
* ZonedDateTime withDayOfMonth(int dayOfMonth) 指定对象在当月的日期
* ZonedDateTime withDayOfYear(int dayOfYear) 指定对象在当年的日期
* ZonedDateTime withHour(int hour) 指定对象的小时数
* ZonedDateTime withMinute(int minute) 指定对象的分钟数
* ZonedDateTime withSecond(int second) 指定对象在当⽉的秒数
* ZonedDateTime withNano(int nanoOfSecond) 指定对象在当年的纳秒数
*
* 3.常用的plusXxx()系列操作,增加时间的方法:
* ZonedDateTime plusYears(long years) 增加指定年份数
* ZonedDateTime plusMonths(long months) 增加指定⽉份数
* ZonedDateTime plusDays(long days) 增加指定天数
* ZonedDateTime plusWeeks(long weeks) 增加指定周数
* ZonedDateTime plusHours(long hours) 增加指定小时
* ZonedDateTime plusMinutes(long minutes) 增加指定分钟
* ZonedDateTime plusSeconds(long seconds) 增加指定秒
* ZonedDateTime plusNanos(long nanos) 增加指定纳秒
*
* 4.常用的minusXxx()系列操作,减少时间的方法:
* ZonedDateTime minusYears(long years) 减去指定年份
* ZonedDateTime minusMonths(long months) 减去指定月份
* ZonedDateTime minusDays(long days) 减去指定天数
* ZonedDateTime minusWeeks(long weeks) 减去指定周数
* ZonedDateTime minusHours(long hours) 减去指定小时
* ZonedDateTime minusMinutes(long minutes) 减去指定分钟
* ZonedDateTime minusSeconds(long seconds) 减去指定秒
* ZonedDateTime minusNanos(long nanos) 减去指定纳秒
*/
// 案例直接参考LocalDateTime
}
}
时间间隔
java.time.Duration(时间值)
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
public class JavaDateTest {
public static void main(String[] args) {
/**
* 实例化指定单位的持续时间对象
* 注意: 默认的打印结果为ISO国际标准化组织规定的日期格式,PT2H中的H,表示Hour小时,M代表Minute分钟,S代表Second秒数
*/
Duration durationDays1 = Duration.ofDays(10); // 10天
Duration durationDays2 = Duration.of(10, ChronoUnit.DAYS); // 10天
System.out.println(durationDays1); // PT240H
System.out.println(durationDays2); // PT240H
Duration durationHours1 = Duration.ofHours(1); // 1小时
Duration durationHours2 = Duration.of(1, ChronoUnit.HOURS); // 1小时
System.out.println(durationHours1); // PT1H
System.out.println(durationHours2); // PT1H
Duration durationMinutes1 = Duration.ofMinutes(1); // 1分
Duration durationMinutes2 = Duration.of(1, ChronoUnit.MINUTES); // 1分
System.out.println(durationMinutes1); // PT1M
System.out.println(durationMinutes2); // PT1M
Duration durationSeconds1 = Duration.ofSeconds(1); // 1秒
Duration durationSeconds2 = Duration.of(1, ChronoUnit.SECONDS); // 1秒
System.out.println(durationSeconds1); // PT1S
System.out.println(durationSeconds2); // PT1S
Duration durationMillis1 = Duration.ofMillis(1000); // 1000毫秒
Duration durationMillis2 = Duration.of(1000, ChronoUnit.MILLIS); // 1000毫秒
System.out.println(durationMillis1); // PT1S
System.out.println(durationMillis2); // PT1S
Duration durationNanos1 = Duration.ofNanos(100000000); // 10000000纳秒
Duration durationNanos2 = Duration.of(100000000, ChronoUnit.NANOS); // 10000000纳秒
System.out.println(durationNanos1); // PT0.1S
System.out.println(durationNanos2); // PT0.1S
Duration durationFrom = Duration.from(ChronoUnit.DAYS.getDuration());
System.out.println(durationFrom); // PT24H
/**
* 获取指定单位的持续时间
* long toDays() 这段时间的总天数
* long toHours() 这段时间的小时数
* long toMinutes() 这段时间的分钟数
* long toSeconds() 这段时间的秒数
* long toMillis() 这段时间的毫秒数
* long toNanos() 这段时间的纳秒数
* String toString() 此持续时间的字符串表示形式,使用基于ISO-8601秒*的表示形式,例如 PT8H6M12.345S
*/
Duration durationOne = Duration.ofDays(1); // 设置1天的时间
System.out.println("toDay天 = "+ durationOne.toDays()); // toDay时间 = 1
System.out.println("toHours时 = "+ durationOne.toHours()); // toHours时间 = 24
System.out.println("toMinutes分 = "+ durationOne.toMinutes()); // toMinutes时间 = 1440
System.out.println("toMinutes秒 = "+ durationOne.toSeconds()); // toMinutes秒 = 86400
System.out.println("toMillis毫秒 = "+ durationOne.toMillis()); // toMillis时间 = 86400000
System.out.println("toNanos纳秒 = "+ durationOne.toNanos()); // toNanos时间 = 86400000000000
System.out.println("toString格式 = "+ durationOne.toString()); // toString时间 = PT24H
/**
* 获取2个时间点之间差值的持续时间
* Duration.between()方法创建Duration对象,注意这个天数是可以负数,意味着如果开始时间比结束时间更后面就会得到负数天数
*/
LocalDateTime from = LocalDateTime.of(2017, 01, 1, 00, 0, 0); // 2017-01-01 00:00:00
LocalDateTime to = LocalDateTime.of(2019, 9, 12, 14, 28, 0); // 2019-09-12 14:28:00
Duration duration1 = Duration.between(from, to); // 表示从 from 到 to 这段时间(第⼆个参数减第⼀个参数)
System.out.println(duration1.toDays()); // 984
System.out.println(duration1.toHours()); // 23630
System.out.println(duration1.toMinutes()); // 1417828
System.out.println(duration1.getSeconds()); // 85069680
System.out.println(duration1.toMillis()); // 85069680000
System.out.println(duration1.toNanos()); // 85069680000000000
/**
* Duration时间的加减,可以参考LocalDateTime中的plusXxx、minusXxx和withXxx()系列的方法
* 注意: Duration包含两部分:seconds秒,nanos纳秒,它们的组合表达了时间长度。所以withXxx()只有withSeconds()和withNanos()方法
*/
System.out.println(Duration.ofDays(4).withSeconds(360).toHours()); // 加8小时(4天8小时):输出:0
System.out.println(Duration.ofDays(4).plusHours(8).toHours()); // 加8小时(4天8小时):输出:104
System.out.println(Duration.ofDays(4).minusHours(8).toHours()); // 加8小时(4天8小时):输出:88
/**
* Duration可以接收:LocalDate、LocalTime、LocalDateTime、Instant
* Duration只能处理两个Instant、LocalTime, LocalDateTime, ZonedDateTime,
* 参数不能混搭,混搭会报异常,如果传入的是LocalDate,将会抛出异常
*/
Duration.between(LocalTime.now(), LocalTime.now());
Duration.between(LocalDateTime.now(), LocalDateTime.now());
Duration.between(Instant.now(), Instant.now());
}
}
java.time.Period(日期值)
import java.time.Duration;
import java.time.LocalDate;
import java.time.Period;
import java.time.temporal.ChronoUnit;
public class JavaDateTest {
public static void main(String[] args) {
/**
* 实例化指定单位的持续日期对象
* 注意: 默认的打印结果为ISO国际标准化组织规定的日期格式,P3Y2M1D中的,Y表示Year年,M代表Month月,D代表Day天
*/
System.out.println(Period.between(LocalDate.now(), LocalDate.now())); // P0D
System.out.println(Period.of(1,2,3)); // P1Y2M3D
System.out.println(Period.ofYears(1)); // P1Y
System.out.println(Period.ofMonths(2)); // P2M
System.out.println(Period.ofDays(25)); // P25D
System.out.println(Period.ofWeeks(4)); // P28D
System.out.println(Period.from(Period.of(3, 2, 1))); // P3Y2M1D
/**
* 获取指定单位的持续时间
*/
Period periodYears = Period.ofYears(1); // 设置1年的时间
System.out.println(periodYears.getYears()); // 1
System.out.println(periodYears.getMonths()); // 0
System.out.println(periodYears.getDays()); // 0
System.out.println(periodYears.get(ChronoUnit.YEARS)); // 1
System.out.println(periodYears.get(ChronoUnit.MONTHS)); // 0
System.out.println(periodYears.get(ChronoUnit.DAYS)); // 0
System.out.println(periodYears.getChronology()); // 获取此Period的年表,即ISO日历系统:ISO
System.out.println(periodYears.getUnits()); // 查看支持的枚举类型:[Years, Months, Days]
/**
* Period时间的加减,可以参考LocalDateTime中的plusXxx、minusXxx和withXxx()系列的方法
*/
System.out.println(Period.of(1,2,3).withYears(8).getYears()); // 3
System.out.println(Period.of(1,2,3).withMonths(8).getMonths()); // 3
System.out.println(Period.of(1,2,3).withDays(8).getDays()); // 8
System.out.println(Period.of(1,2,3).plusYears(8).getYears()); // 3
System.out.println(Period.of(1,2,3).plusMonths(8).getMonths()); // 3
System.out.println(Period.of(1,2,3).plusDays(8).getDays()); // 11
System.out.println(Period.of(1,2,3).minusYears(8).getYears()); // 3
System.out.println(Period.of(1,2,3).minusMonths(8).getMonths()); // 3
System.out.println(Period.of(1,2,3).minusDays(8).getDays()); // -5
}
}
TemporalAdjuster 矫正器
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
public class JavaDateTest {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now(); // 首先获取当前时间
System.out.println("当前时间:"+now); // 当前时间:2022-02-17T22:01:45.718728600
/**
* 方式一:使用TemporalAdjuster接口自定义日期方式实现
*/
TemporalAdjuster adJuster = (temporal) -> {
LocalDateTime dateTime = (LocalDateTime) temporal;
DayOfWeek dayOfWeek = dateTime.getDayOfWeek(); // 先获取周几
if (DayOfWeek.FRIDAY.equals(dayOfWeek)) {
return dateTime.plusDays(3); // 周五加三天等于工作日
} else if (DayOfWeek.SATURDAY.equals(dayOfWeek)) {
return dateTime.plusDays(2); // 周六加两天
}
return dateTime.plusDays(1); // 其他均加一天
};
// 下一个工作日:2022-02-18T22:01:45.718728600
System.out.println("下一个工作日:" + now.with(adJuster));
/**
* 方式二:使用TemporalAdjusters工具类提供的日期来实现
*/
LocalDateTime with1 = now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
// 下周日:2022-02-20T22:01:45.718728600
System.out.println("下周日:" + with1);
LocalDateTime with2 = now.with(TemporalAdjusters.firstDayOfMonth());
// 这个月的第一天:2022-02-01T22:01:45.718728600
System.out.println("这个月的第一天:" + with2);
LocalDateTime with3 = now.with(TemporalAdjusters.firstDayOfNextMonth());
// 下个月的第一天:2022-03-01T22:01:45.718728600
System.out.println("下个月的第一天:" + with3);
}
}