<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆-4  評(píng)論-4  文章-0  trackbacks-0

    本文從Google blogger上搬過來的,原文由于眾所周知的原因在國(guó)內(nèi)無法訪問了,順帶鄙視一下。

    前段時(shí)間 CSDN 上有人問起 Win32 FileTime 格式與 Java 中Date格式如何進(jìn)行相互轉(zhuǎn)換。詳見:http://topic.csdn.net/u/20090420/11/8016744d-d151-4041-a837-5a14f2592e3f.html

    根據(jù) MSDN 上關(guān)于FILETIME結(jié)構(gòu)的描述,可以很方便地在FILETIME與 Java 中Date進(jìn)行互轉(zhuǎn)。MSDN 上稱,FILETIME采用 64 位數(shù)值表示與 UTC 時(shí)間 1601 年 1 月 1 日 0 時(shí)起百納秒的時(shí)間間隔。

    MSDN 上FILETIME結(jié)構(gòu)的描述為:

    typedef struct _FILETIME {
        DWORD dwLowDateTime;
        DWORD dwHighDateTime;
    } FILETIME, *PFILETIME;
    

    由于DWORD僅能表示 32 位無符號(hào)的整數(shù),因此需要使用兩個(gè)DWORD才能表示 file time。dwLowDateTime是指 file time 的低 32 位值,而dwHighDateTime是指 file time 的高 32 位值。

    在 Java 中的時(shí)間是采用 Unix 紀(jì)元,即與 UTC 時(shí)間 1970 年 1 月 1 日 0 時(shí)起的毫秒時(shí)間間隔,在 Java 中是使用long類型來表示這個(gè)值的。

    有了上面的知識(shí)點(diǎn),就可以很容易地把 Win32 FileTime 時(shí)間與 Java 中Date進(jìn)行互相轉(zhuǎn)換。需要做的是計(jì)算出 1601 年 1 月 1 日 0 時(shí)與 1970 年 1 月 1 日 0 時(shí)之間的毫秒數(shù)差值,加上 Unix 紀(jì)元的毫秒數(shù)時(shí)間,再將其換算成百納秒就可以進(jìn)行轉(zhuǎn)換了。按 Unix 紀(jì)元 1970 年 1 月 1 日 0 時(shí)之前均為負(fù)數(shù)。

    由于涉及時(shí)間計(jì)算,為了保證正確性,先用代碼來校驗(yàn)一下時(shí)區(qū),看看 1970 年 1 月 1 日 0 時(shí)是否為 0。

    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class Test5 {
    
        public static void main(String[] args) {
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = parseDate("1970-01-01 00:00:00", format);
            System.out.println(date.getTime());
        }
    
        public static Date parseDate(String str, DateFormat format) {
            Date date = null;
            try {
                date = format.parse(str);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }
    

    上面代碼運(yùn)行的結(jié)果是:

    -28800000
    

    可見這個(gè)結(jié)果是不正確的,由于我們當(dāng)前系統(tǒng)的時(shí)區(qū)是 GMT+8 區(qū),也就是比格林尼治標(biāo)準(zhǔn)時(shí)間相差 8 個(gè)小時(shí),這 28800000 也正好是 8 個(gè)小時(shí)的毫秒數(shù)。我們只要為DateFormat加上下面這一段代碼就可以將格式化器轉(zhuǎn)為 GMT 時(shí)間(對(duì)于本文而言 UTC 時(shí)間與 GMT 時(shí)間沒有區(qū)別,具體的區(qū)別可以參考 更多閱讀 中提供的資料)。

    public static void main(String[] args) {
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        format.setTimeZone(TimeZone.getTimeZone("UTC"));
        Date date = parseDate("1970-01-01 00:00:00", format);
        System.out.println(date.getTime());
    }
    

    此時(shí)我們輸出的結(jié)果就是 0 了,再將其換成“1601-01-01 00:00:00”時(shí)輸出為:

    -11644473600000
    

    由于這個(gè)值是個(gè)常量固定值,將這個(gè)值取絕對(duì)值暫且命名為UNIX_FILETIME_MILLISECOND_DIFF

    接下來需要獲得毫秒數(shù)與百納秒數(shù)的倍率。眾所周知,1 秒等于 103 毫秒,而 1 毫秒等于 106 納秒,因此可以推算出 1 毫秒等于 104 百納秒。

    由于FILETIME結(jié)構(gòu)是采用兩個(gè)DWORD來表示的,對(duì)于 Java 而言,可以將DWORD映射為int類型。通過移位運(yùn)算符<<可以將這兩個(gè) 32 位的int轉(zhuǎn)換為 64 位的long數(shù)據(jù),以便于對(duì) Unix 紀(jì)元毫秒數(shù)的計(jì)算。

    為了采用面向?qū)ο蟮姆绞竭M(jìn)行設(shè)計(jì),可以仿照FILETIME結(jié)構(gòu)的定義,聲明一個(gè)FILETIME的類,其中包含高 32 位數(shù)字和低 32 位數(shù)字。為了封裝一下,把 Unix 紀(jì)元與FILETIME零起點(diǎn)的毫秒值與毫秒與百納秒的倍率置為常量。

    public class FileTime {
    
        /**
         * Unix 時(shí)間 1970-01-01 00:00:00 與 Win32 FileTime 時(shí)間 1601-01-01 00:00:00
         * 毫秒數(shù)差
         */
        public final static long UNIX_FILETIME_MILLISECOND_DIFF = 11644473600000L;
    
        /**
         * Win32 FileTime 采用 100ns 為單位的,定義 100ns 與 1ms 的倍率
         */
        public final static int MILLISECOND_100NANOSECOND_MULTIPLE = 10000;
    
        /**
         * FileTime 的低 32 位數(shù)
         */
        private int low;
    
        /**
         * FileTime 的高 32 位數(shù)
         */
        private int high;
    
        public FileTime() {
    
        }
    
        /**
         * 獲得 FileTime 以 64 位數(shù)字表示的數(shù)據(jù)
         * @return
         */
        public long getFileTime() {
            return (((long)high << 32) & 0xffffffff) | ((long)low & 0xffffffff);
        }
    
        public FileTime(int low, int high) {
            this.low = low;
            this.high = high;
        }
    
        public int getLow() {
            return low;
        }
    
        public void setLow(int low) {
            this.low = low;
        }
    
        public int getHigh() {
            return high;
        }
    
        public void setHigh(int high) {
            this.high = high;
        }
    
        public String toString() {
            return "high: " + high + ", low: " + low;
        }
    }
    

    定義好了結(jié)構(gòu),為了能與java.util.Date互轉(zhuǎn),還需要增加一個(gè)toDate的方法和一個(gè)date2FileTime的靜態(tài)方法。

    /**
     * 將 Win32 的 FileTime 結(jié)構(gòu)轉(zhuǎn)為 Java 中的 Date 類型
     * @param fileTime
     * @return
     */
    public Date toDate() {
        return new Date(getFileTime() / MILLISECOND_100NANOSECOND_MULTIPLE - 
                UNIX_FILETIME_MILLISECOND_DIFF);
    }
    
    /**
     * 將 Java 中的 Date 類型轉(zhuǎn)為 Win32 的 FileTime 結(jié)構(gòu)
     * @param date
     * @return
     */
    public static FileTime date2FileTime(Date date) {
        long time = (UNIX_FILETIME_MILLISECOND_DIFF + date.getTime()) * 
                MILLISECOND_100NANOSECOND_MULTIPLE;
        FileTime fileTime = new FileTime();
        fileTime.setHigh((int)(time >> 32) & 0xffffffff);
        fileTime.setLow((int)time & 0xffffffff);
        return fileTime;
    }
    

    結(jié)構(gòu)和代碼都定義完成了,寫個(gè)測(cè)試代碼來測(cè)試一下,看看“2010-07-10 15:35:18”的 FileTime 值是多少。

    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class Test5 {
    
        public static void main(String[] args) {
    
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
            Date date1 = parseDate("2010-07-10 15:35:18", format);
    
            FileTime fileTime = FileTime.date2FileTime(date1);
            System.out.println(fileTime.toString());
    
            FileTime fileTile = new FileTime();
            fileTile.setHigh(30089218);
            fileTile.setLow(1907785472);
            Date date2 = fileTile.toDate();
            System.out.println(format.format(date2));
        }
    
        public static Date parseDate(String str, DateFormat format) {
            Date date = null;
            try {
                date = format.parse(str);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }
    
    更多閱讀
    posted on 2011-03-26 23:47 菜菜寶寶 閱讀(2410) 評(píng)論(0)  編輯  收藏 所屬分類: Java基礎(chǔ)

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲av无码潮喷在线观看| 成人毛片18女人毛片免费| 又爽又黄无遮挡高清免费视频| 91亚洲自偷在线观看国产馆| 亚洲毛片免费视频| 亚洲bt加勒比一区二区| 嫩草在线视频www免费观看| 久久精品国产亚洲一区二区| 在线免费播放一级毛片| 亚洲乱码精品久久久久..| 999zyz**站免费毛片| 亚洲av无码国产精品夜色午夜| 日本在线免费播放| 色拍自拍亚洲综合图区| free哆啪啪免费永久| 亚洲AV无码精品蜜桃| 国产网站免费观看| yellow视频免费看| 亚洲精品无码精品mV在线观看| 久久99精品视免费看| 亚洲乱码中文论理电影| 成人超污免费网站在线看| 国产精品亚洲综合天堂夜夜| 亚洲毛片av日韩av无码| 免费国产99久久久香蕉| 亚洲日本在线免费观看| 日韩激情淫片免费看| caoporn成人免费公开| 亚洲福利在线视频| A在线观看免费网站大全| 亚洲第一综合天堂另类专| 亚洲精品偷拍视频免费观看| 久久er国产精品免费观看2| 亚洲三级视频在线观看| 国产一级高清视频免费看| 中文字幕高清免费不卡视频| 亚洲免费黄色网址| 亚洲另类少妇17p| 69xx免费观看视频| 一道本在线免费视频| 亚洲精品日韩专区silk|