日期处理
三代日期是如何一步一步优化的
第一代日期类
1、Date类
Date类对象用来表示时间和日期,该类提供了一系列操作时间和日期各组成部分的方法。Date类中使用最多的是获取系统当前的日期和时间。如:Date date = new Date();这句代码是使用当前系统时间创建日期对象。
2、DateFormat类
此类是格式化日期时间的类,它在Java.text 包下,是一个抽象类,提供了多种格式化和解析时间的方法。格式化是指将日期转换为文本,解析是指将文本转化成日期格式。使用比较多的是它的子类SimpleDateFormat,SimpleDateFormat类是一个以与语言环境有关的方式来格式化和解析日期的具体类,如:“yyyy-MM-dd HH:mm:ss” 就是指定的一种日期和时间的格式。
3、DateFormat类的示例
import java.text.SimpleDateFormat;
import java.util.Date;
public class csae2 {
public static void main(String[] args) {
Date date = new Date(); //获取当前时间
SimpleDateFormat mat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //格式化
System.out.println("当前时间为:" + mat.format(date)); //输出时间
}
}
4、String 类转成 Date 类
我们会想要把一个格式化的 String 转成对应的 Date ,当我们直接转换时,得到的Date 在输出时仍然是按照国外的形式,如果希望指定格式输出,需要使用 sdf 格式进行转换,并且需要和你给的 String 的格式一样,否则会抛出转换异常。
String s = "1996 年 01 月 01 日 10:20:30 星期一";
Date parse = sdf.parse(s);
System.out.println("parse=" + sdf.format(parse));
第二代日期类
Calendar类
- YEAR 年
- MINUTE 分
- DAY_OF_WEEK_IN_MONTH 某月中第几周
- MONTH 月
- SECOND/MILLISECOND 秒/毫秒
- WEEK_OF_MONTH 日历式的第几周
- DATE 日
- DAY_OF_MONTH 和DATE一样
- DAY_OF_YEAR 一年的第多少天
- HOUR_OF_DAY 时
- DAY_OF_WEEK 周几
- WEEK_OF_YEAR 一年的第多少周
public class CalendarDemo {
public static void main(String[] args) {
// 其日历字段已由当前日期和时间初始化:
Calendar rightNow = Calendar.getInstance(); // 子类对象
int year = rightNow.get(Calendar.YEAR); // 获取年
int month = rightNow.get(Calendar.MONTH);// 获取月
int date = rightNow.get(Calendar.DATE); // 获取日
int hour = rightNow.get(Calendar.HOUR_OF_DAY);//获取几点
int moa = rightNow.get(Calendar.AM_PM);//获取上午下午
if (moa == 1)
System.out.println("下午");
else
System.out.println("上午");
System.out.println(year + "年" + (month + 1) + "月" + date + "日" + hour + "时");
rightNow.add(Calendar.YEAR, 5);
rightNow.add(Calendar.DATE, -10);
int year1 = rightNow.get(Calendar.YEAR);
int date1 = rightNow.get(Calendar.DATE);
System.out.println(year1 + "年" + (month + 1) + "月" + date1 + "日" + hour + "时");
}
}
前两代的不足
JDK 1.0中包含了一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用了、而Calendar也存在问题。
如:
- 可变性 : 像日期和时间这样的类应该是不可变的。
- 偏移性 : Date中的年份是从1900开始的,而月份都从0开始。
- 格式化 : 格式化只对Date有用,Calendar则不行。
此外,它们也不是线程安全的;不能处理闺秒等(每隔2天,多出1s)
JDK8加入新的日期表示方式:
- LocalDate :只包含(日期/年月日),可以获取日期字段
- LocalTime :只包含(时间/时分秒), 可以获取时间字段
- LocalDateTime :包含(日间/年月日时分秒),可以获取日期和时间字段
第三代日期类
Java8日期处理
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
public class demo5 {
public static void main(String[] args) {
//示例1:Java 8中获取今天的日期
LocalDate today = LocalDate.now();
System.out.println("示例1:今天的日期:"+today);
//示例2:Java 8中获取年、月、日信息
int year = today.getYear();
int month = today.getMonthValue();
int day = today.getDayOfMonth();
System.out.println("示例2:year:"+year+";;;month:"+month+";;;day:"+day);
//示例3:Java 8中处理特定日期
LocalDate birthday = LocalDate.of(1997,5,6);
System.out.println("示例3:自定义日期:"+birthday);
//示例4:Java 8中判断两个日期是否相等
if(today.equals(birthday)){
System.out.println("示例4:时间相等");
}else{
System.out.println("示例4:时间不等");
}
//示例5:Java 8中检查像生日这种周期性事件
MonthDay birthdayMonthDay = MonthDay.of(birthday.getMonth(),birthday.getDayOfMonth());
MonthDay currentMonthDay = MonthDay.from(today);
if(currentMonthDay.equals(birthdayMonthDay)){
System.out.println("示例5:是你的生日");
}else{
System.out.println("示例5:你的生日还没有到");
}
//示例6:Java 8中获取当前时间
LocalTime time = LocalTime.now();
System.out.println("示例6:获取当前的时间,不含有日期:"+time);
//示例7:Java 8中获取当前时间
LocalTime after3HoursTime = time.plusHours(3);
System.out.println("示例7:三个小时后的时间为:"+after3HoursTime);
//示例8:Java 8如何计算一周后的日期
LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
System.out.println("示例8:一周后的日期为:"+nextWeek);
//示例9:Java 8计算一年前或一年后的日期
LocalDate previousYear = today.minus(1, ChronoUnit.YEARS);
LocalDate nextYear = today.plus(1, ChronoUnit.YEARS);
System.out.println("示例9:一年前的日期 : " + previousYear + ";;;一年后的日期:"+nextYear);
//示例10:Java 8的Clock时钟类
// Returns the current time based on your system clock and set to UTC.
Clock clock = Clock.systemUTC();
System.out.println("示例10:Clock : " + clock.millis());
// Returns time based on system clock zone
Clock defaultClock = Clock.systemDefaultZone();
System.out.println("示例10:Clock : " + defaultClock.millis());
//示例11:如何用Java判断日期是早于还是晚于另一个日期
LocalDate yesterday = today.minus(1, ChronoUnit.DAYS);
if(yesterday.isAfter(today)){
System.out.println("示例11:之后的日期:"+yesterday);
}
if(yesterday.isBefore(today)){
System.out.println("示例11:之前的日期:"+yesterday);
}
//示例12:Java 8中处理时区
// Date and time with timezone in Java 8
ZoneId america = ZoneId.of("America/New_York");
LocalDateTime localtDateAndTime = LocalDateTime.now();
ZonedDateTime dateAndTimeInNewYork = ZonedDateTime.of(localtDateAndTime, america );
System.out.println("示例12:Current date and time in a particular timezone : " + dateAndTimeInNewYork);
//示例13:如何表示信用卡到期这类固定日期,答案就在YearMonth
YearMonth currentYearMonth = YearMonth.now();
System.out.printf("示例13:Days in month year %s: %d%n", currentYearMonth, currentYearMonth.lengthOfMonth());
YearMonth creditCardExpiry = YearMonth.of(2019, Month.FEBRUARY);
System.out.printf("示例13:Your credit card expires on %s %n", creditCardExpiry);
//示例14:如何在Java 8中检查闰年
if(today.isLeapYear()){
System.out.println("示例14:This year is Leap year");
}else {
System.out.println("示例14:2018 is not a Leap year");
}
//示例15:计算两个日期之间的天数和月数(不跨年)
LocalDate java8Release = LocalDate.of(2023, 1, 2);
Period periodToNextJavaRelease = Period.between(java8Release, today);
System.out.println("示例15:Months left between today and Java 8 release : " + periodToNextJavaRelease.getMonths() );
//示例16:在Java 8中获取当前的时间戳
Instant timestamp = Instant.now();
System.out.println("示例16:What is value of this instant " + timestamp.toEpochMilli());
//示例17:Java 8中如何使用预定义的格式化工具去解析或格式化日期
String dataStr = "19970506";
LocalDate formatted = LocalDate.parse(dataStr, DateTimeFormatter.BASIC_ISO_DATE);
System.out.println("示例17:" + dataStr+" 格式化后的日期为: "+formatted);
//示例18:字符串互转日期类型
LocalDateTime date = LocalDateTime.now();
DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
//日期转字符串
String str = date.format(format1);
System.out.println("示例18:日期转换为字符串:"+str);
DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
//字符串转日期
LocalDate date2 = LocalDate.parse(str,format2);
System.out.println("示例18:日期类型:"+date2);
}
}
运行结果:
示例1:今天的日期:2023-05-15
示例2:year:2023;;;month:5;;;day:15
示例3:自定义日期:1997-05-06
示例4:时间不等
示例5:你的生日还没有到
示例6:获取当前的时间,不含有日期:16:27:12.795
示例7:三个小时后的时间为:19:27:12.795
示例8:一周后的日期为:2023-05-22
示例9:一年前的日期 : 2022-05-15;;;一年后的日期:2024-05-15
示例10:Clock : 1684139232796
示例10:Clock : 1684139232796
示例11:之前的日期:2023-05-14
示例12:Current date and time in a particular timezone : 2023-05-15T16:27:12.798-04:00[America/New_York]
示例13:Days in month year 2023-05: 31
示例13:Your credit card expires on 2019-02
示例14:2018 is not a Leap year
示例15:Months left between today and Java 8 release : 4
示例16:What is value of this instant 1684139232815
示例17:19970506 格式化后的日期为: 1997-05-06
示例18:日期转换为字符串:2023/05/15 16:27:12
示例18:日期类型:2023-05-15
其他
推荐commons-lang3的工具类
格式化日期
再也不用手写 SimpleDateFormat 格式化了
// Date类型转String类型
String date = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
System.out.println(date); // 输出 2021-05-01 01:01:01
// String类型转Date类型
Date date = DateUtils.parseDate("2021-05-01 01:01:01", "yyyy-MM-dd HH:mm:ss");
// 计算一个小时后的日期
Date date = DateUtils.addHours(new Date(), 1);
Hutool工具类
hutool工具类存在争议, 具体可以百度查看各位大佬们的发言。
有些公司是吧hutool加入了黑名单了。
不过这个工具在使用方便程度好用是真的好用。
文档也清晰:https://hutool.cn/docs/#/