参考:常用API-15-JDK7时间-Date_哔哩哔哩_bilibili
目录
参考:常用API-15-JDK7时间-Date_哔哩哔哩_bilibili
JDK7以前时间相关类
Date 时间
时间的相关知识点
Date时间类
时间计算
总结
SimpleDateFormate 格式化时间
作用
构造方法以及常用方法
Calendar 日历
获取Calendar日历类对象的方法
获取日历对象
修改日历代表的时间
获取年月日
修改年份/月份/日期等
增加时间/减少时间
JDK8新增时间相关类
ZoneId时区
Instant 时间戳
ZonDateTime 带时区的时间
DateTimeFormatter 用于时间的格式化和解析
LocalDate 、LocalTime、LocalDateTime
Duration 计算两个时间间隔(秒、纳秒)
Period 计算两个日期间隔(年、月、日)
ChronoUnit 计算两个日期间隔
包装类
两种方法获取对象的区别(掌握)
Integer成员方法
键盘录入
综合练习
第一题 键盘录入
第二题 将字符串形式的数据转换成整数
第三题 实现toBinaryString方法的效果
第四题 时间相关
第五题 判断一个年份是否为闰年
JDK7以前时间相关类
Date 时间
时间的相关知识点
全世界的时间,有一个统一的计算标准
世界标准时间:
过去:格林尼治时间/格林威治时间,简称GMT;
现在:目前世界标准时间UTC已经替换为:原子钟
中国标准时间:世界标准时间+8h
时间单位换算:
1秒 = 1000 毫秒
1毫秒 = 1000 微秒
1微秒 = 1000 纳秒
时间原点:1970年1月1日0点0分,中国标准时间需要在次基础上加8小时。
Date时间类
Date类是一个JDK写好的javabean类,用来描述时间,精确到毫秒。
利用空参构造创建的对象,默认表示系统当前时间。
利用有参构造创建的对象,表示指定的时间。
public Date() 创建Date对象,表示当前时间的毫秒值
public Date(long date) 创建Date对象,表示指定时间
public void setTime(long time) 设置/修改毫秒值
public long getTime() 获取时间对象的毫秒值
实现:
时间计算
时间对象Date不能进行相关的运算,所以进行时间运算的时候,需要先把时间对象的毫秒值获取出来再进行运算。
1. 打印时间原点开始一年之后的时间
2. 定义任意两个Date对象,比较一下哪个时间在前,哪个时间在后
总结
1. 如何创建日期对象?
Date date = new Date();
Data date = new Date(指定毫秒值);
2. 如何修改对象中的毫秒值
setTime(毫秒值);
3. 如何获取时间对象中的毫秒值
getTime();
SimpleDateFormate 格式化时间
作用
- 格式化:把时间变成我们喜欢的格式
- 解析:把字符串表示的时间变成Date对象
构造方法以及常用方法
格式化的时间形式的常用模式对应关系如下:
-
public final String format(Date date) 格式化时间(日期对象 -> 字符串) 1. 利用空参构造创建SimpleDateFormat对象,默认格式
//1. 利用空参构造创建SimpleDateFormat对象,默认格式 SimpleDateFormat sdf = new SimpleDateFormat(); Date d = new Date(0L); String str = sdf.format(d); System.out.println(str);//1970/1/1 上午8:00
2. 利用带参构造创建SimpleDateFormat对象,指定格式
//2. 利用带参构造创建SimpleDateFormat对象,指定格式 SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String str2 = sdf2.format(d); System.out.println(str2);//1970年01月01日 08:00:00
3. 在格式化时间时,加入星期
//课堂练习:yyyy年MM月dd日 HH:mm:ss 星期 SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EE"); String str3 = sdf3.format(d); System.out.println(str3);//1970年01月01日 08:00:00
- public Date Parse(String source) 解析(字符串 -> 日期对象)
//定义一个字符串表示时间 String str = "2023-11-11 11:11:11"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = sdf.parse(str); System.out.println(date);//Sat Nov 11 11:11:11 CST 2023
练习
1. 假设,你初恋的出生年月日为:2000-11-11,请用字符串表示这个数据,并将其转换为
//练习 //可以通过200-11-11进行解析,解析成一个Date对象 String str = "2000-11-11"; SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd"); Date date = sdf1.parse(str); //格式化 SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日"); String str2 = sdf2.format(date); System.out.println(str2);
2. 秒杀活动
需求:
public class Demo2 { public static void main(String[] args) throws ParseException { String startStr = "2023年11月11日 0:0:0"; String endStr = "2023年11月11日 0:10:0"; String orderStr1 = "2023年11月11日 0:01:00";//小贾参加活动的时间 String orderStr2 = "2023年11月11日 0:11:00"; //解析时间到毫秒值 SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); Date date1 = sdf.parse(startStr); Date date2 = sdf.parse(endStr); Date orderDate1 = sdf.parse(orderStr1); Date orderDate2 = sdf.parse(orderStr2); long startTime = date1.getTime(); long endTime = date2.getTime(); long orderTime1 = orderDate1.getTime(); long orderTime2 = orderDate2.getTime(); if(orderTime1 >= startTime && orderTime1 <= endTime){ System.out.println("小贾参加活动成功"); }else{ System.out.println("小贾参加活动失败"); } if(orderTime2 >= startTime && orderTime2 <= endTime){ System.out.println("小皮参加活动成功"); }else{ System.out.println("小皮参加活动失败"); } } }
Calendar 日历
Calendar代表了系统当前时间的日历对象,可以单独修改、获取时间中的年、月、日
细节
1. Calender是一个抽象类,不能直接创建对象,而是通过静态方法获取子类对象
底层原理:会根据系统的不同时区来获取不同的日历对象,默认表示当前时间
会把时间中的纪元、年、月、日、时、分、秒、星期,等等的都放在一个数组当中
0:纪元
1:年
2: 月
3:一年中的第几周
4:一个月中的第几周
5:一个月中的第几天(日期)
...
2. 月份:范围0~11,如果获取出来的时0,实际上是1月,以此类推
星期:在国外,星期日是一周中的第一天所以
1(星期日)... 7(星期六)
获取Calendar日历类对象的方法
public static Calender getInstance() 获取当前时间的日历对象
获取日历对象
Calendar c = Calendar.getInstance();
修改日历代表的时间
//获取日历对象 Calendar c = Calendar.getInstance(); //修改日历代表的时间 Date d = new Date(0L); c.setTime(d);
获取年月日
int year = c.get(1); int month = c.get(2); int date = c.get(5); System.out.println(year + ", " + month + ", " + date);//1970, 0, 1
改写:
Java在Calendar类中,把索引对应的数字都定义成常量
int year = c.get(Calendar.YEAR); int month = c.get(Calendar.MONTH); int date = c.get(Calendar.DAY_OF_YEAR); System.out.println(year + ", " + month + ", " + date );//1970, 0, 1
因为上述方法返回的都是数字,假如 对于星期,不想让它返回单独的数字,想直接返回“星期几”,可以写一个方法,通过方法来返回星期
查表法:
表:容器
让数据产生对应关系
修改年份/月份/日期等
增加时间/减少时间
(第二个参数是正数则代表增加时间,如果是负数则代表减少时间)
JDK8新增时间相关类
ZoneId时区
public class Demo1 { public static void main(String[] args) { Set<String> zoneIds = ZoneId.getAvailableZoneIds(); System.out.println(zoneIds.size());//603 System.out.println(zoneIds);//所有的时区 //获取当前系统的默认时区 ZoneId zoneId = ZoneId.systemDefault(); System.out.println(zoneId);//Asia/Shanghai //获取指定时时区 ZoneId zoneId1 = ZoneId.of("Africa/Nairobi"); System.out.println(zoneId1);//Africa/Nairobi } }
Instant 时间戳
ZonDateTime 带时区的时间
DateTimeFormatter 用于时间的格式化和解析
LocalDate 、LocalTime、LocalDateTime
LocalDate只能获取到年月日
LocalTime只能获取到时分秒
LocalDateTime既能获取到年月日又能获取到时分秒,可以转换成LocalTime或者LocalDate。
LocalDate
LocalTime
LocalDateTime
Duration 计算两个时间间隔(秒、纳秒)
Period 计算两个日期间隔(年、月、日)
ChronoUnit 计算两个日期间隔
包装类
以Integer为例
获取Integer对象(JDK5以前)
两种方法获取对象的区别(掌握)
Integer在底层会将-128~127之间所有的数据都创建好Integer的对象,放到数组中,如果当我们使用valueOf获取对象时,会判断该数据是否在-128~127之间,如果在此区间,不会创建新对象,而是返回已经创建好的对象。
在JDK5的时候提供了一个机制:自动装箱和自动拆箱
自动装箱:把基本数据类型会自动的变成其对应的包装类
自动拆箱:把包装类自动的变成其对象的基本数据乐星
在底层,此时还会去自动调用静态方法valueof得到一个Integer对象,只不过这个动作不需要我们自己去操作了
总结
Integer成员方法
返回类型为什么是String?
1. 二进制有可能是010101...的形式,但是整数类型不能以0开头
2. int类型有范围限制,但二进制的位数很长
3. 十六进制中有字母
将字符串类型的整数转成int类型的整数
强类型语言:每种数据在java中都有各自的数据类型
在计算的时候,如果不是同一种数据类型,是无法直接计算的。
细节:
- 在类型转换的时候,括号中的参数只能是数字不能是其他,否则代码会报错
- 8种包装类中,除了Character都有对应的parseXxx的方法,进行类型转换
键盘录入
过去:
Scanner sc = new Scanner(System.in); System.out.println("请输入一个字符串");
弊端:当我们使用next、nextInt、nextDouble在接收数据的时候,遇到空格、回车、制表符的时候就停止了,比如键盘录入的是123 123,在接受的时候只能收到空格前面的数据。
之后:
如果我们想要键盘录入,不管什么理性,统一使用nextLine
特点:遇到回车才停止
之后再将该数据转为我们想要的数据
综合练习
第一题 键盘录入
键盘录入一些1~100之间的整数,并添加到集合中,直到集合中所有数据和超过200为止
public class test { public static void main(String[] args) { //键盘录入一些1~100之间的整数,并添加到集合中,直到集合中所有数据和超过200为止 //1. 创建一个集合 ArrayList<Integer> list = new ArrayList<>(); Scanner sc = new Scanner(System.in); //2. 键盘录入 while(true){ System.out.println("请输入一个整数"); String numStr = sc.nextLine(); int num = Integer.parseInt(numStr); if(num < 1 && num > 100){ System.out.println("数据不符合要求,请重新输入"); continue; } //num是基本数据类型,list中添加的数据是Integer,再添加数据的时候出发了自动装箱 list.add(num); int sum = getSum(list); if(sum > 200){ System.out.println("集合中的所有数据和已经满足要求"); break; } } } private static int getSum(ArrayList<Integer> list) { int sum = 0; for (int i = 0; i < list.size(); i++) { int num = list.get(i); sum += num; } return sum; } }
第二题 将字符串形式的数据转换成整数
自己实现parseInt方法的效果,将字符串形式的数据转换成整数 要求: 字符转只能输数字,不能有其他字符 最少一位,最多10位 0不能开头
System.out.println("请输入一个需要转换成整数的字符串"); Scanner sc = new Scanner(System.in); String str = sc.nextLine(); String regex = "[1-9]\d{0,9}"; int number = 0; if(!str.matches(regex)){ System.out.println("数据格式有误"); }else{ for (int i = 0; i < str.length(); i++) { int c = str.charAt(i) - '0'; number = number * 10 + c; } } System.out.println(number + 1);
第三题 实现toBinaryString方法的效果
除基取余法:不断地除以基数(几进制,基数就是几)得到余数
直到商为0,再将余数倒着拼接起来即可
public class test3 { public static void main(String[] args) { //将一个十进制整数转成字符串表示的二进制 System.out.println("请输入一个十进制整数"); Scanner sc = new Scanner(System.in); int num = sc.nextInt(); int yu; StringBuilder sb = new StringBuilder(); while(num != 0){ yu = num % 2; sb.insert(0, yu); num = num / 2; // sb.append(yu); // sb.reverse(); } System.out.println(sb); } }
第四题 时间相关
public class test4 { public static void main(String[] args) throws ParseException { //请用代码实现计算你活了多少天,用jdk7和jdk8两种方式 //jdk7 //用毫秒值进行判断 //计算出生时间的毫秒值 String birthday = "1949年10月1日"; SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日"); Date date = sdf.parse(birthday); long birthdayTime = date.getTime(); //获取当前时间的毫秒值 long todayTime = System.currentTimeMillis(); //计算间隔多少天 long time = todayTime - birthdayTime; System.out.println(time / 1000 / 60 / 60 / 24); //jdk8 LocalDate ld1 = LocalDate.of(1949, 10, 1); LocalDate ld2 = LocalDate.now(); long days = ChronoUnit.DAYS.between(ld1,ld2); System.out.println(days); } }
第五题 判断一个年份是否为闰年
public class test5 { public static void main(String[] args) { /* 要求:用jdk7和jdk8两种方式判断 提示: 二月有29天为闰年 一年有366天是闰年 */ //jdk7 //把时间设置为2000年3月1日 Calendar c = Calendar.getInstance(); c.set(2000, 2, 1);//月份范围:0~11 //把日历往前减一天 c.add(Calendar.DAY_OF_MONTH, -1); //看时间是28号还是29号 int day = c.get(Calendar.DAY_OF_MONTH); System.out.println(day); //直接将日期设定为本年最后一天,获得这一天是这一年中的第几天 Calendar y = Calendar.getInstance(); y.set(2000,11,31); int day2 = y.get(Calendar.DAY_OF_YEAR); System.out.println(day2); //也可以把时间设置为2001年1月1日,把日期往前减一天,看看当前的时间是365天还是366天 //jdk8 LocalDate Id = LocalDate.of(2000,3, 1); LocalDate ld2 = Id.minusDays(1); int day3 = ld2.getDayOfMonth(); System.out.println(day3); System.out.println(Id.isLeapYear());//直接判断是否为闰年的方法,是闰年返回true } }