首页 > 编程语言 >理解 Java8 的时间API(二)时间

理解 Java8 的时间API(二)时间

时间:2023-05-02 15:22:12浏览次数:67  
标签:Instant java time public API static LocalDateTime 时间 Java8

理解 Java8 的时间API:java.time

上一篇介绍了 Java8 里新的时区API。这一篇介绍新的时间API:LocalDateTimeLocalDateLocalTime类。

三、Java8中的时间

最常用的应该是java.time.LocalDateTimejava.time.LocalDatejava.time.LocalTimejava.time.Instant 这几个类。

3.1 LocalDateTime

其实这个类很简单,这里我贴一下它的工厂构造方法 LocalDateTime.of() 的一个重载:

public static LocalDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second) {
    LocalDate date = LocalDate.of(year, month, dayOfMonth);
    LocalTime time = LocalTime.of(hour, minute, second);
    return new LocalDateTime(date, time);
}

显然,一个LocalDateTime实例由“年+月+日+时+分+秒”这几个部分组成(实际上还包含纳秒,这里先忽略)。也就是形如“2023-05-02 11:59:00”这样的信息。并且它不包含时区信息,这也是名称里“Local”的含义。

LocalDateTime还有两个最为常用的工厂方法,第一个是使用系统默认时区构造一个实例,第二个是获取指定时区的当前日期时间。因此同一个“当前时间”,在不同时区,用LocalDateTime.now();方法构造出来的日期时间是不同的。

public static LocalDateTime now();
public static LocalDateTime now(ZoneId zone);

3.2 LocalDate和LocalTime

很好理解:LocalDateTime = LocalDate + LocalTime

LocalDate其实就是LocalDateTime中的日期部分,也就是“2023-05-02”这部分信息。

public static LocalDate of(int year, int month, int dayOfMonth);
public static LocalDate now(); // 获取系统时区的当前日期
public static LocalDate now(ZoneId zone); // 获取指定时区的当前日期

LocalTime其实就是LocalDateTime中的时间部分,也就是“11:59:00”这部分信息。

public static LocalTime of(int hour, int minute, int second);
public static LocalTime now(); // 获取系统时区的当前时间
public static LocalTime now(ZoneId zone); // 获取指定时区的当前时间

3.3 Instant

这个也可以字面理解:时刻、瞬间等含义。可以类比时间戳

public static Instant ofEpochSecond(long epochSecond); // 这里的epochSecond就是秒级时间戳
public static Instant now();
public long toEpochMilli(); // 实例方法,转为毫秒级时间戳

注:
从字面上看,替代java.util.Date类的似乎是java.time.LocalDateTime。其实不然, Date类内部的关键字段是时间戳,从这一点上看,替代Date类的其实是java.time.Instant

3.4 Period和Duration

除了上面这几个表示一个具体时间的类以外,还有几个表示时间段的类:java.time.Periodjava.time.Duration

简而言之:Period最细粒度是“天”,即可以表示几年、几个月、一个月内的几天的时间范围。Duration的最大粒度是“天”,即可以表示几天、几小时、几分钟、几秒等范围。

https://zhuanlan.zhihu.com/p/144372010

四、时间格式的相互转化

最常用的时间格式大概是这两种:1. 时间戳;2. 日期时间字符串(不包含时区)。这两种格式之间的转换莫过于下图里的逻辑:

值得注意,新的时间API推出了线程安全的java.time.format.DateTimeFormatter替代以前的线程不安全的java.text.SimpleDateFormat。上图中在Java中的转换代码示例如下:

