java8日期时间处理

1、日期格式化

package java8.datetime;
​
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
​
/** 
 * @author kyle
 * @version 1.0 2018年8月24日 NEW
 * @function 
 */
public class LocalDateFormat {
    public static void main(String[] args) {
        // 和老的java.util.DateFormat相比较,所有的DateTimeFormatter实例都是线程安全的。所以,你能够以单例模式创建格式器实例
        
        LocalDate date = LocalDate.of(2018, 8, 24);
        String strDate = date.format(DateTimeFormatter.BASIC_ISO_DATE); // BASIC_ISO_DATE去掉分隔符
        System.out.println(strDate);
        String strDate2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE); 
        System.out.println(strDate2);
        
        // 字符串转日期
        LocalDate date1 = LocalDate.parse("20140318", DateTimeFormatter.BASIC_ISO_DATE);
        LocalDate date2 = LocalDate.parse("2014-03-18", DateTimeFormatter.ISO_LOCAL_DATE);
        
        // 日期格式化
        LocalDate ldt = LocalDate.now();
        String strD = ldt.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
        System.out.println(strD);
        
        LocalDateTime ldtTime = LocalDateTime.now();
        String strDTime = ldtTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.out.println(strDTime);
        
        /*
        下面代码中,LocalDate的format方法使用指定的模式生成了一个代表该日期的字符串。
        紧接着,静态的parse方法使用同样的格式器解析了刚才生成的字符串,并重建了该日期对象。
        */
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
        LocalDate date11 = LocalDate.of(2014, 3, 18);
        String formattedDate = date11.format(formatter);
        LocalDate date22 = LocalDate.parse(formattedDate, formatter);
        
        // 创建一个本地化的DateTimeFormatter
        DateTimeFormatter italianFormatter = DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.CHINA);
        LocalDate date111 = LocalDate.of(2018, 8, 24);
        String formattedDate1 = date111.format(italianFormatter); // 18. marzo 2014
        LocalDate date222 = LocalDate.parse(formattedDate1, italianFormatter);
        System.out.println(date222);
    }
}
​

2、日期提取,求日期差值,日期加减。

import java.time.*;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
​
/** 
 * @author kyle
 * @version 1.0 2018年8月23日 NEW
 * @function 
 */
public class MyLocalDate {
    public static void main(String[] args) {
        /*
            TemporalField是一个接口,它定
            义了如何访问temporal对象某个字段的值。ChronoField枚举实现了这一接口,所以你可以很
            方便地使用get方法得到枚举元素的值
        */
        LocalDate data = LocalDate.now();
        int year = data.get(ChronoField.YEAR);
        int month = data.get(ChronoField.MONTH_OF_YEAR);
        int day = data.get(ChronoField.DAY_OF_MONTH);
        
        System.out.println(year);
        System.out.println(month);
        System.out.println(day);
        System.out.println("当前日期:"+year+"-"+month+"-"+day);
        
        LocalDate date = LocalDate.parse("2014-03-18");
        LocalTime time = LocalTime.parse("13:45:20");
        
        System.out.println("日期:"+date);
        System.out.println("时间:"+time);
​
​
        // 合并日期和时间,一步创建日期和时间
        LocalDateTime dt1 = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45, 20);
        System.out.println(dt1.toString().replace("T", " "));
​
        // 组合创建日期和时间
        LocalDateTime d1= LocalDateTime.of(date, time);
        System.out.println(d1);
        
        // 提取日期和时间 
        LocalDate ld = d1.toLocalDate();
        LocalTime lt = d1.toLocalTime();
        
        System.out.println(ld +" "+lt);
​
        Period tenDays = Period.between(LocalDate.of(2014, 03, 8), LocalDate.of(2014, 03, 18));
        
        // 求两个时间的差值很方便
        Period tenDays2 = Period.between(LocalDate.parse("2014-03-08"), LocalDate.parse("2014-03-18"));
​
        System.out.println("两个时间的差值test1:"+tenDays.getDays());
        System.out.println("两个时间的差值test2:"+tenDays2.getDays());
        System.out.println("-----------------------------------------------------------------------------");
​
        /*
            操纵、解析和格式化日期, 如果你已经有一个LocalDate对象,想要创建它的一个修改版,最直接也最简单的方法是使
            用withAttribute方法。withAttribute方法会创建对象的一个副本,并按照需要修改它的属
            性。
        */
        LocalDate date1 = LocalDate.of(2018, 8, 23);
        LocalDate date2 = date1.withYear(2011);  // 年,创建对象的一个副本,不会修改原来对象的内容
        LocalDate date3 = date2.withDayOfMonth(25); // 天
​
        // 两种方式设置月份
        LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 9); // 月
        LocalDate date5 = date3.withMonth(10); // 月
