java 时间日期 详解

来源:互联网 发布:手机vr眼睛 软件 编辑:程序博客网 时间:2024/06/06 03:33
在 JDK1.8 之前都使用时将相关的操作存在多线程问题,可以通过 ThreadLocal 来解决
public classDateFormatThreadLocal {
    private static final ThreadLocal<DateFormat>df= new ThreadLocal<DateFormat>() {
        @Override
       protectedDateFormat initialValue() {
            return new SimpleDateFormat("yyyyMMdd");
        }
    };
    public static final Date convert(String source)throwsParseException {
        return df.get().parse(source);
    }
}

使用 LocalDate、 LocalTime、 LocalDateTime
LocalDate、 LocalTime、 LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供简单的日期或时间,并不包含当前的时间信息,也不包含与时区相关的信息
注 : ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法

LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);

LocalDateTime ld2 = LocalDateTime.of(2016,11,21,10,10,10);
System.out.println(ld2);

LocalDateTime ldt3 = ld2.plusYears(20);
System.out.println(ldt3);

LocalDateTime ldt4 = ld2.minusMonths(2);
System.out.println(ldt4);

System.out.println(ldt.getYear());
System.out.println(ldt.getMonthValue());
System.out.println(ldt.getDayOfMonth());
System.out.println(ldt.getHour());
System.out.println(ldt.getMinute());
System.out.println(ldt.getSecond());
方法描述示例now()静态方法,根据当前时间创建对象
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
of()静态方法,根据指定日期/时间创建对象
LocalDate localDate = LocalDate.of(2016, 10, 26);
LocalTime localTime = LocalTime.of(02, 22, 56);
LocalDateTime localDateTime = LocalDateTime.of(2016, 10, 26, 12, 10, 55);
plusDays, plusWeeks,
plusMonths, plusYears
向当前 LocalDate 对象添加几天、几周、 几个月、 几年 
minusDays, minusWeeks,
minusMonths, minusYears
从当前 LocalDate 对象减去几天、几周、 几个月、 几年 plus, minus添加或减少一个 Duration 或 Period 
withDayOfMonth,
withDayOfYear,
withMonth,
withYear
将月份天数、 年份天数、 月份、 年份 修 改 为 指 定 的 值 并 返 回 新 的LocalDate 对象 getDayOfMonth获得月份天数(1-31) getDayOfYear获得年份天数(1-366) getDayOfWeek获得星期几(返回一个 DayOfWeek枚举值) getMonth获得月份, 返回一个 Month 枚举值 getMonthValue获得月份(1-12) getYear获得年份 until获得两个日期之间的 Period 对象,或者指定 ChronoUnits 的数字 isBefore, isAfter比较两个 LocalDate isLeapYear判断是否是闰年 

Instant 时间戳 (使用 Unix 元年 1970年1月1日 00:00:00 所经历的毫秒值)
用于“时间戳”的运算。它是以Unix元年(传统的设定为UTC时区1970年1月1日午夜时分)开始所经历的描述进行运算
Instant ins = Instant.now(); //默认使用 UTC 时区
System.out.println(ins);

OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8));
System.out.println(odt);

System.out.println(ins.getNano());

Instant ins2 = Instant.ofEpochSecond(5);
System.out.println(ins2);

Duration 和 Period
Duration : 用于计算两个“时间”间隔
Period : 用于计算两个“日期”间隔
Instant ins1 = Instant.now();

System.out.println("--------------------");
try{
    Thread.sleep(1000);
} catch (InterruptedException ignored) {
}

Instant ins2 = Instant.now();

System.out.println("所耗费时间为:"+ Duration.between(ins1, ins2));

System.out.println("----------------------------------");

LocalDate ld1 = LocalDate.now();
LocalDate ld2 = LocalDate.of(2011,1,1);

Period pe = Period.between(ld2, ld1);
System.out.println(pe.getYears());
System.out.println(pe.getMonths());
System.out.println(pe.getDays());

日期的操纵
TemporalAdjuster : 时间校正器。有时我们可能需要获取例如 : 将日期调整到“下个周日”等操作
TemporalAdjusters : 该类通过静态方法提供了大量的常用 TemporalAdjuster 的实现
例如获取下个周日:
LocalDate nextSunday = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.SUNDAY));

LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt);

LocalDateTime ldt2 = ldt.withDayOfMonth(10);
System.out.println(ldt2);

LocalDateTime ldt3 = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
System.out.println(ldt3);

// 自定义:下一个工作日
LocalDateTime ldt5 = ldt.with((l) -> {
    LocalDateTime ldt4 = (LocalDateTime) l;
    DayOfWeek dow = ldt4.getDayOfWeek();
    if (dow.equals(DayOfWeek.FRIDAY)) {
        return ldt4.plusDays(3);
    } else if (dow.equals(DayOfWeek.SATURDAY)) {
        return ldt4.plusDays(2);
    } else {
        return ldt4.plusDays(1);
    }
});
System.out.println(ldt5);

解析与格式化
java.time.format.DateTimeFormatter 类:该类提供了三种格式化方法 :
1> 预定义的标准格式
2> 语言环境相关的格式
3> 自定义的格式
//     DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE;
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E");

