黑马Java基础笔记-12

时间

  • GMT:(格林尼治平均时间),旧时间标准(基于地球自转),已被UTC取代。
  • UTC:现代国际标准时间(基于原子钟),计算机系统默认时间基准。
  • **CST(北京时间(UTC+8)/美国中部时间(UTC-6)/澳大利亚中部时间(UTC+9:30)…):明确标注为UTC+8或Asia/Shanghai时区,避免使用CST缩写。
  • Date存储:以UTC时间1970-01-01T00:00:00为基准的毫秒值,显示时受系统时区影响。

JDK7时间类(线程不安全)

Date
  • 存储基准:内部通过long类型存储的是从1970年1月1日00:00:00 UTC(而非GMT+8)起经过的毫秒值与时区无关

  • 中国时间显示问题:当系统时区设置为东八区时,DatetoString()

    方法会将UTC时间自动偏移+8小时显示(如1970-01-01 08:00:00 CST),但底层存储的毫秒值仍为0。

构造方法
new Date()//当前时间
new Date(0L)//创建日期对象,把当前的毫秒值转成日期对象
常用方法
public long getTime() //把日期对象转换成对应的时间毫秒值。
public void setTime(long time) //把方法参数给定的毫秒值设置给日期对象

SimpleDateFormat
构造方法
public SimpleDateFormat(String pattern);
  • 用给定的模式和默认语言环境的日期格式符号构造SimpleDateFormat。参数pattern是一个字符串,代表日期时间的自定义格式。
  • 不写是默认格式
常用方法
public String format(Date date):将Date对象格式化为字符串。

public Date parse(String source):将字符串解析为Date对象。

Calendar
  • Calendar代表了系统当前时间的日历对象,可以单独修改、获取时间中的年,月,日

  • 细节:Calendar是抽象类,不能直接实例化,必须通过静态方法getInstance()获取子类对象。

    Calendar c = Calendar.getInstance();
    
    //2.修改一下日历代表的时间
    Date d = new Date(OL);
    c.setTime(d);
    
    底层原理
    1. 时区敏感
      根据系统默认时区创建日历对象,默认表示当前时间。
    2. 时间字段存储
      将纪元(Era)、年、月、日、时、分、秒、星期等时间字段存入内部数组,通过常量索引访问(如Calendar.YEAR)。
    关键细节
    月份范围
    • 范围0~11

    • 映射关系:

    数值实际月份
    01月
    12月
    1112月
    星期范围
    • 范围1~7

    • 映射关系:

    数值实际星期
    1星期日(Sunday)
    2星期一(Monday)
    7星期六(Saturday)
常用方法
public int get(int field) 取日期中的某个字段信息
public void set(int field,int value) 修改日历的某个字段信息
public void add(int field,int amount) 为某个字段增加/减少指定的值

JDK8新增时间类(线程安全)

JDK8时间类类名作用
ZoneId时区
Instant时间戳
ZoneDateTime带时区的时间
DateTimeFormatter用于时间的格式化和解析
LocalDate年、月、日
LocalTime时、分、秒
LocalDateTime年、月、日、时、分、秒
Duration时间间隔(秒,纳,秒)
Period时间间隔(年,月,日)
ChronoUnit时间间隔(所有单位)
Date上位
ZoneId 时区
static Set<string> getAvailableZoneIds() 获取Java中支持的所有时区(600多)
static ZoneId systemDefault() 获取系统默认时区(可以在系统设置中改)
static Zoneld of(string zoneld) 获取一个指定时区(配合后续的时间类使用)
//1.获取所有的时区名称
Set<String> zoneIds = ZoneId.getAvailableZoneIds();
System.out.println(zoneIds.size());//600

//2.获取当前系统的默认时区
ZoneId zoneId = ZoneId.systemDefault();
System.out.println(zoneId);//Asia/Shanghai

//3.获取指定的时区
ZoneId zoneId1 = ZoneId.of("Asia/Pontianak");
System.out.println(zoneId1);//Asia/Pontianak

Instant 时间戳

时间戳不可变在减少时间系列的方法与增加时间系列的方法中会返回一个新的时间戳对象,保证线程安全

