Java日期類分析

樓子發表於2019-01-19

時間原點概念

計算機語言中的時間原點都是從1970年1月1日8點0分0秒開始算的,就相當於時間的0。
為什麼對應1970年呢?
其實,現在大部分計算機系統使用的時間都是UNIX時間,而UNIX或類UNIX系統使用的時間表示方式是:從協調世界時1970年1月1日0時0分0秒起至現在的總秒數,不包括閏秒。
為什麼是8點?
因為中國的太平洋時區是UTC-8,剛好和格林威治時間差8個小時。

時間是怎麼計算的

Unix系統有一個時間戳(timestamp),這個時間戳是系統和程式用來計時的一個東西,表示從1970年1月1日(UTC/GMT的午夜)開始所經過的秒數,不考慮閏秒。用的時候再轉化成年月日時分秒。後來隨著UNIX的普及這個方法也被普及,很多後來出現的計算機都用這種方法記錄時間,java、資料庫、許多精密的儀器等也自然也遵循了這一約束。
意思就是所有的日期,都是以時間原點這個0點為基準,每過一毫秒,就+1,單位是毫秒。

建立日期物件

Date d1 = new Date();  //代表當前時間
Date d2 = new Date(5000); //從1970年1月1日 早上8點0分0秒 開始經歷了5000毫秒(也就是5秒)的時間

getTime

getTime() :獲取一個時間的毫秒數,返回一個long型的整數。
例:

Date d1 = new Date();  //代表當前時間
Long time = d1.getTime(); //當前時間毫秒數
System.out.println("當前時間:" + d1); //輸出結果為Thu May 17 11:57:49 CST 2018 表示現在是2018年5月17日11:57:49
System.out.println("當前時間毫秒數:" + time); //輸出結果為1526529469712 ,表示從1970年1月1日8點至現在經過了1526529469712毫秒

還有一個方法與getTime的作用是一樣的 -> System.currentTimeMillis();

例項

下面通過一個例項來理解上面的概念:
藉助隨機數,建立一個從1995.1.1 00:00:00 到 1995.12.31 23:59:59 之間的隨機日期

//第一步,計算1995年的毫秒數
long second = 1000; //一秒為1000毫秒
long min = second * 60; //一分鐘
long hour = min * 60;//一小時
long day = hour * 24;//一天
long year = day * 365;//一年
long leapday = (1995-1970)/4 * day; //每隔四年就有一個閏日
long eightHour = 8 * hour; //1997年8點才是真正開始時間,所以要算1995年1月1日0點得減去8個小時
long _1995Start = year * (1995-1970) + leapday - eightHour; //1995年的毫秒數(從1970年算起)
System.out.println("1995年的第一天:" + new Date(_1995Start));
System.out.println("1995年的最後一天:" + new Date(_1995Start+year-1));
//第二步,定義一個隨機時間
long randomTime = (long)(Math.random() * (year-1) + _1995Start);
Date randomDate = new Date(randomTime);
System.out.println("1995年裡的隨機一天:" + randomDate);

Date d1 = new Date();  //代表當前時間
Long time = d1.getTime(); //從1970年1月1日 早上8點0分0秒 開始經歷了5000毫秒(也就是5秒)的時間
System.out.println("當前時間:" + d1);
System.out.println("當前時間毫秒數:" + time);

執行結果:
1995年的第一天:Sun Jan 01 00:00:00 CST 1995
1995年的最後一天:Sun Dec 31 23:59:59 CST 1995
1995年裡的隨機一天:Wed Sep 20 02:54:59 CST 1995

日期格式化

上面的例子直接列印物件,會看到 “Wed Sep 20 02:54:59 CST 1995” 這樣的格式,可讀性比較差,為了獲得“1995/9/20 02:54:59”這樣的格式,就要將日期進行格式化。
y 代表年
M 代表月
d 代表日
H 代表24進位制的小時
h 代表12進位制的小時
m 代表分鐘
s 代表秒
S 代表毫秒

SimpleDateFormat 日期格式化類
format 日期轉字串
parse 字串轉日期

1.日期轉字串

SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS" );
Date d= new Date();
String str = sdf.format(d);
System.out.println("當前時間通過 yyyy-MM-dd HH:mm:ss SSS 格式化後的輸出: "+str);

輸出結果: 當前時間通過 yyyy-MM-dd HH:mm:ss SSS 格式化後的輸出: 2018-05-17 15:38:42 224

2.字串轉日期
模式(yyyy/MM/dd HH:mm:ss)需要和字串格式保持一致,如果不一樣就會丟擲解析異常ParseException

SimpleDateFormat sdf =new SimpleDateFormat("yyyy/MM/dd HH:mm:ss" );
  
String str = "2016/1/5 12:12:12";

try {
Date d = sdf.parse(str);
System.out.printf("字串 %s 通過格式  yyyy/MM/dd HH:mm:ss %n轉換為日期物件: %s",str,d.toString());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Calendar類

Calendar類即日曆類,常用於進行“翻日曆”,比如下個月的今天是多久
1.Calendar與Date進行轉換

//採用單例模式獲取日曆物件Calendar.getInstance();
Calendar c = Calendar.getInstance();

Date d2 = new Date(0);
c.setTime(d2); //把這個日曆,調成日期 : 1970.1.1 08:00:00
Date d = c.getTime();//通過日曆物件得到日期物件
System.out.println("當前日曆的日起物件: "+d);

輸出結果為:Thu Jan 01 08:00:00 CST 1970

2.翻日曆
add方法,在原日期上增加年/月/日
set方法,直接設定年/月/日

private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
Date now = c.getTime();
// 當前日期
System.out.println("當前日期:	" + format(c.getTime()));

// 下個月的今天
c.setTime(now);
c.add(Calendar.MONTH, 1);
System.out.println("下個月的今天:	" +format(c.getTime()));

// 去年的今天
c.setTime(now);
c.add(Calendar.YEAR, -1);
System.out.println("去年的今天:	" +format(c.getTime()));

// 上個月的第三天
c.setTime(now);
c.add(Calendar.MONTH, -1);
c.set(Calendar.DATE, 3);
System.out.println("上個月的第三天:	" +format(c.getTime()));

}

private static String format(Date time) {
return sdf.format(time);
}

相關文章