JAVA时间类及JAVA8新时间类

news2024/11/14 20:44:40

文章目录

  • 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、时间戳、统一标准时间、时区

  1. GMT:格林尼治标准时间,是计算机中时间原点:1970年1月1日 00:00:00
  2. 时间戳:自1970年1月1日(00:00:00 GMT)至当前时间的总秒数
  3. UTC:统一的标准时间
    在这里插入图片描述
  4. 时区: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时间类

  1. 创建时间对象
  • 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();
  1. 对象规范化
    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(时区) 的概念。

┌─────────────┐─────────────┐────────────┐────────────┐
│  LocalDateLocalTimeZoneOffsetZoneId   │
└─────────────┘─────────────┘────────────┘────────────┘
┌───────────────────────────┐
│       LocalDateTime       │
└───────────────────────────┘
┌────────────────────────────────────────┐
│             OffsetDateTime             │
└────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│                    ZonedDateTime                    │
└─────────────────────────────────────────────────────┘

分割时间(ZonedDateTime):2022-02-18T20:41:14.164538200+08:00[Asia/Shanghai]
LocalDate2022-02-18
LocalTimeT20: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);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/355478.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vulnhub-DC-2实战靶场

Vulnhub-DC-2实战靶场 https://blog.csdn.net/ierciyuan/article/details/127560871 这次试试DC-2&#xff0c;目标是找到官方设置的5个flag。 一. 环境搭建 1. 准备工具 虚拟机Kali&#xff1a; 自备&#xff0c;我的kali的IP为192.168.3.129 靶场机&#xff1a; https…

接口和抽象类

接口(Interface)和抽象类(Abstract Class)是支持抽象类定义的两种机制。 1.抽象类 (1)说明 在Java中被abstract关键字修饰的类称为抽象类&#xff0c;被abstract关键字修饰的方法称为抽象方法&#xff0c;抽象方法只有方法的声明&#xff0c;没有方法体。抽象类是用来捕捉子…

CCNP350-401学习笔记(151-200题)

151、Which two LISP infrastructure elements are needed to support LISP to non-LISP internetworking? (Choose two.)A. PETR B. PITRC. MR D. MS E. ALT 152、In an SD-WAN deployment, which action in the vSmart controller responsible for? A. handle, maintain, …

一文搞懂C/C++内存管理原理与实现

C 语言内存管理指对系统内存的分配、创建、使用这一系列操作。在内存管理中&#xff0c;由于是操作系统内存&#xff0c;使用不当会造成毕竟麻烦的结果。本文将从系统内存的分配、创建出发&#xff0c;并且使用例子来举例说明内存管理不当会出现的情况及解决办法。 一、内存 …

[python入门㊽] - 自定义异常 raise 关键字

目录 ❤ 自定义抛出异常关键字 - raise ❤ 使用raise主动引发异常 ❤ raise 关键字的用法 ❤ 触发异常 ❤ 自定义异常类 在前面我们学过异常三个关键字分别是try、except 以及 finally 在编程过程中合理的使用异常可以使得程序正常的执行。有直接抛出异常的形式&…

【HTML】HTML 表格总结 ★★★ ( 表格标签 | 行标签 | 单元格标签 | 表格标签属性 | 表头单元格标签 | 表格标题标签 | 合并单元格 )

文章目录一、表格标签组成 ( 表格标签 | 行标签 | 单元格标签 )二、table 表格属性 ( border 属性 | align 属性 | width 属性 | height 属性 )三、表头单元格标签四、表格标题标签五、合并单元格1、合并单元格方式2、合并单元格顺序3、合并单元格流程六、合并单元格示例1、原始…

Linux之ping\kill\killall命令

参考视频&#xff1a;linux命令&#xff08;ping&#xff09;linux命令&#xff08;kill、killall&#xff09;Linux ping 命令用于检测主机。执行 ping 指令会使用 ICMP 传输协议&#xff0c;发出要求回应的信息&#xff0c;若远端主机的网络功能没有问题&#xff0c;就会回应…

Redis进阶:布隆过滤器(Bloom Filter)及误判率数学推导

1 缘起 有一次偶然间听到有同事在说某个项目中使用了布隆过滤器&#xff0c; 哎呦&#xff0c;我去&#xff0c;我竟然不知道啥是布隆过滤器&#xff0c; 这我哪能忍&#xff1f;其实&#xff0c;也可以忍&#xff0c;但是&#xff0c;可能有的面试官不能忍&#xff01;&#…

简介JVM

目录 一、内存分区 1、程序计数器 2、栈 3、堆 4、方法区 二、类加载 1、Loading 2、Linking Verification Preparation Resolution 3、Initializing 4、双亲委派模型 三、垃圾回收 1、如何判断为垃圾&#xff1f; 引入引用计数 可达性分析 2、如…

