首页 > 编程语言 >Java8 日期时间

Java8 日期时间

时间:2023-11-23 21:04:59浏览次数:37  
标签:UTC Instant System long 日期 时间 now Java8

概念

彻底弄懂GMT、UTC、时区和夏令时
java中的时间与时区:LocalDateTime和Date

UTC

public static Instant java.time.Instant#now() {
    return Clock.systemUTC().instant();
}

UTC(Coodinated Universal Time),协调世界时,又称世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。
在军事中,协调世界时会使用“Z”来表示。又由于Z在无线电联络中使用“Zulu”作代称,协调世界时也会被称为"Zulu time"。

GMT
GMT(Greenwich Mean Time), 格林威治平时(也称格林威治时间)。
它规定太阳每天经过位于英国伦敦郊区的皇家格林威治天文台的时间为中午12点。

1972年之前,格林威治时间(GMT)一直是世界时间的标准。1972年之后,GMT 不再是一个时间标准了。

T 和 Z
2023-10-23T09:04:59.435228400Z
T表示分隔符(日期和时间分隔符),Z表示的是UTC。
UTC:世界标准时间,在标准时间上加上8小时,即东八区时间,也就是北京时间。

Instant 的 toString 就是 UTC 时间
LocalDateTime 的 toString 无论哪个时区,都不会有 Z

// 2023-10-23T09:06:14.321339500Z
// 2023-10-23T17:06:14.383132800
System.out.println(Instant.now());
System.out.println(LocalDateTime.now());


public String java.time.LocalDateTime#toString() {
    return date.toString() + 'T' + time.toString();
}

Instant

Instant 类返回的值计算从 1970 年 1 月 1 日(1970-01-01T00:00:0Z)第一秒开始的时间, 也称为 EPOCH。 发生在时期之前的瞬间具有负值,并且发生在时期后的瞬间具有正值。

  • now
  • getEpochSecond:秒数
  • getNano:adjustment,在 getEpochSecond 基础上便宜的纳秒数,也即 getEpochSecond 转纳秒 + getNano 才是真正的纳秒

System.currentTimeMillis()

输出

8:22:41 GMT
...16:22:41.193561500
public class Demo04 {
    public static void main(String[] args) {
        printNow();
        System.out.println(LocalDateTime.now());
    }


    private static void printNow() {
        //获得系统的时间,单位为毫秒,转换为妙
        long totalMilliSeconds = System.currentTimeMillis();
        long totalSeconds = totalMilliSeconds / 1000;

        //求出现在的秒
        long currentSecond = totalSeconds % 60;

        //求出现在的分
        long totalMinutes = totalSeconds / 60;
        long currentMinute = totalMinutes % 60;

        //求出现在的小时
        long totalHour = totalMinutes / 60;
        long currentHour = totalHour % 24;

        //显示时间
        System.out.println(currentHour + ":" + currentMinute + ":" + currentSecond + " GMT");
    }
}

System.currentTimeMillis() 无论是哪个时区在同一时刻得到的结果都是相同的,printNow 得到的也是 UTC 时间,相对北京时间慢 8h。

Instant.now()

public static Instant java.time.Instant#now() {
    return Clock.systemUTC().instant();
}

public static Clock java.time.Clock#systemUTC {
    return SystemClock.UTC;
}

static final class SystemClock extends Clock implements Serializable {
    private static final long OFFSET_SEED =
            System.currentTimeMillis() / 1000 - 1024; // initial offest
    static final SystemClock UTC = new SystemClock(ZoneOffset.UTC);

    private final ZoneId zone;

    // 注意这个是 SystemClock.OFFSET_SEED, static final 的
    private transient long offset;

    SystemClock(ZoneId zone) {
        this.zone = zone;
        this.offset = OFFSET_SEED;
    }

    // 新的时区, 新的实例
    public Clock withZone(ZoneId zone) {
        if (zone.equals(this.zone)) {  // intentional NPE
            return this;
        }
        return new SystemClock(zone);
    }

    // 毫秒直接使用 System.currentTimeMillis
    public long millis() {
        return System.currentTimeMillis();
    }

    // 转 instant
    public Instant instant() {
        // 注意这个是 SystemClock.OFFSET_SEED, static final 的
        long localOffset = offset;
        // 偏移, 相对于 localOffset 这个时间点的偏移
        long adjustment = VM.getNanoTimeAdjustment(localOffset);

        // 说明相对 OFFSET_SEED 时间太远, 重新获取
        if (adjustment == -1) {
            localOffset = System.currentTimeMillis()/1000 - 1024;

            // retry
            adjustment = VM.getNanoTimeAdjustment(localOffset);

            if (adjustment == -1) {
                throw new InternalError("Offset " + localOffset + " is not in range");
            } else {
                offset = localOffset;
            }
        }
        // 转 Instant
        return Instant.ofEpochSecond(localOffset, adjustment);
    }
}

Instant 转 LocalDateTime

会加上时区偏移对应的秒数来最终获取时间,也即 UTC 时间 + 时区相差的时间

