高级JAVA开发必备技能:java8 新日期时间API((五)JSR-310:实战+源码分析)

java.time.temporal包是Java 8中引入的新的日期和时间API的一部分,它提供了一组接口和类,用于表示和操作日期和时间 java.time.temporal包是Java 8中引入的新的日期和时间API的一部分,它提供了一组接口和类,用于表示和操作日期和时间。这个包主要包含了TemporalAccessor、TemporalField、TemporalUnit、TemporalQuery、TemporalAdjuster等接口,以及LocalDate、LocalTime、LocalDateTime、ZonedDateTime、OffsetDateTime、Instant等实现类。 阅读详情

方法名称:cn.hutool.core.date.LocalDateTimeUtil.of(java.time.temporal.TemporalAccessor)

方法描述

{@link TemporalAccessor}转{@link LocalDateTime},使用默认时区

支持版本及以上

参数描述:

参数名描述
TemporalAccessor temporalAccessor
temporalAccessor {@link TemporalAccessor}

返回值:

{@link LocalDateTime}

参考案例:

		String dateStr = "2021-05-22T10:23:56";
		//使用默认时区
		TemporalAccessor temporalAccessor = DateTimeFormatter.ISO_DATE_TIME.parse(dateStr);
		LocalDateTime localDateTime = LocalDateTimeUtil.of(temporalAccessor);
		Assert.assertEquals("2021-05-22T10:23:56", l
**作者徽是vip1024c**
ocalDateTime.toString());

源码解析:

	public static LocalDateTime of(TemporalAccessor temporalAccessor) {
		if (null == temporalAccessor) {
			return null;
		}

		if(temporalAccessor instanceof LocalDate){
			return ((LocalDate)temporalAccessor).atStartOfDay();
		}

		return LocalDateTime.of(
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.YEAR),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.MONTH_OF_YEAR),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.DAY_OF_MONTH),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.HOUR_OF_DAY),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.MINUTE_OF_HOUR),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.SECOND_OF_MINUTE),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.NANO_OF_SECOND)
		);
	}

因为入参TemporalAccessor time的实现类常用的有如下几个(java8提供的):

  • LocalDateTime
  • LocalDate
  • LocalTime

好习惯,先判断参数temporalAccessor是否为空

然后判断temporalAccessor是否为LocalDate对象,如果是则调用LocalDate.atStartOfDay(),返回值是localDate+‘00:00’

//LocalDate
public LocalDateTime atStartOfDay() {
        return LocalDateTime.of(this, LocalTime.MIDNIGHT);
    }

/\*\*
 \* The time of midnight at the start of the day, '00:00'.
 \*/
public static final LocalTime MIDNIGHT;

public static LocalDateTime of(LocalDate date, LocalTime time) {
    Objects.requireNonNull(date, "date");
    Objects.requireNonNull(time, "time");
    return new LocalDateTime(date, time);
}

最后通过LocalDateTime.of 方法获取LocalDateTime对象的值。

但是博主发现一个问题,LocalTime 是没有年月日的,那怎么转化为LocalDateTime ,我们来写个demo看看效果

LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTimeUtil.of(localTime);
System.out.println(localDateTime);

image-20210919154701692

居然没有报错,这是为什么呢

return LocalDateTime.of(
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.YEAR),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.MONTH_OF_YEAR),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.DAY_OF_MONTH),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.HOUR_OF_DAY),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.MINUTE_OF_HOUR),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.SECOND_OF_MINUTE),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.NANO_OF_SECOND)
		);

这里也是hutool自己封装的方法,都是调用**public static int get(TemporalAccessor temporalAccessor, TemporalField field) ** 源码如下

public static int get(TemporalAccessor temporalAccessor, TemporalField field) {
   if (temporalAccessor.isSupported(field)) {
      return temporalAccessor.get(field);
   }

   return (int)field.range().getMinimum();
}

这个代码很好理解,就是取temporalAccessor 对象对应的属性值,如果不存在,则取这个属性值的最小值。

断点看效果:

1、localtime是不存在year属性的

image-20210919155438622

2、取这个字段的最小值。

image-20210919155550186

其他字段获取方式也差不多。

方法明细-ofDate(java.time.temporal.TemporalAccessor)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.ofDate(java.time.temporal.TemporalAccessor)

方法描述

{@link TemporalAccessor}转{@link LocalDate},使用默认时区

支持版本及以上

5.3.10

参数描述:

参数名描述
TemporalAccessor temporalAccessor
temporalAccessor {@link TemporalAccessor}

返回值:

{@link LocalDate}

参考案例:

		String dateStr = "2021-05-22T10:23:56";
		//使用默认时区
		TemporalAccessor temporalAccessor = DateTimeFormatter.ISO_DATE_TIME.parse(dateStr);
		LocalDate localDate = LocalDateTimeUtil.ofDate(temporalAccessor);
		Assert.assertEquals("2021-05-22", localDate.toString());

源码解析:

	public static LocalDate ofDate(TemporalAccessor temporalAccessor) {
		if (null == temporalAccessor) {
			return null;
		}

		if(temporalAccessor instanceof LocalDateTime){
			return ((LocalDateTime)temporalAccessor).toLocalDate();
		}

		return LocalDate.of(
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.YEAR),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.MONTH_OF_YEAR),
				TemporalAccessorUtil.get(temporalAccessor, ChronoField.DAY_OF_MONTH)
		);
	}

因为入参TemporalAccessor time的实现类常用的有如下几个(java8提供的):

  • LocalDateTime
  • LocalDate
  • LocalTime

好习惯,先判断参数temporalAccessor是否为空

然后判断temporalAccessor是否为LocalDateTime对象,如果是则调用LocalDateTime.toLocalDate(),返回值是localDate,因为LocalDateTime=localDate+LocalTime

