參考
Java日期時間使用總結(jié)
Java Calendar,Date,DateFormat,TimeZone,Locale(1) Calendar
Java Calendar,Date,DateFormat,TimeZone,Locale(2) 自己封裝的Calendar接口
Java Calendar,Date,DateFormat,TimeZone,Locale(3) Date
Java Calendar,Date,DateFormat,TimeZone,Locale(4) DateFormat
Java Calendar,Date,DateFormat,TimeZone,Locale(5) SimpleDateFormat
Java Calendar,Date,DateFormat,TimeZone,Locale(6) Locale
Java Calendar,Date,DateFormat,TimeZone,Locale(7) TimeZone
一、概念
參考時間標(biāo)準(zhǔn)總結(jié) IAT、UT、UTC、GMT、夏令時
1.格林尼治標(biāo)準(zhǔn)時間:Greenwich Mean Time(簡稱 GMT)
GMT 以格林尼治天文臺經(jīng)線為 0 度經(jīng)線,將世界分為 24 個時區(qū),向東時間快,向西時間慢。
UTC是基于標(biāo)準(zhǔn)的GMT提供的準(zhǔn)確時間。(在計算機中 GMT 時間和 UTC 時間是一樣的)
2.夏令時與冬令時 Daylight Saving Time(簡稱 DST)
又稱“日光節(jié)約時制”和“夏令時間”,是一種為節(jié)約能源而人為規(guī)定地方時間的制度,在這一制度實行期間所采用的統(tǒng)一時間稱為“夏令時間”。
一般在天亮早的夏季人為將時間提前一小時,可以使人早起早睡,減少照明量,以充分利用光照資源,從而節(jié)約照明用電。各個采納夏時制的國家具體規(guī)定不同。目前全世界有近110個國家每年要實行夏令時。
自2011年3月27日開始俄羅斯永久使用夏令時,把時間撥快一小時,不再調(diào)回。
簡單來說,使用夏令時和冬令時即在夏季將時間撥快一個小時,等到冬季再將時間撥慢一個小時。
舉個例子總結(jié)一下:
假設(shè)當(dāng)前 GMT 時間為 13:00,已知北京時間為 GMT+8(北京位于東 8 區(qū)),所以北京時間為 13:00 + 8 = 21:00。
但當(dāng)存在夏令時時,會出現(xiàn)不同。比如已知莫斯科時間為 GMT+3,理論上莫斯科時間為 16:00,但是由于俄羅斯永久使用夏令時,所以實際上莫斯科時間為 17:00。
3.開發(fā)規(guī)范
在實際開發(fā)中,當(dāng)時間用于顯示時,非特殊要求下一般使用系統(tǒng)默認的時區(qū)時間作為顯示時間。將時間做為數(shù)據(jù)存儲或傳遞給其他系統(tǒng)時(特別是跨平臺調(diào)用),則最好使用標(biāo)準(zhǔn)的UTC/GMT時間(后面統(tǒng)稱GMT),除非事先約定或標(biāo)識了時間的類型。
因為用戶很有可能會有更改時區(qū)的操作出現(xiàn),如果使用對應(yīng)時區(qū)的時間戳,并且時間戳作為某種標(biāo)記量存入了數(shù)據(jù)庫,那么一旦時區(qū)發(fā)生改變,已存數(shù)據(jù)將會與當(dāng)前時區(qū)設(shè)置產(chǎn)生問題;而使用標(biāo)準(zhǔn)時間戳則可以避免這一問題,因為通過程序可以很容易地將時間戳轉(zhuǎn)化為標(biāo)準(zhǔn)時間戳,并且標(biāo)準(zhǔn)時間戳是固定的,這樣就能保證即使在修改了時區(qū)的情況下,也能正確處理日期時間。
二、Calendar日歷 與 Gregorian Calendar公歷
參考Java Calendar類詳解
在歷史上有著許多種紀(jì)元的方法。它們的差異實在太大了,比如說一個人的生日是"八月八日" 那么一種可能是陽(公)歷的八月八日,但也可以是陰(農(nóng))歷的日期。所以為了計時的統(tǒng)一,必需指定一個日歷的選擇。那現(xiàn)在最為普及和通用的日歷就是 "Gregorian Calendar"。也就是我們在講述年份時常用 "公元幾幾年"。Calendar 抽象類定義了足夠的方法,讓我們能夠表述日歷的規(guī)則。Java 本身提供了對 "Gregorian Calendar" 規(guī)則的實現(xiàn)。我們從 Calendar.getInstance() 中所獲得的實例就是一個 "GreogrianCalendar" 對象(與您通過 new GregorianCalendar() 獲得的結(jié)果一致)。
Calendar 在 Java 中是一個抽象類(Abstract Class),GregorianCalendar 是它的一個具體實現(xiàn)。
我們也可以自己的 Calendar 實現(xiàn)類,然后將它作為 Calendar 對象返回(面向?qū)ο蟮奶匦?。在 IBM alphaWorks 上,IBM 的開發(fā)人員實現(xiàn)了多種日歷。同樣在 Internet 上,也有對中國農(nóng)歷的實現(xiàn)。本文對如何擴展 Calendar 不作討論,大家可以通過察看上述 Calendar 的源碼來學(xué)習(xí)。
三、Date DateFormat SimpleDateFormat
java.util.Date
類 Date 表示特定的瞬間,精確到毫秒。從 JDK 1.1 開始,應(yīng)該使用 Calendar 類實現(xiàn)日期和時間字段之間轉(zhuǎn)換,使用 DateFormat 類來格式化和分析日期字符串。Date 中的把日期解釋為年、月、日、小時、分鐘和秒值的方法已廢棄。
java.text.DateFormat(抽象類)
DateFormat 是日期/時間格式化子類的抽象類,它以與語言無關(guān)的方式格式化并分析日期或時間。日期/時間格式化子類(如 SimpleDateFormat)允許進行格式化(也就是日期 -> 文本)、分析(文本-> 日期)和標(biāo)準(zhǔn)化。將日期表示為 Date 對象,或者表示為從 GMT(格林尼治標(biāo)準(zhǔn)時間)1970 年,1 月 1 日 00:00:00 這一刻開始的毫秒數(shù)。
java.text.SimpleDateFormat(DateFormat的直接子類)
參考深入理解Java:SimpleDateFormat安全的時間格式化
SimpleDateFormat 是一個以與語言環(huán)境相關(guān)的方式來格式化和分析日期的具體類。它允許進行格式化(日期 -> 文本)、分析(文本 -> 日期)和規(guī)范化。
SimpleDateFormat 使得可以選擇任何用戶定義的日期-時間格式的模式。但是,仍然建議通過 DateFormat 中的 getTimeInstance、getDateInstance 或 getDateTimeInstance 來新的創(chuàng)建日期-時間格式化程序。
import java.text.SimpleDateFormat;
import java.util.Date;
public class Data {
public static void main(String[] args) {
SimpleDateFormat dateFormat =
new SimpleDateFormat("yyyy-MM-dd E");//可以查API,根據(jù)自己的需要顯示格式
Date date = new Date();
System.out.println("今天的日期是: "+dateFormat.format(date));
}
}
DateFormat 和SimpleDateFormat 的區(qū)別
參考日期操作類(DateFormat與SimpleDateFormat)的區(qū)別和實例
1.DateFormat 可以直接使用,但其本身是一個抽象類,可以根據(jù)Locate指定的區(qū)域得到對應(yīng)的日期時間格式
2.SimpleDateFormat 類是DateFormat 類的子類,一般情況下來講 DateFormat 類很少會直接使用。而都使用SimpleDateFormat 類完成。
Locale
參考Locale簡介
import java.util.Locale;
public class LocaleOne {
public static void main(String[] args) {
Locale myLocale = Locale.getDefault();
System.out.println(myLocale.getCountry());//CN
System.out.println(myLocale.getLanguage());//zh
System.out.println(myLocale.getDisplayCountry());//中國
System.out.println(myLocale.getDisplayLanguage());//中文
}
}
與SimpleDateFormat一起使用:
public static final SimpleDateFormat sdfMd = new
SimpleDateFormat("M/d", Locale.getDefault());
四、在Android中需要特別注意的事項
參考Android中關(guān)于日期時間與時區(qū)的使用總結(jié)
Android中表示日期時間的類型,有Date、Calendar,他們在沒有顯示設(shè)置其時區(qū)時,取到的當(dāng)前時間均為系統(tǒng)默認時區(qū)的時間,即使給定一個時間,同樣是按系統(tǒng)默認時區(qū)來換算時間,所以說他們都是與時區(qū)相關(guān)的。SimpleDateFormat對象本身也是跟時區(qū)相關(guān)。當(dāng)使用parse將一個字符串格式的日期轉(zhuǎn)換為Date對象,或者將一個Date對象轉(zhuǎn)換為字符串日期時,這個字符串日期的時區(qū)以SimpleDateFormat關(guān)聯(lián)的時區(qū)為準(zhǔn),如果通過setTimeZone修改了時區(qū),則這個字符串日期以修改后的時區(qū)為準(zhǔn)。
// 2013-1-31 22:17:14
Date date = new Date(1359641834000L);
System.out.println(date);
String dateStr = "2013-1-31 22:17:14";
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
try
{
//對于已經(jīng)設(shè)定為GMT時間標(biāo)準(zhǔn)的dateFormat來說,
//一切需要他轉(zhuǎn)換的字符串日期都是GMT標(biāo)準(zhǔn)時間,
//轉(zhuǎn)換后返回的Date由于默認遵守系統(tǒng)默認時區(qū),
//所以轉(zhuǎn)換給Date的日期需要+8(例如北京標(biāo)準(zhǔn)時區(qū)),
//也就是時區(qū)與標(biāo)準(zhǔn)不同導(dǎo)致的時差。
Date dateTmp = dateFormat.parse(dateStr);
System.out.println(dateTmp);
}
catch (ParseException e)
{
e.printStackTrace();
}
// Date還是按系統(tǒng)默認時區(qū),而format格式化處來的字符串是GMT,所以要-8。
String dateStrTmp = dateFormat.format(date);
System.out.println(dateStrTmp);