public static void main(String[] args) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    ZoneId zoneId = ZoneId.of("America/Los_Angeles");

    // 1. LocalDateTime 转成其他格式
    LocalDateTime dateTime = LocalDateTime.of(2023, 5, 2, 11, 59, 0);
    // 1.1 LocalDateTime => 日期时间字符串
    String dateTimeStr1 = formatter.format(dateTime); // 2023-05-02 11:59:00
    String dateTimeStr2 = dateTime.format(formatter); // 2023-05-02 11:59:00

    // 这里是由于夏令时的存在,相同的zoneId,不同时间的offset可能会不一样
    ZoneOffset offset = zoneId.getRules().getOffset(dateTime);
    // 1.2 LocalDateTime => 时间戳
    long epochSecond = dateTime.toEpochSecond(offset);
    // 1.3 LocalDateTime => Instant
    Instant instant = dateTime.toInstant(offset);

    // 1.4 LocalDateTime => ZonedDateTime => Instant
    ZonedDateTime zonedDateTime = dateTime.atZone(zoneId);
    Instant instant1 = zonedDateTime.toInstant();

    // 2. Instant 转成其他格式
    Instant now = Instant.now();
    // 2.1 Instant => LocalDateTime
    LocalDateTime dateTime1 = LocalDateTime.ofInstant(instant, zoneId);
    // 2.2 Instant => 时间戳
    long epochSecond1 = now.getEpochSecond();
    long epochMilli = now.toEpochMilli();
    // 2.3 Instant => UTC时区的日期时间
    String s = now.toString(); // 2023-05-02T05:43:09.605Z

    // 3. 时间戳 转成其他格式
    long timestamp = System.currentTimeMillis();
    // 3.1 时间戳 => Instant
    Instant instant2 = Instant.ofEpochMilli(timestamp);
    Instant instant3 = Instant.ofEpochSecond(timestamp / 1000);
    // 3.2 时间戳 => Instant => LocalDateTime
    LocalDateTime dateTime2 = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), zoneId);

    // 4. 日期时间字符串 转成其他格式
    String dateTimeStr = "2023-05-02 11:59:00";
    // 4.1 日期时间字符串 => LocalDateTime
    LocalDateTime parse = LocalDateTime.parse(dateTimeStr, formatter);
}

上面的转换代码组合一下,一个时间工具类就出来了:

import lombok.experimental.UtilityClass;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

@UtilityClass
public class DateTimeUtils {

    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    private static final ZoneId zoneId = ZoneId.of("America/Los_Angeles");

    /**
     * 如果是北京时间,下面要用到zoneOffset的地方直接用这个就行,不需要用zoneId来转换
     */
    private static final ZoneOffset beijingOffset = ZoneOffset.of("+8");

    /**
     * @param dateTimeStr 日期时间字符串
     * @return 毫秒时间戳
     */
    public static long dateTimeStr2Timestamp(String dateTimeStr) {
        LocalDateTime parse = LocalDateTime.parse(dateTimeStr, formatter);
        return parse.toEpochSecond(getOffset(parse));
    }

    /**
     * @param timestamp 毫秒时间戳
     * @return 日期时间字符串
     */
    public static String timestamp2DateTimeStr(long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        LocalDateTime dateTime = LocalDateTime.ofInstant(instant, zoneId);
        return dateTime.format(formatter);
    }

    /**
     * 毫秒时间戳 => Instant
     */
    public static Instant timestamp2Instant(long timestamp) {
        return Instant.ofEpochMilli(timestamp);
    }

    /**
     * Instant => 毫秒时间戳
     */
    public static long instant2Timestamp(Instant instant) {
        return instant.toEpochMilli();
    }

    /**
     * LocalDateTime => 秒级时间戳
     */
    public static long localDateTime2Second(LocalDateTime localDateTime) {
        ZoneOffset zoneOffset = getOffset(localDateTime);
        return localDateTime.toEpochSecond(zoneOffset);
    }

    /**
     * 日期时间字符串 => LocalDateTime
     */
    public static LocalDateTime dateTimeStr2LocalDateTime(String dateTimeStr) {
        return LocalDateTime.parse(dateTimeStr, formatter);
    }

    /**
     * LocalDateTime => 日期时间字符串
     */
    public static String localDateTime2DateTimeStr(LocalDateTime localDateTime) {
        return localDateTime.format(formatter);
    }

    /**
     * Instant => LocalDateTime
     */
    private static LocalDateTime instant2LocalDateTime(Instant instant) {
        return LocalDateTime.ofInstant(instant, zoneId);
    }

    /**
     * LocalDateTime => Instant
     */
    private static Instant localDateTime2Instant(LocalDateTime localDateTime) {
        ZoneOffset zoneOffset = getOffset(localDateTime);
        return localDateTime.toInstant(zoneOffset);
    }

    private static ZoneOffset getOffset(LocalDateTime localDateTime) {
        return zoneId.getRules().getOffset(localDateTime);
    }

    private static ZoneOffset getOffset(Instant instant) {
        return zoneId.getRules().getOffset(instant);
    }

}