Transformer论文阅读:Swin Transformer算法笔记

标题&#xff1a;Swin Transformer: Hierarchical Vision Transformer using Shifted Windows 会议&#xff1a;ICCV2021 论文地址&#xff1a;https://ieeexplore.ieee.org/document/9710580/ 官方代码&#xff1a;https://github.com/microsoft/Swin-Transformer 作者单位&am…

[安装之2] 台式计算机加固态硬盘,台式机添加固态硬盘教程_台式主机固态硬盘怎么安装

固态硬盘是用固态电子存储芯片阵列制成的硬盘&#xff0c;也是电脑中比较常见的内存硬件&#xff0c;有些用户在使用电脑时候&#xff0c;由于内存不足导致系统运行较卡的情况&#xff0c;往往会选择添加固态硬盘来解决&#xff0c;那么台式主机固态硬盘怎么安装呢&#xff1f;…

shell脚本内调用另外一个shell脚本的几种方法

有时会在一个shell脚本(如test_call_other_shell.sh)中调用另外一个shell脚本(如parameter_usage.sh)&#xff0c;这里总结几种可行的方法&#xff0c;这些方法在linux上和windows上(通过Git Bash)均适用&#xff1a; 1.通过source: 运行在相同的进程&#xff0c;在test_…

CCIE重认证-300-401-拖图题全

拖图 拖图题 编程 snippet&#xff1b;192.168.5.0&#xff0c;mask 255.255.255.0&#xff1b;number是192.168.5.0&#xff1b;mask是255.255.255.0 snippets&#xff1b;edit-config对config&#xff0c;loopback对name 100&#xff0c;address对primary&#xff0c;mask…

广度优先搜索算法 - 迷宫找路

广度优先搜索算法1 思考问题1.1 这个迷宫需不需要指定入口和出口&#xff1f;2 先粗略实现2.1 源码2.2 源码解释3 优化代码3.1 优化读取文件部分3.2 增加错误处理4 再优化-让程序变得更加灵活4.1 用户外部可以循环输入入口和出口5 完整代码这是一个提问者的提出的问题&#xff…

制造业的云ERP在外网怎么访问?内网服务器一步映射到公网

随着企业信息化、智能化时代的到来&#xff0c;很多制造业企业都在用云ERP。用友U 9cloud通过双版本公有云专属、私有云订阅、传统软件购买三种模式满足众多制造业企业的需求&#xff0c;成为一款适配中型及中大型制造业的云ERP&#xff0c;是企业数智制造的创新平台。 用友U 9…

python 面向对象利用selenium【获取某东商品信息】

用python程序和谷歌selenium插件获取某东商品详细信息【商品名称、商品简介&#xff0c;超链接】利用selenium自动化程序 中的css页面结构索取来获取详细数据关于谷歌selenium的安装方法和使用方法第一步检查自己谷歌浏览器的版本1.1 找到设置&#xff1a;并鼠标点击进入1.2进入…

排序评估指标——NDCG和MAP

在搜索和推荐任务中&#xff0c;系统常返回一个item列表。如何衡量这个返回的列表是否优秀呢&#xff1f; 例如&#xff0c;当我们检索【推荐排序】&#xff0c;网页返回了与推荐排序相关的链接列表。列表可能会是[A,B,C,G,D,E,F],也可能是[C,F,A,E,D]&#xff0c;现在问题来了…

使用canvas写一个flappy bird小游戏

简介 canvas 是HTML5 提供的一种新标签&#xff0c;它可以支持 JavaScript 在上面绘画&#xff0c;控制每一个像素&#xff0c;它经常被用来制作小游戏&#xff0c;接下来我将用它来模仿制作一款叫flappy bird的小游戏。flappy bird&#xff08;中文名&#xff1a;笨鸟先飞&am…

XSS注入进阶练习篇(一)XSS-LABS通关教程

XSS注入进阶练习篇1.常用标签整理2. XSS-LABS 练习2.1 level 1 无限制2.2 level 2 双引号闭合2.3 level 3 源码函数书写不全&#xff0c;单引号绕过2.4 level 4 无尖括号绕过2.5 level 5 a标签使用2.6 level 6 大小写绕过2.7 level 7 置空替换绕过2.8 level 8 URL编码绕过 - 重…

安全—07day

Tomcat AJP 文件包含漏洞&#xff08;CVE-2020- 1938&#xff09; 漏洞概述 Ghostcat(幽灵猫&#xff09;是由长亭科技安全研究员发现的存在于Tomcat 中的安全漏洞&#xff0c;由于Tomcat AJP 协议设计上存在缺陷,攻击者通过Tomcat AJP Connector可以读取或包含 Tomcat上所有…