Calendar在不手動設(shè)置時區(qū)時,是與系統(tǒng)默認時區(qū)相關(guān)的。在手動修改時區(qū)后,不能使用calendar.getTime方法來直接獲取Date日期,因為此時的日期與setTime時的值相同,想要正確獲取修改時區(qū)后的時間,應(yīng)該通過calendar的get方法。
Date date = new Date(1359641834000L);
System.out.println(date);
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
//或者可以 Calendar calendar =
//Calendar.getInstance(TimeZone.getTimeZone("GMT"));
calendar.setTime(date);
System.out.println(calendar.get(Calendar.HOUR_OF_DAY) + ":"
+ calendar.get(Calendar.MINUTE));
Calendar calendar2 = Calendar.getInstance();
calendar2.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
System.out.println(calendar.getTime());
System.out.println(calendar2.getTime());

五、DatePickerDialog TimePickerDialog
參考Android中DatePickerDialog對話框和TimePickerDialog對話框的使用



package com.lovo;
import java.util.Calendar;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 獲得設(shè)置日期按鈕
Button dateBtn = (Button) findViewById(R.id.btn1);
// 獲得設(shè)置時間按鈕
Button timeBtn = (Button) findViewById(R.id.btn2);
// 為設(shè)置日期按鈕綁定監(jiān)聽器
dateBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Calendar c = Calendar.getInstance();
// 直接創(chuàng)建一個DatePickerDialog對話框?qū)嵗⑺@示出來
new DatePickerDialog(MainActivity.this,
// 綁定監(jiān)聽器
new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
TextView show = (TextView) findViewById(R.id.txt1);
show.setText("您選擇了:" + year + "年" + monthOfYear
+ "月" + dayOfMonth + "日");
}
}
// 設(shè)置初始日期
, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c
.get(Calendar.DAY_OF_MONTH)).show();
}
});
// 為設(shè)置時間按鈕綁定監(jiān)聽器
timeBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Calendar c = Calendar.getInstance();
// 創(chuàng)建一個TimePickerDialog實例,并把它顯示出來
new TimePickerDialog(MainActivity.this,
// 綁定監(jiān)聽器
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view,
int hourOfDay, int minute) {
TextView show = (TextView) findViewById(R.id.txt2);
show.setText("您選擇了:" + hourOfDay + "時" + minute
+ "分");
}
}
// 設(shè)置初始時間
, c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE),
// true表示采用24小時制
true).show();
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical" >
<Button
android:id="@+id/btn1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="設(shè)置日期" />
<Button
android:id="@+id/btn2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="設(shè)置時間" />
<TextView
android:id="@+id/txt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/txt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>