https://www.baeldung.com/java-localdatetime-zoneddatetime

另外:

https://dev.mysql.com/doc/refman/8.0/en/datetime.html
MySQL里时间相关的类型:

  • DATETIMEDATETIME:也是不包含时区信息的,和LocalDateTime,LocalDate,LocalTime可以一一对应;
  • TIMESTAMP:和 Instant 可以对应。

标签:Instant,java,time,public,API,static,LocalDateTime,时间,Java8
From: https://www.cnblogs.com/recycer/p/17367742.html

相关文章

  • 磁盘单双缓冲区时间计算题总结
    题型一:问处理一个块所用的总时间是多少这是要处理多块数据,但是题目问处理一块的时间。这是一个套路,一般人会直接算出150。根据甘特图推出结论,单缓冲区处理每块数据用时为:MAX(缓冲区到磁盘所用时间,CPU处理所用时间)+工作区到缓冲区所用时间直接代入得出120。套路就是:求一个......
  • 手机操作API
    目录手机操作API获取手机分辨率手机截图获取和设置手机网络发送键到设备操作手机通知栏总结手机操作API获取手机分辨率应用场景自动化测试可能会需要根据当前设备的屏幕分辨率来计算一些点击或者滑动的坐标核心代码#获取手机分辨率print(driver.get_window_size())执行结......
  • Linux系统之部署Chrony时间服务器
    (Linux系统之部署Chrony时间服务器)一、Chrony介绍1.Chrony简介Chrony是一个开源自由的网络时间协议NTP的客户端和服务器软软件。它能让计算机保持系统时钟与时钟服务器(NTP)同步,因此让你的计算机保持精确的时间,Chrony也可以作为服务端软件为其他计算机提供时间同步服务。2.......
  • 时间转化Fri Apr 07 11:43:24 +0800 2022
    原格式:FriApr0711:43:24+08002022灵感:获取微博某时间段到...之间的内容转化格式:2022-04-07#实现importdatetimedate_str="FriApr0711:43:24+08002022"date=datetime.datetime.strptime(date_str,"%a%b%d%H:%M:%S%z%Y")formatted_date=date.str......
  • 如何通过 API 查看 cnblogs 博客访问量和博客积分与排名 All In One
    如何通过API查看cnblogs博客访问量和博客排名AllInOne开启配置https://i.cnblogs.com/preference博客访问量APIhttps://www.cnblogs.com/`username`/ajax/blogStats博客排名APIhttps://www.cnblogs.com/`username`/ajax/sidecolumn.aspxdemos博客访问量......
  • 时序预测 | MATLAB实现BO-CNN-LSTM贝叶斯优化卷积神经网络-长短期记忆网络时间序列预
    ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • android2.3新增API StrictMode介绍
    google在android2.3中新增了StrictModeAPI来设置对一个thread的策略(ui线程或者分线程),它主要检测了读写操作,访问网络,数据库读写等耗时的操作并将其以log或者dialog等形式打印出来。分析这些日志,我们可以尽快找出程序运行缓慢的原因进而优化代码,避免ANR(ApplicationNotRespondin......
  • 关于Linux操作系统OS账号最后一次登录时间的审计
    本文以RedHatEnterpriseLinuxrelease8.1(Ootpa)为例,应该也能适用于7.x版本的如果对操作系统中的账号审计,其中有一个项目可能会比较重要(尤其是对于个人账号),那就是最后一次登录的记录如果需要查看每一个OS账号的最后一次登录记录,可以使用lastlog命令[qq-5201351@localho......
  • Linux用ntpdate自动同步时间后使用crontab定时任务更新
     两种同步linux系统的时间方法:(1)开启ntpd服务,即配置ntp服务器实现时间同步。(2)利用ntp客户端程序,即ntpdate同步时间。注意:因为ntp服务器本来就会与上层时间服务器进行同步,所以在默认的情况下,ntp服务器不可以使用ntpdate,也就是说ntpdate和ntpd不能同时启用。上一篇已经介绍......
  • MetaWeblog API
    MetaWeblogAPIMetaWeblogThefollowingmethodsaresupported:blogger.deletePostblogger.getUsersBlogsmetaWeblog.editPostmetaWeblog.getCategoriesmetaWeblog.getPostmetaWeblog.getRecentPostsmetaWeblog.newMediaObjectmetaWeblog.newPostmethodblog......