javaSE基础-日期时间
日期时间类
日期时间主要类
jdk8之前常用的日期时间API
System静态方法
//System类中的currentTimeMillis()
@Test
public void test1(){
//返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差(俗称时间戳)
long time = System.currentTimeMillis();
System.out.println(time);//1661945707478
}
Date类
java.util.Date类
1、两个构造器的使用
构造器一:Date():创建一个对应当前时间的Date对象
构造器二:创建指定毫秒数的Date对象
2、两个方法的使用:
toString():显示当前时间的年月日时分秒
getTime():获取当前Date对象对应的毫秒数(时间戳)
java.sql.Date类
示例:构造器使用
@Test
public void test2(){
//构造器一
Date date1 = new Date();
System.out.println(date1.toString());//Mon Aug 22 16:34:19 CST 2022
long time = date1.getTime();
System.out.println(time);//1661157259360
//构造器二
Date date2 = new Date(3465436457L);
System.out.println(date2.toString());
//sql中Date的构造器
java.sql.Date date3 = new java.sql.Date(1661157259360L);
System.out.println(date3.toString());//2022-08-22
}
如何将java.util.Date对象转换为 java.sql.Date对象
@Test
public void test2(){
//java.util.Date对象转换为java.sql.Date,使用getTime()时间毫秒数转换
//情况一:
Date date5 = new java.sql.Date(3465436457L);
java.sql.Date date6 = (java.sql.Date) date5;
System.out.println(date6.toString()); //1970-02-10
//情况二:date1.getTime()为java.util.Date的时间戳
java.sql.Date date4 = new java.sql.Date(date1.getTime());
System.out.println(date4.toString());//2022-08-22
}
Calendar类
Calendar日历类(abstract)的使用
获取实例的方式:
1、使用Canlendar.getInstance()方法
2、调用它的子类GregorianCalendar的构造器
@Test
public void test3(){
//实例化
GregorianCalendar gc = new GregorianCalendar();
System.out.println(gc.getClass());//class java.util.GregorianCalendar
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getClass());//class java.util.GregorianCalendar
//常用方法
//get()
int days = calendar.get(Calendar.DAY_OF_YEAR);//这一年的第几天
System.out.println(days);
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//这一月的第几天
System.out.println(calendar.get(Calendar.DAY_OF_WEEK));//从周日开始算一周的第一天,这一周的第几天
//set()
//calendar可变性
calendar.set(Calendar.DAY_OF_MONTH, 26);//设置当前Date日期为 26日
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
//add()
calendar.add(Calendar.DAY_OF_MONTH, 2);//当前日期下 +2,注:减三天则值为-3
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
//getTime(): Calendar日历类 --> Date
Date date = calendar.getTime();
System.out.println(date);
//setTime()
Date date1 = new Date();
calendar.setTime(date1);//重置当前Date日期时间
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
}
注:
获取月份时:一月是 0,二月是1
获取星期时:周日是1,周一是2
SimpleDateFormat类
SimpleDateFormat的使用:SimpleDateFormat对日期Date类的格式化和解析
1、格式化:日期 -->字符串
xxx.format()
2、解析:字符串 --> 日期
xxx.parse()
@Test
public void test1() throws ParseException {
//SimpleDateFormat()无参构造的方式
SimpleDateFormat sdf = new SimpleDateFormat();
Date date1 = new Date();
System.out.println(date1);//Wed Aug 24 15:14:51 CST 2022
//格式化
String str1 = sdf.format(date1);
System.out.println(str1);//22-8-24 下午3:14
//解析
Date parseDate = sdf.parse("22-10-24 下午3:14");
System.out.println(parseDate);//Mon Oct 24 15:14:00 CST 2022
System.out.println("***********************");
//有参构造,自定义格式话标准
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str2 = sdf2.format(date1);
System.out.println(str2);//2022-08-24 15:25:40
Date date4 = sdf2.parse("2022-10-11 13:25:09");
System.out.println(date4);//Tue Oct 11 13:25:09 CST 2022
}
/**
* 字符串“2020-12-01” 转换为 java.sql.Date类的日期
*/
@Test
public void test2() throws ParseException {
String info = "2020-12-01";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse(info);
System.out.println(date);//Tue Dec 01 00:00:00 CST 2020
java.sql.Date date1 = new java.sql.Date(date.getTime());//将date调用getTime()转为时间戳
System.out.println(date1);//2020-12-01
}
jdk8中新的日期时间API
Java8汲取Joda-Time第三方jar包的日期时间API,开发出全新的java.time的API
LocalDate、LocalTime、LocalDateTime类是主要的使用类,它们的实例对象是不可变的对象,分别表示使用ISO-8601日历系统的日期、时间、日期和时间。
LocalDateTimeL较其它两个使用频率更高
注:ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法,也就是公历。
LocalDate \ LocalTime \ LocalDateTime类
常用方法
示例
click me
@Test
public void test2(){
//实例化localDateTime
//1、now():获取当前的日期+时间
LocalDateTime localDateTime = LocalDateTime.now();
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
System.out.println(localDateTime);
System.out.println(localDate);
System.out.println(localTime);
//2、of():设置指定具体的年、月、日、时、分、秒,没有偏移量设置
LocalDateTime localDateTime2 = LocalDateTime.of(2022, 8, 26, 13, 38, 10);
System.out.println(localDateTime2);
//获取具体字段时间的方法:xxx.get()
//获取年份
int year = localDateTime.getYear();
System.out.println(year);//2022
//获取月份,enum形式
Month month = localDateTime.getMonth();
System.out.println(month);//AUGUST
//获取月份,数字形式
int monthValue = localDateTime.getMonthValue();
System.out.println(monthValue);//8
//获取月份的第几天,相当于当前几号
int day = localDateTime.getDayOfMonth();
System.out.println(day);//26
//获取一周的第几天,相当于周几
DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
System.out.println(dayOfWeek);//FRIDAY
//获取一年的第几天
int dayOfYear = localDateTime.getDayOfYear();
System.out.println(dayOfYear);//238
//设置时间
LocalDateTime localDateTime3 = localDateTime.withDayOfMonth(28);//设置当前为28日
System.out.println(localDateTime);//2022-08-26T13:56:28.256,原来的时间不可变
System.out.println(localDateTime3);//2022-08-28T13:56:28.256
//指定时间增加操作
LocalDateTime localDateTime4 = localDateTime.plusDays(3);//当前时间+3
System.out.println(localDateTime);//2022-08-26T14:00:27.193
System.out.println(localDateTime4);//2022-08-29T14:00:27.193
//指定时间减小操作
LocalDateTime localDateTime5 = localDateTime.minusDays(5);
System.out.println(localDateTime);//2022-08-26T14:02:34.666
System.out.println(localDateTime5);//2022-08-21T14:02:34.666
}
Instant类
时间上的一个瞬时点。概念上,只是简单的表示自1970年1月1日0时0分0秒(UTC开始的秒数)
常用方法
示例
click me
@Test
public void test3(){
//实例化:now():获取本初子午线对应的标准时间
Instant instant = Instant.now();
System.out.println(instant);
//添加时间偏移量
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.UTC);
System.out.println(offsetDateTime);//2022-08-26T07:29:14.259Z
//获取自1970年1月1日0时0分0秒的 毫秒数
long milli = instant.toEpochMilli();
System.out.println(milli);//1661499089722
//将指定的毫秒数 转换为 Instant的实例对象
Instant instant1 = Instant.ofEpochMilli(1661499089722L);
System.out.println(instant1);//2022-08-26T07:31:29.722Z
}
DateTimeFormatter类
DateTimeFormatter类:格式化、解析日期时间常用方法
三种格式化方式
- 预定义的标准格式:ISO_LOCAL_DATE_TIME、ISO_LOCAL_DATE、ISO_LOCAL_TIME
- 本地化的格式:ofLocalizedDateTime() 、ofLocalizedDate()、ofLocalizedTime()
- 自定义格式:ofPattern("yyyy-MM-dd hh:mm:ss E")
常用方法
示例
click me
@Test
public void test4(){
//方式一:预定义标准格式:ISO_LOCAL_DATE_TIME、ISO_LOCAL_DATE、ISO_LOCAL_TIME
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
//格式化: 日期 --> 字符串
LocalDateTime localDateTime = LocalDateTime.now();
String str = dateTimeFormatter.format(localDateTime);
System.out.println(str);//2022-08-26T15:59:49.101
//解析: 字符串--> 日期
TemporalAccessor dateTime = dateTimeFormatter.parse("2022-08-26T15:59:49.101");
System.out.println(dateTime);//{},ISO resolved to 2022-08-26T15:59:49.101
//方式二:本地化
//①ofLocalizedDateTime(): 参数有FormatStyle.LONG \ FormatStyle.MEDIUM \ FormatStyle.SHORT,用于格式化LocalDateTime类的时间形式
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
String str2 = formatter.format(LocalDateTime.now());
System.out.println(str2);//2022年8月26日 下午04时16分23秒
//②ofLocalizedDate():参数有 FormatStyle.FULL \ FormatStyle.LONG \ FormatStyle.MEDIUM \ FormatStyle.SHORT,用于格式化LocalDateTime类的时间形式
DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
String str3 = formatter2.format(LocalDateTime.now());
System.out.println(str3);//2022年8月26日 星期五
//③ofLocalizedTime(): 参数有FormatStyle.LONG \ FormatStyle.MEDIUM \ FormatStyle.SHORT,用于格式化LocalDateTime类的时间形式
DateTimeFormatter formatter3 = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
String str4 = formatter3.format(LocalDateTime.now());
System.out.println(str4);//下午4:21
//方式三: 自定义的格式(常用的)如 ofPattern("yyyy-MM-dd hh:mm:ss E")
DateTimeFormatter formatter4 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss E");
//格式化
String str5 = formatter4.format(LocalDateTime.now());
System.out.println(str5);//2022-08-26 04:26:37 星期五
//解析
TemporalAccessor dateTime2 = formatter4.parse("2022-08-26 04:26:37 星期五");
System.out.println(dateTime2);//{MinuteOfHour=26, HourOfAmPm=4, NanoOfSecond=0, MilliOfSecond=0, SecondOfMinute=37, MicroOfSecond=0},ISO resolved to 2022-08-26
}
总结
日期时间API迭代
第一代:jdk1.0 Date类API
第二代:jdk1.1 Calendar日历类API
第三代:jdk1.8 LocalDateTime类等全新的API
jdk1.8中日期时间API包含的包:
java.time 日期、时间、时刻主要的API,和持续时间。
java.time.chrono 除了默认的标准以外的日历系统的通用的。
java.time.format 提供打印和解析日期和时间的类。
java.time.temporal 访问日期和时间的应用领域和单位,时间和日期的调节。
java.time.zone 支持时区及其规则。
前两代日期时间存在的问题:
可变性:日期时间这样的类本该不可改变的,但如Calendar类的set()方法,可以修改当前对象的时间
@Test
public void test3(){
//实例化
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getClass());//class java.util.GregorianCalendar
//set():返回值位void,覆盖了原来对象的值
calendar.set(Calendar.DAY_OF_MONTH, 26);//设置当前Date日期为 26日
System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
}
偏移性:Date中的年份是从1900开始计算,月份是从0开始的
@Test
public void test1(){
Date date = new Date(2022,9,10,12,1,31);
System.out.println(date);//Tue Oct 10 12:01:31 CST 3922
//偏移量问题
Date date2 = new Date(2022-1900,9-1,10,12,1,31);
System.out.println(date2);//Sat Sep 10 12:01:31 CST 2022
}
格式化:格式化只针对Date用,Calendar类不行
@Test
public void test1() throws ParseException {
//SimpleDateFormat()无参构造的方式:日期时间 --> 字符串
SimpleDateFormat sdf = new SimpleDateFormat();
Date date1 = new Date();
System.out.println(date1);//Wed Aug 24 15:14:51 CST 2022
//格式化
String str1 = sdf.format(date1);
System.out.println(str1);//22-8-24 下午3:14
}
其它拓展
案例:三天打渔,两天晒网。终端输入一个日期(如2023-5-3),计算从某个固定日期(如1990-01-01)开始轮回打渔晒网操作,计算此时5月3日当天打渔还是晒网?
分析
示例
click me
public class FishTest2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入年份:");
int year = sc.nextInt();
System.out.println("请输入月份:");
int month = sc.nextInt();
System.out.println("请输入日期:");
int day = sc.nextInt();
String nowDate = year + "-" + month + "-" + day;
try {
//从1990-01-01开始到输入当年相差的天数
int thisDays = getDays(year, month, day);
//输入当年日期在这一年的第几天的天数
int dateNum = getDays2(year);
printInfo(thisDays, dateNum, nowDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
//获取输入日期为当年的第几天
public static int getDays(int year, int month, int day) throws ParseException {
String str = year + "-" + month + "-" + day;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse(str);
Calendar calendar = Calendar.getInstance();
//将Calendar日历类设置为某个日期
calendar.setTime(date);
//求该日期为这一年的第几天
int secondPart = calendar.get(Calendar.DAY_OF_YEAR) - 1;
return secondPart;
}
//判断这一年是否为闰年
public static boolean isRunNian(int year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
return true;
}
return false;
}
//计算1990-01-01起到指定日期的当年相差天数
@Test
public static int getDays2(int year) throws ParseException {
String str = "1990-01-01";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date startDate = sdf.parse(str);
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
int startDay = calendar.get(Calendar.DAY_OF_YEAR);
int startYear = calendar.get(Calendar.YEAR);
int firstPartDay = 0;
if (isRunNian(startYear)) {
firstPartDay = 366 - startDay;
} else {
firstPartDay = 365 - startDay;
}
int dateNum = 0;
for (int i = startYear + 1; i < year; i++) {
if (isRunNian(year)) {
dateNum += 366;
} else {
dateNum += 365;
}
}
int firstPart = dateNum + firstPartDay;
return firstPart;
}
//输出打印 打渔还是晒网:总天数 % 5 ==1,2,3 为打渔;总天数 % 5 ==0,4 为晒网
static void printInfo(int thisDate, int dateNum, String nowDate) {
int sumDate = thisDate + dateNum;
if (sumDate % 5 == 1 || sumDate % 5 == 2 || sumDate % 5 == 3) {
System.out.println(nowDate + ",这一天在打渔!");
} else {
System.out.println(nowDate + ",这一天在晒网!");
}
}
}