最后通过LocalDate.of 方法获取LocalDate对象的值。

方法明细-parse(java.lang.CharSequence)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.parse(java.lang.CharSequence)

方法描述

解析日期时间字符串为{@link LocalDateTime},仅支持yyyy-MM-dd’T’HH:mm:ss格式,例如:2007-12-03T10:15:30

支持版本及以上

参数描述:

参数名描述
CharSequence text
text 日期时间字符串

返回值:

{@link LocalDateTime}

参考案例:

		final LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56");
		Assert.assertEquals("2020-01-23T12:23:56", localDateTime.toString());

image-20210919160344393

源码解析:

	/\*\*
 \* 解析日期时间字符串为{@link LocalDateTime},仅支持yyyy-MM-dd'T'HH:mm:ss格式,例如:2007-12-03T10:15:30
 \*
 \* @param text 日期时间字符串
 \* @return {@link LocalDateTime}
 \*/
	public static LocalDateTime parse(CharSequence text) {
		return parse(text, (DateTimeFormatter)null);
	}

请看下面的源码分析。

方法明细-parse(java.lang.CharSequence, java.time.format.DateTimeFormatter)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.parse(java.lang.CharSequence, java.time.format.DateTimeFormatter)

方法描述

解析日期时间字符串为{@link LocalDateTime},格式支持日期时间、日期、时间

支持版本及以上

参数描述:

参数名描述
CharSequence text
text 日期时间字符串 当formatter为null时,字符串要符合格式2020-01-23T12:23:56
DateTimeFormatter formatter
formatter 日期格式化器,预定义的格式见:{@link DateTimeFormatter}

返回值:

{@link LocalDateTime}

参考案例:

		final LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56", DateTimeFormatter.ISO_DATE_TIME);
		Assert.assertEquals("2020-01-23T12:23:56", localDateTime.toString());
		System.out.println(localDateTime);

image-20210919160344393

源码解析:

	public static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter) {
		if (null == text) {
			return null;
		}
		if (null == formatter) {
			return LocalDateTime.parse(text);
		}

		return of(formatter.parse(text));
	}

如果有同学对CharSequence 对象陌生的话,那对String 应该不会陌生,String 是CharSequence 的实现接口

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    ...
    }

DateTimeFormatter 是jdk8提供的日期时间格式化器,用来替换我们的老朋友 simpledateformat 。

好习惯,先判断参数CharSequence是否为空

然后再判断参数DateTimeFormatter 是否为空,如果为空,则直接调用LocalDateTime.parse(text)

来看看源码

public static LocalDateTime parse(CharSequence text) {
    return parse(text, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}

这里用的日期格式化字符串要像这种格式的:

such as ‘2011-12-03T10:15:30’

那如果传入的CharSequence参数不是这种格式的字符串,会是什么结果

//符合格式2020-01-23T12:23:56
LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56", DateTimeFormatter.ISO_DATE_TIME);
Assert.assertEquals("2020-01-23T12:23:56", localDateTime.toString());
System.out.println(localDateTime);

//不符合格式的
DateTimeFormatter dateTimeFormatter = null;
localDateTime = LocalDateTimeUtil.parse("2020-01-23", dateTimeFormatter);
System.out.println(localDateTime);

执行结果,在预料之中,直接报错,这里是个坑,大家要注意

java.time.format.DateTimeParseException: Text ‘2020-01-23’ could not be parsed at index 10

image-20210919161934470

最后调用of(formatter.parse(text))

formatter.parse(text) 返回结果是TemporalAccessor,不一定是我们想要的LocalDateTime ,所以还要再通过of转一下

formatter.parse(text) 是原生JDK8自带的方法。

方法明细-parse(java.lang.CharSequence, java.lang.String)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.parse(java.lang.CharSequence, java.lang.String)

方法描述

解析日期时间字符串为{@link LocalDateTime}

支持版本及以上

参数描述:

参数名描述
CharSequence text
text 日期时间字符串
String format
format 日期格式,类似于yyyy-MM-dd HH:mm:ss,SSS

返回值:

{@link LocalDateTime}

参考案例:

		final LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23", DatePattern.NORM_DATE_PATTERN);
		Assert.assertEquals("2020-01-23T00:00", localDateTime.toString());

源码解析:

	public static LocalDateTime parse(CharSequence text, String format) {
		if (null == text) {
			return null;
		}

		DateTimeFormatter formatter = null;
		if(StrUtil.isNotBlank(format)){
			// 修复yyyyMMddHHmmssSSS格式不能解析的问题
			// fix issue#1082
			//see https://stackoverflow.com/questions/22588051/is-java-time-failing-to-parse-fraction-of-second
			// jdk8 bug at: https://bugs.openjdk.java.net/browse/JDK-8031085
			if(StrUtil.startWithIgnoreEquals(format, DatePattern.PURE_DATETIME_PATTERN)){
				final String fraction = StrUtil.removePrefix(format, DatePattern.PURE_DATETIME_PATTERN);
				if(ReUtil.isMatch("[S]{1,2}", fraction)){
					//将yyyyMMddHHmmssS、yyyyMMddHHmmssSS的日期统一替换为yyyyMMddHHmmssSSS格式,用0补
					text += StrUtil.repeat('0', 3-fraction.length());
				}
				formatter = new DateTimeFormatterBuilder()
						.appendPattern(DatePattern.PURE_DATETIME_PATTERN)
						.appendValue(ChronoField.MILLI_OF_SECOND, 3)
						.toFormatter();
			} else{
				formatter = DateTimeFormatter.ofPattern(format);
			}
		}

		return parse(text, formatter);
	}

养成好习惯,先判断参数CharSequence和format是否为空

这边针对jdk8的一个bug进行了兼容处理

1、在正常配置按照标准格式的字符串日期,是能够正常转换的。如果月,日,时,分,秒在不足两位的情况需要补0,否则的话会转换失败,抛出异常。
		DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
		LocalDateTime dt1 = LocalDateTime.parse("2021-7-20 23:46:43.946", DATE_TIME_FORMATTER);
		System.out.println(dt1);

会报错:

image-202107208183

java.time.format.DateTimeParseException: Text '2021-7-20 23:46:43.946' could not be parsed at index 5

分析原因:是格式字符串与实际的时间不匹配

“yyyy-MM-dd HH:mm:ss.SSS”

“2021-7-20 23:46:43.946”

中间的月份格式是MM,实际时间是7

解决方案:保持格式字符串与实际的时间匹配

	DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
		LocalDateTime dt1 = LocalDateTime.parse("2021-07-20 23:46:43.946", DATE_TIME_FORMATTER);
		System.out.println(dt1);

image-20210720504067

方法明细-parseDate(java.lang.CharSequence)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.parseDate(java.lang.CharSequence)

方法描述

解析日期时间字符串为{@link LocalDate},仅支持yyyy-MM-dd’T’HH:mm:ss格式,例如:2007-12-03T10:15:30

支持版本及以上

5.3.10

参数描述:

参数名描述
CharSequence text
text 日期时间字符串

返回值:

{@link LocalDate}

参考案例:

		LocalDate localDate = LocalDateTimeUtil.parseDate("2020-01-23");		Assert.assertEquals("2020-01-23", localDate.toString());

源码解析:

	/\*\*
 \* 解析日期时间字符串为{@link LocalDate},仅支持yyyy-MM-dd'T'HH:mm:ss格式,例如:2007-12-03T10:15:30
 \*
 \* @param text 日期时间字符串
 \* @return {@link LocalDate}
 \* @since 5.3.10
 \*/
	public static LocalDate parseDate(CharSequence text) {
		return parseDate(text, (DateTimeFormatter)null);
	}

请看下面的源码分析。

方法明细-parseDate(java.lang.CharSequence, java.time.format.DateTimeFormatter)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.parseDate(java.lang.CharSequence, java.time.format.DateTimeFormatter)

方法描述

解析日期时间字符串为{@link LocalDate},格式支持日期

支持版本及以上

5.3.10

参数描述:

参数名描述
CharSequence text
text 日期时间字符串
DateTimeFormatter formatter
formatter 日期格式化器,预定义的格式见:{@link DateTimeFormatter}

返回值:

{@link LocalDate}

参考案例:

		final LocalDateTime localDateTime = LocalDateTimeUtil.parse("12:23:56", DatePattern.NORM_TIME_PATTERN);
		Assert.assertEquals("12:23:56", localDateTime.toLocalTime().toString());

源码解析:

	public static LocalDate parseDate(CharSequence text, DateTimeFormatter formatter) {
		if (null == text) {
			return null;
		}
		if (null == formatter) {
			return LocalDate.parse(text);
		}

		return ofDate(formatter.parse(text));
	}

如果有同学对CharSequence 对象陌生的话,那对String 应该不会陌生,String 是CharSequence 的实现接口

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    ...
    }

