阿里规定代码中禁用static修饰SimpleDateFormat,为何?

LocalDateTime、LocalDate、LocalTime与Date对比 Java8以前,我们一直长期使用Date和Calendar来处理时间,而在使用Date处理日期时间问题上会存在一定的隐患,产生线程不安全的问题,最典型的就是在一定负载并发量的情况下使用SimpleDateFormat引发的线程安全性问题。如今Java8提供了LocalDate、LocalTime、LocalDateTime三个日期时间类,在安全性和操作性上对比Date和Calendar非常可观,... 阅读详情

在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗?

通过阅读本篇文章你将了解到:

  • 为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】
  • java8新的时间API的使用方式,包括创建、格式化、解析、计算、修改

为什么需要LocalDate、LocalTime、LocalDateTime

1.Date如果不格式化,打印出的日期可读性差

Tue Sep 10 09:34:04 CST 2019

2.使用SimpleDateFormat对时间进行格式化,但SimpleDateFormat是线程不安全的SimpleDateFormat的format方法最终调用代码:

private StringBuffer format(Date date, StringBuffer toAppendTo,
                              FieldDelegate delegate) {
        // Convert input date to time field list
        calendar.setTime(date);

        boolean useDateFormatSymbols = useDateFormatSymbols();

        for (int i = 0; i < compiledPattern.length; ) {
            int tag = compiledPattern[i] >>> 8;
            int count = compiledPattern[i++] & 0xff;
            if (count == 255) {
                count = compiledPattern[i++] << 16;
                count |= compiledPattern[i++];
            }

            switch (tag) {
            case TAG_QUOTE_ASCII_CHAR:
                toAppendTo.append((char)count);
                break;

            case TAG_QUOTE_CHARS:
                toAppendTo.append(compiledPattern, i, count);
                i += count;
                break;

            default:
                subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);
                break;
            }
        }
        return toAppendTo;
    }

calendar是共享变量,并且这个共享变量没有做线程安全控制。当多个线程同时使用相同的SimpleDateFormat对象【如用static修饰的SimpleDateFormat】调用format方法时,多个线程会同时调用calendar.setTime方法,可能一个线程刚设置好time值另外的一个线程马上把设置的time值给修改了导致返回的格式化时间可能是错误的。

在多并发情况下使用SimpleDateFormat需格外注意SimpleDateFormat除了format是线程不安全以外,parse方法也是线程不安全的。parse方法实际调用alb.establish(calendar).getTime()方法来解析,alb.establish(calendar)方法里主要完成了:

  • 重置日期对象cal的属性值
  • 使用calb中中属性设置cal
  • 返回设置好的cal对象

但是这三步不是原子操作

多线程并发如何保证线程安全 - 避免线程之间共享一个SimpleDateFormat对象,每个线程使用时都创建一次SimpleDateFormat对象 => 创建和销毁对象的开销大 - 对使用format和parse方法的地方进行加锁 => 线程阻塞性能差 - 使用ThreadLocal保证每个线程最多只创建一次SimpleDateFormat对象 => 较好的方法

  • Date对时间处理比较麻烦,比如想获取某年、某月、某星期,以及n天以后的时间,如果用Date来处理的话真是太难了,你可能会说Date类不是有getYear、getMonth这些方法吗,获取年月日很Easy,但都被弃用了啊

Come On 一起使用java8全新的日期和时间API

LocalDate

只会获取年月日

  • 创建LocalDate
//获取当前年月日
LocalDate localDate = LocalDate.now();
//构造指定的年月日
LocalDate localDate1 = LocalDate.of(2019, 9, 10);
  • 获取年、月、日、星期几
int year = localDate.getYear();
int year1 = localDate.get(ChronoField.YEAR);
Month month = localDate.getMonth();
int month1 = localDate.get(ChronoField.MONTH_OF_YEAR);
int day = localDate.getDayOfMonth();
int day1 = localDate.get(ChronoField.DAY_OF_MONTH);
DayOfWeek dayOfWeek = localDate.getDayOfWeek();
int dayOfWeek1 = localDate.get(ChronoField.DAY_OF_WEEK);

LocalTime

只会获取几点几分几秒

  • 创建LocalTime
 LocalTime localTime = LocalTime.of(13, 51, 10);
 LocalTime localTime1 = LocalTime.now();
  • 获取时分秒
//获取小时
int hour = localTime.getHour();
int hour1 = localTime.get(ChronoField.HOUR_OF_DAY);
//获取分
int minute = localTime.getMinute();
int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR);
//获取秒
int second = localTime.getSecond();
int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);

LocalDateTime

