全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2024-04-21_为什么现在连Date类都不建议使用了?

您的位置:首页 >> 新闻 >> 行业资讯

为什么现在连Date类都不建议使用了? 一、有什么问题吗java.util.Date?image.pngjava.util.Date(Date从现在开始)是一个糟糕的类型,这解释了为什么它的大部分内容在 Java 1.1 中被弃用(但不幸的是仍在使用)。 设计缺陷包括: 它的名称具有误导性:它并不代表 a Date,而是代表时间的一个瞬间。所以它应该被称为Instant——正如它的java.time等价物一样。它是非最终的:这鼓励了对继承的不良使用,例如java.sql.Date(这意味着代表一个日期,并且由于具有相同的短名称而也令人困惑)它是可变的:日期/时间类型是自然值,可以通过不可变类型有效地建模。可变的事实Date(例如通过setTime方法)意味着勤奋的开发人员最终会在各处创建防御性副本。它在许多地方(包括)隐式使用系统本地时区,toString()这让许多开发人员感到困惑。有关此内容的更多信息,请参阅“什么是即时”部分它的月份编号是从 0 开始的,是从 C 语言复制的。这导致了很多很多相差一的错误。它的年份编号是基于 1900 年的,也是从 C 语言复制的。当然,当 Java 出现时,我们已经意识到这不利于可读性?它的方法命名不明确:getDate()返回月份中的某一天,并getDay()返回星期几。给这些更具描述性的名字有多难?对于是否支持闰秒含糊其辞:“秒由 0 到 61 之间的整数表示;值 60 和 61 仅在闰秒时出现,即使如此,也仅在实际正确跟踪闰秒的 Java 实现中出现。”我强烈怀疑大多数开发人员(包括我自己)都做了很多假设,认为 for 的范围getSeconds()实际上在 0-59 范围内(含)。它的宽容没有明显的理由:“在所有情况下,为这些目的而对方法给出的论据不必落在指定的范围内;例如,日期可以指定为 1 月 32 日,并被解释为 2 月 1 日。”多久有用一次?原文如下:为什么要避免使用Date类? 二、为啥要改?我们要改的原因很简单,我们的代码缺陷扫描规则认为这是一个必须修改的缺陷,否则不给发布,不改不行,服了。 image.png解决思路:避免使用java.util.Date与java.sql.Date类和其提供的API,考虑使用java.time.Instant类或java.time.LocalDateTime类及其提供的API替代。 三、怎么改?只能说这种基础的类改起来牵一发动全身,需要从DO实体类看起,然后就是各种Converter,最后是DTO。由于我们还是微服务架构,业务服务依赖于基础服务的API,所以必须要一起改否则就会报错。这里就不细说修改流程了,主要说一下我们在改造的时候遇到的一些问题。 1. 耐心比对数据库日期字段和DO的映射 (1)确定字段类型首先你需要确定数据对象中的 Date 字段代表的是日期、时间还是时间戳。 如果字段代表日期和时间,则可能需要使用LocalDateTime。如果字段仅代表日期,则可能需要使用LocalDate。如果字段仅代表时间,则可能需要使用LocalTime。如果字段需要保存时间戳(带时区的),则可能需要使用Instant或ZonedDateTime。(2)更新数据对象类更新数据对象类中的字段,把 Date 类型改为适当的 java.time 类型。 2. 将DateUtil中的方法改造 (1)替换原来的new Date()和Calendar.getInstance().getTime()原来的方式: DatenowDate=newDate(); DatenowCalendarDate=Calendar.getInstance().getTime(); 使用 java.time 改造后: //使用Instant代表一个时间点,这与Date类似 InstantnowInstant=Instant.now(); //如果需要用到具体的日期和时间(例如年、月、日、时、分、秒) LocalDateTimenowLocalDateTime=LocalDateTime.now(); //如果你需要和特定的时区交互,可以使用ZonedDateTime ZonedDateTimenowZonedDateTime=ZonedDateTime.now(); //如果你需要转换回java.util.Date,你可以这样做(假设你的代码其他部分还需要使用Date) DatenowFromDateInstant=Date.from(nowInstant); //如果需要与java.sql.Timestamp交互 java.sql.TimestampnowFromInstant=java.sql.Timestamp.from(nowInstant); 一些注意点: Instant表示的是一个时间点,它是时区无关的,相当于旧的Date类。它通常用于表示时间戳。LocalDateTime表示没有时区信息的日期和时间,它不能直接转换为时间戳,除非你将其与时区结合使用(例如通过ZonedDateTime)。ZonedDateTime包含时区信息的日期和时间,它更类似于Calendar,因为Calendar也包含时区信息。当你需要将java.time对象转换回java.util.Date对象时,可以使用Date.from(Instant)方法。这在你的代码需要与旧的API或库交互时非常有用。(2)一些基础的方法改造a. dateFormat原来的方式 public static String dateFormat(Date date, String dateFormat) { SimpleDateFormat formatter = new SimpleDateFormat(dateFormat); return formatter.format(date); } 使用java.time改造后 publicstaticStringdateFormat(LocalDateTimedate,StringdateFormat){ DateTimeFormatterformatter=DateTimeFormatter.ofPattern(dateFormat); returndate.format(formatter); } b. addSecond、addMinute、addHour、addDay、addMonth、addYear原来的方式 publicstaticDateaddSecond(Datedate,intsecond){ Calendarcalendar=Calendar.getInstance(); calendar.setTime(date); calendar.add(13,second); returncalendar.getTime(); } publicstaticDateaddMinute(Datedate,intminute){ Calendarcalendar=Calendar.getInstance(); calendar.setTime(date); calendar.add(12,minute); returncalendar.getTime(); } publicstaticDateaddHour(Datedate,inthour){ Calendarcalendar=Calendar.getInstance(); calendar.setTime(date); calendar.add(10,hour); returncalendar.getTime(); } publicstaticDateaddDay(Datedate,intday){ Calendarcalendar=Calendar.getInstance(); calendar.setTime(date); calendar.add(5,day); returncalendar.getTime(); } publicstaticDateaddMonth(Datedate,intmonth){ Calendarcalendar=Calendar.getInstance(); calendar.setTime(date); calendar.add(2,month); returncalendar.getTime(); } publicstaticDateaddYear(Datedate,intyear){ Calendarcalendar=Calendar.getInstance(); calendar.setTime(date); calendar.add(1,year); returncalendar.getTime(); } 使用java.time改造后 publicstaticLocalDateTimeaddSecond(LocalDateTimedate,intsecond){ returndate.plusSeconds(second); } publicstaticLocalDateTimeaddMinute(LocalDateTimedate,intminute){ returndate.plusMinutes(minute); } publicstaticLocalDateTimeaddHour(LocalDateTimedate,inthour){ returndate.plusHours(hour); } publicstaticLocalDateTimeaddDay(LocalDateTimedate,intday){ returndate.plusDays(day); } publicstaticLocalDateTimeaddMonth(LocalDateTimedate,intmonth){ returndate.plusMonths(month); } publicstaticLocalDateTimeaddYear(LocalDateTimedate,intyear){ returndate.plusYears(year); } c. dateToWeek原来的方式 publicstaticfinalString[]WEEK_DAY_OF_CHINESE=newString[]{"周日","周一","周二","周三","周四","周五","周六"}; publicstaticStringdateToWeek(Datedate){ Calendarcal=Calendar.getInstance(); cal.setTime(date); returnWEEK_DAY_OF_CHINESE[cal.get(7)-1]; } 使用java.time改造后 publicstaticfinalString[]WEEK_DAY_OF_CHINESE=newString[]{"周日","周一","周二","周三","周四","周五","周六"}; publicstaticStringdateToWeek(LocalDatedate){ DayOfWeekdayOfWeek=date.getDayOfWeek(); returnWEEK_DAY_OF_CHINESE[dayOfWeek.getValue()%7]; } d. getStartOfDay和getEndOfDay原来的方式 publicstaticDategetStartTimeOfDay(Datedate){ if(date==null){ returnnull; }else{ LocalDateTimelocalDateTime=LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()),ZoneId.systemDefault()); LocalDateTimestartOfDay=localDateTime.with(LocalTime.MIN); returnDate.from(startOfDay.atZone(ZoneId.systemDefault()).toInstant()); } } publicstaticDategetEndTimeOfDay(Datedate){ if(date==null){ returnnull; }else{ LocalDateTimelocalDateTime=LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()),ZoneId.systemDefault()); LocalDateTimeendOfDay=localDateTime.with(LocalTime.MAX); returnDate.from(endOfDay.atZone(ZoneId.systemDefault()).toInstant()); } } 使用java.time改造后 publicstaticLocalDateTimegetStartTimeOfDay(LocalDateTimedate){ if(date==null){ returnnull; }else{ //获取一天的开始时间,即00:00 returndate.toLocalDate().atStartOfDay(); } } publicstaticLocalDateTimegetEndTimeOfDay(LocalDateTimedate){ if(date==null){ returnnull; }else{ //获取一天的结束时间,即23:59:59.999999999 returndate.toLocalDate().atTime(LocalTime.MAX); } } e. betweenStartAndEnd原来的方式 publicstaticBooleanbetweenStartAndEnd(DatenowTime,DatebeginTime,DateendTime){ Calendardate=Calendar.getInstance(); date.setTime(nowTime); Calendarbegin=Calendar.getInstance(); begin.setTime(beginTime); Calendarend=Calendar.getInstance(); end.setTime(endTime); returndate.after(begin)date.before(end); } 使用java.time改造后 publicstaticBooleanbetweenStartAndEnd(InstantnowTime,InstantbeginTime,InstantendTime){ returnnowTime.isAfter(beginTime)nowTime.isBefore(endTime); } 我这里就只列了一些,如果有缺失的可以自己补充,不会写的话直接问问ChatGPT,它最会干这事了。最后把这些修改后的方法替换一下就行了。 四、小结一下这个改造难度不高,但是复杂度非常高,一个地方没改好,轻则接口报错,重则启动失败,非常耗费精力,真不想改。 文末小彩蛋,自己花一个星期做的小网站,放出来给大家看看,网址如下:http://47.120.49.119:8080 阅读原文

上一篇:2021-10-09_不要拒绝面试询问休假时间的人:20年老程序员总结的经验 下一篇:2019-09-15_「转」想把3分钟看完XX的视频都拉黑!

TAG标签:

12
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价