​
        LocalDate date7 = date1.withYear(date1.getYear()-1);
        
        System.out.println("date1: "+ date1);
        System.out.println("date2: "+ date2);
        System.out.println("date3: "+ date3);
        System.out.println("date4: "+ date4);
        System.out.println("date5: "+ date5);
        System.out.println("date7: "+ date7);
        System.out.println("-----------------------------------上面是加,下面是减时间------------------------------------------");
​
        // 日期加减
        LocalDate date11 = LocalDate.of(2018, 8, 23);
        LocalDate date22 = date11.plusWeeks(1);
        System.out.println("原日期:"+date11);
        System.out.println("更改后:"+date22);
        
        LocalDate date33 = date22.minusYears(3); // 减3年
        LocalDate date55 = date33.plus(5, ChronoUnit.MONTHS); // 加5个月
        LocalDate date77 = date55.plusMonths(1); // 加一个月
        System.out.println("date33: "+date33);
        System.out.println("date55: "+date55);
        System.out.println("date77: "+date77);
        
        // 经过下面这些操作,date变量的值是什么?
        LocalDate date9 = LocalDate.of(2014, 3, 18);
        date9 = date9.with(ChronoField.MONTH_OF_YEAR, 9);
        date9 = date9.plusYears(2).minusDays(10);
​
        /*
          date9.withYear(2011) 此处没赋值(即设置值之后没有将值赋值给变量LocalDate date = date9.withYear(2011))所以不会改变date9的日期
          with只是创建复本不会对原来的对象做出修改
         */
        date9.withYear(2011); //
​
        System.out.println(date9);
        
        // 答案:2016-09-08。
    }
}

3、时区与日期设置

package java8.datetime;
​
import java.sql.Timestamp;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
​
public class MyOffsetDateTime {
    public static void main(String[] args) {
        ZoneId chinaZone = ZoneId.of("Asia/Shanghai");
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        OffsetDateTime now = OffsetDateTime.now(chinaZone);
​
        // 当前日期减一天
        OffsetDateTime start = now.plusDays(-1L).withHour(0).withMinute(0).withSecond(0).withNano(0);
​
        // 在当前日期减一天的基础上设置时分秒为23:59:59
        OffsetDateTime end = start.withHour(23).withMinute(59).withSecond(59).withNano(0);
​
        System.out.println("start: "+ start.format(dtf));
        System.out.println("end: "+ end.format(dtf));
​
        System.out.println("start_Instant: "+ Timestamp.from(start.toInstant()));
        System.out.println("end_Instant: "  + Timestamp.from(end.toInstant()));
​
    }
}
​

4、指定月份最后一天,根据规则求日期

package java8.datetime;
​
import java.time.LocalDate;
import static java.time.temporal.TemporalAdjusters.*;
import java.time.DayOfWeek;
import java.time.OffsetDateTime;
import java.time.temporal.TemporalAdjusters;
​
/** 
 * @author kyle
 * @version 1.0 2018年8月23日 NEW
 * @function 
 */
public class MyTemporalAdjuster {
    public static void main(String[] args) {
        
        /**
            dayOfWeekInMonth 创建一个新的日期,它的值为同一个月中每一周的第几天
            firstDayOfMonth 创建一个新的日期,它的值为当月的第一天
            firstDayOfNextMonth 创建一个新的日期,它的值为下月的第一天
            firstDayOfNextYear 创建一个新的日期,它的值为明年的第一天
            firstDayOfYear 创建一个新的日期,它的值为当年的第一天
            firstInMonth 创建一个新的日期,它的值为同一个月中,第一个符合星期几要求的值
            lastDayOfMonth 创建一个新的日期,它的值为当月的最后一天
            lastDayOfNextMonth 创建一个新的日期,它的值为下月的最后一天
            lastDayOfNextYear 创建一个新的日期,它的值为明年的最后一天
            lastDayOfYear 创建一个新的日期,它的值为今年的最后一天
            lastInMonth 创建一个新的日期,它的值为同一个月中,最后一个符合星期几要求的值
            next/previous
            创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星
            期几要求的日期
            nextOrSame/previousOrSame
            创建一个新的日期,并将其值设定为日期调整后或者调整前,第一个符合指定星
            期几要求的日期,如果该日期已经符合要求,直接返回该对象
        */
​
        // 根据指定日期求出和指定日期最近的下一个周一和当月的最后一天
        LocalDate date1 = LocalDate.of(2021, 07, 22);
        LocalDate date2 = date1.with(nextOrSame(DayOfWeek.MONDAY)); // 下周一(第一个符合指定星期几要求的日期)
        LocalDate date3 = date1.with(lastDayOfMonth()); // 当月的最后一天
        System.out.println(date2);
        System.out.println(date3);
​
​
        // 根据当前日期求出当月的最后一天
        LocalDate endDay  = LocalDate.now().with(lastDayOfMonth());
        System.out.println(endDay);
​
        // 求指写月份的最后一天,比如2月,这样我们就不用去判断是不是润年了
        LocalDate twoMonthEndDay  = LocalDate.now().withMonth(2).with(lastDayOfMonth());
        System.out.println(twoMonthEndDay);
​
        OffsetDateTime time = OffsetDateTime.now();
​
        // 指定某个月的第几周并返回日期,如5月第2个周日 dayOfWeekInMonth(2, DayOfWeek.SUNDAY)代表第2个周日
        System.out.println(
                time.withMonth(5) // 固定设置为5月
                .with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.SUNDAY)) // 动态计算的5月第二周是哪天
                .toLocalDate().toString());