获取年月日时分秒,等于LocalDate+LocalTime

  • 创建LocalDateTime
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime1 = LocalDateTime.of(2019, Month.SEPTEMBER, 10, 14, 46, 56);
LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime);
LocalDateTime localDateTime3 = localDate.atTime(localTime);
LocalDateTime localDateTime4 = localTime.atDate(localDate);
  • 获取LocalDate
 LocalDate localDate2 = localDateTime.toLocalDate();
  • 获取LocalTime
LocalTime localTime2 = localDateTime.toLocalTime();

Instant

获取秒数

  • 创建Instant对象
Instant instant = Instant.now();
  • 获取秒数
long currentSecond = instant.getEpochSecond();
  • 获取毫秒数
long currentMilli = instant.toEpochMilli();

个人觉得如果只是为了获取秒数或者毫秒数,使用System.currentTimeMillis()来得更为方便

修改LocalDate、LocalTime、LocalDateTime、Instant

LocalDate、LocalTime、LocalDateTime、Instant为不可变对象,修改这些对象对象会返回一个副本

  • 增加、减少年数、月数、天数等 以LocalDateTime为例
LocalDateTime localDateTime = LocalDateTime.of(2019, Month.SEPTEMBER, 10,
              14, 46, 56);
//增加一年
localDateTime = localDateTime.plusYears(1);
localDateTime = localDateTime.plus(1, ChronoUnit.YEARS);
//减少一个月
localDateTime = localDateTime.minusMonths(1);
localDateTime = localDateTime.minus(1, ChronoUnit.MONTHS);
  • 通过with修改某些值
//修改年为2019
localDateTime = localDateTime.withYear(2020);
//修改为2022
localDateTime = localDateTime.with(ChronoField.YEAR, 2022);
还可以修改月、日

时间计算

比如有些时候想知道这个月的最后一天是几号、下个周末是几号,通过提供的时间和日期API可以很快得到答案

LocalDate localDate = LocalDate.now();
LocalDate localDate1 = localDate.with(firstDayOfYear());

比如通过firstDayOfYear()返回了当前日期的第一天日期,还有很多方法这里不在举例说明

格式化时间

LocalDate localDate = LocalDate.of(2019, 9, 10);
String s1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE);
String s2 = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
//自定义格式化
DateTimeFormatter dateTimeFormatter =   DateTimeFormatter.ofPattern("dd/MM/yyyy");
String s3 = localDate.format(dateTimeFormatter);

DateTimeFormatter默认提供了多种格式化方式,如果默认提供的不能满足要求,可以通过DateTimeFormatter的ofPattern方法创建自定义格式化方式

解析时间

LocalDate localDate1 = LocalDate.parse("20190910", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate localDate2 = LocalDate.parse("2019-09-10", DateTimeFormatter.ISO_LOCAL_DATE);

和SimpleDateFormat相比,DateTimeFormatter是线程安全的

小结

LocalDateTime:Date有的我都有,Date没有的我也有,日期选择请Pick Me。

SpringBoot中应用LocalDateTime

1.将LocalDateTime字段以时间戳的方式返回给前端

添加日期转化类

public class LocalDateTimeConverter extends JsonSerializer<LocalDateTime> {

    @Override
    public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
    gen.writeNumber(value.toInstant(ZoneOffset.of("+8")).toEpochMilli());
    }
}

并在LocalDateTime字段上添加@JsonSerialize(using =
LocalDateTimeConverter.class)注解,如下:

@JsonSerialize(using = LocalDateTimeConverter.class)
protected LocalDateTime gmtModified;

2.将LocalDateTime字段以指定格式化日期的方式返回给前端

在LocalDateTime字段上添加@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")注解即可,如下:

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
protected LocalDateTime gmtModified;

3.对前端传入的日期进行格式化

在LocalDateTime字段上添加@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")注解即可,如下:

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
protected LocalDateTime gmtModified;
JAVA-LocalDateTime时间格式化,转换时间戳和源码分析(万字长文详解) 这篇文章主要介绍了JAVA8新增的LocalDateTime时间的格式化,和时间戳的互相转换。以及对应的源码分析,有这完整的源码调用链。源码的执行分析。逐行对源码进行了注释,方便大家看懂。万字长文带图带代码示例,一文带你彻底了解时间类型。看完本篇文章,你将获得源码技术++,源码阅读量++,JAVA水平++。对于JAVA源码的解析希望能给你帮助。并提升阅读源码的思维。 阅读详情

相关推荐

Java代码弱点与修复之——STCAL: Static use of type Calendar or DateFormat

