Java進階日期概念

來源:互聯網
上載者:User
如果你的Java 程式向處在不同時區或者不同國家的使用者顯示時間和日期,那麼你需要瞭解Java日期類的一些更加進階的方面。在“使用Java Date和Calendar類計算,定製和解析日期”的這篇文章裡我們提供了對日期,日期資料的格式化,日期資料的解析和日期計算的一個概覽。對於這些概念的深入的理解對於討論更進階的諸如時區,國際化標準格式和SQL日期資料等這些有關日期的問題是關鍵的。

我們在本文中討論的類將包含java.text.DateFormat,以及java.util.TimeZone和java.util.Locate。我們還將討論如何使用一個java.util.Date的子類java.sql.Date來從Oracle資料庫裡提取和儲存Java日期資料。

地區的問題
在我們國際化我們的日期資料以前,我們需要進一步的學習Locale類,也就是java.util.Locale。Locale類的一個執行個體通常包含國家和語言資訊。其中的每一個部分都是由基於國際標準組織(ISO)制定的國家代碼ISO-3166和語言代碼ISO-639的兩字元的字串構成的。

讓我們來建立兩個Locale執行個體,其中一個對應的是美國英語而另一個對應的是法國法語。見表A。

表A 

import java.util.Locale;

public class DateExample6 {

public static void main(String[] args) {
// Create a locale for the English language in the US.
Locale localeEN = new Locale("en", "US");

System.out.println("Display Name: " +
localeEN.getDisplayName());
System.out.println("Country: " + localeEN.getCountry());
System.out.println("Language: " + localeEN.getLanguage());

// Create a locale for the French language in France.
Locale localeFR = new Locale("fr", "FR");
System.out.println("/nDisplay Name: " +
localeFR.getDisplayName());
System.out.println("Country: " + localeFR.getCountry());
System.out.println("Language: " + localeFR.getLanguage());

// Display the English-US locale in French
System.out.println("/nen Display Name in French: " +
localeEN.getDisplayName(localeFR));
}
}

在這個例子中,我們用getDisplayName方法來顯示Locale的一個更易讀的文本。你還應該注意到我們在最後一次調用getDisplayName的時候,我們在對English Locale對象調用getDisplayName的時候同時傳遞了French Locale對象。這允許我們選擇顯示Locale對象所用的語言,讓我們用英語顯示法語Locale對象的內容。下面是這個例子的輸出:

Display Name: English (United States)
Country: US
Language: en
Display Name: French (France)
Country: FR
Language: fr
en Display Name in French: anglais (états-Unis)

多個地區的日期格式化
使用java.util.Locale和java.text.DateFormat類我們就能夠格式化日期資料把它顯示給在另一個地區的使用者,比方法國。表B中的例子為英語和法語各建立了一個完整的日期格式化器。

表 B 

import java.util.Locale;
import java.util.Date;
import java.text.DateFormat;

public class DateExample7 {

public static void main(String[] args) {
// Get the current system date and time.
Date date = new Date();

// Get a France locale using a Locale constant.
Locale localeFR = Locale.FRANCE;

// Create an English/US locale using the constructor.
Locale localeEN = new Locale("en", "US" );

// Get a date time formatter for display in France.
DateFormat fullDateFormatFR =
DateFormat.getDateTimeInstance(
DateFormat.FULL,
DateFormat.FULL,
localeFR);

// Get a date time formatter for display in the U.S.
DateFormat fullDateFormatEN =
DateFormat.getDateTimeInstance(
DateFormat.FULL,
DateFormat.FULL,
localeEN);

System.out.println("Locale: " + localeFR.getDisplayName());
System.out.println(fullDateFormatFR.format(date));
System.out.println("Locale: " + localeEN.getDisplayName());
System.out.println(fullDateFormatEN.format(date));
}
}

這個例子的輸出是:

Locale: French (France)
vendredi 5 octobre 2001 21 h 05 GMT-04:00
Locale: English (United States)
Friday, October 5, 2001 9:05:54 PM EDT

注意這個輸出包括了時區資訊:GMT-04:00 和 PM EDT。這個時區是人系統的時區設定裡捕獲的。你可以看見,日期是以那個地區的使用者期望的格式顯示的。讓我們等一下來看看時區的概念 

時區
TimeZone類,即java.util.TimeZone類的執行個體包含了一個與格林威治標準時間(GMT)相比較得出的以微秒為單位的時區位移量,而且它還處理夏令時
。要獲得一個所有支援的進區的列表,你可以使用方法TimeZone.getAvailableIDs,它將返回一個包含了所有進區ID的字串數組。要知道關於TimeZone類的更多細節,可以參看Sun公司的Web網站。

