1. 程式人生 > >計算兩個時間戳之間的天數的一種比較高效的演算法

計算兩個時間戳之間的天數的一種比較高效的演算法

因為在做hadoop計算的時候需要按照時間來分片,所以需要對long型的時間戳進行Partition,本來想了一下兩個時間先歸零到當天的0點,然後想減除以24小時就是中間的天數,這個演算法沒錯,但是我沒有考慮到時區的問題,歸零的演算法是(t1-t1%h24)t是時間戳,h表示一小時的毫秒數,這樣歸零其實是格林威治時間的歸零,在我們這邊正好的8點鐘,這樣就會把兩天的資料併到一個分割槽裡面,網上也有做法是

new Long((dateformat.parse(dateformat.format(new Date(curDay))).getTime()-dateformat.parse(dateformat.format(new Date(t1))).getTime())/(1000 * 60 * 60 * 24)).intValue();

但是這種做法肯定很慢而卻佔用記憶體,對於每天原始資料有100多個G的檔案進行分割槽這個肯定不行,於是繼續改我的歸零演算法,最後就改成下面的鳥樣

private static void test8() throws Exception{
final DateFormat dateformat = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss",Locale.CHINA);


long h8 = 1000 * 60 * 60 *8;
long h16 = h8*2;
long curDay = System.currentTimeMillis();//此處+ut8是因為可以減少在分割槽的時候做一次減法
long h24 = h8*3;
curDay = curDay - curDay % h24 + (curDay % h24>=h16?h24:0);
System.out.println(dateformat.format(new Date(curDay)));

long t1 = 1368892799999L;
long m = t1%h24;
long i = (curDay-(t1-m+(m>=h16?h24:0)))/h24;

System.out.println(i);
t1 = 1368892799999L-h24+1;
i = (curDay-(t1-m+(m>=h16?h24:0)))/h24;
System.out.println(i);
t1 = 1368892800000L;
i = (curDay-(t1-m+(m>=h16?h24:0)))/h24;
System.out.println(i);
long d1 = System.currentTimeMillis();
for(int a=0;a<1000;a++){
i=new Long((dateformat.parse(dateformat.format(new Date(curDay))).getTime()-dateformat.parse(dateformat.format(new Date(t1))).getTime())/(1000 * 60 * 60 * 24)).intValue();

System.out.println(i);
}
long d2 = System.currentTimeMillis();
for(int a=0;a<1000;a++){
m = t1%h24;
i = (curDay-(t1-m+(m>=h16?h24:0)))/h24;
System.out.println(i);
}
long d3 = System.currentTimeMillis();
System.out.println(d2-d1);
System.out.println(d3-d2);
}


上面是我的測試程式碼,懶得解釋,也很簡單,但確效率至少在100倍以上,拿出來唄大家copy用,呵呵