注意点:
1.字符串-格式1-日期-格式2-字符串
2.转化成日期时,*不能识别字符串中任何形式的周,*只能识别数字月份,(SimpleDateFormate的类介绍很含蓄得写了,通过测试证实了)
以下是封装的方法和测试代码
//TimeUtils类
package common.utils;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
/**
* <p>日期字符串跟日期互转工具</p>
* <P>字符串转化成日期,需要格式绝对匹配,格式字符之间的空格都很严格</p>
* <p>格式:[yHms同理]一万个d跟2个d效果一样;因为规则是day大于格式,格式往大补,day小于格式,输出补0</p>
* <p>格式:1个M,数字前不显示0;2个M小于10显示0,大于等于3个M,显示中文</p>
* <p>格式:小写z:GMT+08:00,有GMT有冒号;大写Z:+0800,没GMT没冒号:</p>
* @author lizhifeng
*
*/
public class TimeUtils {
private TimeUtils timeUtils;
/**
* <p>gmt/cst格林时间格式:M d yyyy HH:mm:ss z</p>
* <p>最大匹配:Thu Apr 14 2019 18:3:00 GMT+08:00 (中国标准时间)</p>
* <p>[Thu] Apr(or 4) 14 2019 18:3:00 GMT+08:00 [(中国标准时间)]</p>
* <p>中括号内容可以缺省,or是另一种写法</p>
*/
public final static String format_gmt = "M d yyyy HH:mm:ss z";
/**
*
* <p>常用日期格式1:yyyy-MM-dd HH:mm:ss</p>
*/
public final static String format_common1 = "yyyy-MM-dd HH:mm:ss";
/**
* 标准月份简写数组
*/
private final static String[] monStr = {"Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"};
/**
* 标准周简写数组,sat周六后面的元素是见过的别名,因为匹配直接删除,所以拓展不受影响,
如有需要可以用空间换逻辑,即用拓展名下标取余后等于原下标
*/
private final static String[] weekStr = {"Sun","Mon","Tue","Wed","Thur","Fri","Sat","Tues","Thu"};
private TimeUtils() {};
public TimeUtils getInstance() {
//如果并发情况下使用初始化方法
/*
* 因为进入同步块就消耗资源了,所以要并发时追求锁住最少代码且尽可能不进入同步块,
* 如果在同步块内才if~null检查,那么造成的局面时总要进入同步块,
* 如果是双重if~null检查,那么在前面的线程已经完成实例化后,后面的线程不需要再进过synchronized了
* */
if(null == timeUtils) {
synchronized(this) {
if(null == timeUtils)
timeUtils = new TimeUtils();
}
}
return timeUtils;
}
/**
* <p>从格式1日期字符串转化成格式2日期字符串</p>
* @param dateStr 日期字符串
* @param format_in 开始格式
* @param format_out 最终格式
* @return
* @throws ParseException
*/
public static String dateStr2dateStr(String dateStr,String format_in,String format_out) throws ParseException {
if(null == dateStr)
return null;
if(format_in.equals(format_out)/* && !format_in.equals(format_gmt)*/) {
System.out.println("前后格式相同");
return dateStr;
}
//获取gmt可识别部分
if(format_in == TimeUtils.format_gmt) {
boolean isChange = false;
//将(中国标准时间)替换为空[.任意字符 *前一个字符的所有字符 ]
dateStr = dateStr.replaceAll("\\(.*\\)","");
/*如果gmt格式是小z,且GMT跟时差有空格,正则表达式将空格替换成加号(逻辑不够完美:如果GMT跟+有空格则消除;如果跟带冒号数字有空格就替换成+-)*/
dateStr = dateStr.replaceAll("GMT\\s*","GMT+");
System.out.println("dateStr:"+dateStr);
//在替换月份的同时截断周,因为转日期时,月份只识别数字,且不识别周
for (int i = 0; i < monStr.length; i++) {
String curMon = monStr[i];
if(dateStr.contains(curMon)) {
dateStr = dateStr.substring(dateStr.indexOf(curMon)).replaceFirst(curMon,(i+1)+"");
isChange = true;
break;
}
}
//如果没有找到标准月份简写,就没有截断周,需要自己截断周
if(!isChange)
for (String week : weekStr)
if(dateStr.contains(week)) {
dateStr = dateStr.substring(week.length()+1);
break;
}
}
//保证str->date->str 在date阶段可以识别
return new SimpleDateFormat(format_out).format(new SimpleDateFormat(format_in).parse(dateStr));
}
/**
* 可识别的日期字符串转化成日期
* @param date_str
* @param format
* @return 日期型数据
* @throws ParseException
*/
public static Date dateStrToDate(String date_str,String format) throws ParseException{
if(null == date_str)
return null;
return new SimpleDateFormat(format).parse(date_str);
}
}
测试代码:
String com = "2019-04-14 18:03:00";
String gmt = "Thu Apr 14 2019 18:3:00 GMT+08:00 (中国标准时间)";
String time = TimeUtils.dateStr2dateStr(gmt, TimeUtils.format_1, TimeUtils.format_gmt);
System.out.println(time);