避免静态使用 Calendar 和 DateFormat 类型可以提高程序的健壮性和可维护性,以及避免多线程环境下可能出现的错误。

oscar999的专栏 1364

JS获取当前时间戳的方法

JavaScript 获取当前时间戳:第一种方法:(这种方法只精确到秒) var timestamp = Date.parse(new Date()); 结果:1280977330000 第二种方法: var timestamp = (new Date()).valueOf(); 结果:1280977330748 第三种方法: var timestamp=new Date().getTime(); 结果:1280977330748 第一种:获取的时间戳是把毫秒改成000显示,因.

gonewithwind00的专栏 1661

STM32 HAL库定时器中断里读编码器速度准吗?聊聊MG310电机的测速与防溢出处理

本文探讨了STM32 HAL库在定时器中断中读取编码器速度的精度问题,特别针对MG310电机的测速与防溢出处理提供了解决方案。通过对比定时中断法和编码器模式的性能,揭示了硬件编码器接口在降低误差和CPU占用率方面的优势,并详细介绍了CubeMX配置技巧和防溢出处理的工程实践。

weixin_28720767的博客 401

LocalDateTime详解

java8新特性之LocalDateTime

xiaotu的博客 1万+

gcc/g++ 链接库的编译与链接

gcc/g++ 链接库的编译与链接 surgewong@gmail.com http://blog.youkuaiyun.com/surgewong       程序编译一般需要经预处理、编译、汇编和链接几个步骤。在实际应用中,有些公共代码需要反复使用,就把这些代码编译成为“库”文件。在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中,这种库称为静态(链接)库,其特点是可

Surge 4万+

统信UOS/麒麟Kylin OS下利用pyenv实现Python多版本开发环境搭建指南

本文详细介绍了在统信UOS和麒麟Kylin OS国产操作系统下使用pyenv搭建Python多版本开发环境的完整指南。从系统环境准备、pyenv定制安装到Python版本编译实战,提供了针对国产CPU架构的特殊优化方案和常见问题解决方法,帮助开发者高效管理不同Python版本需求。

sea99的博客 1054

simpledateformat格式_阿里规定代码中禁用static修饰SimpleDateFormat,为何?

作者:何田田在吗 来自:8rr.co/4KkS在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗?通过阅读本篇文章你将了解到:为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】java8新的时间API的使用方式,包括创建、格式化、解析、计算、修改为什么需要LocalDa...

weixin_39906130的博客 97

从仿真到打样:PMOS栅极泄放电路设计全流程复盘与三个踩坑点总结

本文详细复盘了PMOS栅极泄放电路从仿真到打样的全流程设计,重点总结了三个关键踩坑点:三极管BE结过压击穿、静态功耗超标和栅极振荡现象。通过优化缓启动电路、改进保护设计和布局调整,最终实现18ms开通时间、190μs关断时间和8μA静态功耗的工业级性能指标,为类似电源开关设计提供实用参考。

weixin_28693683的博客 371

为什么阿里规定代码中禁用static修饰 SimpleDateFormat?

点击“开发者技术前线”,选择“星标????”在看|星标|留言, 真爱作者:何甜甜在吗来源:https://juejin.im/post/5d7787625188252388753eae...

开发者技术前线-DevolperFront 391

《自然语言处理实战入门》文本分类 ---- 使用词向量与SVM 进行文本分类

文本分类用电脑对文本集(或其他实体或物件)按照一定的分类体系或标准进行自动分类标记。 它根据一个已经被标注的训练文档集合, 找到文档特征和文档类别之间的关系模型, 然后利用这种学习得到的关系模型对 新的文档进行类别判断 。文本分类从基于知识的方法逐渐转变为基于统计 和机器学习的方法。

shiter编写程序的艺术 2390

使用Mask2Former和X-Decoder训练自定义数据集及结果复现报告

本报告记录了使用MMDetection框架中的Mask2Former和X-Decoder模型在自定义数据集上的训练过程。报告包含环境配置、数据集准备、模型训练与优化(解决了Mask2Former的PQ值异常问题)、性能评估等关键环节。详细展示了从数据集转换(将客户提供的COCO格式数据适配MMDetection框架)、配置文件修改、到最终模型训练和评估的全流程。特别针对Mask2Former训练中的PQ值异常问题提供了解决方案,并对比了两种模型在自定义数据集上的表现。报告还包含完整的代码实现和技术细节。

huanghm88的专栏 1108

为啥阿里巴巴规定代码中禁用static修饰SimpleDateFormat?

