java工具类,字符串转时间
java工具类字符串转时间packagecom.tomato.test2;importorg.apache.commons.lang3.StringUtils;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importjava.time.Instant;importjava.time.LocalDateTime;importjava.time.ZoneId;importjava.time.ZonedDateTime;importjava.time.format.DateTimeFormatter;importjava.time.format.DateTimeParseException;importjava.util.Arrays;importjava.util.Locale;importjava.util.Map;importjava.util.concurrent.ConcurrentHashMap;importjava.util.regex.Matcher;importjava.util.regex.Pattern;publicclassTimeUtil{privatestaticfinalLoggerLOGGERLoggerFactory.getLogger(TimeUtil.class);privatestaticfinalMapString,DateTimeFormatterFORMATTER_CACHEnewConcurrentHashMap();// 常用格式常量publicstaticfinalStringDEFAULT_YMDHMS_FORMATyyyy-MM-dd HH:mm:ss;publicstaticfinalStringDMYHMS_FORMATdd/MM/yyyy HH:mm:ss;publicstaticfinalStringDEFAULT_YMD_FORMATyyyy-MM-dd;publicstaticfinalStringDEFAULT_DATE_FORMATyyyy/MM/dd;publicstaticfinalStringSOLR_TDATE_FORMATyyyy-MM-ddTHH:mm:ss.SSSZ;publicstaticfinalStringSOLR_TDATE_RETURN_FORMATyyyy-MM-ddTHH:mm:ssZ;publicstaticfinalStringORACLE_TDATE_RETURN_FORMATyyyy-MM-dd HH:mm:ss.SSS;publicstaticfinalStringJS_TDATE_RETURN_FORMATyyyy-MM-dd HH:mm:ss.S;publicstaticfinalStringCOMPACT_YMDHMS_FORMATyyyyMMddHHmmss;publicstaticfinalStringCOMPACT_YMD_FORMATyyyyMMdd;publicstaticfinalStringCOMPACT_YMDH_FORMATyyyyMMddHH;publicstaticfinalStringUS_TIME_FORMATEEE MMM d HH:mm:ss z yyyy;publicstaticfinalStringTDATE_RETURN_FORMATyyyy-MM-dd HH:mm:ss.nnnnnnnnn;publicstaticfinalStringCOMPACT_CHINESE_FORMATyyyy年MM月dd日;publicstaticfinalStringYMDHS_FORMATyyyy/MM/dd HH:mm;publicstaticfinalStringYMDHS_FORMAT_WITHOUT_SPLIT_TAGyyyyMMddHHmm;privatestaticfinalPatternDATE_ONLY_PATTERNPattern.compile((\\d{4})-(\\d{1,2})-(\\d{1,2}));privatestaticfinalPatternDATE_TIME_PATTERNPattern.compile((\\d{4}-\\d{2}-\\d{2})(?:[T ](\\d{1,2})(?::(\\d{1,2})(?::(\\d{1,2}))?)?)?);static{Arrays.asList(DEFAULT_YMDHMS_FORMAT,DMYHMS_FORMAT,DEFAULT_YMD_FORMAT,DEFAULT_DATE_FORMAT,SOLR_TDATE_FORMAT,SOLR_TDATE_RETURN_FORMAT,ORACLE_TDATE_RETURN_FORMAT,JS_TDATE_RETURN_FORMAT,COMPACT_YMDHMS_FORMAT,COMPACT_YMD_FORMAT,COMPACT_YMDH_FORMAT,COMPACT_CHINESE_FORMAT,YMDHS_FORMAT,YMDHS_FORMAT_WITHOUT_SPLIT_TAG,yyyy-MM-dd HH:mm:ss.S,yyyy-MM-dd HH:mm:ss.SSS,yyyy-MM-dd HH:mm:ss.nnnnnnnnn,dd/MM/yyyy HH:mm:ss).forEach(pattern-FORMATTER_CACHE.put(pattern,DateTimeFormatter.ofPattern(pattern)));FORMATTER_CACHE.put(US_TIME_FORMAT,DateTimeFormatter.ofPattern(US_TIME_FORMAT,Locale.US));}privatestaticDateTimeFormattergetFormatter(Stringpattern){if(StringUtils.isBlank(pattern)){thrownewIllegalArgumentException(DateTime pattern must not be blank);}returnFORMATTER_CACHE.computeIfAbsent(pattern,p-{try{returnDateTimeFormatter.ofPattern(p);}catch(Exceptione){LOGGER.error(Failed to create DateTimeFormatter for pattern: {},p,e);thrownewIllegalArgumentException(Invalid date pattern: p,e);}});}publicstaticLocalDateTimeparseTime(StringtimeStr,Stringpattern){if(StringUtils.isBlank(timeStr)||null.equalsIgnoreCase(timeStr.trim())){returnnull;}timeStrtimeStr.trim();timeStrpreprocessTimeStr(timeStr,pattern);if(StringUtils.isNotBlank(pattern)){try{DateTimeFormatterformattergetFormatter(pattern);StringinputtimeStr;if(isDateOnlyPattern(pattern)){// 处理纯日期模式截取日期部分并解析为 LocalDate → LocalDateTimeif(input.length()10input.matches(\\d{4}-\\d{2}-\\d{2}.*)){inputinput.substring(0,10);}java.time.LocalDatedatejava.time.LocalDate.parse(input,formatter);returndate.atStartOfDay();}else{// 含时间的模式直接解析 LocalDateTimereturnLocalDateTime.parse(input,formatter);}}catch(Exceptione){LOGGER.debug(指定格式解析失败{}pattern{},timeStr,pattern,e);}}if(timeStr.contains(长期)){returnLocalDateTime.of(2999,12,31,0,0,0);}returnparseByAutoDetect(timeStr);}privatestaticLocalDateTimeparseByAutoDetect(StringtimeStr){intlentimeStr.length();if(len10StringUtils.isNumeric(timeStr)){try{returnInstant.ofEpochSecond(Long.parseLong(timeStr)).atZone(ZoneId.systemDefault()).toLocalDateTime();}catch(Exceptionignored){}}if(len8)returntryParse(timeStr,COMPACT_YMD_FORMAT);if(len12)returntryParse(timeStr,YMDHS_FORMAT_WITHOUT_SPLIT_TAG);if(len14)returntryParse(timeStr,COMPACT_YMDHMS_FORMAT);if(len10){if(timeStr.contains(-))returntryParse(timeStr,DEFAULT_YMD_FORMAT);if(timeStr.contains(/))returntryParse(timeStr,DEFAULT_DATE_FORMAT);}if(len16len19){returntryParse(timeStr,DEFAULT_YMDHMS_FORMAT);}if(len21)returntryParse(timeStr,JS_TDATE_RETURN_FORMAT);if(len23)returntryParse(timeStr,ORACLE_TDATE_RETURN_FORMAT);if(len20)returntryParse(timeStr,SOLR_TDATE_RETURN_FORMAT);// 重点修复SOLR UTC 格式必须用 Instant.parseJDK 8 支持if(len24timeStr.endsWith(Z)){try{InstantinstantInstant.parse(timeStr);returnLocalDateTime.ofInstant(instant,ZoneId.systemDefault());}catch(Exceptionignored){}}if(timeStr.contains(年)timeStr.contains(月)timeStr.contains(日)){returntryParse(timeStr,COMPACT_CHINESE_FORMAT);}if(timeStr.matches(^[A-Za-z]{3} [A-Za-z]{3} \\d{1,2} .* \\d{4}$)){try{ZonedDateTimezdtZonedDateTime.parse(timeStr,getFormatter(US_TIME_FORMAT));returnzdt.toLocalDateTime();}catch(Exceptionignored){}}LOGGER.warn(无法自动解析时间字符串: {},timeStr);returnnull;}privatestaticLocalDateTimetryParse(Stringtext,Stringpattern){try{returnLocalDateTime.parse(text,getFormatter(pattern));}catch(DateTimeParseExceptione){returnnull;}}publicstaticStringformat(LocalDateTimedateTime,Stringpattern){if(dateTimenull||StringUtils.isBlank(pattern))return;returndateTime.format(getFormatter(pattern));}privatestaticbooleanisDateOnlyPattern(Stringpattern){if(patternnull)returnfalse;Stringppattern;return!p.contains(H)!p.contains(h)!p.contains(m)!p.contains(s)!p.contains(S)!p.contains(n);}privatestaticStringpadToTwoDigits(Stringpart){if(partnull)return00;try{intnumInteger.parseInt(part);if(num0||num59)return00;returnString.format(%02d,num);}catch(NumberFormatExceptione){LOGGER.debug(非法时间数字部分: {},part);return00;}}privatestaticStringpreprocessTimeStr(StringtimeStr,Stringpattern){if(StringUtils.isBlank(timeStr)){returntimeStr;}StringstandardizedtimeStr.replaceAll([./],-);// 显式声明 Matcher 类型JDK 8 不支持 varMatcherdateMatcherDATE_ONLY_PATTERN.matcher(standardized);if(dateMatcher.find()){StringyeardateMatcher.group(1);StringmonthpadToTwoDigits(dateMatcher.group(2));StringdaypadToTwoDigits(dateMatcher.group(3));standardizeddateMatcher.replaceFirst(year-month-day);}if(StringUtils.isNotBlank(pattern)){booleanneedsHourpattern.contains(H)||pattern.contains(k)||pattern.contains(K)||pattern.contains(h);booleanneedsMinutepattern.contains(m);booleanneedsSecondpattern.contains(s);if(needsHour||needsMinute||needsSecond){// 显式声明 MatcherMatcherdtMatcherDATE_TIME_PATTERN.matcher(standardized);if(dtMatcher.matches()){StringdatePartdtMatcher.group(1);StringhourdtMatcher.group(2);StringminutedtMatcher.group(3);StringseconddtMatcher.group(4);StringBuilderresultnewStringBuilder(datePart);if(needsHour){result.append( ).append(padToTwoDigits(hour));}else{returndatePart;}if(needsMinute){result.append(:).append(padToTwoDigits(minute));}if(needsSecond){result.append(:).append(padToTwoDigits(second));}standardizedresult.toString();}}}returnstandardized;}publicstaticvoidmain(String[]args){// 年月日没有时分秒// String pattern yyyy-MM-dd;// LocalDateTime localDateTime TimeUtil.parseTime(2012-05-05 12:34:56, pattern);// 补全时分秒// String pattern yyyy-MM-dd HH:mm:ss;// LocalDateTime localDateTime TimeUtil.parseTime(2012-01-05 12:36, pattern);// 补全一位日期// String pattern yyyy-MM-dd HH:mm:ss;// LocalDateTime localDateTime TimeUtil.parseTime(2012-1-05 12:36, pattern);// 无法转换,localDateTime返回为nullStringpatternyyyy-MM-dd HH:mm:ss;LocalDateTimelocalDateTimeTimeUtil.parseTime(abc,pattern);if(localDateTimenull){System.out.println(无法转换);return;}System.out.println(localDateTime.format(DateTimeFormatter.ofPattern(pattern)));}}