1、为什么推荐用Java8中的日期和时间API呢?
首先,当然是因为新的东西是在旧的东西基础之上修改的。(瞎扯)
常用的日期时间类:java.util.Date类->是在Java 1.0中;而java.util.Calendar类->是在Java 1.1中。2014年3月份已经发行Java 1.8 也就是我们说的Java 8。
java.util.Date缺点:(1)年份是从1970开始算的;(2)DateFormat方法不是线程安全的。
java.util.Calendar缺点:和Date类一样都是可变的。而且经常会同时用Date和Calendar,很混乱。
因此,在Java8中进一步增强和改进了日期和时间的API。
2、在传统的javaweb 开发中在前端控件中:经常有开始日期时间和结束日期时间(格式一般为:yyyy-MM-ddHH:mm:ss),假设我们现在对日期时间的判断全部由服务端判断,不考虑前端去比较。
假如有如下要求:
(1)服务端需要将前端传入的日期时间字符串转成日期时间格式
(2)保证开始时间不能大于结束时间
(3)结束时间不能比开始时间超过7天
代码示例:
public class Java8Date {
private final static Logger LOG = LoggerFactory.getLogger(Java8Date.class);
private final static Duration SEVEN_DAY_DURATION = Duration.ofDays(7);
private final static DateTimeFormatter MY_DATE_TIME_FORMATTER;
static{
MY_DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
}
public static void main(String[] args) {
//1、将字符串日期时间parse成日期时间
String beginDateTimeStr = "2017-04-01 22:39:40";
String stopDateTimeStr = "2017-04-06 22:44:21";
LocalDateTime beginDateTime = LocalDateTime.parse(beginDateTimeStr, MY_DATE_TIME_FORMATTER);
LocalDateTime stopDateTime = LocalDateTime.parse(stopDateTimeStr, MY_DATE_TIME_FORMATTER);
//2、判断两个日期之间的比较
Duration duration = Duration.between(beginDateTime, stopDateTime);
//2.1 开始日期不能大于结束时间
if(duration.isNegative() || beginDateTime.isAfter(stopDateTime)){
LOG.error("BeginTime is bigger than stopTime, params is:[beginDateTime is {}, stopDateTime is {}].",
beginDateTime.format(MY_DATE_TIME_FORMATTER), stopDateTime.format(MY_DATE_TIME_FORMATTER));
return ;
}
//2.2 开始日期与结束日期之间的间隔不能够超过一个礼拜(即七天)
if(duration.compareTo(SEVEN_DAY_DURATION)>0){
LOG.error("StopTime can't be more than seven days than beginTime, parms is:[beginDateTime is {}, stopDateTime is {}].",
beginDateTime.format(MY_DATE_TIME_FORMATTER), stopDateTime.format(MY_DATE_TIME_FORMATTER));
return ;
}
}
}
代码解析:
在这段代码中,我们用到以下java.time.*(这是java 1.8 提供的)中的API接口:
LocalDateTime、Duration、DateTimeFormatter
为了将日期时间字符串转成日期时间格式,我们定义了一个新的DateTimeFormatter(由于Java 1.8中DateTimeFormatter自身带的格式不满足我们要求),然后,调用parse静态方法将其转成我们需要的日期时间。
为了比较开始日期时间与结束日期时间之间的关系,我们利用Duration,可以获取两个Temporal之间的差(LocalDateTime实现该接口)。然后,在比较是否开始日期时间大于结束日期时间以及结束日期时间不能比开始日期时间远七天(这里重新定义了一个Duration.ofDays(7)表示跨度7天,使得代码更易阅读),都通过其内部自带的方法。
日期时间格式再转成日期时间字符串需调用format方法:beginDateTime.format(MY_DATE_TIME_FORMATTER)
3、补充Jav8日期时间知识点:
(1)如何获取当前的时间戳
java 1.8 之前:System.currentTimeMillis()/1000
java 1.8 写法:Instant.now().getEpochSecond();这里Instant类Java 8专门用来表示时间戳。
(2)日期时间格式如何转成Unix时间戳
Java 1.8 之前:
Date date =new Date();
long timeStamp= date.getTime()/1000;
Java 1.8 写法:
LocalDateTimelocalDateTime = LocateDateTime.now();
long timeStamp= localDateTime.toEpochSecond(ZonOffSet.ofHours(8));
在Java 8中日期时间格式转成时间戳一定要显示的指定时区,而在Date中会默认只用系统当前的时间区间。显然,java 1.8的写法更严谨,因为对于同一个时间如果换了一个时区(比如说换了一个地点),时间的概念就不一样了。
PS:中国大陆的时区需要该参数ZonOffSet.ofHours(8)。
(3)时间戳如何转成LocateDateTime日期时间格式
LocalDateTimedateTime = LocalDateTime.ofEpochSecond(timeStamp, 0, ZoneOffset.ofHours(8))
时区的概念同上。