Java SE8中的新的日期和时间API

众所周知Java的时间和日期对象异常恶心...所幸JDK8终于更新了这部分。

1、Instant和Duration

一个Instant类似于一个Date,同时包含日期和时刻信息,是时间线上的一个点,Duration则是两个Instant之间的间隔。

//创建Instant对象
Instant startInstant = Instant.now();

//some code...

Instant endInstant = Instant.now();

//得到两个时刻点的间隔
Duration timeElapsed = Duration.between(formerInstant,afterInstant);
long days = timeElapsed.toDays();
long hours = timeElapsed.toHours();
long minutes = timeElapsed.toMinutes();
long millis = timeElapsed.toMillis();
long nanos = timeElapsed.toNanos();
System.out.println(days+"-"+hours+"-"+minutes+"-"+millis+"-"+nanos);

还可以对Duration对象直接进行运算操作

//注意Instant和Duration都是不可变类,所有的操作都不会改变Duration对象本身
//plus和minus方法
duration1.plus(duration2);
//plusXX和minusXX方法
duration1.plusDays(1);
//multipliedBy和dividedBy方法
duration1.multipliedBy(2);
//isZero和isNegative方法
boolean negative = duration1.isNegative();
boolean zero = duration1.isZero();

Duration还可以通过ofXX直接创建

Duration.ofDays(15);
Duration.ofHours(15);

2、LocalDate

LocalDate是一个带有年份、月份、当月天数的日期,不包含时区信息。

//创建LocalDate对象
//使用now方法获取当前日期
LocalDate localDate = LocalDate.now();
//使用of方法创建,注意1就代表一月,1就代表周一,和Calendar中不同
LocalDate localDate1 = LocalDate.of(2017,1,1);

//plusXX、minusXX方法
LocalDate localDate2 = localDate.plusDays(1);
LocalDate localDate3 = localDate.plusYears(1);

//plus、minus方法,加上一个时段(duration或period)
localDate.plus(Duration.ofDays(15));
localDate.minus(Duration.ofDays(15));

//withDayOfWeek、withDayOfMonth修改日期,日期都从1开始
//withYear、withMonth修改年份、月份
localDate.withDayOfMonth(2);
localDate.withDayOfMonth(3);
localDate.withMonth(3);
localDate.withYear(1982);

//getXX方法获取日期
localDate.getDayOfMonth();
localDate.getYear();

//获取两个日期之间的Period对象
Period per = localDate1.until(localDate);
//输出P2M22D
System.out.println(per);
//可以用ChronoUnit制定输出的格式
long until = localDate1.until(localDate, ChronoUnit.DAYS);
//输出81
System.out.println(until);

//isBefore、isAfter比较前后
boolean before = localDate.isBefore(localDate1);

3、TemporalAdjuster

TemporalAdjuster为日期校正对象,用来对LocalDate对象进行一些校正操作,例如:

LocalDate localDate = LocalDate.now();

//next和previous方法、nextOrSame和previousOrSame方法
//获取当前日期的下一个周四
LocalDate localDate1 = localDate.with(TemporalAdjusters.next(DayOfWeek.THURSDAY));
//获取当前日期(如果当前是周一)或当前日期的前一个周四
LocalDate localDate2 = localDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.THURSDAY));

//dayOfWeekInMonth方法获取指定的当月的第几个周几
localDate.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.MONDAY));

//lastInMonth当月的最后一个周几
localDate.with(TemporalAdjusters.lastInMonth(DayOfWeek.MONDAY));

//lastDayOfMonth、firstDayOfMonth、lastDayOfYear、firstDayOfYear...等一系列顾名思义的日期
localDate.with(TemporalAdjusters.lastDayOfMonth());

还可以通过重写来自定义TemporalAdjuster对象

//自定义日期操作,计算下一个工作日
TemporalAdjuster NEXT_WORKDAY = temporal -> {
    //注意一定要对Temporal对象进行强转
    LocalDate result = (LocalDate)temporal;
    do{
        result = result.plusDays(1);
    }while (result.getDayOfWeek().getValue()>=6);
    return  result;
};

4、LocalTime、LocalDate和LocalDateTime

LocalDate(本地日期)只带有日期信息,相对的LocalTime(本地时间)则只带有一天内的时刻信息,而没有日期信息。

LocalDateTime则是LocalDate和LocalTime的结合,这两个类的方法都和LocalDate的方法类似。

5、ZonedDateTime

和LocalDate(本地日期)相对应的,还有一种时间ZonedDate(带时区的时间)。

在不需要考虑时区的场合中,使用LocalDate比较合理,也能避免“夏令时”等带来的可能的错误

但是在需要考虑时区变化的场合中,使用ZonedDateTime就比较方便。

由于我很少有可能会接触到时区变化,这里不做详解。

6、DateTimeFormatter格式化和解析

LocalDateTime localDateTime = LocalDateTime.now();
//直接使用对象的toString方法就可以得到默认的输出格式
localDateTime.toString();

//使用DateTimeFormatter的预定义的标准格式
//诸如此类的预定义格式还有很多,可以查阅API查看
DateTimeFormatter.ISO_DATE.format(localDateTime);




//和之前使用的SimpleDateFormat类似,也可以自定义格式,具体格式同样可以查阅API
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("E yyyy-MM-dd HH:mm:ss");
String formatedTime = dateTimeFormatter.format(localDateTime);

7、和前版本对象的相互转化

Instant类似与之前的Date类,可以通过toInstant方法和from方法相互转化。

类似的,ZonedDateTime和GregorianCalendar类似,可以通过toZonedDateTime和from相互转化。

7.1、将LocalDate转回Date

public static void main(String[] args) {
    LocalDate localDate = LocalDate.now();
    localDate.minusDays(5);
    System.out.println(localDate);
    Instant instant = localDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
    System.out.println(Date.from(instant));
}

8、具体操作示例

8.1、获取一个月中的所有工作日(节假日类似)

public class Main {
    public static void main(String[] args) {
        //自定义日期操作,计算下一个工作日
        TemporalAdjuster NEXT_WORKDAY = temporal -> {
            //注意一定要对Temporal对象进行强转
            LocalDate result = (LocalDate)temporal;
            do{
                result = result.plusDays(1);
            }while (result.getDayOfWeek().getValue()>=6);
            return  result;
        };
        List<Integer> list = new ArrayList<>();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        LocalDate localDate1 = LocalDate.of(2017,2,1);
        LocalDate localDate2 = LocalDate.of(2017,2,28);
        do {
            list.add(Integer.parseInt(dateTimeFormatter.format(localDate1)));
            localDate1 = localDate1.with(NEXT_WORKDAY);
        }while (localDate1.isBefore(localDate2)||localDate1.isEqual(localDate2));
        System.out.println(Arrays.toString(list.toArray()));
    }
}

 

转载于:https://my.oschina.net/pierrecai/blog/866003

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值