JDK8.0 时间类获取当前时间对象原理

JDK1.8新增的一些时间类:
Clock(时钟类)、ZoneId(时区)、ZoneOffset(时区补偿)
LocalDate(获取关键三个属性,getYear(),getMonthValue(),getDayOfMonth)、
LocalTime(获取关键四个属性,getHour(),getMinute(),getSecond(),getNano,然后算术方法)、
LocalDateTime(两个属性:localDate和localTime,可以获取两个类的关键取值方法)、
完整体:ZoneDateTime(LocalDateTime,ZoneOffset补偿,ZoneId时区)
时间戳Instant(获取关键两个属性:getEpochSecond()距1970的毫秒值,getNano()获取纳秒值)等。
·------------------------
以LocalDate为例:
//有三种重载方法now()创建LocalDate,原理都是now(Clock)

class LocalDate {
	public static LocalDate now() {
	    //now()调用了重载方法now(Clock)
	    return now(Clock.systemDefaultZone());
	}
	public static LocalDate now(ZoneId zone) {
	    //now(ZoneId)调用重载方法now(Clock)
	    return now(Clock.system(zone));
	}
	public static LocalDate now(Clock clock) {//Clock.systemDefaultZone()
	    Objects.requireNonNull(clock, "clock"); //判断是否为null,if null Return NullPointerException
	    // inline to avoid creating object and Instant checks
	    final Instant now = clock.instant(); //获取当前时间戳,用来获取秒值
	    //ZoneId clock.getZone(),取到clock对象的时区
	    //ZoneRules clock.getZone().getRules(),拿到一些时区规则
	    //总的来说就是通过时间戳now、默认Clock来获取一个ZoneOffset对象(时区补偿)
	    ZoneOffset offset = clock.getZone().getRules().getOffset(now);
	    //实际秒数=clock的秒数 + 时区补偿秒数?
	    long epochSec = now.getEpochSecond() + offset.getTotalSeconds();  // overflow caught later
	    //通过毫秒值获取距离1970的天数
	    long epochDay = Math.floorDiv(epochSec, SECONDS_PER_DAY);
	    return LocalDate.ofEpochDay(epochDay);
	}
	//通过距离1970的天数,计算出年 月 日 然后返回LocalDate对象,创建完成
	public static LocalDate ofEpochDay(long epochDay) {
	    .....
	    return new LocalDate(year, month, dom);
	}
}

同理LocalTime、LocalDateTime也是通过clock和ZoneOff先获取到秒数,然后计算结果不同而已。
·--------------------------------
Clock子类:SystemClock,调用的是时间戳Instant的类方法ofEpochMilli(millis());

class SystemClock extends Clock{
    SystemClock(ZoneId zone) {
        this.zone = zone;
    }
    @Override
    public Instant instant() {
        return Instant.ofEpochMilli(millis());
    }
    @Override //系统毫秒值
    public long millis() {
        return System.currentTimeMillis();
    }
}

--------------------------
class Clock {
    //就是通过系统默认时区创建了个Clock对象
    public static Clock systemDefaultZone() {
        return new SystemClock(ZoneId.systemDefault());
    }
}

时间戳Instant

    final class Instant {
        public static Instant ofEpochMilli(long epochMilli) {
            //floorDiv(x,y)===> (int)x/y,取整,负数除不尽需要进行--
            long secs = Math.floorDiv(epochMilli, 1000);
            //foorMod(x,y)==> x - floorDiv(x, y) * y;拿到毫秒
            int mos = (int)Math.floorMod(epochMilli, 1000);
            return create(secs, mos * 1000_000);
        }
        //通过秒+纳秒创建Instant
        private static Instant create(long seconds, int nanoOfSecond) {
            if ((seconds | nanoOfSecond) == 0) {
                return EPOCH;
            }
            if (seconds < MIN_SECOND || seconds > MAX_SECOND) {
                throw new DateTimeException("Instant exceeds minimum or maximum instant");
            }
            return new Instant(seconds, nanoOfSecond);
        }
        private Instant(long epochSecond, int nanos) {
            super();
            this.seconds = epochSecond;
            this.nanos = nanos;
        }
        public int getNano() { //获取纳秒值(0-999,999,999)
            return nanos;
        }
        public long getEpochSecond() { //获取毫秒值(距离1970-1-1 0:0:0)
            return seconds;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值