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

总结

就写到这了,也算是给这段时间的面试做一个总结,查漏补缺,祝自己好运吧,也希望正在求职或者打算跳槽的 程序员看到这个文章能有一点点帮助或收获,我就心满意足了。多思考,多问为什么。希望小伙伴们早点收到满意的offer! 越努力越幸运!

金九银十已经过了,就目前国内的面试模式来讲,在面试前积极的准备面试,复习整个 Java 知识体系将变得非常重要,可以很负责任的说一句,复习准备的是否充分,将直接影响你入职的成功率。但很多小伙伴却苦于没有合适的资料来回顾整个 Java 知识体系,或者有的小伙伴可能都不知道该从哪里开始复习。我偶然得到一份整理的资料,不论是从整个 Java 知识体系,还是从面试的角度来看,都是一份含技术量很高的资料。

三面蚂蚁核心金融部,Java开发岗(缓存+一致性哈希+分布式)

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

然后调用**formatTo(temporal, buf)**方法

public void formatTo(TemporalAccessor temporal, Appendable appendable) {

Objects.requireNonNull(temporal, “temporal”);

Objects.requireNonNull(appendable, “appendable”);

try {

DateTimePrintContext context = new DateTimePrintContext(temporal, this);

if (appendable instanceof StringBuilder) {

printerParser.format(context, (StringBuilder) appendable);

} else {

// buffer output to avoid writing to appendable in case of error

StringBuilder buf = new StringBuilder(32);

printerParser.format(context, buf);

appendable.append(buf);

}

} catch (IOException ex) {

throw new DateTimeException(ex.getMessage(), ex);

}

}

**formatTo(temporal, buf)**方法也是先判断两个入参空处理。

然后,Instant对象被封装在一个新new的DateTimePrintContext对象

运行demo有问题,进行排查

//根据特定格式格式化日期

DateTimeFormatter dtf = DateTimeFormatter.ofPattern(“yyyy-MM-dd”);

String dateStr = DateUtil.format(new Date(),dtf);

System.out.println(dateStr);

image-20210725195348793

到这里已经是jdk的源码了DateTimeFormatter.format

image-20210725195424950

image-20210725195522610

image-20210725195636339

从上面可知,会调用 NumberPrinterParser.format() NumberPrinterParser是在DateTimeFormatterBuilder类中的。

image-20210725195947802

到这一步会报错

image-20210725200153850

为什么会报错呢,我们来看下context.getValue(field)发生了什么:

image-20210725200349650

从上面代码可行,temporal实际上是Instant对象,Instant.getLong只支持四种字段类型。。

NANO_OF_SECOND

MICRO_OF_SECOND

MILLI_OF_SECOND

INSTANT_SECONDS

image-20210725200551164

如果不是上面这几种字段类型,则抛出异常

DateUtil.format当遇到DateTimeFormatter会将Date对象首先转换为Instant,因为缺少时区,导致报错。

解决方案:

/**

  • 根据特定格式格式化日期

  • @param date 被格式化的日期

  • @param format

  • @return 格式化后的字符串

  • @since 5.0.0

*/

public static String format(Date date, DateTimeFormatter format) {

if (null == format || null == date) {

return null;

}

Instant instant = date.toInstant();

ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());

LocalDateTime localDateTime = zonedDateTime.toLocalDateTime();

return format.format(localDateTime);

}

先把date类型转化为LocalDateTime类型,然后再进行DateTimeFormatter.format(LocalDateTime)的格式化

测试demo

//根据特定格式格式化日期

String str = “2021-07-25 20:11:25”;

DateTimeFormatter dtf = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:dd”);

Date date = DateUtil.parse(str);

String dateStr = DateUtil.format(date,dtf);

System.out.println(dateStr);

Assert.assertEquals(str, dateStr);

image-20210725201444728

DateTimeFormatterBuilder

============================================================================================

DateTimeFormatterBuilder类说明


DateTimeFormatter 的所有格式化器都是用DateTimeFormatterBuilder 建造器类创建的。

看下面两个ofPattern 源码:

//DateTimeFormatter

public static DateTimeFormatter ofPattern(String pattern) {

return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter();

}

public static DateTimeFormatter ofPattern(String pattern, Locale locale) {

return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(locale);

}

解析风格配置


官方提供了四种解析风格的配置,如下枚举 SettingsParser

static enum SettingsParser implements DateTimePrinterParser {

// 大小写敏感

SENSITIVE,

// 大小写不敏感

INSENSITIVE,

//严格

STRICT,

//宽松

LENIENT;

}

对应DateTimeFormatterBuilder 类中的方法:

// 大小写敏感

public DateTimeFormatterBuilder parseCaseSensitive()

// 大小写不敏感

public DateTimeFormatterBuilder parseCaseInsensitive()

// 严格

public DateTimeFormatterBuilder parseStrict()

// 宽松

public DateTimeFormatterBuilder parseLenient()

这四个方法对应的源码如下:

// 大小写敏感

public DateTimeFormatterBuilder parseCaseSensitive() {

appendInternal(SettingsParser.SENSITIVE);

return this;

}

// 大小写不敏感