Instant 的默认输出遵循 ISO-8601 标准,格式为 YYYY-MM-DDTHH:mm:ss.SSSSSSSSSZ,其中:

  • T 是日期和时间的分隔符;

  • Z 表示UTC时区(零时区);

  • .SSSSSSSSS 部分为纳秒精度,若纳秒值为零则省略

    2024-01-07T14:44:58.805Z
    

    此处 805 表示 805 毫秒(即 805,000,000 纳秒),若存在非零纳秒,会显示完整 9 位(如 123456789 纳秒会显示为 .123456789

static Instant now() 获取当前时间的Instant对象(标准时间)
static Instant ofXxxx(long epochMilli) 根据(/毫秒/纳秒)获取Instant对象
ZonedDateTime atZone(ZoneIdzone) 指定时区
boolean isxxx(Instant otherInstant) 判断系列的方法(大于还是小于)
Instant minusXxx(long millisToSubtract) 减少时间系列的方法
Instant plusXxx(long millisToSubtract) 增加时间系列的方法
//1.获取当前时间的Instant对象(标准时间)
Instant now = Instant.now();
System.out.println(now);

//2.根据(秒/毫秒/纳秒)获取Instant对象
Instant instant1 = Instant.ofEpochMilli(0L);
System.out.println(instant1);//1970-01-01T00:00:00z

Instant instant2 = Instant.ofEpochSecond(1L);
System.out.println(instant2);//1970-01-01T00:00:01Z

Instant instant3 = Instant.ofEpochSecond(1L, 1000000000L);
System.out.println(instant3);//1970-01-01T00:00:027

//3. 指定时区
ZonedDateTime time = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(time);  会加上8小时

//4.isXxx 判断
Instant instant4=Instant.ofEpochMilli(0L);
Instant instant5 =Instant.ofEpochMilli(1000L);

//5.用于时间的判断
//isBefore:判断调用者代表的时间是否在参数表示时间的前面
boolean result1=instant4.isBefore(instant5);
System.out.println(result1);//true

//isAfter:判断调用者代表的时间是否在参数表示时间的后面
boolean result2 = instant4.isAfter(instant5);
System.out.println(result2);//false

//6.Instant minusXxx(long millisToSubtract) 减少时间系列的方法
Instant instant6 =Instant.ofEpochMilli(3000L);
System.out.println(instant6);//1970-01-01T00:00:03Z

Instant instant7 =instant6.minusSeconds(1);
System.out.println(instant7);//1970-01-01T00:00:02Z

ZoneDateTime 带时区的时间

与时间戳一样都为不可变的,修改返回的都是新对象

static ZonedDateTime now() 获取当前时间的ZonedDateTime对象(带时区,默认电脑时区)
static ZonedDateTime ofXxxx(。。。) 获取指定时间的ZonedDateTime对象
ZonedDateTime withXxx(时间) 修改时间系列的方法
ZonedDateTime minusXxx(时间) 减少时间系列的方法
ZonedDateTime plusXxx(时间) 增加时间系列的方法
//1.获取当前时间对象(带时区)
ZonedDateTime now = ZonedDateTime.now();
System.out.println(now);

//2.获取指定的时间对象(带时区)1/年月日时分秒纳秒方式指定
ZonedDateTime time1 = ZonedDateTime.of(2023,10,1,11,12,12,0,ZoneId.of("Asia/Shanghai"));
System.out.println(time1);

//通过Instant + 时区的方式指定获取时间对象
Instant instant = Instant.ofEpochMilli(0L);
ZoneId zoneId = ZoneId.of("Asia/Shanghai");
ZonedDateTime time2 = ZonedDateTime.ofInstant(instant, zoneId);
System.out.println(time2);

//3.withXxx 修改时间系列的方法
ZonedDateTime time3 = time2.withYear(2000);
System.out.println(time3);

//4. 减少时间
ZonedDateTime time4 = time3.minusYears(1);
System.out.println(time4);

//5.增加时间
ZonedDateTime time5 = time4.plusYears(1);
System.out.println(time5);

SimpleDateFormat上位

DateTimeFormatter 用于时间的格式化和解析
static DateTimeFormatter ofPattern(格式) 获取格式对象
String format(时间对象) 按照指定方式格式化
//获取时间对象
ZonedDateTime time = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));

// 解析/格式化器
DateTimeFormatter dtf1=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm;ss EE a");
// 格式化
System.out.println(dtf1.format(time));
Calendar上位

LocalDate 年、月、日

LocalTime 时、分、秒

LocalDateTime 年、月、日、时、分、秒

