java8新特性之日期时间 API

日期工具类DateTimeFormatter

简介
在旧版的 Java 中,日期时间 API 存在诸多问题,其中有:

(1)非线程安全 − java.util.Date 是非线程安全的,所有的日期类都是可变的,以及 SimpleDateFormat 的非线程安全,这是Java日期类最大的问题之一。

(2)设计很差 − Java的日期/时间类的定义并不一致,在java.util和java.sql的包中都有日期类,此外用于格式化和解析的类在java.text包中定义。java.util.Date同时包含日期和时间,而java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。

(3)时区处理麻烦 − 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar和java.util.TimeZone类,但他们同样存在上述所有的问题。

Java 8 在 java.time 包下提供了很多新的 API。
以下为两个比较重要的 API:
(1)Local(本地) − 简化了日期时间的处理,没有时区的问题。
(2)Zoned(时区) − 通过制定的时区处理日期时间。
新的java.time包涵盖了所有处理日期,时间,日期/时间,时区,时刻(instants),过程(during)与时钟(clock)的操作。

关键类
Instant:瞬时实例。
LocalDate:本地日期,不包含具体时间 例如:2014-01-14 可以用来记录生日、纪念日、加盟日等。
LocalTime:本地时间,不包含日期。
LocalDateTime:组合了日期和时间,但不包含时差和时区信息。
ZonedDateTime:最完整的日期时间,包含时区和相对UTC或格林威治的时差。
新API还引入了 ZoneOffSet 和 ZoneId 类,使得解决时区问题更为简便。解析、格式化时间的 DateTimeFormatter
类也全部重新设计。
实际操作

package date;

import org.junit.Test;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Date;

public class DateTest {

    //1.获取今天的日期
    @Test
    public void getCurrentDate(){
        // LocalDate 用于表示当天日期,它只有日期,不包含时间。
        LocalDate today = LocalDate.now();
        System.out.println("Today's Local date : " + today);

        //这个是作为对比
        Date date = new Date();
        System.out.println(date);
    }