LocalDateTime.ofInstant(Instant.now(), ZoneOffset.ofHours(8));
LocalDate.ofInstant(Instant.now(), ZoneOffset.ofHours(8));
LocalTime.ofInstant(Instant.now(), ZoneOffset.ofHours(8));

LocalDateTime 是不带时区的(LocalDate、LocalTime也不带)。

ZonedDateTime、OffsetDateTime 是带时区的。

System.out.println(ZonedDateTime.now());
System.out.println(OffsetDateTime.now());

时区当地时间 + 相对 UTC 时间偏移 + 时区

2023-10-23T17:14:08.198466100+08:00[Asia/Shanghai]
2023-10-23T17:14:08.198466100+08:00

Instant 转

System.out.println(ZonedDateTime.ofInstant(Instant.now(), ZoneOffset.ofHours(8)));
System.out.println(OffsetDateTime.ofInstant(Instant.now(), ZoneOffset.ofHours(8)));
2023-10-23T17:15:14.939259900+08:00
2023-10-23T17:15:14.942248300+08:00

转 Instant

  • LocalDateTime.toInstant:需要时区参数,从而能转成 UTC 的毫秒数
  • ZonedDateTime、OffsetDateTime 能直接 toInstant

Duration/Period 时间差

  • Duration:用于计算 2 个时间(LocalTime,时分秒)的差值
  • Period:用于计算 2 个 日期(LocalDate,年月日)的差值

between 方法

Date、LocalDate 转换

主要是通过中间 Instant 转换,因为时区不同,但是同一时刻 Instant 是相同的

标签:UTC,Instant,System,long,日期,时间,now,Java8
From: https://www.cnblogs.com/chenxingyang/p/17783012.html

相关文章

  • delphi 时间格式化,动态显示时间,显示最新时间
    动态显示时间(需要Timer控制的支持,以下代码放到Timer事件中)Label1.Caption:=FormatDateTime('yyyy-mm-dd  hh:mm:ss',Now);显示当前时间(放在窗体的OnShow事件中)edit1.text:=FormatDateTime('YYYYMMDDHHMMSSZZZ',now());时间格式化Windows中的时间格式还真不少,什么......
  • 获取多种日期格式
    日期工具类importjava.sql.Timestamp;importjava.text.ParseException;importjava.text.SimpleDateFormat;importjava.util.*;publicfinalclassDateUtils{privateDateUtils(){}/***显示年月日时分秒,例如2015-08-1109:51:53.*/......
  • 时间复杂度与空间复杂度
    时间复杂度:主要衡量的是一个算法的运行速度。空间复杂度:主要衡量一个算法所需要的额外空间。在计算机发展的早期,计算机的存储容量很小,所以对空间复杂度很是在乎。但是随着计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法......
  • java常用时间日期类总结
    前置知识:UTC时间(CoordinatedUniversalTime):协调世界时,主要的世界时间标准,0时区的时间UTC+8:东八区时间Epoch(纪元):1970-01-0100:00:00UTC(北京时间1970-01-0100:08:00UTC+8) 常用类描述 System.currentTimeMillis()返回Epoch至今的毫秒数 java.ut......
  • 管理时间的四象限法则
    在管理工作和生活中,我们经常面临着各种各样的任务和事务。为了更好地处理这些任务,可以借鉴“重要紧急”、“重要不紧急”、“不重要紧急”以及“不重要不紧急”这四个象限的概念。重要紧急:这类任务需要立刻行动,因为它们对目标或责任的实现产生直接影响。应该全身心投入这类任务,确......
  • Java8函数式接口, 方法引用, 构造器引用, 数组引用
    函数式(Functional)接口只包含一个抽象方法的接口,称为函数式接口。你可以通过Lambda表达式来创建该接口的对象。(若Lambda表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明我们可以在一个接口上使用@Functionallnterface注解,这样做可以检查......
  • oracle 日期时间函数使用总结
    常用日期数据格式获取年的最后一位,两位,三位,四位--获取年的最后一位selectto_char(sysdate,'Y')fromdual;--获取年的最后两位selectto_char(sysdate,'YY')fromdual;--获取年的最后三位selectto_char(sysdate,'YYY')fromdual;--获取年的最后四位select......
  • pandas datetime 获取当前时间之前一个月的时间
    在Python中,我们可以使用pandas和datetime模块来获取当前日期之前一个月的时间。以下是一个示例:使用pandas:importpandasaspdfrompandas.tseries.offsetsimportDateOffset#获取当前日期now=pd.to_datetime('today')#计算一个月前的日期one_month_ago=now-DateOf......
  • Date、Calendar(日历对象)、LocalDateTime三大时间日期类的各种处理方式【精选集】
    Date类:1.1、将字符串型时间日期转化为date类型StringtimeString="2023-11-1709:27:00";SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-ddHH:mm:ss");//创建"简单时间格式化"对象,格式为:yyyy-MM-ddHH:mm:sstry{D......
  • Java时间截和日期格式相互转换的方法。
    1.将时间戳转换为日期格式: 2.将日期格式转换为时间戳: ......