packagecom.study.test;importjava.io.Serializable;importjava.text.SimpleDateFormat;import java.util.*;/*** 实现Java中日期的简单格式化,支持以下字段:
* yyyy:年
* MM:月
* dd:日
* hh:1~12小时制(1-12)
* HH:24小时制(0-23)
* mm:分
* ss:秒
* S:毫秒
* E:星期几
* a: 上午/下午*/
public class DateFormatter implementsSerializable {private static Map tokenFieldMap = new HashMap<>();private static final int NO_LENGTH = 1000; //不用自动补0的属性,例如毫秒
private static final int LOCALE = NO_LENGTH + 1000; //用Locale获取值的属性,例如星期//tokenFieldMap,将字符与Calendar中的field对应
static{
tokenFieldMap.put('y', Calendar.YEAR);
tokenFieldMap.put('M', Calendar.MONTH);
tokenFieldMap.put('d', Calendar.DATE);
tokenFieldMap.put('h', Calendar.HOUR);
tokenFieldMap.put('H', Calendar.HOUR_OF_DAY);
tokenFieldMap.put('m', Calendar.MINUTE);
tokenFieldMap.put('s', Calendar.SECOND);
tokenFieldMap.put('a', Calendar.AM_PM +LOCALE);
tokenFieldMap.put('S',Calendar.MILLISECOND +NO_LENGTH);
tokenFieldMap.put('E',Calendar.DAY_OF_WEEK +LOCALE);
}private static class Token implementsSerializable {int field; //Calendar中的field对应
int length; //自动补0的长度
public Token(int field, intlength) {this.field =field;this.length =length;
}
}//解析出的token,可能是token或者是String
private Listtokens;privateString format;publicDateFormatter(String format) {this.format =format;
parseTokens();
}publicString getFormat() {returnformat;
}publicString format(Date date){if(date == null){throw new IllegalArgumentException("null argument!");
}
StringBuilder sb= newStringBuilder();
Calendar calendar=Calendar.getInstance();
calendar.setTime(date);for(Object token : tokens){if(token instanceofToken){
token2String(sb,(Token)token,calendar);
}else{
sb.append(token);
}
}returnsb.toString();
}private voidparseTokens() {
tokens= new ArrayList<>();
StringBuilder temp= newStringBuilder();for (int i = 0; i < format.length(); i++) {char c =format.charAt(i);
Integer field=tokenFieldMap.get(c);if (field != null) {
checkStr(temp);if(field
i++;
num++;
}
tokens.add(newToken(field, num));
}else{
tokens.add(new Token(field, 0));
}
}else{
temp.append(c);
}
}
checkStr(temp);
}private voidcheckStr(StringBuilder temp) {if (temp.length() > 0) {
tokens.add(temp.toString());
temp.setLength(0);
}
}
@SuppressWarnings("MagicConstant")private voidtoken2String(StringBuilder sb, Token token, Calendar calendar){int field =token.field;if(field >LOCALE){
sb.append(calendar.getDisplayName(field-LOCALE,Calendar.SHORT,Locale.getDefault()));
}else if(field >NO_LENGTH){
sb.append(calendar.get(field-NO_LENGTH));
}else{int val =calendar.get(field);if(field ==Calendar.MONTH){
val++; //如果是月,取出的范围是0-11,需要加一
}
String value=String.valueOf(val);if(value.length() >token.length){if(token.field == Calendar.YEAR){ //如果是年,才截取,比如2018可以截取成18年,小时分钟不能截取
sb.append(value.substring(value.length() -token.length));
}else{
sb.append(value);
}
}else{for(int i=0;i
sb.append('0');
}
sb.append(value);
}
}
}public static void main(String[] args)throwsException {
String fmt= "yy-M-dd a h:m:s E";
Date date= newDate();
DateFormatter formatter= newDateFormatter(fmt);
String result=formatter.format(date);
System.out.println(result);
SimpleDateFormat simpleDateFormat= newSimpleDateFormat(fmt);
System.out.println(simpleDateFormat.format(date));//性能测试
long t1 =System.currentTimeMillis();for(int i=0;i<30000;i++){
simpleDateFormat.format(new Date(System.currentTimeMillis() + i * 3000));
}long t2 =System.currentTimeMillis();for(int i=0;i<30000;i++){
formatter.format(new Date(System.currentTimeMillis() + i * 3000));
}long t3 =System.currentTimeMillis();
System.out.println("formatter cost : " + (t3 -t2));
System.out.println("java format cost : " + (t2 -t1));
}
}