java获取date的年月日 java中获取当前时间的方法


前言 上一周在做一个产品的需求的时候有个动态计算时间段(如现在是13:00,则时间段为15:10-17:10、17:10-19:10、19:10-21:10;即最早的出发时间为当前时间 参数【2h10min】,最迟的时间段为开始时间在20点前结束时间在20点后的时间段),期间大量使用到了日期时间类库,本着熟悉日期时间类库才有了这篇文章,文章最后我会把我如何实现的这个需求的一个算法贴出来 。
一、JDK8以前版本中的时间类库 1.1 原始时间类库存在的缺陷与不足 我们在使用Java8之前的类库时,都会在处理日期-时间的时候总是不爽,这其中包括且不限于以下的槽点:
在Java 1.0版本中,对时间、日期的操作完全依赖于 java.util.Data 类,只能以毫秒的精度表示时间,无法表示日期 。
在易用性方面有着很大的缺陷,年份的起始时间选择是1900年,月份是从0开始 。toString 方法返回值不直观,带有时区 。在Java1.1 版本中,废弃了很多Date 类中的很多方法,并且新增了 java.util.Calendar 。但是与Date相同,Calendar 类也有类似的问题和设计缺陷,导致在使用这些类写出的代码也很容易出错 。
月份依然是从0开始计算 。常用的日期、时间操作需要同时使用Date、Canendar、SimpleDateFormat,比较繁琐 。部分特性只存在于某一个类(解析和格式化日期或时间的DateFormat方法只存在于Date类中) 。DateFormat 不是线程安全的,如果两个线程尝试使用同一个formatter 解析日期,可能会得到无法预期的结果 。Date 和 Canendar 都是可变的 。1.2 关于SimpleDateFormat 线程不安全的原因 由于 parse 方法使用的贡献变量 calendar 不是线程安全的 。在 format (subFormat) 方法中进行了 calendar 的赋值,在 parse 进行了值得处理,因此在并发的情况下会造成 calendar 清理不及时,值被覆盖的情况 。
protected Calendar calendar;@Overridepublic StringBuffer format(Date date, StringBuffer toAppendTo,FieldPosition pos){pos.beginIndex = pos.endIndex = 0;return format(date, toAppendTo, pos.getFieldDelegate());}// Called from Format after creating a FieldDelegateprivate StringBuffer format(Date date, StringBuffer toAppendTo,FieldDelegate delegate) {// Convert input date to time field listcalendar.setTime(date); // At this point the fields of Calendar have been set.Calendar // will fill in default values for missing fields when the time // is computed. pos.index = start; Date parsedDate; try {parsedDate = calb.establish(calendar).getTime();// If the year value is ambiguous,// then the two-digit year == the default start yearif (ambiguousYear[0]) {if (parsedDate.before(defaultCenturyStart)) {parsedDate = calb.addYear(100).establish(calendar).getTime();}} }} 1.3 如何解决上述线程不安全问题?

    使用ThreadLocal 为每个线程都创建一个线程独享 SimpleDateFormat 变量;需要的时候创建局部变量;使用 org.apacle.commons.lang3.time.DateFormatUtils使用Joda-Time (后面介绍)

    推荐阅读