    //2.获取当前时间使用的是 LocalTime 类,默认的格式是hh:mm:ss:nnn。
    @Test
    public void getCurrentTime() {
        LocalTime time = LocalTime.now();
        System.out.println("local time now : " + time);

    }
    //3.增加小时,这些方法返回一个全新的LocalTime实例,由于其不可变性,返回后一定要用变量赋值。
    @Test
    public void plusHours() {
        LocalTime time = LocalTime.now();
        LocalTime newTime = time.plusHours(2); // 增加两小时
        System.out.println("Time after 2 hours : " + newTime);
    }
    //4.如何计算一周后的日期,LocalDate日期不包含时间信息,
    // 它的plus()方法用来增加天、周、月,ChronoUnit类声明了这些时间单位
    @Test
    public void nextWeek() {
        LocalDate today = LocalDate.now();
        LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);    //使用变量赋值
        System.out.println("Today is : " + today);
        System.out.println("Date after 1 week : " + nextWeek);
    }
     //5.计算一年前或一年后的日期,通过 minus() 方法计算一年前的日期
    @Test
    public void minusDate() {
        LocalDate today = LocalDate.now();
        LocalDate previousYear = today.minus(1, ChronoUnit.YEARS);
        System.out.println("Date before 1 year : " + previousYear);

        LocalDate nextYear = today.plus(1, ChronoUnit.YEARS);
        System.out.println("Date after 1 year : " + nextYear);
    }

    //6.获取年、月、日信息
    @Test
    public void getDetailDate() {

        LocalDate today = LocalDate.now();
        System.out.println(today);

        int year = today.getYear();
        int month = today.getMonthValue();
        int day = today.getDayOfMonth();
        System.out.printf("Year : %d  Month : %d  day : %d t %n", year, month, day);
    }

    //7.处理特定日期
    @Test
    public void handleSpecilDate() {
        //可以调用另一个有用的工厂方法 LocalDate.of() 创建任意日期,
        // 该方法需要传入年、月、日做参数,返回对应的LocalDate实例
        LocalDate dateOfBirth = LocalDate.of(2020, 06, 07);
        System.out.println("The specil date is : " + dateOfBirth);
    }

    //8.判断两个日期是否相等
    @Test
    public void compareDate() {
        //LocalDate 重载了equal方法。如果比较的日期是字符型的,需要先解析成日期对象再作判断。
        LocalDate today = LocalDate.now();
        LocalDate date1 = LocalDate.of(2020, 06, 07);

        if (date1.equals(today)) {
            System.out.printf("TODAY %s and DATE1 %s are same date %n", today, date1);
        }
    }

    //9.处理周期性的日期,比如生日,法定假日
    @Test
    public void cycleDate() {
        LocalDate today = LocalDate.now();
        LocalDate dateOfBirth = LocalDate.of(2020, 06, 07);
        //MonthDay这个类组合了月份和日,去掉了年,这意味着你可以用它判断每年都会发生事件。
        MonthDay birthday = MonthDay.of(dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth());
        System.out.println("The birthday date is : " + birthday);
        MonthDay currentMonthDay = MonthDay.from(today);
        System.out.println("The currentMonthDay date is : " + currentMonthDay);
        if (currentMonthDay.equals(birthday)) {
            System.out.println("Many Many happy returns of the day !!");
        } else {
            System.out.println("Sorry, today is not your birthday");
        }
    }

    //10.Clock 时钟类用于获取当时的时间戳,或当前时区下的日期时间信息。
    // 以前用到System.currentTimeInMillis() 和 TimeZone.getDefault() 的地方都可用Clock替换。
    @Test
    public void clock() {
        // 根据系统时间返回当前时间并设置为UTC。
        Clock clock = Clock.systemUTC();
        System.out.println("Clock : " + clock);

        // 根据系统时钟区域返回时间
        Clock defaultClock = Clock.systemDefaultZone();
        System.out.println("Clock : " + clock);
    }

    //11.如何用Java判断日期是早于还是晚于另一个日期
    @Test
    public void isBeforeOrIsAfter() {
        LocalDate today = LocalDate.now();

        LocalDate tomorrow = LocalDate.of(2020, 6, 8);
        if (tomorrow.isAfter(today)) {
            System.out.println("Tomorrow comes after today");
        }

        //减去一天
        LocalDate yesterday = today.minus(1, ChronoUnit.DAYS);

        if (yesterday.isBefore(today)) {
            System.out.println("Yesterday is day before today");
        }
    }

    //12检查闰年
    @Test
    public void isLeapYear() {
        LocalDate today = LocalDate.now();
        if (today.isLeapYear()) {
            System.out.println("This year is Leap year");
        } else {
            System.out.println("2020 is not a Leap year");
        }
    }


    //13.计算两个日期之间的天数和月数
    @Test
    public void calcDateDays() {
        LocalDate today = LocalDate.now();

        LocalDate java8Release = LocalDate.of(2020, Month.DECEMBER, 23);

        Period periodToNextJavaRelease = Period.between(today, java8Release);
        //月份与月份比,天数与天数比
        System.out.println("相差Months : "
                + periodToNextJavaRelease.getMonths()+"相差Days : "+ periodToNextJavaRelease.getDays());

    }

    //14.Instant类有一个静态工厂方法now()会返回当前的时间戳
    @Test
    public void getTimestamp() {
        Instant timestamp = Instant.now();
        System.out.println("What is value of this instant " + timestamp);
    }
    //15.使用预定义的格式化工具去解析或格式化日期
    @Test
    public void formateDate() {
        //1.格式化成2020-06-07
        String today = "20200607";
        LocalDate fma1 = LocalDate.parse(today, DateTimeFormatter.BASIC_ISO_DATE);
        System.out.println("BASIC_ISO_DATE格式化后的时间:"+ fma1);

        // 2.自定义格式化格式
        LocalDateTime localDateTime = LocalDateTime.now();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format1 = dtf.format(localDateTime);
        System.out.println(format1);

        //3.将字符串转化为日期

        LocalDateTime parse = LocalDateTime.parse("2019-01-26T10:15:30");// 日期字符串转为日期
        System.out.println(parse);

        String format4 = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"));
        System.out.println("1字符串转化为日期:"+format4);
        //第一个参数时日期字符串,第二个参数是日期格式化的字符串类型
        LocalDateTime parse2 = LocalDateTime.parse(format4,DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"));
        System.out.println("1字符串转化为日期:"+parse2);

    }

 }

相关参考:参考地址
菜鸟相关API地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值