為了示範這個概念,我們將建立三個時區對象。第一個對象將使用getDefault從系統時鐘返回時區資料;第二個和第三個對象將傳入一個時區字串ID。見表C中的代碼。

表 C 

import java.util.TimeZone;
import java.util.Date;
import java.text.DateFormat;
import java.util.Locale;

public class DateExample8 {

public static void main(String[] args) {
// Get the system time zone.
TimeZone timeZoneFL = TimeZone.getDefault();
System.out.println("/n" + timeZoneFL.getDisplayName());
System.out.println("RawOffset: " + timeZoneFL.getRawOffset());
System.out.println("Uses daylight saving: " + timeZoneFL.useDaylightTime());

TimeZone timeZoneLondon = TimeZone.getTimeZone("Europe/London");
System.out.println("/n" + timeZoneLondon.getDisplayName());
System.out.println("RawOffset: " + timeZoneLondon.getRawOffset());
System.out.println("Uses daylight saving: " + timeZoneLondon.useDaylightTime());

燭imeZone timeZoneParis = TimeZone.getTimeZone("Europe/Paris");
System.out.println("/n" + timeZoneParis.getDisplayName());
System.out.println("RawOffset: " + timeZoneParis.getRawOffset());
System.out.println("Uses daylight saving: " + timeZoneParis.useDaylightTime());
}
}

其輸出如下:

Eastern Standard Time
RawOffset: -18000000
Uses daylight saving: true
GMT+00:00
RawOffset: 0
Uses daylight saving: true

Central European Standard Time
RawOffset: 3600000
Uses daylight saving: true

正如你所看見的,TimeZone對象給我們的是原始的位移量,也就是與GMT相差的微秒數,而且還會告訴我們這個時區是否使用夏令時。有個這個資訊,我們就能夠繼續將時區對象和日期格式化器結合在一起在其它的時區和其它的語言顯示時間了。

國際化的時期顯示了時區轉換
讓我們來看一個結合了國際化顯示,時區和日期格式化的例子。表D為一個在邁阿密和巴黎擁有辦公室的公司顯示了當前的完整日期和時間。對於邁阿密的辦公室,我們將在每個辦公室裡用英語顯示完整的日期和時間。對於巴黎的辦公室,我們將用法語顯示完整的當前日期和時間。

表 D 

import java.util.TimeZone;
import java.util.Date;
import java.util.Locale;
import java.text.DateFormat;

public class DateExample9 {

public static void main(String[] args) {
Locale localeEN = Locale.US;
Locale localeFrance = Locale.FRANCE;

TimeZone timeZoneMiami = TimeZone.getDefault();
TimeZone timeZoneParis = TimeZone.getTimeZone("Europe/Paris");

DateFormat dateFormatter = DateFormat.getDateTimeInstance(
DateFormat.FULL,
DateFormat.FULL,
localeEN);
DateFormat dateFormatterParis = DateFormat.getDateTimeInstance(
DateFormat.FULL,
DateFormat.FULL,
localeFrance);

Date curDate = new Date();

System.out.println("Display for Miami office.");
// Print the Miami time zone display name in English
System.out.println(timeZoneMiami.getDisplayName(localeEN));
// Set the time zone of the dateFormatter to Miami time zone.
dateFormatter.setTimeZone(timeZoneMiami);
// Print the formatted date.
System.out.println(dateFormatter.format(curDate));

// Set the time zone of the date formatter to Paris time zone.
dateFormatter.setTimeZone(timeZoneParis);
// Print the Paris time zone display name in English.
System.out.println(timeZoneParis.getDisplayName(localeEN));
// Print the Paris time in english.
System.out.println(dateFormatter.format(curDate));

System.out.println("/nDisplay for Paris office.");
// Print the Miami time zone display name in French
System.out.println(timeZoneMiami.getDisplayName(localeFrance));
// Set the timezone of the
// dateFormatterParis to Miami time zone.
dateFormatterParis.setTimeZone(timeZoneMiami);
// Print the formatted date in French.
燬ystem.out.println(dateFormatterParis.format(curDate));

// Set the timezone of the date formatter to Paris time zone.
dateFormatterParis.setTimeZone(timeZoneParis);
// Print the Paris time zone display name in French.
System.out.println(timeZoneParis.getDisplayName(localeFrance));
// Print the Paris time in French.
System.out.println(dateFormatterParis.format(curDate));
}
}

這個例子的輸出是:

Display for Miami office. 
Eastern Standard Time
Friday, October 5, 2001 10:28:02 PM EDT
Central European Standard Time
Saturday, October 6, 2001 4:28:02 AM CEST
Display for Paris office. 
GMT-05:00
vendredi 5 octobre 2001 22 h 28 GMT-04:00
GMT+01:00
samedi 6 octobre 2001 04 h 28 GMT+02:00 
在一個SQL資料庫中儲存和提取日期資料我們將要使用的下一個類是java.sql.Date,它是java.util.Date的子類但它使用了Java資料庫連接(JDBC)方法 
。讓我們來看一個簡單的只有一個表單--LAST_ACCESS的ORACLE資料庫,它是用下面的SQL建立的:
create table LAST_ACCESS (
LAST_HIT date
);

這個表單只有一個記錄,用下面的插入語句建立:
insert into LAST_ACCESS values (Sysdate);

表E示範了如何修改和提取LAST_HIT資料庫域。

表 E 

import java.sql.*;
import java.text.DateFormat;
import java.util.Date;

public class DateExample10 {

public static void main(String[] args) {
// Get a full date formatter.
DateFormat dateFormatter = DateFormat.getDateTimeInstance(
DateFormat.FULL,
DateFormat.FULL);
// Get the system date and time.
java.util.Date utilDate = new Date();
// Convert it to java.sql.Date
java.sql.Date date = new java.sql.Date(utilDate.getTime());
// Display the date before storing.
System.out.println(dateFormatter.format(date));
// Save the date to the database.
setLastHit(date);
// Get the date from the database.
Date dateFromDB = getLastHit();
// Display the date from the database.
System.out.println(dateFormatter.format(dateFromDB));
}

public static void setLastHit(java.sql.Date date) {

try {
// Load the class.
Class.forName("oracle.jdbc.driver.OracleDriver");
// Get a connection.
燙onnection connection = DriverManager.getConnection(
// Database URL
"jdbc:oracle:thin:@localhost:1521:buzz2",
"web_site", // Username
"web_site"); // Password
try {
/ Get a prepared statement fromthe connection
// specifying the update SQL.
PreparedStatement ps = connection.prepareStatement(
"update LAST_ACCESS set LAST_HIT=");
try {
/ set the date letting JDBC to the work of
// formatting the SQL appropriately.
ps.setDate(1, date);
// Execute the update statement.
int iRowsUpdated = ps.executeUpdate();
System.out.println("Rows updated: " + iRowsUpdated);
} finally {
ps.close();
}
} finally {
connection.close();
}
} catch (Exception ex) {
System.out.println("Error: " + ex.getMessage());
}
}

public static java.sql.Date getLastHit() {
java.sql.Date returnDate = null;

try {
// Load the driver class.
Class.forName("oracle.jdbc.driver.OracleDriver");
// Get the connection.
Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:buzz2",
"web_site", "web_site");
try {
/ Get the prepared statement specifying the
// select SQL.
PreparedStatement ps = connection.prepareStatement(
"select LAST_HIT from LAST_ACCESS");
try {
// Execute the SQL and get the ResultSet object.
ResultSet rs = ps.executeQuery();
try {
// Retreive the record.
if (rs else {
燬ystem.out.println("Did not get last hit.");
}
}
finally {
rs.close();
}

} finally {
ps.close();

} finally {
connection.close();
}
} catch (Exception ex) {
System.out.println("Error: " + ex.getMessage());
}
return returnDate;
}

}

這個例子的輸出如下:

Friday, October 5, 2001 10:42:34 PM EDT
Rows updated: 1
Successfully retrieved last hit.
Friday, October 5, 2001 12:00:00 AM EDT

雖然這個例子沒有為儲存和提取日期資料提供效能上優良的方法,但它確實示範了如何為一條更新和刪除語句將Java日期資料轉換成SQL日期資料。從一個java.util.Date對象設定Oracle date資料域的過程是由以下的語句處理的:
ps.setDate(1, date);

它是我們預定義語句介面java.sql.PreparedStatement.setDate 的一個方法。

這行代碼出現在我們的setLastHit方法裡。它將Java以微秒為單位的長整型日期值轉換成ORACLE的SQL日期格式。當我們能夠在getLastHit方法裡用java.sql.PreparedStatement.getDate從資料庫取得日期資料的時候這種轉換就能夠完成。

你還應該注意到只有日期被設定了。小時,分鐘,秒,和微秒都沒有包括在從Java日期資料到SQL日期資料的轉換過程中。

結論
一旦你掌握了這些概念,你就應該能夠基於系統時間或者一個輸入的時間建立日期對象了。另外,你還應該能夠使用標準和定製的格式化過程格式化日期資料,將文本的日期資料解析成日期對象,並以多種語言和多種時區顯示一個日期資料。最後,你將能夠在一個SQL資料庫裡儲存和提取日期值

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.