在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗? 通过阅读本篇文章你将了解到: 为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】 java8新的时间API的使用方式,包括创建、格式化、解析、计算、修改 为什么需要LocalDate、LocalTime、LocalDateTime 1.Date如果不格式化,打印出的日期可读性差 Tue Sep 10 09:34:04 C.

weixin_47067712的博客 149

simpledateformat格式_为啥阿里巴巴规定代码中禁用static修饰SimpleDateFormat?

在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗?通过阅读本篇文章你将了解到:为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】java8新的时间API的使用方式,包括创建、格式化、解析、计算、修改为什么需要LocalDate、LocalTime、LocalDateT...

weixin_39797393的博客 58

YOLO小目标检测优化:9种实用方案,准确率直接提升15%

小目标检测是个系统工程,没有银弹,但有明确的优化路径。优先搞数据。Copy-Paste + 提升分辨率,这俩加起来成本最低、收益最大,能解决80%的小目标问题。别一上来就改模型结构。调参走在改结构前面。锚框聚类、损失加权、增强优化,这些都是零成本的,先做满了再说改模型的事。P2层是大杀器,但不要轻易用。加了P2层,TensorRT部署、后处理、速度都要跟着调,工程化工作量翻倍。数据和训练做到位还不够,再加也不迟。滑动窗口是兜底的。能从训练端解决的问题,就不要拖到推理端。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 195

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

为什么阿里巴巴规定代码中禁用static修饰SimpleDateFormat?

点击“开发者技术前线”,选择“星标????”在看|星标|留言, 真爱来自:8rr.co/4KkS在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用stat...

开发者技术前线-DevolperFront 249

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

simpledateformat_为什么阿里巴巴规定代码中禁用 static 修饰 SimpleDateFormat?

在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗?通过阅读本篇文章你将了解到:为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】java8新的时间API的使用方式,包括创建、格式化、解析、计算、修改为什么需要LocalDate、LocalTime、Local...

weixin_39539807的博客 69

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

为啥阿里巴巴规定代码中禁用 static 修饰 SimpleDateFormat?

点击上方“Java基基”,选择“设为星标”做积极的人,而不是积极废人!源码精品专栏原创 | Java 2020超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析...

weixin_44421461的博客 127

simpledateformat 毫秒_阿里巴巴为什么规定代码中禁用static修饰SimpleDateFormat?

在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗?通过阅读本篇文章你将了解到:为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】java8新的时间API的使用方式,包括创建、格式化、解析、计算、修改为什么需要LocalDate、LocalTime、LocalDateT...

weixin_39807352的博客 75

为什么阿里巴巴禁止static修饰SimpleDateFormat?

每天早晨,干货准时奉上!本文作者:何甜甜在吗来源:juejin.im/post/5d7787625188252388753eae在项目开发过程中经常遇到时间处理,但是你真的用对了吗?所以理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat真的很重要。《阿里巴巴Java开发手册》是这样规定的:通过阅读本篇文章你将了解到:1、为什么需要LocalDate、LocalTime、Lo...

Java学习之道 2307

simpledateformat 毫秒_为什么阿里巴巴规定代码中禁用static修饰SimpleDateFormat?

点击“开发者技术前线”,选择“星标?”在看|星标|留言, 真爱来自:8rr.co/4KkS在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗?通过阅读本篇文章你将了解到:为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】java8新的时间API的使用方式,包...

weixin_39563132的博客 82

broker可以禁用吗 time_为什么阿里巴巴规定代码中禁用 static 修饰 SimpleDateFormat?...

在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗?通过阅读本篇文章你将了解到:为什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的类】java8新的时间API的使用方式,包括创建、格式化、解析、计算、修改为什么需要LocalDate、LocalTime、Local...

weixin_36319281的博客 110

Java代码规范实战:从命名风格到工程架构的最佳实践

代码规范是软件开发中的基础工程实践,其核心价值在于建立团队协作的统一语言。从技术原理看,良好的命名规范(如大驼峰命名法)能提升代码可读性,合理的异常处理策略可降低系统I/O开销。在工程实践中,阿里巴巴的统计数据显示,约38%的线上事故与代码规范问题直接相关。特别是在微服务架构和金融交易系统等场景中,严格的代码规范能显著降低维护成本。本文通过电商项目等实际案例,详解包括OOP设计、集合处理、日志规范等Java开发中的关键规范要点,并分享在500人团队中落地规范的组织策略。

weixin_34378969的博客 683
上一篇: 看完这篇Redis缓存三大问题,保你面试能造火箭,工作能拧螺丝
下一篇: 关于 equals 和 hashCode,看这一篇真的够了
JavaMonsterr
博客等级 码龄4年 211粉丝 481原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值