LocalDateTime ldt = LocalDateTime.now();
String strDate = ldt.format(dtf);
System.out.println(strDate);

LocalDateTime newLdt = ldt.parse(strDate, dtf);
System.out.println(newLdt);

时区的处理
Java8 中加入了对时区的支持,带时区的时间为分别为 : ZonedDate、 ZonedTime、 ZonedDateTime
其中每个时区都对应着 ID,地区ID都为 “ {区域}/{城市}”的格式
例如 : Asia/Shanghai 等
ZoneId : 该类中包含了所有的时区信息
              getAvailableZoneIds() : 可以获取所有时区时区信息
              of(id) : 用指定的时区信息获取 ZoneId 对象

Set<String> set = ZoneId.getAvailableZoneIds();
set.forEach(System.out::println);

LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
System.out.println(ldt);

ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("US/Pacific"));
System.out.println(zdt);

与传统日期处理的转换
To 遗留类 
From 遗留类
java.time.Instant
java.util.Date
Date.from(instant)date.toInstant()
java.time.Instant
java.sql.Timestamp
Timestamp.from(instant)timestamp.toInstant()
java.time.ZonedDateTime
java.util.GregorianCalendar
GregorianCalendar.from(zonedDateTime)cal.toZonedDateTime()
java.time.LocalDate
java.sql.Time
Date.valueOf(localDate)date.toLocalDate()
java.time.LocalTime
java.sql.Time
Date.valueOf(localDate)date.toLocalTime()
java.time.LocalDateTime
java.sql.Timestamp
Timestamp.valueOf(localDateTime)timestamp.toLocalDateTime()
java.time.ZoneId
java.util.TimeZone
Timezone.getTimeZone(id)timeZone.toZoneId()
java.time.format.DateTimeFormatter
java.text.DateFormat
formatter.toFormat()无

JDK1.8前的时间操作与之后的时间操作
以下操作存在问题
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Callable<Date> task =new Callable<Date>() {
   @Override
  public Date call() throwsException {
      return sdf.parse("20161121");
   }
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<Date>> results =new ArrayList<>();
for(inti = 0; i < 10; i++) {
   results.add(pool.submit(task));
}
for(Future<Date> future : results) {
   System.out.println(future.get());
}
pool.shutdown();

解决多线程安全问题
Callable<Date> task = new Callable<Date>() {
    @Override
   public Date call() throwsException {
        return DateFormatThreadLocal.convert("20161121");
    }
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<Date>> results =new ArrayList<>();
for(inti = 0; i < 10; i++) {
    results.add(pool.submit(task));
}
for(Future<Date> future : results) {
    System.out.println(future.get());
}
pool.shutdown();

使用 JDK1.8 的 DateTimeFormatter 就不存在 多线程问题
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
Callable<LocalDate> task =new Callable<LocalDate>() {
    @Override
   public LocalDate call() throwsException {
        LocalDate ld = LocalDate.parse("20161121",dtf);
        return ld;
    }
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<LocalDate>> results =new ArrayList<>();
for(inti = 0; i < 10; i++) {
    results.add(pool.submit(task));
}
for(Future<LocalDate> future : results) {
    System.out.println(future.get());
}
pool.shutdown();

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 在银座的押金拿不出来怎么办 唯品会退货时快递单号填错了怎么办 天猫店铺快递已发到不了怎么办 中邮消费贷没审核通过怎么办 房贷扣款日忘存钱了怎么办 农业银行卡输密码次数超限载怎么办 农业银行卡丢了不知道卡号怎么办 银行卡短信扣费失败怎么恢复怎么办 歌华有线遥控器点了tvav怎么办 一级注册结构延续注册晚了怎么办 在京东买的黄金项链买贵了怎么办 京东上面买的商品不符合实际怎么办 在京东买东西卖家迟迟不发货怎么办 淘宝商家买的货一直不到怎么办 国美买的格力空调发票丢了怎么办 国美实体店发票丢了怎么办 我在苏宁买的冰箱发票丢了怎么办 信用卡家庭电单位电话换了怎么办 常住户囗和实际住址没房子怎么办 退货淘宝极速退款 卖家拒收怎么办 淘宝退货极速退款后卖家拒收怎么办 蘑菇街付款成功怎么申请退款怎么办 淘宝上拍错地址联系卖家不管怎么办 收到货想退款卖家不同意怎么办 小米小店复合通过qq群怎么办 买了火车票在订单上查不到怎么办 用支付宝付款扣款没成功怎么办 在京东买东西只收到空盒子怎么办 魅族移动数据是灰色的怎么办? 魅族手机账号密码忘记了怎么办视频 淘宝购物退货把单号写错了怎么办 天猫想退货商家不给退货地址怎么办 天天爱消除四星宠物等级已满怎么办 店不干了店里面的财神怎么办 微信显示登陆注册语言打不开怎么办 三星手机解锁以后突然不量怎么办 耐克、阿迪品牌鉴定买到假货怎么办 小米4c盒子不支持有线连接怎么办 一个手机号绑着两个小米账号怎么办 小米5s手机听筒声音小怎么办 淘宝上买手机买到翻新怎么办