public DateTimeFormatterBuilder parseCaseInsensitive() {

appendInternal(SettingsParser.INSENSITIVE);

return this;

}

// 严格

public DateTimeFormatterBuilder parseStrict() {

appendInternal(SettingsParser.STRICT);

return this;

}

// 宽松

public DateTimeFormatterBuilder parseLenient() {

appendInternal(SettingsParser.LENIENT);

return this;

}

可以看出,都是调用appendInternal 方法。

接着往下看 appendInternal 源码:

private int appendInternal(DateTimePrinterParser pp) {

Objects.requireNonNull(pp, “pp”);

if (active.padNextWidth > 0) {

if (pp != null) {

pp = new PadPrinterParserDecorator(pp, active.padNextWidth, active.padNextChar);

}

active.padNextWidth = 0;

active.padNextChar = 0;

}

active.printerParsers.add(pp);

active.valueParserIndex = -1;

return active.printerParsers.size() - 1;

}

其中active 是一个DateTimeFormatterBuilder 实例,且这个DateTimeFormatterBuilder 实例内部有一个列表 List< DateTimePrinterParser > ,看了源码可知,真正做解析工作的是DateTimePrinterParser 对应的实例来做的。

DateTimePrinterParser 的源码:

interface DateTimePrinterParser {

boolean format(DateTimePrintContext context, StringBuilder buf);

int parse(DateTimeParseContext context, CharSequence text, int position);

}

源码有一共有16个DateTimePrinterParser 的实例。

//1.Composite printer and parser.

static final class CompositePrinterParser implements DateTimePrinterParser {…}

//2.Pads the output to a fixed width.

static final class PadPrinterParserDecorator implements DateTimePrinterParser {…}

//3.Enumeration to apply simple parse settings.

static enum SettingsParser implements DateTimePrinterParser{…}

//4. Defaults a value into the parse if not currently present.

static class DefaultValueParser implements DateTimePrinterParser {…}

//5.Prints or parses a character literal.

static final class CharLiteralPrinterParser implements DateTimePrinterParser {…}

//6.Prints or parses a string literal.

static final class StringLiteralPrinterParser implements DateTimePrinterParser {…}

//7.Prints and parses a numeric date-time field with optional padding.

static class NumberPrinterParser implements DateTimePrinterParser {…}

//8.Prints and parses a numeric date-time field with optional padding.

static final class FractionPrinterParser implements DateTimePrinterParser {…}

//9.Prints or parses field text.

static final class TextPrinterParser implements DateTimePrinterParser {…}

//10.Prints or parses an ISO-8601 instant.

static final class InstantPrinterParser implements DateTimePrinterParser {…}

//11.Prints or parses an offset ID.

static final class OffsetIdPrinterParser implements DateTimePrinterParser {…}

//12.Prints or parses an offset ID.

static final class LocalizedOffsetIdPrinterParser implements DateTimePrinterParser {…}

//13.Prints or parses a zone ID.

static class ZoneIdPrinterParser implements DateTimePrinterParser {…}

//14. Prints or parses a chronology.

static final class ChronoPrinterParser implements DateTimePrinterParser {…}

//15.Prints or parses a localized pattern.

static final class LocalizedPrinterParser implements DateTimePrinterParser {…}

//16.Prints or parses a localized pattern from a localized field.

static final class WeekBasedFieldPrinterParser implements DateTimePrinterParser {…}

推荐相关文章

==========================================================================

hutool日期时间系列文章


1DateUtil(时间工具类)-当前时间和当前时间戳

2DateUtil(时间工具类)-常用的时间类型Date,DateTime,Calendar和TemporalAccessor(LocalDateTime)转换

3DateUtil(时间工具类)-获取日期的各种内容

4DateUtil(时间工具类)-格式化时间

5DateUtil(时间工具类)-解析被格式化的时间

6DateUtil(时间工具类)-时间偏移量获取

7DateUtil(时间工具类)-日期计算

8ChineseDate(农历日期工具类)

9LocalDateTimeUtil(JDK8+中的{@link LocalDateTime} 工具类封装)

10TemporalAccessorUtil{@link TemporalAccessor} 工具类封装

其他


要探索JDK的核心底层源码,那必须掌握native用法

万字博文教你搞懂java源码的日期和时间相关用法

最后

这份《“java高分面试指南”-25分类227页1000+题50w+字解析》同样可分享给有需要的朋友,感兴趣的伙伴们可挑战一下自我,在不看答案解析的情况,测试测试自己的解题水平,这样也能达到事半功倍的效果!(好东西要大家一起看才香)

image

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

oralAccessorUtil{@link TemporalAccessor} 工具类封装]( )

其他


要探索JDK的核心底层源码,那必须掌握native用法

万字博文教你搞懂java源码的日期和时间相关用法

最后

这份《“java高分面试指南”-25分类227页1000+题50w+字解析》同样可分享给有需要的朋友,感兴趣的伙伴们可挑战一下自我,在不看答案解析的情况,测试测试自己的解题水平,这样也能达到事半功倍的效果!(好东西要大家一起看才香)

[外链图片转存中…(img-r3jEO0c2-1715721149134)]

[外链图片转存中…(img-cb771CXn-1715721149135)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值