根據時間戳轉Date實現(Java)及實現原理分析
阿新 • • 發佈:2018-12-11
時間戳是指格林威治時間1970年01月01日00時00分00秒(北京時間1970年01月01日08時00分00秒)起至現在的總秒數。
本次實現跟根據Java.text.* 包中的工具類實現的,示例程式碼:
import java.text.SimpleDateFormat; public class TestTimestemp { public static void main(String[] args) { SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd"); long currentTimeMillis = System.currentTimeMillis(); System.out.println(currentTimeMillis); // 1540034763419 String format = sf.format(currentTimeMillis);//1540034763419 System.out.println(format); //2018-10-20 } }
以下是對原始碼簡單分析的筆記:
1. 先看SimpleDateFormat的類繼承關係
public class SimpleDateFormat extends DateFormat {...}
public abstract class DateFormat extends Format {...}
public abstract class Format implements Serializable, Cloneable {...}
2. 上面sf.format()呼叫的是Format類中的方法,最終其實呼叫的是抽象方法,原始碼如下:
public abstract class Format implements Serializable, Cloneable { public final String format (Object obj) { return format(obj, new StringBuffer(), new FieldPosition(0)).toString(); } public abstract StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos); }
3. Format中的抽象方法的實現類在DateFormat中,DateFormat最終呼叫的也是抽象方法,原始碼如下:
public abstract class DateFormat extends Format { public final StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition fieldPosition) { if (obj instanceof Date) return format( (Date)obj, toAppendTo, fieldPosition ); else if (obj instanceof Number) return format( new Date(((Number)obj).longValue()), toAppendTo, fieldPosition ); else throw new IllegalArgumentException("Cannot format given Object as a Date"); } public abstract StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition); }
4. DateFormat中的抽象方法實現類在SimpleDateFormat中,具體的轉換演算法也是在該類中實現,原始碼如下:
public class SimpleDateFormat extends DateFormat {
protected Calendar calendar;//建立SimpleDateFormat物件時會例項化該物件,具體方法可查原始碼
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo,
FieldPosition pos)
{
pos.beginIndex = pos.endIndex = 0;
return format(date, toAppendTo, pos.getFieldDelegate());
}
// Called from Format after creating a FieldDelegate
private StringBuffer format(Date date, StringBuffer toAppendTo,
FieldDelegate delegate) {
// Convert input date to time field list
calendar.setTime(date);
boolean useDateFormatSymbols = useDateFormatSymbols();
for (int i = 0; i < compiledPattern.length; ) {
int tag = compiledPattern[i] >>> 8;
int count = compiledPattern[i++] & 0xff;
if (count == 255) {
count = compiledPattern[i++] << 16;
count |= compiledPattern[i++];
}
switch (tag) {
case TAG_QUOTE_ASCII_CHAR:
toAppendTo.append((char)count);
break;
case TAG_QUOTE_CHARS:
toAppendTo.append(compiledPattern, i, count);
i += count;
break;
default:
subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);
break;
}
}
return toAppendTo;
}
}