国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

「轉載」JAVA Calendar詳解

microelec / 1052人閱讀

摘要:對象由兩部分構成字段和相對于的微秒時間差。經過后,直接操作會產生不穩定的情況。如,對嗎結果是另一個規則是,如果比它小的字段是不可變的由的實現類決定,那么該小字段會修正到變化最小的值。

(在文章的最后,將會介紹Date類,如果有興趣,可以直接翻到最后去閱讀)

究竟什么是一個 Calendar 呢?中文的翻譯就是日歷,那我們立刻可以想到我們生活中有陽(公)歷、陰(農)歷之分。它們的區別在哪呢?

比如有:
月份的定義 - 陽`(公)歷 一年12 個月,每個月的天數各不同;陰(農)歷,每個月固定28天
每周的第一天 - 陽(公)歷星期日是第一天;陰(農)歷,星期一是第一天

實際上,在歷史上有著許多種紀元的方法。它們的差異實在太大了,比如說一個人的生日是"八月八日" 那么一種可能是陽(公)歷的八月八日,但也可以是陰(農)歷的日期。所以為了計時的統一,必需指定一個日歷的選擇。那現在最為普及和通用的日歷就是 "Gregorian Calendar"。也就是我們在講述年份時常用 "公元幾幾年"。Calendar 抽象類定義了足夠的方法,讓我們能夠表述日歷的規則。Java 本身提供了對 "Gregorian Calendar" 規則的實現。我們從 Calendar.getInstance() 中所獲得的實例就是一個 "GreogrianCalendar" 對象(與您通過 new GregorianCalendar() 獲得的結果一致)。

下面的代碼可以證明這一點:

import java.io.*;
import java.util.*;

public class WhatIsCalendar
{
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
if (calendar instanceof GregorianCalendar)
System.out.println("It is an instance of GregorianCalendar"t;
}
}

Calendar 在 Java 中是一個抽象類(Abstract Class),GregorianCalendar 是它的一個具體實現。

我們也可以自己的 Calendar 實現類,然后將它作為 Calendar 對象返回(面向對象的特性)。在 IBM alphaWorks 上,IBM 的開發人員實現了多種日歷(http://www.alphaworks.ibm.com/tech/calendars)。同樣在 Internet 上,也有對中國農歷的實現。本文對如何擴展 Calendar 不作討論,大家可以通過察看上述 Calendar 的源碼來學習。

Calendar 與 Date 的轉換非常簡單:

Calendar calendar = Calendar.getInstance();
// 從一個 Calendar 對象中獲取 Date 對象
Date date = calendar.getTime();
// 將 Date 對象反應到一個 Calendar 對象中,
// Calendar/GregorianCalendar 沒有構造函數可以接受 Date 對象
// 所以我們必需先獲得一個實例,然后設置 Date 對象
calendar.setTime(date);

Calendar 對象在使用時,有一些值得注意的事項:

Calendar 的 set() 方法

set(int field, int value) - 是用來設置"年/月/日/小時/分鐘/秒/微秒"等值

field 的定義在 Calendar 中

set(int year, int month, int day, int hour, int minute, int second) 但沒有

set(int year, int month, int day, int hour, int minute, int second, int millisecond) 前面 set(int,int,int,int,int,int) 方法不會自動將 MilliSecond 清為 0。

另外,月份的起始值為0而不是1,所以要設置八月時,我們用7而不是8。

calendar.set(Calendar.MONTH, 7);

我們通常需要在程序邏輯中將它清為 0,否則可能會出現下面的情況:

import java.io.*;
import java.util.*;

public class WhatIsCalendarWrite
{
public static void main(String[] args) throws Exception{
ObjectOutputStream out =
new ObjectOutputStream(
new FileOutputStream("calendar.out"t);
Calendar cal1 = Calendar.getInstance();
cal1.set(2000, 7, 1, 0, 0, 0);
out.writeObject(cal1);
Calendar cal2 = Calendar.getInstance();
cal2.set(2000, 7, 1, 0, 0, 0);
cal2.set(Calendar.MILLISECOND, 0);
out.writeObject(cal2);
out.close();
}
}

我們將 Calendar 保存到文件中

import java.io.*;
import java.util.*;

public class WhatIsCalendarRead
{
public static void main(String[] args) throws Exception{
ObjectInputStream in =
new ObjectInputStream(
new FileInputStream("calendar.out"t);
Calendar cal2 = (Calendar)in.readObject();
Calendar cal1 = Calendar.getInstance();
cal1.set(2000, 7, 1, 0, 0, 0);
if (cal1.equals(cal2))
System.out.println("Equals"t;
else
System.out.println("NotEqual"t;
System.out.println("Old calendar "+cal2.getTime().getTime());
System.out.println("New calendar "+cal1.getTime().getTime());
cal1.set(Calendar.MILLISECOND, 0);
cal2 = (Calendar)in.readObject();
if (cal1.equals(cal2))
System.out.println("Equals"t;
else
System.out.println("NotEqual"t;
System.out.println("Processed Old calendar "+cal2.getTime().getTime());
System.out.println("Processed New calendar "+cal1.getTime().getTime());
}
}

然后再另外一個程序中取回來(模擬對數據庫的存儲),但是執行的結果是:

NotEqual
Old calendar 965113200422 <------------ 最后三位的MilliSecond與當前時間有關
New calendar 965113200059 <-----------/
Equals
Processed Old calendar 965113200000
Processed New calendar 965113200000

另外我們要注意的一點是,Calendar 為了性能原因對 set() 方法采取延緩計算的方法。在 JavaDoc 中有下面的例子來說明這個問題:

Calendar cal1 = Calendar.getInstance();
cal1.set(2000, 7, 31, 0, 0 , 0); //2000-8-31
cal1.set(Calendar.MONTH, Calendar.SEPTEMBER); //應該是 2000-9-31,也就是 2000-10-1
cal1.set(Calendar.DAY_OF_MONTH, 30); //如果 Calendar 轉化到 2000-10-1,那么現在的結果就該是 2000-10-30
System.out.println(cal1.getTime()); //輸出的是2000-9-30,說明 Calendar 不是馬上就刷新其內部的記錄

在 Calendar 的方法中,get() 和 add() 會讓 Calendar 立刻刷新。Set() 的這個特性會給我們的開發帶來一些意想不到的結果。我們后面會看到這個問題。

Calendar 對象的容錯性,Lenient 設置
我們知道特定的月份有不同的日期,當一個用戶給出錯誤的日期時,Calendar 如何處理的呢?

import java.io.*;
import java.util.*;

public class WhatIsCalendar
{
public static void main(String[] args) throws Exception{
Calendar cal1 = Calendar.getInstance();
cal1.set(2000, 1, 32, 0, 0, 0);
System.out.println(cal1.getTime());
cal1.setLenient(false);
cal1.set(2000, 1, 32, 0, 0, 0);
System.out.println(cal1.getTime());
}
}

它的執行結果是:

Tue Feb 01 00:00:00 PST 2000
Exception in thread "main" java.lang.IllegalArgumentException
at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:1368)
at java.util.Calendar.updateTime(Calendar.java:1508)
at java.util.Calendar.getTimeInMillis(Calendar.java:890)
at java.util.Calendar.getTime(Calendar.java:871)
at WhatIsCalendar.main(WhatIsCalendar.java:12)
當我們設置該 Calendar 為 Lenient false 時,它會依據特定的月份檢查出錯誤的賦值。

不穩定的 Calendar

我們知道 Calendar 是可以被 serialize 的,但是我們要注意下面的問題

import java.io.*;
import java.util.*;

public class UnstableCalendar implements Serializable
{

public static void main(String[] args) throws Exception{
Calendar cal1 = Calendar.getInstance();
cal1.set(2000, 7, 1, 0, 0 , 0);
cal1.set(Calendar.MILLISECOND, 0);
ObjectOutputStream out =
new ObjectOutputStream(
new FileOutputStream("newCalendar.out"t);
out.writeObject(cal1);
out.close();
ObjectInputStream in =
new ObjectInputStream(
new FileInputStream("newCalendar.out"t);
Calendar cal2 = (Calendar)in.readObject();
cal2.set(Calendar.MILLISECOND, 0);
System.out.println(cal2.getTime());
}
}

運行的結果竟然是: Thu Jan 01 00:00:00 PST 1970

它被復原到 EPOC 的起始點,我們稱該 Calendar 是處于不穩定狀態。這個問題的根本原因是 Java 在 serialize GregorianCalendar 時沒有保存所有的信息,所以當它被恢復到內存中,又缺少足夠的信息時,Calendar 會被恢復到 EPOCH 的起始值。Calendar 對象由兩部分構成:字段和相對于 EPOC 的微秒時間差。字段信息是由微秒時間差計算出的,而 set() 方法不會強制 Calendar 重新計算字段。這樣字段值就不對了。

下面的代碼可以解決這個問題:

import java.io.*;
import java.util.*;

public class StableCalendar implements Serializable
{

public static void main(String[] args) throws Exception{
Calendar cal1 = Calendar.getInstance();
cal1.set(2000, 7, 1, 0, 0 , 0);
cal1.set(Calendar.MILLISECOND, 0);
ObjectOutputStream out =
new ObjectOutputStream(
new FileOutputStream("newCalendar.out"t);
out.writeObject(cal1);
out.close();
ObjectInputStream in =
new ObjectInputStream(
new FileInputStream("newCalendar.out"t);
Calendar cal2 = (Calendar)in.readObject();
cal2.get(Calendar.MILLISECOND); //先調用 get(),強制 Calendar 刷新
cal2.set(Calendar.MILLISECOND, 0);//再設值
System.out.println(cal2.getTime());
}
}

運行的結果是: Tue Aug 01 00:00:00 PDT 2000

這個問題主要會影響到在 EJB 編程中,參數對象中包含 Calendar 時。經過 Serialize/Deserialize 后,直接操作 Calendar 會產生不穩定的情況。

add() 與 roll() 的區別

add() 的功能非常強大,add 可以對 Calendar 的字段進行計算。如果需要減去值,那么使用負數值就可以了,如 add(field, -value)。

add() 有兩條規則:

當被修改的字段超出它可以的范圍時,那么比它大的字段會自動修正。如:
Calendar cal1 = Calendar.getInstance();
cal1.set(2000, 7, 31, 0, 0 , 0); //2000-8-31
cal1.add(Calendar.MONTH, 1); //2000-9-31 => 2000-10-1,對嗎?
System.out.println(cal1.getTime()); //結果是 2000-9-30

另一個規則是,如果比它小的字段是不可變的(由 Calendar 的實現類決定),那么該小字段會修正到變化最小的值。

以上面的例子,9-31 就會變成 9-30,因為變化最小。

Roll() 的規則只有一條:
當被修改的字段超出它可以的范圍時,那么比它大的字段不會被修正。如:

Calendar cal1 = Calendar.getInstance();
cal1.set(1999, 5, 6, 0, 0, 0); //1999-6-6, 周日
cal1.roll(Calendar.WEEK_OF_MONTH, -1); //1999-6-1, 周二
cal1.set(1999, 5, 6, 0, 0, 0); //1999-6-6, 周日
cal1.add(Calendar.WEEK_OF_MONTH, -1); //1999-5-30, 周日
WEEK_OF_MONTH 比 MONTH 字段小,所以 roll 不能修正 MONTH 字段。

Date類介紹

Data和Calendar類:
一、創建一個日期對象r

讓我們看一個使用系統的當前日期和時間創建一個日期對象并返回一個長整數的簡
單例子. 這個時間通常被稱為Java 虛擬機(JVM)主機環境的系統時間.
import java.util.Date;

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

System.out.println(date.getTime());
}
}

在星期六, 2001年9月29日, 下午大約是6:50的樣子, 上面的例子在系統輸出設備上
顯示的結果是 1001803809710. 在這個例子中,值得注意的是我們使用了Date 構造
函數創建一個日期對象, 這個構造函數沒有接受任何參數. 而這個構造函數在內部
使用了System.currentTimeMillis() 方法來從系統獲取日期.如果用

System.out.println(new Date());

則輸出形式為:Tue Nov 08 14:28:07 CST 2005

那么, 現在我們已經知道了如何獲取從1970年1月1日開始經歷的毫秒數了. 我們如
何才能以一種用戶明白的格式來顯示這個日期呢? 在這里類java.text.
SimpleDateFormat 和它的抽象基類 java.text.DateFormat 就派得上用場了.

二、日期數據的定制格式

假如我們希望定制日期數據的格式, 比方星期六-9月-29日-2001年. 下面的例子展
示了如何完成這個工作:

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateExample2 {

public static void main(String[] args) {

SimpleDateFormat bartDateFormat =
new SimpleDateFormat("EEEE-MMMM-dd-yyyy");

Date date = new Date();

System.out.println(bartDateFormat.format(date));
}
}

只要通過向SimpleDateFormat 的構造函數傳遞格式字符串"EEE-MMMM-dd-yyyy",
我們就能夠指明自己想要的格式. 你應該可以看見, 格式字符串中的ASCII 字符
告訴格式化函數下面顯示日期數據的哪一個部分. EEEE是星期, MMMM是月, dd是日
, yyyy是年. 字符的個數決定了日期是如何格式化的.傳遞"EE-MM-dd-yy"會顯示
Sat-09-29-01. 請察看Sun 公司的Web 站點獲取日期格式化選項的完整的指示.

三、將文本數據解析成日期對象r

假設我們有一個文本字符串包含了一個格式化了的日期對象, 而我們希望解析這個
字符串并從文本日期數據創建一個日期對象. 我們將再次以格式化字符串
"MM-dd-yyyy" 調用SimpleDateFormat類, 但是這一次, 我們使用格式化解析而不
是生成一個文本日期數據. 我們的例子, 顯示在下面, 將解析文本字符串
"9-29-2001"并創建一個值為001736000000 的日期對象.

例子程序:

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateExample3 {

public static void main(String[] args) {
// Create a date formatter that can parse dates of
// the form MM-dd-yyyy.
SimpleDateFormat bartDateFormat =
new SimpleDateFormat("MM-dd-yyyy");

// Create a string containing a text date to be parsed.
String dateStringToParse = "9-29-2001";

try {
// Parse the text version of the date.
// We have to perform the parse method in a
// try-catch construct in case dateStringToParse
// does not contain a date in the format we are expecting.
Date date = bartDateFormat.parse(dateStringToParse);

// Now send the parsed date as a long value
// to the system output.
System.out.println(date.getTime());
}
catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}

五、使用標準的日期格式化過程

既然我們已經可以生成和解析定制的日期格式了, 讓我們來看一看如何使用內建的
格式化過程. 方法 DateFormat.getDateTimeInstance() 讓我們得以用幾種不同的
方法獲得標準的日期格式化過程. 在下面的例子中, 我們獲取了四個內建的日期格
式化過程. 它們包括一個短的, 中等的, 長的, 和完整的日期格式.

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

public class DateExample4 {

public static void main(String[] args) {
Date date = new Date();

DateFormat shortDateFormat =
DateFormat.getDateTimeInstance(
DateFormat.SHORT,
DateFormat.SHORT);

DateFormat mediumDateFormat =
DateFormat.getDateTimeInstance(
DateFormat.MEDIUM,
DateFormat.MEDIUM);

DateFormat longDateFormat =
DateFormat.getDateTimeInstance(
DateFormat.LONG,
DateFormat.LONG);

DateFormat fullDateFormat =
DateFormat.getDateTimeInstance(
DateFormat.FULL,
DateFormat.FULL);

System.out.println(shortDateFormat.format(date));
System.out.println(mediumDateFormat.format(date));
System.out.println(longDateFormat.format(date));
System.out.println(fullDateFormat.format(date));
}
}

注意我們在對 getDateTimeInstance的每次調用中都傳遞了兩個值. 第一個參數
是日期風格, 而第二個參數是時間風格. 它們都是基本數據類型int(整型). 考慮
到可讀性, 我們使用了DateFormat 類提供的常量: SHORT, MEDIUM, LONG, 和
FULL. 要知道獲取時間和日期格式化過程的更多的方法和選項, 請看Sun 公司Web
站點上的解釋.

運行我們的例子程序的時候, 它將向標準輸出設備輸出下面的內容:
9/29/01 8:44 PM
Sep 29, 2001 8:44:45 PM
September 29, 2001 8:44:45 PM EDT
Saturday, September 29, 2001 8:44:45 PM EDT

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/64173.html

相關文章

  • 慕課網_《Java定時任務調度工具詳解之Timer篇》學習總結

    時間:2017年05月24日星期三說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:無個人學習源碼:https://github.com/zccodere/s... 第一章:課程介紹 1-1 課程介紹 什么是定時任務調度 基于給定的時間點,給定的時間間隔或者給定的執行次數自動執行的任務 在Java中的定時調度工具 Timer:小弟,能實現日常60%的定...

    wind5o 評論0 收藏0
  • Java語言的Calendar和Date類

    摘要:轉載語言的和類語言的日歷日期,和日期格式組成了標準的一個基本但是非常重要的部分。值得注意的是我們使用了構造函數創建一個日期對象,這個構造函數沒有接受任何參數,而這個構造函數在內部使用了方法來從系統獲取日期。 「轉載」Java語言的Calendar和Date類 Java 語言的Calendar(日歷),Date(日期),和DateFormat(日期格式)組成了Java標準的一個基本但是...

    elarity 評論0 收藏0
  • 寫完這段代碼,就被開除了……

    摘要:最近在技術棧微信公眾號粉絲微信群里看到一張圖,說是剛寫完這段下面這段代碼就被開除了。想離職找不到借口那還不容易,哥送你這段加強版,復制這段代碼,提交打包測試上線,坐等開除。 最近在Java技術棧微信公眾號粉絲微信群里看到一張圖,說是剛寫完這段下面這段代碼就被開除了。 showImg(https://segmentfault.com/img/remote/1460000016870809...

    Ali_ 評論0 收藏0
  • Java獲取當天、當前月、當前年(今年)的開始和結束時間戳

    摘要:最近在做統計相關的功能的時候涉及到了獲取當天的開始和結束的時間戳當月和當年的開始結束時間戳,特此記錄,以作備忘。 最近在做統計相關的功能的時候涉及到了獲取當天的開始和結束的時間戳、當月和當年的開始結束時間戳,特此記錄,以作備忘。 相關代碼 package com.lingyejun.authenticator; import java.time.Instant; import jav...

    BenCHou 評論0 收藏0
  • Java基礎知識整理之操作日期

    摘要:基礎知識之日期操作簡介中的時間使用標準類庫的其表示特定的瞬間,精確到毫秒。常用的方法實例化對象簡介是一個以與語言環境有關的方式來格式化和解析日期的具體類。它允許進行格式化日期文本解析文本日期和規范化。 Java基礎知識之日期操作 1. Date 簡介 Java中的時間使用標準類庫的java.util.Date,其表示特定的瞬間,精確到毫秒。 是用距離一個固定時間點的毫秒數(可正可負,l...

    leap_frog 評論0 收藏0

發表評論

0條評論

microelec

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<