DateTimeFormatter 是jdk8提供的日期时间格式化器,用来替换我们的老朋友 simpledateformat 。

好习惯,先判断参数CharSequence是否为空

然后再判断参数DateTimeFormatter 是否为空,如果为空,则直接调用LocalDate.parse(text)

来看看源码

 public static LocalDate parse(CharSequence text) {
        return parse(text, DateTimeFormatter.ISO_LOCAL_DATE);
    }

这里用的日期格式化字符串要像这种格式的:

such as ‘2011-12-03’

最后调用of(formatter.parse(text))

formatter.parse(text) 返回结果是TemporalAccessor,不一定是我们想要的LocalDate ,所以还要再通过of转一下

formatter.parse(text) 是原生JDK8自带的方法。

方法明细-parseDate(java.lang.CharSequence, java.lang.String)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.parseDate(java.lang.CharSequence, java.lang.String)

方法描述

解析日期字符串为{@link LocalDate}

支持版本及以上

参数描述:

参数名描述
CharSequence text
text 日期字符串
String format
format 日期格式,类似于yyyy-MM-dd

返回值:

{@link LocalDateTime}

参考案例:

		//第一个参数和第二个参数格式保持一致
		LocalDate localDate = LocalDateTimeUtil.parseDate("2020-01-23 12:23:56","yyyy-MM-dd hh:mm:ss");
		Assert.assertEquals("2020-01-23", localDate.toString());
		 localDate = LocalDateTimeUtil.parseDate("2020/01/23 12:23:56","yyyy/MM/dd hh:mm:ss");
		Assert.assertEquals("2020-01-23", localDate.toString());

源码解析:

	public static LocalDate parseDate(CharSequence text, String format) {
		if (null == text) {
			return null;
		}
		return parseDate(text, DateTimeFormatter.ofPattern(format));
	}

请看上面的源码分析。

方法明细-formatNormal(java.time.LocalDateTime)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.formatNormal(java.time.LocalDateTime)

方法描述

格式化日期时间为yyyy-MM-dd HH:mm:ss格式

支持版本及以上

5.3.11

参数描述:

参数名描述
LocalDateTime time
time {@link LocalDateTime}

返回值:

格式化后的字符串

参考案例:

        final LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56");
	    String	format = LocalDateTimeUtil.formatNormal(localDateTime);
		Assert.assertEquals("2020-01-23 12:23:56", format);

源码解析:

	/\*\*
 \* 格式化日期时间为yyyy-MM-dd HH:mm:ss格式
 \*
 \* @param time {@link LocalDateTime}
 \* @return 格式化后的字符串
 \* @since 5.3.11
 \*/
	public static String formatNormal(LocalDateTime time) {
		return format(time, DatePattern.NORM_DATETIME_FORMATTER);
	}

