這個問題出自我寫的代碼需要運行在服務器上。本來的代碼是這樣寫的:
import java.text.*;
import java.util.*;
public final class NowDateTime
{
public static final String get()
{
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String cdate = df.format(cal.getTime());
return cdate;
}
public static void main(String[] args)
{
System.out.println(get());
}
}
乍看之下沒有問題,確實,在我自己的電腦上獲取的確實是當前的時間,本人在中國,要的也是中國時間,這一點在這篇文章中很重要。
但是奇怪的,明明格式中寫了“HH”,也就是要求24小時制的時間,可是每一次把程序上傳到服務器之後,運行的到的程序都是12小時制的,奇了怪了。由於服務器是ubuntu的,開始的時候,我以爲是ubuntu的jvm和windows的jvm對相同的代碼有不同的行爲,雖然java本身以跨平臺爲特色,但是有那麼一兩個bug也是可以接受的嘛~~
結果有一天……我仔細看了一下java的文檔,雖然文檔沒有直接說明我的困惑,但是一個方法卻讓我發現了端倪,那是DateFormat.setTimeZone方法。是的!是時區,服務器再美國,所以在服務器上獲取的時間,是美國時間相差12個小時。雖然以前就知道,但是沒想到真的如此接近,只相差幾分鐘,這幾分鐘被習以爲常地用誤差解釋了。實際上,陰差陽錯的是,我次測試都是在下午,中國時間>12,美國時間<12,就造成了一個24小時制,一個是12小時制的假象,所以根本沒有注意到時區的問題。知道什麼問題之後我改寫了代碼,明確說明要中國的時區——"Asia/Chongqing"(即“亞洲/重慶”)或"Asia/shanghai"。
所以更改之後的代碼如下:
import java.text.*;
import java.util.*;
// 獲取當前日期時間的靜態方法
public final class NowDateTime
{
public static final String get()
{
Calendar cal = Calendar.getInstance();
// 設置格式化的SimpleDateFormat對象,指定中國語言環境
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
// 創建時區(TimeZone)對象,設置時區爲“亞洲/重慶"
TimeZone TZ = TimeZone.getTimeZone("Asia/Chongqing");
// 將SimpleDateFormat強制轉換爲DateFormat
DateFormat df = null;
try
{
df = (DateFormat)sdf;
}
catch(Exception E)
{
E.printStackTrace();
}
// 爲DateFormat對象設置時區
df.setTimeZone(TZ);
// 獲取時間表達式
String cdate = df.format(cal.getTime());
return cdate;
}
public static void main(String[] args)
{
System.out.println(get());
}
}
這樣在任何國家和地區,任何支持java SE的機器上,都能直接拿到中國時間了(如果java跨平臺特性真的是完善的話)。