方法类型方法名/模式功能说明适用类
静态工厂方法static XXX now()获取当前时间对象(默认时区)LocalDate/Time/DateTime
static XXX of(...)指定参数创建时间对象(如 of(2025, 4, 27)同上
字段获取getYear() / getMonth()获取年、月、日、时、分、秒等字段值同上
getDayOfWeek()获取星期枚举(如 SUNDAYLocalDate/DateTime
时间比较isBefore(其他时间对象)判断当前时间是否早于指定时间同上
isAfter(其他时间对象)判断当前时间是否晚于指定时间同上
时间修改withYear(2026)直接修改特定字段(年、月、日、时等)同上
with(TemporalAdjuster)高级调整(如设置为当月第一天)LocalDate/DateTime
时间增减plusDays(7)增加指定时间量(天、月、年、时、分等)同上
minusHours(3)减少指定时间量(链式操作,返回新对象)同上

工具类
  • **Duration **: 用于计算两个“时间”间隔(秒,纳秒)

    System.out.println("相差的时间间隔对象:" + duration); // 输出:PT197637H27M42.639166S  
    
    • 格式规则:

    • PT 表示“时间段开始”(P 是 Period 前缀,T 分隔日期与时间)。

    • H 表示小时,M 表示分钟,S 表示秒(含纳秒精度)。

    • 含义:时间差为

    197,637 小时 27 分钟 42.639166 秒。

    • 注意Duration 不会自动将小时转换为天(如 24 小时 = 1 天),而是以单一单位累加(25小时,26小时…)。

    使用:duration.toXXX(),将其转化为天/小时/分钟等

  • **Period **: 用于计算两个“日期”间隔(年、月、日)

    Period age = Period.between(birthDate, LocalDate.now());
    System.out.println("相差的时间间隔对象:" + period);  // 输出:P22Y6M17D
    System.out.println(period.getYears());          // 输出:22
    System.out.println(period.getMonths());         // 输出:6
    System.out.println(period.getDays());           // 输出:17
    
    • 格式说明P 是 Period 的前缀,后跟 年(Y)月(M)日(D) 的组合。
    • 含义:表示时间间隔为 22 年 6 个月 17 天
    • 注意:若某个字段为 0 会被省略(例如 P0Y3M2D 会显示为 P3M2D
  • ChronoUnit :用于计算两个“日期”间隔(最常用)

    long totalMinutes = ChronoUnit.MINUTES.between(birthDate, today);  
    

    long between(Temporal start, Temporal end)中间加上要返回的单位


包装类

包装类:基本数据类型对应的引用类型

基本类型对应的包装类(位于java.lang包中)
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

integer

// 测试 Integer 缓存范围(-128~127)  
Integer i6 = Integer.valueOf(127);  
Integer i7 = Integer.valueOf(127);  
System.out.println(i6 == i7); // true(值在缓存范围内,对象复用)  

Integer i8 = Integer.valueOf(128);  
Integer i9 = Integer.valueOf(128);  
System.out.println(i8 == i9); // false(超出缓存范围,创建新对象)  

// 使用 new 关键字强制创建新对象(即使值在缓存范围内)  
Integer i10 = new Integer(127);  
Integer i11 = new Integer(127);  
System.out.println(i10 == i11); // false(new 每次生成新对象)  
创建方式行为适用场景
Integer.valueOf(int)-128~127 的整数,直接从缓存池返回对象;否则创建新对象。优先使用,节省内存(复用缓存对象)
new Integer(int)强制创建新对象,无论数值是否在缓存范围内需要独立对象时(极少使用)
2. 关键规则
  • 缓存机制

    • Integer 类默认缓存了 -128~127 之间的整数对象(存在cache数组中),通过 valueOf() 或自动装箱(如 Integer i = 127)会复用这些对象。
    • 超出此范围的数值,每次调用 valueOf() 或自动装箱都会创建新对象。
  • 对象比较

    • ==:比较对象内存地址。仅对缓存范围内的 Integer 对象返回 true
    • equals():比较实际数值,推荐使用。
    Integer a = 128;  
    Integer b = 128;  
    System.out.println(a.equals(b)); // true(数值相等)  
    
自动装箱(Autoboxing)

代码示例

Integer i1 = 10;  
// 等价于:  
Integer i1 = Integer.valueOf(10);  
  • 底层方法:
    • Integer.valueOf(int):将基本类型 int 转换为 Integer 对象。
    • 缓存机制:对 -128~127 范围内的值,返回缓存对象;超出范围则新建对象。
自动拆箱(Unboxing)

代码示例

Integer i2 = new Integer(20);  
int i = i2;  
// 等价于:  
int i = i2.intValue();  
  • 底层方法:
    • Integer.intValue():将 Integer 对象转换为基本类型 int

这两个在集合中非常常用

常用方法
方法名功能分类参数说明返回值示例注意事项
Integer.toBinaryString(int i)进制转换i: 十进制整数StringtoBinaryString(10) → "1010"• 结果无前缀(如 "1010" 而非 0b1010) • 负数返回补码二进制字符串
Integer.toOctalString(int i)进制转换i: 十进制整数StringtoOctalString(10) → "12"• 结果无前缀(如 "12" 而非 0o12
Integer.toHexString(int i)进制转换i: 十进制整数StringtoHexString(255) → "ff"• 结果无前缀且字母小写(如 "ff" 而非 0xff"FF"
Integer.parseInt(String s)字符串转整数s: 十进制数字字符串intparseInt("123") → 123• 字符串非法时抛出 NumberFormatException • 仅支持十进制输入
Integer.parseInt(String s, int radix)字符串转整数s: 数字字符串 radix: 进制(2~36)intparseInt("1010", 2) → 10• 支持 2~36 进制(如 16 进制允许 0-9a-f) • 字母不区分大小写
  • 除了Character都有parseXXX的方法

计算闰年取巧

使用java的时间类:

  • 设置为所需判断的年份的第一天2000年1月1日与最后一天2000年12月31日然后相减,判断是不是366天.
  • 设置为判断的年份的3月1日然后减一天,判断是否为2月29日

直接使用.isLeapYear()方法判断是否为闰年(jdk8+)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值