//------------------------------
public static String format(LocalDateTime time, DateTimeFormatter formatter) {
		return TemporalAccessorUtil.format(time, formatter);
	}

TemporalAccessorUtil 类是hutool封装的工具类,看下面的源码,也是比较好理解的。

//TemporalAccessorUtil
/\*\*
 \* 格式化日期时间为指定格式
 \*
 \* @param time {@link TemporalAccessor}
 \* @param formatter 日期格式化器,预定义的格式见:{@link DateTimeFormatter}
 \* @return 格式化后的字符串
 \* @since 5.3.10
 \*/
public static String format(TemporalAccessor time, DateTimeFormatter formatter) {
   if (null == time) {
      return null;
   }

   if(null == formatter){
      formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
   }


   try {
      return formatter.format(time);
   } catch (UnsupportedTemporalTypeException e){
      if(time instanceof LocalDate && e.getMessage().contains("HourOfDay")){
         // 用户传入LocalDate,但是要求格式化带有时间部分,转换为LocalDateTime重试
         return formatter.format(((LocalDate) time).atStartOfDay());
      }else if(time instanceof LocalTime && e.getMessage().contains("YearOfEra")){
         // 用户传入LocalTime,但是要求格式化带有日期部分,转换为LocalDateTime重试
         return formatter.format(((LocalTime) time).atDate(LocalDate.now()));
      }
      throw e;
   }
}

养成好习惯,先判断参数TemporalAccessor 和DateTimeFormatter 是否为空

如果DateTimeFormatter 为空,则给默认值DateTimeFormatter.ISO_LOCAL_DATE_TIME

such as ‘2011-12-03T10:15:30’

然后调用格式化方法formatter.format(time) 如果time 不是LocalDateTime 对象,则会报错,然后在catch里做了兼容处理,对LocalDate 和 LocalTime 对象可以进行格式化处理,其他的直接返回异常。

方法明细-format(java.time.LocalDateTime, java.time.format.DateTimeFormatter)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.format(java.time.LocalDateTime, java.time.format.DateTimeFormatter)

方法描述

格式化日期时间为指定格式

支持版本及以上

参数描述:

参数名描述
LocalDateTime time
time {@link LocalDateTime}
DateTimeFormatter formatter
formatter 日期格式化器,预定义的格式见:{@link DateTimeFormatter}

返回值:

格式化后的字符串

参考案例:

		LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56");
		String format = LocalDateTimeUtil.format(localDateTime, DateTimeFormatter.ISO_DATE_TIME);
		Assert.assertEquals("2020-01-23T12:23:56", format);

源码解析:

	/\*\*
 \* 格式化日期时间为指定格式
 \*
 \* @param time {@link LocalDateTime}
 \* @param formatter 日期格式化器,预定义的格式见:{@link DateTimeFormatter}
 \* @return 格式化后的字符串
 \*/
	public static String format(LocalDateTime time, DateTimeFormatter formatter) {
		return TemporalAccessorUtil.format(time, formatter);
	}

请看上面的源码分析。

方法明细-format(java.time.LocalDateTime, java.lang.String)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.format(java.time.LocalDateTime, java.lang.String)

方法描述

格式化日期时间为指定格式

支持版本及以上

参数描述:

参数名描述
LocalDateTime time
time {@link LocalDateTime}
String format
format 日期格式,类似于yyyy-MM-dd HH:mm:ss,SSS

返回值:

格式化后的字符串

参考案例:

		final LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56");
		String format = LocalDateTimeUtil.format(localDateTime, DatePattern.NORM_DATETIME_PATTERN);
		Assert.assertEquals("2020-01-23 12:23:56", format);

源码解析:

	public static String format(LocalDateTime time, String format) {
		if (null == time) {
			return null;
		}
		return format(time, DateTimeFormatter.ofPattern(format));
	}

DateTimeFormatter.ofPattern(format) 执行完会返回DateTimeFormatter

