现在有一个表示时间的字符串“2019/12/1 22:13:55”,现在我要对其计算1小时后的时间是多少?
思路:
1、解析该字符串,获得其pattern
2、解析该字符串获得时间类的实例
3、进行加法计算
4、(使用前面的pattern)将结果format,并得到最终结果
在使用JDK1.6的时候,我曾经写过类似的代码(没发过),基本思路是:
1、预先定义一些pattern以及其的正则表达式,字符串能够匹配正则,则找到其pattern
2、用SimpleDateFormat解析得到Date
3、将Date转换成Calendar调用add进行计算
4、Calendar实例转换成Date,再format得到字符串
现在用JDK1.8了,而1.8有了新的时间类LocalDateTime,是否也可以用LocalDateTime进行字符串时间的加法计算?
so重新梳理了一下思路:
1、匹配pattern原先的太狭隘了!按如下原则重写该部分功能:
1.a、时间单位是按从大到小的顺序,即:年、月、日、时、分、秒、毫秒
1.b、间隔符可以是任意不与pattern关键字重复的字符,也可以是多个连续的字符;
1.c、有间隔符时,表示时间的数字无需保证位数足够,如十二点一分三十五秒可以为:12:1:35;而无时间间隔符时表示时间的位数必须足够,上例时间为:120135
2、解析该字符串成为LocalDateTime。注意:如果该字符串表示的时间没有小时或更小的单位,需要特殊处理!
3、LocalDateTime调用plus进行计算
4、LocalDateTime调用format得到计算结果
相关代码如下:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
public class DateUtil2 {
//yyyy-MM-dd HH:mm:ss SSS
private static String PATTERN_YEAR="y";
private static String PATTERN_MONTH="M";
private static String PATTERN_DAY="d";
private static String PATTERN_HOUR="H";
private static String PATTERN_MINUTE="m";
private static String PATTERN_SECOND="s";
private static String PATTERN_MILLISECOND="S";
private static ChronoUnit getMinUnit4Pattern(String pattern) {
if(pattern!=null) {
if(pattern.contains(PATTERN_MILLISECOND)) {
return ChronoUnit.MILLIS;
}else if(pattern.contains(PATTERN_SECOND)) {
return ChronoUnit.SECONDS;
}else if(pattern.contains(PATTERN_MINUTE)) {
return ChronoUnit.MINUTES;
}else if(pattern.contains(PATTERN_HOUR)) {
return ChronoUnit.HOURS;
}else if(pattern.contains(PATTERN_DAY)) {
return ChronoUnit.DAYS;
}else if(pattern.contains(PATTERN_MONTH)) {
return ChronoUnit.MONTHS;
}else if(pattern.contains(PATTERN_YEAR)) {
return ChronoUnit.YEARS;
}
}
return null;
}
private static String getPattern(String strDt) {
if(strDt!=null) {
String[] ss = new String[] {PATTERN_YEAR,PATTERN_MONTH,PATTERN_DAY
,PATTERN_HOUR,PATTERN_MINUTE,PATTERN_SECOND,PATTERN_MILLISECOND};
int pos=0,count=0;
StringBuffer buffer=new StringBuffer();
for(int index=0;index<strDt.length();index++) {
if(Character.isDigit(strDt.charAt(index))) {
if(pos==ss.length) {//长度超了!有未知的信息
return null;
}
buffer.append(ss[pos]);
count++;
if(PATTERN_YEAR.equals(ss[pos])) {//年是4位
if(count==4) {
pos++;
count=0;
}
}else if(PATTERN_MILLISECOND.equals(ss[pos])){//毫秒是3位
if(count==3) {
pos++;
count=0;
}
}else if(count==2) {//其他单位是2位
pos++;
count=0;
}
}else {
buffer.append(strDt.charAt(index));
if(count>0) {
pos++;
count=0;
}
}
}
return buffer.toString();
}
return null;
}
public static long interval(String strDt1,String strDt2) {
String pattern = getPattern(strDt1);
ChronoUnit unit =getMinUnit4Pattern(pattern);
return interval(strDt1,strDt2,unit);
}
public static long interval(String strDt1,String strDt2, ChronoUnit unit) {
LocalDateTime dt1 = parse(strDt1);
LocalDateTime dt2 = parse(strDt2);
return unit.between(dt1, dt2);
}
public static LocalDateTime parse(String strDt) {
String pattern=getPattern(strDt);
if(pattern!=null) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
LocalDateTime dt;
if(pattern.contains(PATTERN_HOUR)) {
dt=LocalDateTime.parse(strDt, formatter);
}else {
LocalDate date=LocalDate.parse(strDt,formatter);
LocalTime time=LocalTime.parse("00:00");
dt=LocalDateTime.of(date, time);
}
return dt;
}
return null;
}
public static String plus(String strDt,long num) {
String pattern=getPattern(strDt);
ChronoUnit unit= getMinUnit4Pattern(pattern);
return plus(strDt,num,unit);
}
public static String plus(String strDt,long num,ChronoUnit unit) {
String pattern=getPattern(strDt);
LocalDateTime dt=parse(strDt);
if(dt!=null) {
LocalDateTime dt2=dt.plus(num, unit);
return dt2.format(DateTimeFormatter.ofPattern(pattern));
}
return null;
}
public static void main(String[] args) {
System.out.println(interval("2017/5/3 01","20180521",ChronoUnit.DAYS));
System.out.println(plus("2018/1*30",13,ChronoUnit.MONTHS));
}
}