嘘~ 正在从服务器偷取页面 . . .

java8 日期时间API


Java 8 日期时间 API

Java 8通过发布新的Date-Time API (JSR 310)来进一步加强对日期与时间的处理。 旧版的java.util.Date是非线程安全的。

1. java8日期时间

LocalDate(本地日期)− 简化了日期处理,不带时间。

LocalTime(本地时间)− 简化了时间处理,不带日期且没有偏移信息、无时区的时间。

LocalDateTime(本地日期时间)− 日期+时间的处理。

上面的三个类的实例是不可变的对象,分布表示使用ISO-8601日历系统的日期、时间、日期时间。无时区相关信息。

方法说明
now()静态方法,根据当前时间创建对象
of()静态方法,根据当前时间或日期创建对象
plusDays, plusWeeks,
plusMonths, plusYears
向当前LocalDate 对象添加几天、几周、几个月、几年的运算
minisDays, minisWeeks,
minisMonths, minisYears
从当前LocalDate 对象减去几天、几周、几个月、几年的运算
withDayOfMonth, withDayOfYear,
withMonth, withYear
将月份天数、年份天数、月份年份修改为指定的值并返回新的LocalDate对象
getDayOfMonth获取月份天数(1-31)
getDayOfYear获取年份天数(1-366)
getDayOfWeek获取星期几,返回一个DayOfWeek的枚举值
getMonth获取月份,返回一个Month的枚举值
getMonthValue获取月份数值(1-12)
getYear获取年份
unitl获取两个日期之间的 Period 对象,或者指定 ChronoUnits 的数字
isBefore,isAfter比较两个LocalDate
isLeapYear判断是否是闰年
```java
package com.zxc.jdk8;

import java.time.*;
import java.util.Date;

import static java.lang.System.out;

public class DateTimeTest {

    public static void main(String[] args) {


        LocalDate ldt = LocalDate.now();//日期
        out.println(" ldt = " + ldt);

        LocalTime time = LocalTime.now();//时间
        out.println(" time = " + time);

        LocalDateTime dttm = LocalDateTime.now();
        out.println(" dttm = " + dttm);


        LocalDate date2 = LocalDate.of(2020, 07,11);//日期
        out.println(" date2 = " + date2);

        LocalTime time2 = LocalTime.of(10,22,33);//时间
        out.println(" time2 = " + time2);

        LocalDateTime dttm2 = LocalDateTime.of(2020,07,11,10,22,33);
        out.println(" dttm2 = " + dttm2);

        LocalDateTime ldt3 = ld2.plusYears(20);
        System.out.println(ldt3);

        LocalDateTime ldt4 = ld2.minusMonths(2);
        System.out.println(ldt4);

        System.out.println(ldt.getYear());
        System.out.println(ldt.getMonthValue());
        System.out.println(ldt.getDayOfMonth());
        System.out.println(ldt.getHour());
        System.out.println(ldt.getMinute());
        System.out.println(ldt.getSecond());

        // 日期比较
        LocalDate date1 = LocalDate.of(2020, 1, 15);
        LocalDate date2 = LocalDate.of(2020, 3, 10);
        // isBefore
        boolean b1 = date1.isBefore(date2);
        out.println(" date1 在date2的前面 :" + b1);
        // isAfter
        boolean b2 = date1.isAfter(date2);
        out.println(" date1 在date2的后面 :" + b2);

        boolean b3 = date1.equals(date2);
        out.println(" date1   equals  date2  ? " + b3);

        // 日期时间比较
        LocalDateTime dttm1 = LocalDateTime.now();
        out.println(" dttm1 = " + dttm1);
        LocalDateTime dttm2 = dttm1.plusDays(1);
        out.println(" dttm2 = " + dttm2);
        boolean b4 = dttm1.isBefore(dttm2);
        out.println(" dttm1 在 dttm2 的前面 :" + b4);
}

2. java8 时间戳

Instant(时间戳)-精确到纳秒的的某个时间点,不包含时区,允许加减运算。该方法默认使用的是UTC(协调世界时——由原子钟提供)时间(Unix元年开始经历描述进行运算),可以使用
equealcompareTo 来比较两个时间点的值。支持旧版时间转换新版时间戳。

    @Test
    public void test2(){
        Instant ins = Instant.now();  //默认使用 UTC 时区
        System.out.println(ins);

        OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8));
        System.out.println(odt);

        System.out.println(ins.getNano());

        Instant ins2 = Instant.ofEpochSecond(5);
        System.out.println(ins2);

                // 时间戳
        Instant now = Instant.now();
        out.println(" now = " + now);

        // 将java.util.Date转换为Instant
        Instant instant1 = Instant.ofEpochMilli(new Date().getTime());
        out.println(instant1);

        // 从字符串类型中创建Instant类型的时间
        Instant instant2 = Instant.parse("1995-10-23T10:12:35Z");


    }

3. Duration 和 Period。

    @Test
    public void caculteTest(){

        Instant instant3 = Instant.now();
        // 将现在的时间加上2个小时10分钟
        Instant changeIns = instant3.plus(Duration.ofHours(2).plusMinutes(10));
        out.println(changeIns);
        System.out.println("--------------------");
        // 使用instant计算7天前
        instant3.minus(7, ChronoUnit.DAYS); // 方法1
        instant3.minus(Duration.ofDays(7)); // 方法2

        // 计算两个Instant之间的分钟数
        Instant instant4 = Instant.now();
        // long diffAsMinutes = instant.periodUntil(instant3, ChronoUnit.MINUTES); //
        // 方法1
        long diffAsMinutes1 = ChronoUnit.MINUTES.between(instant1, instant4); // 方法2
        out.println(diffAsMinutes1 / 60 );
        System.out.println("--------------------");

        Instant ins1 = Instant.now();

        System.out.println("--------------------");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }

        Instant ins2 = Instant.now();

        System.out.println("所耗费时间为:" + Duration.between(ins1, ins2));

        System.out.println("----------------------------------");

        LocalDate ld1 = LocalDate.now();
        LocalDate ld2 = LocalDate.of(2011, 1, 1);

        Period pe = Period.between(ld2, ld1);
        System.out.println(pe.getYears());
        System.out.println(pe.getMonths());
        System.out.println(pe.getDays());

        // 一周从周日开始
        WeekFields weekFields = WeekFields.of(DayOfWeek.SUNDAY, 7);
        LocalDate today = LocalDate.now();
        out.println("今天是今年第" + today.get(weekFields.weekOfYear()) + "周");

        // 计算date的相差天数
        out.println(LocalDate.now().toEpochDay() - LocalDate.now().minusDays(5).toEpochDay());
        // 计算date的相差月数
        out.println(LocalDate.now().until(LocalDate.now().minusDays(5), ChronoUnit.MONTHS));
        // 计算date的相差月天,(相差0年1月24天)
        LocalDate date1 = LocalDate.of(2020, 1, 15);
        LocalDate date2 = LocalDate.of(2020, 3, 10);
        Period period = Period.between(date1, date2);
        out.println(period.getYears() + "-" + period.getMonths() + "-" + period.getDays());
    }

4. 时区处理

Zoned (时区) − 通过制定的时区处理日期时间。

ZoneDate(时区日期)- 包含时区的日期。

ZoneTime(时区时间)- 包含时区的时间。

ZoneDateTime(时区日期时间)- 包含时区的完整的日期时间,偏移量是以UTC/格林威治时间为基准的。ZonedDateTime代表带时区的时间,等同于以前的GregorianCalendar类。使用该类,可以将本地时间转换成另一个时区中的对应时间。

ZonId代表的是某个特定时区,里面的getAvailableZoneIds() 方法可以获取所有时区信息。里面的of() 方法是用指定的时区信息获取ZoneId对象

package com.zxc.jdk8;

import static java.lang.System.out;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class TimeZoneTest {

    public static void main(String[] args) {
        // 获取全部时区列表
        Set<String> set = ZoneId.getAvailableZoneIds();
        set.forEach(System.out::println);

        LocalDateTime localDateTime = LocalDateTime.now();
        out.println(" localDateTime = " + localDateTime);

        ZoneId zone = ZoneId.of(ZoneId.SHORT_IDS.get("CTT"));//取定义好的时区
        out.println(" zone = " + zone);

        //包含时区的时间
        ZonedDateTime dtWithZone = ZonedDateTime.of(localDateTime, zone);
        out.println(" dtWithZone = " + dtWithZone);
    }
}

输出

 localDateTime = 2020-05-31T23:54:42.831
 zone = Asia/Shanghai
 dtWithZone = 2020-05-31T23:54:42.831+08:00[Asia/Shanghai]

注意:对应时区的文本可以直接手动填写,也可以调用系统默认定义的。

5. 格式化处理

java.time.format.DateTimeFormatter提供格式化和解析功能。有三种格式化方法:

(1)预定义的标准格式,在DateTimeFormatter类中。
(2)语言环境相关的格式
(3)自定义格式,如带中文。


    //5. DateTimeFormatter : 解析和格式化日期或时间
    @Test
    public void formatterTest(){

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E");

        LocalDateTime ldt = LocalDateTime.now();
        String strDate = ldt.format(dtf);

        System.out.println(strDate);

        LocalDateTime newLdt = ldt.parse(strDate, dtf);
        System.out.println(newLdt);
    }

6. 时间校正器

TemporalAdjuster是时间校正器。有时候需要获取”下个周日”这种操作。

TemporalAdjusters 该类是通过静态方法提供大量常用的TemporalAdjuster的实现。

    @Test
    public void test4(){
        //取下个周末
        LocalDateTime ldt1 = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
        System.out.println(ldt1);

        LocalDateTime ldt2 = ldt.withDayOfMonth(10);
        System.out.println(ldt2);

        //自定义:下一个工作日
        LocalDateTime ldt5 = ldt.with((l) -> {
            LocalDateTime ldt4 = (LocalDateTime) l;

            DayOfWeek dow = ldt4.getDayOfWeek();

            if(dow.equals(DayOfWeek.FRIDAY)){
                return ldt4.plusDays(3);
            }else if(dow.equals(DayOfWeek.SATURDAY)){
                return ldt4.plusDays(2);
            }else{
                return ldt4.plusDays(1);
            }
        });

        System.out.println(ldt5);

    }

7. 其他相关

Locale (本地) − 简化了日期时间的处理,没有时区的问题。

MonthDay- 月日组合。它是一个值类(value class),由,不包含年信息,可以用来代表每年重复出现的一些日期或其他组合。

YearMonth - 年月组合。

WeekFields(周) - 处理周的计算。

Clock - 时钟。可以获取某个时区下(对时区是敏感的)当前的瞬时时间、日期。用来代替System.currentTimelnMillis()与TimeZone.getDefault()方法。

package com.zxc.jdk8;

import java.time.*;
import java.util.Date;

import static java.lang.System.out;

public class DateTimeTest {

    public static void main(String[] args) {


        Locale l = Locale.getDefault();
        out.println(l);

        MonthDay md = MonthDay.now();
        out.println(" md :"+md);

        YearMonth ym = YearMonth.of(2020, 07);
        out.println(" ym :"+ym);

        Clock utc_cl = Clock.systemUTC();
        out.println(" utc_cl :" +utc_cl);
        Clock def_cl = Clock.systemDefaultZone();
        out.println(" def_cl :" +def_cl);

    }

}

8 与传统日期转换

To 遗留类From 遗留类
java.time.Instant
java.util.Date
Date.from(Instant it)date.toInstant()
java.time.Instant
java.util.Timestamp
Timestamp.from(Instant it)tmestamp.toInstant()
java.time.ZonedDateTime
java.util.GregorianCalendar
GregorianCalendar.from(ZonedDateTime zd)cal.toZonedDateTime()
java.time.LocalDate
java.sql.Time
Date.valueOf(LocalDate ld)date.toLocalDate()
java.time.LocalTime
java.sql.Time
Date.valueOf(LocalTime lt)date.toLocalTime()
java.time.LocalDateTime
java.sql.Timestamp
Timestamp.valueOf(LocalDateTime ldt)tmestamp.toLocalDateTime()
java.time.ZoneId
java.sql.TimeZone
TimeZone.getTimeZone(ZoneId ldt)tmeZone.toZoneId()
java.time.format.DateTimeFormatter
java.text.DateFormat
formatter.toFormat()-

部分示例如下。其他同理:

package com.zhangxiaocai.cn.java8.datetime;

import java.sql.Timestamp;
import java.time.Instant;
import java.util.Date;
import java.util.Locale;

import org.junit.Test;

public class TestOtherDateTime {

    @Test
    public void test(){

        Locale l = Locale.getDefault();
        System.out.println(l);

        Instant it = Instant.now();
        Date date = Date.from(it);
        System.out.println(" date :"+date);

        Instant it2 = date.toInstant();
        System.out.println(" it2 : "+it2);

        Timestamp ts = Timestamp.from(it);
        System.out.println(" ts : "+ts);
        Instant ts2 = ts.toInstant();
        System.out.println(" ts2 : "+ts2);
    }
}

9 其他

可以参考java 8 API,在实际遇到再补充。



版权声明: 本博客所有文章除特別声明外,均采用 CC BY-SA 4.0 许可协议。转载请注明来源 Small-Rose / 张小菜 !
评论
  目录