然后会调用 format(time, DateTimeFormatter 方法

请看上面的源码分析。

方法明细-formatNormal(java.time.LocalDate)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.formatNormal(java.time.LocalDate)

方法描述

格式化日期时间为yyyy-MM-dd格式

支持版本及以上

5.3.11

参数描述:

参数名描述
LocalDate date
date {@link LocalDate}

返回值:

格式化后的字符串

参考案例:

		final LocalDate date = LocalDate.parse("2020-01-23");
		String format = LocalDateTimeUtil.format(date, DatePattern.NORM_DATE_PATTERN);
		Assert.assertEquals("2020-01-23", format);

		format = LocalDateTimeUtil.formatNormal(date);
		Assert.assertEquals("2020-01-23", format);

源码解析:

public static String formatNormal(LocalDate date) {
		return format(date, DatePattern.NORM_DATE_FORMATTER);
	}

请看上面的源码分析。

方法明细-format(java.time.LocalDate, java.time.format.DateTimeFormatter)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.format(java.time.LocalDate, java.time.format.DateTimeFormatter)

方法描述

格式化日期时间为指定格式

支持版本及以上

5.3.10

参数描述:

参数名描述
LocalDate date
date {@link LocalDate}
DateTimeFormatter formatter
formatter 日期格式化器,预定义的格式见:{@link DateTimeFormatter}

返回值:

格式化后的字符串

参考案例:

		final LocalDate date = LocalDate.parse("2021-05-22");
		String format = LocalDateTimeUtil.format(date, DateTimeFormatter.ISO_DATE);
		Assert.assertEquals("2021-05-22", format);

源码解析:

	public static String format(LocalDate date, DateTimeFormatter formatter) {
		return TemporalAccessorUtil.format(date, formatter);
	}

请看上面的源码分析。

方法明细-format(java.time.LocalDate, java.lang.String)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.format(java.time.LocalDate, java.lang.String)

方法描述

格式化日期时间为指定格式

支持版本及以上

5.3.10

参数描述:

参数名描述
LocalDate date
date {@link LocalDate}
String format
format 日期格式,类似于yyyy-MM-dd

返回值:

格式化后的字符串

参考案例:

		final LocalDate date = LocalDate.parse("2020-01-23");
		String format = LocalDateTimeUtil.format(date, DatePattern.NORM_DATE_PATTERN);
		Assert.assertEquals("2020-01-23", format);


源码解析:

	public static String format(LocalDate date, String format) {
		if (null == date) {
			return null;
		}
		return format(date, DateTimeFormatter.ofPattern(format));
	}

请看上面的源码分析。

方法明细-offset(java.time.LocalDateTime, long, java.time.temporal.TemporalUnit)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.offset(java.time.LocalDateTime, long, java.time.temporal.TemporalUnit)

方法描述

日期偏移,根据field不同加不同值(偏移会修改传入的对象)

支持版本及以上

参数描述:

参数名描述
LocalDateTime time
time {@link LocalDateTime}
long number
number 偏移量,正数为向后偏移,负数为向前偏移
TemporalUnit field
field 偏移单位,见{@link ChronoUnit},不能为null

返回值:

偏移后的日期时间

参考案例:

		final LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56");
		LocalDateTime offset = LocalDateTimeUtil.offset(localDateTime, 1, ChronoUnit.DAYS);
		// 非同一对象
		Assert.assertNotSame(localDateTime, offset);

		Assert.assertEquals("2020-01-24T12:23:56", offset.toString());

源码解析:

	/\*\*
 \* 日期偏移,根据field不同加不同值(偏移会修改传入的对象)
 \*
 \* @param time {@link LocalDateTime}
 \* @param number 偏移量,正数为向后偏移,负数为向前偏移
 \* @param field 偏移单位,见{@link ChronoUnit},不能为null
 \* @return 偏移后的日期时间
 \*/
	public static LocalDateTime offset(LocalDateTime time, long number, TemporalUnit field) {
		if (null == time) {
			return null;
		}

		return time.plus(number, field);
	}


time.plus(number, field) 是jdk8提供的方法

	LocalDateTime localDateTime = LocalDateTime.of(2021, 8, 30, 23, 14, 20);
	LocalDateTime offset = localDateTime.plus(1, ChronoUnit.DAYS);
	// 非同一对象
	Assert.assertNotSame(localDateTime, offset);
	System.out.println(offset);

image-20210831233938785

方法明细-between(java.time.LocalDateTime, java.time.LocalDateTime)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.between(java.time.LocalDateTime, java.time.LocalDateTime)

方法描述

获取两个日期的差,如果结束时间早于开始时间,获取结果为负。

返回结果为{@link Duration}对象,通过调用toXXX方法返回相差单位 ## 支持版本及以上

参数描述:

参数名描述
LocalDateTime startTimeInclude
startTimeInclude 开始时间(包含)
LocalDateTime endTimeExclude
endTimeExclude 结束时间(不包含)

返回值:

时间差 {@link Duration}对象

参考案例:

		final Duration between = LocalDateTimeUtil.between(
				LocalDateTimeUtil.parse("2019-02-02T00:00:00"),
				LocalDateTimeUtil.parse("2020-02-02T00:00:00"));
		Assert.assertEquals(365, between.toDays());

源码解析:

	public static Duration between(LocalDateTime startTimeInclude, LocalDateTime endTimeExclude) {
		return TemporalUtil.between(startTimeInclude, endTimeExclude);
	}

其中TemporalUtil 是hutool封装的工具类,源码如下:

/\*\*
 \* 获取两个日期的差,如果结束时间早于开始时间,获取结果为负。
 \* <p>
 \* 返回结果为{@link Duration}对象,通过调用toXXX方法返回相差单位
 \*
 \* @param startTimeInclude 开始时间(包含)
 \* @param endTimeExclude 结束时间(不包含)
 \* @return 时间差 {@link Duration}对象
 \*/
public static Duration between(Temporal startTimeInclude, Temporal endTimeExclude) {
   return Duration.between(startTimeInclude, endTimeExclude);
}

Duration 适合处理较短的时间,需要更高的精确性。我们能使用between()方法比较两个瞬间的差。

Duration.between 是JDK8提供的方法。

方法明细-between(java.time.LocalDateTime, java.time.LocalDateTime, java.time.temporal.ChronoUnit)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.between(java.time.LocalDateTime, java.time.LocalDateTime, java.time.temporal.ChronoUnit)

方法描述

获取两个日期的差,如果结束时间早于开始时间,获取结果为负。

返回结果为时间差的long值

支持版本及以上

5.4.5

参数描述:

参数名描述
LocalDateTime startTimeInclude
startTimeInclude 开始时间(包括)
LocalDateTime endTimeExclude
endTimeExclude 结束时间(不包括)
ChronoUnit unit
unit 时间差单位

返回值:

时间差

参考案例:

		final long betweenWeek = DateUtil.betweenWeek(
				DateUtil.parse("2020-11-21"),
				DateUtil.parse("2020-11-23"), false);

		final long betweenWeek2 = LocalDateTimeUtil.between(
				LocalDateTimeUtil.parse("2020-11-21", "yyy-MM-dd"),
				LocalDateTimeUtil.parse("2020-11-23", "yyy-MM-dd"),
				ChronoUnit.WEEKS);
		Assert.assertEquals(betweenWeek, betweenWeek2);

源码解析:

public static long between(LocalDateTime startTimeInclude, LocalDateTime endTimeExclude, ChronoUnit unit) {
		return TemporalUtil.between(startTimeInclude, endTimeExclude, unit);
	}

多了一个时间单位的选项

public static long between(Temporal startTimeInclude, Temporal endTimeExclude, ChronoUnit unit) {
   return unit.between(startTimeInclude, endTimeExclude);
}

这个返回的数据为0

image-20210919181335622

这个返回的数据为1

image-20210919181709928

这两个demo的数据,反应出了结果是按时间差单位来产生的。

方法明细-betweenPeriod(java.time.LocalDate, java.time.LocalDate)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.betweenPeriod(java.time.LocalDate, java.time.LocalDate)

方法描述

获取两个日期的表象时间差,如果结束时间早于开始时间,获取结果为负。

比如2011年2月1日,和2021年8月11日,日相差了10天,月相差6月

支持版本及以上

5.4.5

参数描述:

参数名描述
LocalDate startTimeInclude
startTimeInclude 开始时间(包括)
LocalDate endTimeExclude
endTimeExclude 结束时间(不包括)

返回值:

时间差

参考案例:

		final LocalDate localDate1= LocalDate.parse("2021-05-22");
		final LocalDate localDate2= LocalDate.parse("2021-06-23");

		Period period = LocalDateTimeUtil.betweenPeriod(localDate1,localDate2);
		Assert.assertEquals(1, period.getMonths());
		Assert.assertEquals(1, period.getDays());

		period = LocalDateTimeUtil.betweenPeriod(localDate2,localDate1);
		Assert.assertEquals(-1, period.getMonths());
		Assert.assertEquals(-1, period.getDays());
		final LocalDate localDate3= LocalDate.parse("2021-06-22");
		period = LocalDateTimeUtil.betweenPeriod(localDate1,localDate3);
		Assert.assertEquals(1, period.getMonths());
		Assert.assertEquals(0, period.getDays());

源码解析:

public static Period betweenPeriod(LocalDate startTimeInclude, LocalDate endTimeExclude) {
		return Period.between(startTimeInclude, endTimeExclude);
	}

Period.between 是JDK8提供的方法

Period 是ChronoPeriod 的实现类,类里包含两个变量years ,months 和 days ,所以Period 是由年,月和日组成的时间量。

	LocalDate first = LocalDate.of(2021, 8, 29);
	LocalDate second = LocalDate.of(2022, 9, 30);
	Period period = Period.between(first, second);
	System.out.println(period);

image-20210830224610563

方法明细-beginOfDay(java.time.LocalDateTime)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.beginOfDay(java.time.LocalDateTime)

方法描述

修改为一天的开始时间,例如:2020-02-02 00:00:00,000

支持版本及以上

参数描述:

参数名描述
LocalDateTime time
time 日期时间

返回值:

一天的开始时间

参考案例:

		final LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56");
		final LocalDateTime beginOfDay = LocalDateTimeUtil.beginOfDay(localDateTime);
		Assert.assertEquals("2020-01-23T00:00", beginOfDay.toString());

源码解析:

/\*\*
 \* 修改为一天的开始时间,例如:2020-02-02 00:00:00,000
 \*
 \* @param time 日期时间
 \* @return 一天的开始时间
 \*/
	public static LocalDateTime beginOfDay(LocalDateTime time) {
		return time.with(LocalTime.MIN);
	}

LocalDateTime.with 是jdk8提供的方法。

日期时间的加减法及修改
	LocalDateTime currentTime = LocalDateTime.now(); // 当前日期和时间
	System.out.println("------------------时间的加减法及修改-----------------------");
	//3.LocalDateTime的加减法包含了LocalDate和LocalTime的所有加减,上面说过,这里就只做简单介绍
	System.out.println("3.当前时间:" + currentTime);
	System.out.println("3.当前时间加5年:" + currentTime.plusYears(5));
	System.out.println("3.当前时间加2个月:" + currentTime.plusMonths(2));
	System.out.println("3.当前时间减2天:" + currentTime.minusDays(2));
	System.out.println("3.当前时间减5个小时:" + currentTime.minusHours(5));
	System.out.println("3.当前时间加5分钟:" + currentTime.plusMinutes(5));
	System.out.println("3.当前时间加20秒:" + currentTime.plusSeconds(20));
	//还可以灵活运用比如:向后加一年,向前减一天,向后加2个小时,向前减5分钟,可以进行连写
	System.out.println("3.同时修改(向后加一年,向前减一天,向后加2个小时,向前减5分钟):" + currentTime.plusYears(1).minusDays(1).plusHours(2).minusMinutes(5));
	System.out.println("3.修改年为2025年:" + currentTime.withYear(2025));
	System.out.println("3.修改月为12月:" + currentTime.withMonth(12));
	System.out.println("3.修改日为27日:" + currentTime.withDayOfMonth(27));
	System.out.println("3.修改小时为12:" + currentTime.withHour(12));
	System.out.println("3.修改分钟为12:" + currentTime.withMinute(12));
	System.out.println("3.修改秒为12:" + currentTime.withSecond(12));

image-20210714941902

方法明细-endOfDay(java.time.LocalDateTime)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.endOfDay(java.time.LocalDateTime)

方法描述

修改为一天的结束时间,例如:2020-02-02 23:59:59,999

支持版本及以上

参数描述:

参数名描述
LocalDateTime time
time 日期时间

返回值:

一天的结束时间

参考案例:

		final LocalDateTime localDateTime = LocalDateTimeUtil.parse("2020-01-23T12:23:56");
		final LocalDateTime endOfDay = LocalDateTimeUtil.endOfDay(localDateTime);
		Assert.assertEquals("2020-01-23T23:59:59.999999999", endOfDay.toString());

源码解析:

	/\*\*
 \* 修改为一天的结束时间,例如:2020-02-02 23:59:59,999
 \*
 \* @param time 日期时间
 \* @return 一天的结束时间
 \*/
	public static LocalDateTime endOfDay(LocalDateTime time) {
		return time.with(LocalTime.MAX);
	}


请看上面的源码分析。

方法明细-toEpochMilli(java.time.temporal.TemporalAccessor)

方法名称:cn.hutool.core.date.LocalDateTimeUtil.toEpochMilli(java.time.temporal.TemporalAccessor)

方法描述

{@link TemporalAccessor}转换为 时间戳(从1970-01-01T00:00:00Z开始的毫秒数)

支持版本及以上

5.4.1

参数描述:

参数名描述
TemporalAccessor temporalAccessor
temporalAccessor Date对象

返回值:

{@link Instant}对象

参考案例:

学习路线:

这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:
在这里插入图片描述

Java8-日期转换工具类 package com.xkzhangsan.time.converter; import java.math.BigDecimal; import java.math.RoundingMode; import java.sql.Timestamp; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.ti. 阅读详情

相关推荐

保姆级教程:用Docker Compose在Linux上一键部署Milvus 2.5.8(附配置文件详解)

本文提供了一份详细的Milvus 2.5.8安装指南,通过Docker Compose在Linux系统上一键部署这款高性能向量数据库。教程涵盖环境准备、配置文件解析、服务启动验证及常见问题解决,帮助开发者快速搭建AI应用所需的基础设施。

weixin_28829629的博客 269

Java中的常用类(二)

Java中的常用类一、JDK8中新日期时间API1、背景2、LocalDate、LocalTime、LocalDateTime3、 瞬时:Instant3、格式化与解析日期或时间4、其他API4、与传统日期处理的转换二、Java比较器1、方式一:自然排序:java.lang.Comparable1、方式二:定制排序:java.util.Comparator三、System类四、 Math类五、 B...

仰望与追逐的博客 1107

SPARTAN6 + Verilog - FPGA step by step 从0开始学习(1)

SPARTAN6 + Verilog - FPGA step by step 从0开始学习(1)Step 1 软件安装Step 2 硬件获取Step 3 开始从头到脚建一个工程Step 3.1 新建一个工程 从0开始学习FPGA,最好的办法就是先建一个最简单的模块,并且跑起来,然后再慢慢展开。下面这个例子是要按照一定的周期点亮核心板上的一个led。 Step 1 软件安装 这个从0开始学习是用的xilinx的SPARTAN6。SPARTAN6集成开发环境用ISE,不能用Vivado,各自对应的版本不同。安装

xfacexx点点记录 5512

java基础笔记

java基础的常用方法总结。

滨海之君的博客 761

samba源码编译安装(版本4.13.0)

这里写目录标题前言编译安装samba下载三个包安装依赖共需要安装samba、gnutls、nettle1、进入解压后的samba目录执行:2、进入解压后的gnutls目录执行3、进入解压后的nettle目录执行3.1 卸载已存在nettle3.2 编译3.3 make3.4 安装4、进入gnutls继续编译4.1 编译4.2 make4.3 安装5、再次进入解压后的samba目录5.1 执行./configure5.2 make5.3 samba安装启动samba 前言 一般来说,安装samba最快的方式应

灵葱的博客 1万+

从ARCore到AICore:揭秘Google如何通过系统级服务推动Android生态创新

本文深入探讨了Google如何通过AICore等系统级服务推动Android生态创新。从ARCore到AICore,Google通过分层解耦策略将AI能力下沉至系统层,实现端侧大模型推理,如Gemini Nano在Pixel 8 Pro中的应用。文章剖析了AICore的技术架构、开发者赋能路径及场景化实践,展示了其在通信、内容创作和生产力工具中的卓越表现。

rust6ferris的博客 545

时间工具类-- LocalDateTimeUtil详解

具体的使用方法都在图中说明,主要是方便LocalDataTime的使用及操作。

世上哪有什么岁月静好,不过是有人替你负重前行 1787

倍福Beckhoff运动控制功能块实战解析:从MC_ReadActualPosition到MC_GearInVelo

本文深入解析倍福(Beckhoff)TwinCAT运动控制功能块,从基础的MC_ReadActualPosition、MC_Power等轴状态读取与使能操作,到MC_MoveAbsolute、MC_MoveRelative等单轴定位指令,并重点剖析了用于动态速度同步的核心功能块MC_GearInVelo在飞锯等场景的应用。文章结合实战经验,详细介绍了齿轮耦合、电子凸轮(MC_CamIn)等高级同步功能的参数配置、调试技巧及常见问题,旨在帮助工程师快速掌握倍福运动控制工具箱,实现复杂的同步工艺。

transformer2023的博客 981

高级JAVA开发必备技能:java8 新日期时间API((五)JSR-310:实战+源码分析)(JAVA 小虚竹)

❤️高级JAVA开发必备技能❤️java8 新日期时间API((五)JSR-310:实战+源码分析),5万字详解(JAVA java 小虚竹)

小虚竹的专栏 9620

Python多进程实战:用BaoStock高效下载股票历史数据的5个优化技巧

本文详细介绍了使用Python多进程技术通过BaoStock高效下载股票历史数据的5个优化技巧。从理解BaoStock的数据获取机制到进程池配置、智能任务分片、异常处理及性能监控,帮助开发者显著提升数据下载效率,特别适合量化交易领域的数据采集需求。

weixin_30369041的博客 456

Loop Engineering 来了:从写 Prompt 到设计 Loop,AI 编程的第四次范式跃迁

文章摘要: Loop Engineering是AI编程领域的新范式,标志着从"人手动喂指令"到"设计自驱动循环"的跃迁。其核心在于通过五个组件(定时器、工作空间、知识体系、连接器和子Agent验证)构建自动化任务流,使AI系统能自主运行。这一概念的火爆源于模型能力和工具链的成熟,使得任务设计成为关键瓶颈。作者指出,从Prompt到Loop的四次范式跃迁(语言学→信息科学→控制论→管理学)反映了人机协作关系的根本变化:人类角色从执行者逐渐退居为目标设定者。落地Loop Engineering的真正挑战在于目标

少说,多做 330

高级JAVA开发必备技能:java8 新日期时间API((五)JSR-310:实战+源码分析)(JAVA 小虚竹(1)

解析日期时间字符串为{@link LocalDateTime},仅支持yyyy-MM-dd’T’HH:mm:ss格式,例如:2007-12-03T10:15:30。解析日期时间字符串为{@link LocalDate},仅支持yyyy-MM-dd’T’HH:mm:ss格式,例如:2007-12-03T10:15:30。{@link TemporalAccessor}转{@link LocalDateTime},使用默认时区。{@link Instant}转{@link LocalDateTime}

2401_84239625的博客 1229

CKS-CN考试之路----04

根据上面信息我们知道,这个pod运行在default命名空间下,pod名字为cpu-77cd5ddcbf-bvb8w。可以从/etc/falco/falco_rules.yaml中获得相关内容,大概在文件的460行左右.编辑/etc/falco/falco_rules.local.yaml。7c688a8bfd69即是我们想要获得的docker id。将行为不当 Pod 的 Deployment 缩放为零副本。根据我们刚才定义的rule生成报告。访问/dev/mem 的 Pod。那么如果考试记不住怎么办?

Q先生 602

高级JAVA开发必备技能:java8 新日期时间API((五)JSR-310:实战+源码分析)(3)

*** 毫秒转{@link LocalDateTime},根据时区不同,结果会产生时间偏移* @param epochMilli 从1970-01-01T00:00:00Z开始计数的毫秒数* @param zoneId 时区*//***/

2401_84141304的博客 102

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

高级JAVA开发必备技能:java8 新日期时间API((五)JSR-310:实战+源码分析)(4)

解析日期时间字符串为{@link LocalDateTime},仅支持yyyy-MM-dd’T’HH:mm:ss格式,例如:2007-12-03T10:15:30。* 解析日期时间字符串为{@link LocalDate},仅支持yyyy-MM-dd’T’HH:mm:ss格式,例如:2007-12-03T10:15:30。* @param formatter 日期格式化器,预定义的格式见:{@link DateTimeFormatter}* 格式化日期时间为yyyy-MM-dd HH:mm:ss格式。

2401_84141304的博客 100

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

高级JAVA开发必备技能:java8 新日期时间API((五)JSR-310:实战+源码分析)(1)

还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!【完整版领取方式在文末!!内容实在太多,不一一截图了。

2401_84545908的博客 336

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

高级JAVA开发必备技能:java8 新日期时间API((三)JSR-310:格式化和解析)(JAVA 小虚竹)

❤️高级JAVA开发必备技能❤️java8 新日期时间API((三)JSR-310:格式化和解析)(JAVA java 小虚竹)

小虚竹的专栏 3万+

十五万字《JDK源码分析》之《JSR-310(java8 新日期时间API)》总结(JAVA 小虚竹,建议收藏)

❤️十五万字《JDK源码分析》之《JSR-310(java8 新日期时间API)》总结❤️(JAVA java 小虚竹)

小虚竹的专栏 1万+

十五万字《JDK源码分析》之《JSR-310(java8 新日期时间API)

方法描述当前时间,默认时区{@link Instant}转{@link LocalDateTime},使用默认时区{@link Instant}转{@link LocalDateTime},使用UTC时区{@link ZonedDateTime}转{@link LocalDateTime}{@link Instant}转{@link LocalDateTime}{@link Instant}转{@link LocalDateTime}毫秒转{@link LocalDateTime},使用默认时区。

2401_83973995的博客 1209

4hutool实战:DateUtil-格式化时间

hutool实战:把日期按照不同的需求格式化成对应的日期字符串 关键字:java java JAVA hutool hutool Hutool 工具类 工具类 工具类 DateUtil DateUtil DateUtil

小虚竹的专栏 12万+

十五万字《JDK源码分析》之《JSR-310(java8 新日期时间API)(1)

方法描述当前时间,默认时区{@link Instant}转{@link LocalDateTime},使用默认时区{@link Instant}转{@link LocalDateTime},使用UTC时区{@link ZonedDateTime}转{@link LocalDateTime}{@link Instant}转{@link LocalDateTime}{@link Instant}转{@link LocalDateTime}毫秒转{@link LocalDateTime},使用默认时区。

2401_83973995的博客 994

高级JAVA开发必备技能:java8 新日期时间API((一)JSR-310:ZoneId 时区和偏移量)(JAVA 小虚竹

​ 提供的TZUpdater 工具允许您使用更新的时区数据更新已安装的 Java 开发工具包 (JDK) 和 Java 运行时环境 (JRE) 软件,以适应不同国家/地区的夏令时 (DST) 更改。Oracle 依赖于通过 IANA 的时区数据库公开提供的时区数据。如果您无法使用 Oracle 最新的 JDK 或 JRE 更新版本,或者如果最新版本上的时区数据不是最新可用的,TZUpdater 工具提供了一种更新时区数据的方法,同时保持其他系统配置和依赖项不变.

2401_84264244的博客 1605

java8新特性之---全新的日期、时间API(JSR 310规范),附SpringMVC、Mybatis中使用JSR310的正确姿势

相关阅读 【小家java】java5新特性(简述十大新特性) 重要一跃 【小家java】java6新特性(简述十大新特性) 鸡肋升级 【小家java】java7新特性(简述八大新特性) 不温不火 【小家java】java8新特性(简述十大新特性) 饱受赞誉 【小家java】java9新特性(简述十大新特性) ...

王笋的专栏 1226
上一篇: XSS漏洞类型原理及防御方式_三种xss漏洞防御
普通网友
博客等级 码龄2年 33粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值