0. SimpleDateFormat API 简介

/**
* SimpleDateFormat
* 一个与语言环境相关的格式化日期和分析日期的工具类。
* 利用该类可以将日期转换成文本,或者将文本转换成日期。
*
* 在使用SimpleDateFormat时需要指定一个需要的格式(pattern)来格式日期(Date).
* 在此请注意几个字母大小写的差异:
*
* 大写的H为24小时制表示一天中的小时数(0-23)
* 小写的h为12小时制表示一天中的小时数(1-12)
*
* 大写的M表示年中的月份
* 小写的m表示小时中的分钟数
*
* 大写的S表示毫秒数
* 小写的s表示秒数
*
* 所以最常用的24小时制的具体日期的pattern为:
* yyyy-MM-dd HH:mm:ss
*
*
* SimpleDateFormat中format()方法小结:
* 1 format()方法的作用是将日期(Date)转换为文本
* 2 format()方法的输入参数是一个Date
*
*
* SimpleDateFormat中parse()方法小结:
* 1 parse()方法的作用是将文本转换为日期(Date)
* 2 parse()方法的输入参数是一个文本,比如String
*/

1. 将日期转换为文本

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


Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
String time = simpleDateFormat.format(date);

System.out.println("----> 格式化后的日期为: "+time);
System.out.println("----------------------------------");

输出:

System.out: ----> 格式化后的日期为: 2019-05-23 22:28:01
System.out: ----------------------------------

2. 将文本转换为日期

/**
* 请注意:
*
* 文本的格式应该与 SimpleDateFormat 中的 pattern 保持一致,否则导致异常
* 比如:
* 2008年08月18日 20:07:33 对应于yyyy年MM月dd日 HH:mm:ss
* 2008-08-18 20:07:33 对应于yyyy-MM-dd HH:mm:ss
*/
private void test2() {
try {
String day = "2008年08月18日 20:07:33";
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss", Locale.getDefault());
Date date = simpleDateFormat.parse(day);
System.out.println("----> 格式化后的日期为: "+date);

day = "2008-08-18 20:07:33";
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
date = simpleDateFormat.parse(day);
System.out.println("----> 格式化后的日期为: "+date);

day = "20131227085009";
simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault());
date = simpleDateFormat.parse(day);
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
String time = simpleDateFormat.format(date);
System.out.println("----> 时间文本为: "+time);

System.out.println("----------------------------------");
} catch (Exception e) {
System.out.println("----> Exception: "+e.toString());
}
}

输出:

System.out: ----> 格式化后的日期为: Mon Aug 18 20:07:33 GMT+08:00 2008
System.out: ----> 格式化后的日期为: Mon Aug 18 20:07:33 GMT+08:00 2008
System.out: ----> 时间文本为: 2013-12-27 08:50:09

3. 将时间戳转换成时间

long timeStamp=System.currentTimeMillis();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Date date = new Date(timeStamp);
String time = simpleDateFormat.format(date);

System.out.println("----> 将时间戳转换为字符串: "+time);
System.out.println("----------------------------------");

输出:

System.out: ----> 将时间戳转换为字符串: 2019-05-23 22:36:27

4. 将时间转换成时间戳


long timeStamp = System.currentTimeMillis();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Date date = new Date(timeStamp);
String time = simpleDateFormat.format(date);

System.out.println("----> 当前时间戳为: "+timeStamp+" ,其字符串为:"+time);

Date parsedDate = simpleDateFormat.parse(time);
long ts = parsedDate.getTime();

System.out.println("----> 将字符串转换为时间戳: "+ts);
System.out.println("----------------------------------");

输出:

----> 当前时间戳为: 1558622317494 ,其字符串为:2019-05-23 22:38:37
----> 将字符串转换为时间戳: 1558622317000

5. java时间戳与unix时间戳的关系

/**
* java中生成的时间戳精确到毫秒,但unix中精确到秒
* 所以两者相差1000倍
*/

long javaTimeStamp = System.currentTimeMillis();
long unixTimeStamp = javaTimeStamp/1000;
System.out.println("----> java时间戳: " + javaTimeStamp+", unix时间戳:" + unixTimeStamp);
System.out.println("----------------------------------");

输出:

System.out: ----> java时间戳: 1558622474893 ,unix时间戳:1558622474

6. 计算两个时间的差值

private String time1="2016-01-02 00:00:00";
private String time2="2013-09-21 00:00:00";


private void getTimeDifference(String time1,String time2) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
try {

Date date1 = simpleDateFormat.parse(time1);
Date date2 = simpleDateFormat.parse(time2);
long difference = date1.getTime() - date2.getTime();
long days = difference / (1000 * 60 * 60 * 24);
System.out.println("----> 两个时间相距:"+days+"天");

} catch (Exception e) {
System.out.println("----> Exception="+e.toString());
}
System.out.println("----------------------------------");
}

输出:

System.out: ----> 两个时间相距:833天

7. 比较两个时间的大小

private void compareTime(String time1, String time2) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Calendar calendar1 = java.util.Calendar.getInstance();
Calendar calendar2 = java.util.Calendar.getInstance();
try {
calendar1.setTime(dateFormat.parse(time1));
calendar2.setTime(dateFormat.parse(time2));
} catch (java.text.ParseException e) {
System.out.println("----> Exception=" + e.toString());
}
int result = calendar1.compareTo(calendar2);
if (result == 0){
System.out.println("----> time1等于time2");
}else if (result < 0) {
System.out.println("----> time1小于time2");
}else {
System.out.println("----> time1大于time2");
}
}

输出:

System.out: ----> time1大于time2

2. 线程安全的使用方法

2.1 ThreadLocal

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

public class ConcurrentDateUtil {

private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
}
};

public static Date parse(String dateStr) throws ParseException {
return threadLocal.get().parse(dateStr);
}

public static String format(Date date) {
return threadLocal.get().format(date);
}
}

使用 ​​ThreadLocal​​, 也是将共享变量变为独享,线程独享肯定能比方法独享在并发环境中能减少不少创建对象的开销。如果对性能要求比较高的情况下,一般推荐使用这种方法。

2.2 Java 8 中的解决办法

Java 8 提供了新的日期时间 API,其中包括用于日期时间格式化的 ​​DateTimeFormatter​​​,它与 ​​SimpleDateFormat​​​ 最大的区别在于:​DateTimeFormatter 是线程安全的,而 ​SimpleDateFormat​ 并不是线程安全。

解析日期

String dateStr= "2018年06月20日";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
LocalDate date= LocalDate.parse(dateStr, formatter);

日期转换为字符串

LocalDateTime now = LocalDateTime.now();  
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy年MM月dd日 hh:mm a");
String nowStr = now.format(format);

参考链接