• 全国 [切换]
  • 二维码
    养老服务网

    手机WAP版

    手机也能找商机,信息同步6大终端平台!

    微信小程序

    微信公众号

    当前位置: 首页 » 行业新闻 » 热点新闻 » 正文

    Java 8 的日期和时间API

    放大字体  缩小字体 发布日期:2024-08-13 20:36:21   浏览次数:72  发布人:8975****  IP:124.223.189***  评论:0
    导读

    Java 8 以前的日期和时间 API 设计有些不足,Java 8 引入了一套新的API,位于 java.time 包下。 Instant Instant 表示时刻,不直接对应年月日信息,需要通过时区转换。 Instant now = Instant.now();可以根据 Epoch Time(纪元时)创建 Instant。 Instant now = Instant.ofEpochMilli(S

    Java 8 以前的日期和时间 API 设计有些不足,Java 8 引入了一套新的API,位于 java.time 包下。

    Instant

    Instant 表示时刻,不直接对应年月日信息,需要通过时区转换。

    Instant now = Instant.now();

    可以根据 Epoch Time(纪元时)创建 Instant。

    Instant now = Instant.ofEpochMilli(System.currentTimeMillis());

    Instant 和 Date 可以通过纪元时相互转换:

    • Date 转 Instant

    public static Instant toInstant(Date date) { return Instant.ofEpochMilli(date.getTime()); }

    • Instant 转 Date

    public static Date toDate(Instant instant) { return new Date(instant.toEpochMilli()); }

    给定一个时刻,使用不同时区解读,日历信息是不同的,默认时区是 ZoneId.systemDefault()。

    public ZonedDateTime atZone(ZoneId zone)

    LocalDateTime

    LocalDateTime 表示与时区无关的日期和时间,不直接对应时刻,需要通过时区转换。

    获取系统默认时区的当前日期和时间:

    LocalDateTime dateTime = LocalDateTime.now();

    直接用年月日等信息构建 LocalDateTime:

    LocalDateTime ldt = LocalDateTime.of(2017, 7, 11, 20, 45, 5);

    获取日历信息:

    public int getYear() public int getMonthValue() public int getDayOfMonth() public int getHour() public int getMinute() public int getSecond() public DayOfWeek getDayOfWeek()

    DayOfWeek 是一个枚举,有 7 个取值,从 DayOfWeek.MonDAY 到 DayOfWeek.SUN-DAY。

    ZoneOffset

    LocalDateTime 不能直接转为时刻 Instant,转换需要一个参数 ZoneOffset。

    ZoneOffset 表示相对于格林尼治的时区差,北京是 +08:00。

    public static Instant toBeijingInstant(LocalDateTime ldt) { return ldt.toInstant(ZoneOffset.of("+08:00")); }

    LocalDate/LocalTime

    可以认为 LocalDateTime 由两部分组成,一部分是日期 LocalDate,另一部分是时间 LocalTime。

    // 表示2017年7月11日 LocalDate ld = LocalDate.of(2017, 7, 11); // 当前时刻按系统默认时区解读的日期 LocalDate now = LocalDate.now(); // 表示21点10分34秒 LocalTime lt = LocalTime.of(21, 10, 34); // 当前时刻按系统默认时区解读的时间 LocalTime time = LocalTime.now();

    LocalDateTime ldt = LocalDateTime.of(2017, 7, 11, 20, 45, 5); LocalDate ld = ldt.toLocalDate(); // 2017-07-11 LocalTime lt = ldt.toLocalTime(); // 20:45:05 // LocalDate加上时间,结果为2017-07-11 21:18:39 LocalDateTime ldt2 = ld.atTime(21, 18, 39); // LocalTime加上日期,结果为2016-03-24 20:45:05 LocalDateTime ldt3 = lt.atDate(LocalDate.of(2016, 3, 24));

    ZonedDateTime

    ZonedDateTime 表示特定时区的日期和时间,获取系统默认时区的当前日期和时间,除了记录日历信息,还会记录时区。

    LocalDateTime.now() 也是获取默认时区的当前日期和时间,但 LocalDateTime 只单纯记录年月日时分秒等信息。

    // 根据Instant和时区构建ZonedDateTime public static ZonedDateTime ofInstant(Instant instant, ZoneId zone) // 根据LocalDate、LocalTime和ZoneId构造 public static ZonedDateTime of(LocalDate date, LocalTime time, ZoneId zone)

    ZonedDateTime 可以直接转换为 Instant。

    ZonedDateTime ldt = ZonedDateTime.now(); Instant now = ldt.toInstant();

    DateTimeFormatter 格式化

    java.time.format.DateTimeFormatter 是线程安全的,用法和 DateFormat 相差不大。

    • DateTimeFormatter.ofPattern(pattern) 实例化
    • format 格式化 TemporalAccessor 接口子类对象转字符串
    • parse 按格式解析字符串转为 TemporalAccessor 接口子类对象

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime dateTime = LocalDateTime.now(); System.out.println(formatter.format(dateTime));

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String str = "2016-08-18 14:20:45"; LocalDateTime ldt = LocalDateTime.parse(str, formatter);

    设置和修改时间

    修改时期和时间有两种方式,一种是直接设置绝对值,另一种是在现有值的基础上进行相对增减操作。

    Java 8的大部分日期和时间类都是不可变类,修改操作是通过创建并返回新对象来实现的,原对象本身不会变。

    • 直接设置

    设置时间为下午 3 点 20 分:

    LocalDateTime ldt = LocalDateTime.now(); ldt = ldt.withHour(15).withMinute(20).withSecond(0).withNano(0);

    LocalDateTime ldt = LocalDateTime.now(); ldt = ldt.toLocalDate().atTime(15, 20);

    设置时间为 0 点:

    LocalDateTime ldt = LocalDateTime.now(); ldt = ldt.with(ChronoField.MILLI_OF_DAY, 0); // ChronoField 是一个枚举

    LocalDateTime ldt = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);

    LocalDateTime ldt = LocalDate.now().atTime(0, 0);

    • 增减操作

    设置时间为 3 小时 5 分钟后:

    LocalDateTime ldt = LocalDateTime.now(); ldt = ldt.plusHours(3).plusMinutes(5);

    设置时间为下一个周二上午 10 点 :

    LocalDate ld = LocalDate.now(); if(! ld.getDayOfWeek().equals(DayOfWeek.MONDAY)){ ld = ld.plusWeeks(1); } LocalDateTime ldt = ld.with(ChronoField.DAY_OF_WEEK, 2).atTime(10, 0);

    Java 8 有一个专门的接口 TemporalAdjuster,这是一个函数式接口,对日期或时间进行调整。

    Instant、LocalDateTime 和 LocalDate 等都实现了它,有一个专门的默认实现类 TemporalAdjusters。

    public interface TemporalAdjuster { Temporal adjustInto(Temporal temporal); }

    设置时间为下一个周二上午 10 点 :

    LocalDate ld = LocalDate.now(); LocalDateTime ldt = ld.with(TemporalAdjusters.next(DayOfWeek.TUESDAY)).atTime(10, 0);

    TemporalAdjusters 的 next 实现:

    public static TemporalAdjuster next(DayOfWeek dayOfWeek) { int dowValue = dayOfWeek.getValue(); return (temporal) -> { int calDow = temporal.get(DAY_OF_WEEK); int daysDiff = calDow - dowValue; return temporal.plus(daysDiff >= 0 ? 7 - daysDiff : -daysDiff, DAYS); }; }

    时间段的计算

    Java 8 中表示时间段的类主要有两个:Period 和 Duration。

    Period 表示日期之间的差,用年月日表示,不能表示时间;

    Duration 表示时间差,用时分秒等表示,也可以用天表示,一天严格等于24小时,不能用年月表示。

    LocalDate ld1 = LocalDate.of(2016, 3, 24); LocalDate ld2 = LocalDate.of(2017, 7, 12); Period period = Period.between(ld1, ld2); System.out.println(period.getYears() + "年" + period.getMonths() + "月" + period.getDays() + "天");

    long lateMinutes = Duration.between(LocalTime.of(9, 0), LocalTime.now()).toMinutes();

    与 Date/Calendar 转换

    Date 可以与 Instant 通过毫秒数相互转换,对于其他类型,可以通过毫秒数与 Instant 相互转换。

    LocalDateTime 转换为 Date:

    public static Date toDate(LocalDateTime ldt){ return new Date(ldt.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); }

    Date 按默认时区转换为 LocalDateTime:

    public static LocalDateTime toLocalDateTime(Date date) { return LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()), ZoneId.systemDefault()); }

    ZonedDateTime 转换为 Calendar:

    public static Calendar toCalendar(ZonedDateTime zdt) { TimeZone tz = TimeZone.getTimeZone(zdt.getZone()); Calendar calendar = Calendar.getInstance(tz); calendar.setTimeInMillis(zdt.toInstant().toEpochMilli()); return calendar; }

    Calendar 转换为 ZonedDateTime:

    public static ZonedDateTime toZonedDateTime(Calendar calendar) { ZonedDateTime zdt = ZonedDateTime.ofInstant( Instant.ofEpochMilli(calendar.getTimeInMillis()), calendar.getTimeZone().toZoneId()); return zdt; }

     
    (文/匿名(若涉版权问题请联系我们核实发布者) / 非法信息举报 / 删稿)
    打赏
    免责声明
    • 
    本文为昵称为 8975**** 发布的作品,本文仅代表发布者个人观点,本站未对其内容进行核实,请读者仅做参考,如若文中涉及有违公德、触犯法律的内容,一经发现,立即删除,发布者需自行承担相应责任。涉及到版权或其他问题,请及时联系我们154208694@qq.com删除,我们积极做(权利人与发布者之间的调停者)中立处理。郑重说明:不 违规举报 视为放弃权利,本站不承担任何责任!
    有个别老鼠屎以营利为目的遇到侵权情况但不联系本站或自己发布违规信息然后直接向本站索取高额赔偿等情况,本站一概以诈骗报警处理,曾经有1例诈骗分子已经绳之以法,本站本着公平公正的原则,若遇 违规举报 我们100%在3个工作日内处理!
    0相关评论
     

    (c)2008-现在 oy3.com All Rights Reserved.