​
    }
}
​

5、日期比较

package java8.datetime;
​
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.MonthDay;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
​
/** 
 * @author kyle
 * @version 1.0 2018年8月24日 NEW
 * @function 
 */
public class MyZoneId {
    public static void main(String[] args) {
​
        // 为时间添加时区信息
        ZoneId shanghai = ZoneId.of("Asia/Shanghai");
        LocalDateTime localDateAndTime = LocalDateTime.now();
        ZonedDateTime dateAndTimeInShanghai  = ZonedDateTime.of(localDateAndTime, shanghai);
        System.out.println("Current date and time in a particular timezone : " + dateAndTimeInShanghai);
        System.out.println(ZoneId.systemDefault());
        System.out.println(dateAndTimeInShanghai.getOffset());
        
        
        // 判断是不是生日
        LocalDate dateOfBirth = LocalDate.of(2018, 8, 24);
        MonthDay birthday = MonthDay.of(dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth());
        
        System.out.println("MonthDay.now(): "+MonthDay.now());
        
        MonthDay currentMonthDay = MonthDay.from(MonthDay.now());
​
        if (currentMonthDay.equals(birthday)) {
            System.out.println("Many Many happy returns of the day !!");
        } else {
            System.out.println("Sorry, today is not your birthday");
        }
​
        // 当前日期
        LocalDate today = LocalDate.now();
​
        // 如何用Java判断日期是早于还是晚于另一个日期
        LocalDate tomorrow = today.plus(1,  ChronoUnit.DAYS);
​
        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");
        }
    }
}
​

6、求下一个跳跃日期

package java8.datetime;
​
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
​
/** 
 * @author kyle
 * @version 1.0 2018年8月24日 NEW
 * @function 
 */
public class NextWorkingDay implements TemporalAdjuster {
    
    // 如果当天的星期介于周一至周五之间,日期向后移动一天;如果当天是周六或者周日,则返回下一个周一。
​
    // 第一种方式实现接口
    @Override
    public Temporal adjustInto(Temporal temporal) {
        DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
        int dayToAdd = 1;
        if(dow == DayOfWeek.FRIDAY) dayToAdd =3;
        else if(dow == DayOfWeek.SATURDAY) dayToAdd = 2;
        // 这里没有判断周日,因为周日到周一也是1天,默认就是移动一天,所以周日和一至周五一样。
        return temporal.plus(dayToAdd, ChronoUnit.DAYS);
    }
​
    public static void main(String[] args) {
        LocalDate date = LocalDate.of(2021, 7, 25);
        /*
            如果你已经有一个LocalDate对象,想要创建它的一个修改版,最直接也最简单的方法是使
            用withAttribute方法。withAttribute方法会创建对象的一个副本,并按照需要修改它的属
            性。
        */
        date = date.with(new NextWorkingDay()); // 创建副本,修改属性
        System.out.println(date);
        
        // 第二种方式,函数式直接实现接口
        date = date.with(temporal -> {
            DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
            int dayToAdd = 1;
            if (dow == DayOfWeek.FRIDAY) dayToAdd = 3;
            else if (dow == DayOfWeek.SATURDAY) dayToAdd = 2;
            return temporal.plus(dayToAdd, ChronoUnit.DAYS);
        });
        
        System.out.println(date);
        
        // 第三种方式,如果你想要使用Lambda表达式定义TemporalAdjuster对象,推荐使用TemporalAdjusters类的静态工厂方法ofDateAdjuster
        TemporalAdjuster nextWorkingDay = TemporalAdjusters.ofDateAdjuster(temporal -> {
            DayOfWeek dow = DayOfWeek.of(temporal.get(ChronoField.DAY_OF_WEEK));
            int dayToAdd = 1;
            if (dow == DayOfWeek.FRIDAY)
                dayToAdd = 3;
            if (dow == DayOfWeek.SATURDAY)
                dayToAdd = 2;
            return temporal.plus(dayToAdd, ChronoUnit.DAYS);
        });
        
        date = date.with(nextWorkingDay);
        System.out.println(date);
    }
​
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值