根据时间戳转Date实现(Java)及实现原理分析

时间戳是指格林威治时间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;
    }
}

猜你喜欢

转载自blog.csdn.net/u010612373/article/details/83216111
今日推荐