Date - Java处理日期和时间

扫描二维码关注公众号,回复: 6122692 查看本文章

在计算机中如何表示日期和时间呢,我们可以想到有几种表示方式,一种是2016-11-20 8::15:01 GMT+08:00,或者我们用其他的

时区,比如GMT+00:00标准时区,或者 America/New_York时区,这种表示方式有什么问题呢,我们先看一下整数在计算机内存中

的表示,当我们定义一个整数变量n,123400的时候,计算机其实在内存中分配了4个字节,来存储这个整数,这4个字节分别是00,01

02,08,当我们打印一个整数的时候,我们可以以System.out.println以十进制的形式打印这个整数,结果是一个字符串"123400",

我们还可以以16进制的形式打印这个整数,printHex(n),结果是"0x1e208",我们还可以按照货币来格式化这个数字,format(n)

例如格式化为$符,"$123,400",这里我们要理解数据的存储和展示,数据的存储方式就是数据在计算机内存的保存方式,而我们

打印出的10进制和16进制,或者是货币的形式,就是数据的展示方式,因此我们看到字符串加上时区,表示的日期和时间,他实际

上是时间的展示方式,那计算机中应该如何存储日期和时间呢,在计算机中我们使用Epoch Time存储日期和时间,Epoch Time

是指从1970年1月1日零点以格林威治时区到现在经历的秒数,例如北京时间2016年11月20号,8点一刻01秒,他的秒数是1479600901

而伦敦的2016年11月20号早上0点一刻01秒,他的秒数和本地时间是一样的,是1479600901,或者我们以毫秒数来表示,就可以在毫秒

后面加上单位毫秒数,或者我们以浮点数表示,把毫秒数以小数点后面的表示出来,当我们要使用Epoch Time表示时间的时候,

我们实际上存储的是一个整数,对于Epoch Time 等于1479600901来说,全球各地的任何一个时区,他的当地时间都可以唯一的被确定

下来,在Java中实际上是使用一个Long类型的整形来表示毫秒数
我们把这个叫做Epoch Time,有的时候我们也把他叫做时间戳,叫TimeStamp


我们再来看一下JAVA提供的API,有两套API,一套定义在util这个包里面,另一套是新的API,它是在JDK1.8引入的,定义在

java.time这个包里,主要包括LocalDate,LocalTime,ZoneDateTime,和Instant这个类,为什么会有两套新旧API呢,就是

历史遗留的原因,旧的API存在很多问题,所以JAVA8引入了新的API,那我们能不能直接使用旧的API使用新的API呢,

现在还不行,因为很多代码仍然在使用旧的API,所以我们现在仍然需要对旧的API有一定的了解,很多时候我们需要在新旧

两种API之间进行转换,我们现在看一下java.util.Date这个类

他表示的是当前的日期和时间,我们通过new Date()就可以获取当前的时间,当我们打印一个Date变量的时候,

我们得到的是标准的我们还可以通过getTime这个方法,返回一个Epoch的Long类型表示的时间戳


当我们需要把java.util.Date转String的时候,我们直接以toString直接以默认的格式转换这个Date,我们通过toGMTString

和toLocaleString通过默认的格式来表示一个String,如果我们希望以我们希望的方式来格式化一个Date,我们就需要用到

SimpleDateFormat这个类



我们把String解析为java.util.Date的时候,也需要用到SimpleDateFormat这个类,我们使用预定义的字符串表示格式化的内容

例如4个小写字母yyyy表示年份,两个大写字母MM表示月份


java.util.Date有几个问题:

1. 首先他不能进行时区的换算

2. 其实对于日期和时间的加减非常困难

3. 他也不能够计算两个日期相差多少天

4. 我们也很难计算某个月的第一个星期一是几号
最后总结一下:

1. 我们要理解Epoch Time在JAVA的表示中是一个Long的整形

2. JAVA有两套日期的API,旧的API主要是包括java.util.Date,和Calendar,而新的API在java.time这个包内

3. 我们还需要正确的使用java.util.Date,我们要知道在Date和Long之间进行转换,以及Date和String之间进行转换

   通过SimpleDateFormat就可以实现
package com.learn.time;

import java.util.Date;

/**
 * 一定要注意import的一定要是java.util.Date
 * 因为JDK提供了两个Date
 * 一个是java.util.Date,一个是java.sql.Date
 * 我们一定要确保import的是java.util.Date
 * @author Leon.Sun
 *
 */
public class Test {

	public static void main(String[] args) {
		/**
		 * 获取系统当前的时间戳
		 * 首先通过System.getCurrentTimeMillis获取当前系统的时间戳
		 * 我们可以得到一个long型的整数
		 */
		System.out.println(System.currentTimeMillis());
		
		/**
		 * 获取当前时间
		 * 然后我们通过new Date获取当前的时间
		 * 我们可以直接打印这个Date对象
		 * Fri May 03 11:40:49 CST 2019
		 * 得到的一个GMT格式的日期和时间
		 */
		Date now = new Date();
		System.out.println(now);
		
		/**
		 * 把Date转成long
		 * 然后我们通过getTime方法把Date对象转成Long类型
		 */
		long t = now.getTime();
		/**
		 * 我们打印这个Long类型
		 */
		System.out.println(t);
		
		/**
		 * 把Long转化为Date
		 * 最后我们再把Long类型转换为Date
		 * 我们只需在创建Date对象的时候传入一个Long类型的整数就可以了
		 */
		System.out.println(new Date(t));
	}
}
package com.learn.time;

import java.util.Date;

/**
 * 我们再来看一下如果把一个Date对象转为一个String
 * @author Leon.Sun
 *
 */
public class Date2String {

	public static void main(String[] args) {
		/**
		 * 获取当前时间
		 * 
		 * 我们首先获取当前的时间
		 */
		Date now = new Date();
		
		/**
		 * 以当前时区打印日期时间
		 * 
		 * 然后我们调用toString方法
		 * Fri May 03 11:48:08 CST 2019
		 * 它会以当前的时区打印当前的日期和时间
		 */
		System.out.println(now.toString());
		
		/**
		 * 以GMT+00:00时区打印时间
		 * 
		 * 然后我们通过GMT方法,以GMT的标准时区打印出日期和时间
		 * 3 May 2019 03:48:08 GMT
		 * 这个时候我们就会注意到会和北京的时间是不一样的
		 */
		System.out.println(now.toGMTString());
		
		/**
		 * 以当前时区+当前Locale打印日期时间
		 * 
		 * 我们最后以toLocale来打印当前的时区,
		 * 并且以当前的Locale来打印
		 * May 3, 2019 11:48:08 AM
		 * 这个时候我们就会以Locale为中文的环境来打印
		 */
		System.out.println(now.toLocaleString());
		
		
	}
}
package com.learn.time;

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

/**
 * 我们看一下如何格式化一个Date对象
 * @author Leon.Sun
 *
 */
public class FormatDemo {

	public static void main(String[] args) {
		/**
		 * 获取当前的时间
		 * 
		 * 我们同样先获取当前的时间
		 */
		Date now = new Date();
		
		/**
		 * 指定格式打印
		 * 
		 * 然后我们通过SimpleDateFormat这个对象来进行格式化
		 * 我们给SimpleDateFormat对象传入的格式化是4个小写字母yyyy
		 * 两个大写字母MM,两个小写字母dd,表示年月日,;两个大写字母HH,
		 * 两个小写字母mm,和两个小写字母ss,表示时分秒,这样我们打印出来的格式
		 * 就是按照我们预定义的格式打印出来的
		 * 
		 * 当我们调整这个顺序的时候,打印出来的顺序也是不一样的
		 * 例如我们以MM/dd/yyyy这个格式打印
		 * 05/03/2019 11:54:46
		 * 我们可以发现打印出的结结果是不同的
		 */
		// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		// SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
		/**
		 * 我们还可以给字符串加一个z表示时区
		 * 05/03/2019 11:55:35 CST
		 * 打印出的CST是中国的标准时区
		 * 如果我们把时区改成大写的Z
		 * 我们再保存执行这个代码
		 * 05/03/2019 11:57:02 +0800
		 * 打印出的时区是以+0800表示的GMT时区
		 * 那我们怎么获取JAVA提供了哪些字符呢
		 * 我们可以打开浏览器,
		 * 在浏览器中搜索JAVA SimpleDateFomrat关键字
		 * 然后转到Oracle的网站
		 * https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html
		 * 我们就可以看到详细的格式
		 * 我们可以按照文档的说明选取我们需要的字符进行格式化
		 * 
		 * 
		 */
		// SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss z");
		SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss Z");
		
		/**
		 * 我们可以看到打印出的格式年月日时分秒
		 * 2019-05-03 11:53:25
		 */
		System.out.println(sdf.format(now));
		
		
	}
}
package com.learn.time;

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

/**
 * 如何把一个字符串解析成一个Date对象
 * @author Leon.Sun
 *
 */
public class ParseDemo {

	public static void main(String[] args) throws Exception {
		/**
		 * 按系统Locale解析时间
		 * 
		 * 我们首先定义了一个字符串表示日期和时间
		 */
		String s1 = "2016-11-20 12:15:59";
		/**
		 * 然后我们传入预定义的字符串格式;来解析这个字符串
		 * 就可以得到一个Date对象
		 */
		Date date1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(s1);
		/**
		 * 我们可以打印一个Date对象
		 * 他的年月日和时分秒
		 * 和我们传入的字符串是一样的
		 */
		System.out.println(date1);
		
		/**
		 * 解析MMM时默认按照系统Locale
		 * 
		 * 如果我们要解析Nov这样的英文单词,
		 * 我们需要传入的字符串格式化需要用三个大写MMM来表示
		 */
		String s2 = "Nov/20/2016 12:15:59";
		/**
		 * 因为我们的系统当前是中文环境,因此我们无法解析到英文的Nov单词
		 * 要按照英文解析Nov的话,
		 * 我们就需要给SimpleDateFormat传入一个英文的Locale
		 * 因此我们传入Locale.US
		 * 就可以正确的解析英文的Nov
		 */
		// Date date2 = new SimpleDateFormat("MMM/dd/yyyy HH:mm:ss").parse(s2);
		Date date2 = new SimpleDateFormat("MMM/dd/yyyy HH:mm:ss",Locale.US).parse(s2);
		System.out.println(date2);
		
		/**
		 * 按ISO 8601标准格式解析
		 * 
		 * 最后我们还可以解析ISO的日期和时间
		 * 在这里ISO 8601使用了一个T来分隔日期和时间
		 * 所以我们在构造格式字符串的时候,
		 * 我们需要使用单引号字符串把T给括起来
		 * 就可以正常的解析ISO的日期和时间了
		 * 
		 */
		String iso = "2016-11-20T12:15:59";
		Date date3 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(iso);
		System.out.println(date3);
		
		
	}
}

猜你喜欢

转载自blog.csdn.net/Leon_Jinhai_Sun/article/details/89785797