Java技能点之SimpleDateFormat进行日期格式化问题

 更新时间:2023年04月18日 15:51:19   作者:程序员大阳  
这篇文章主要介绍了Java技能点之SimpleDateFormat进行日期格式化问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

SimpleDateFormat进行日期格式化

1.为啥要用SimpleDateFormat

众所周知,Java中的日期类是Date,然后日期默认的输出样式很奇怪哦,是这样子的:

package org.maoge.common;
import java.util.Date;
public class SimpleDateFormatDemo {
	public static void main(String[] args) {
		//默认输出格式
		Date date=new Date();
		System.out.println(date);//Fri Oct 27 16:56:37 CST 2017
	}
}

真的好像说,这是什么鬼啊,神经病啊,老板要是发现你在前端把日期显示成这样子,非要…觉得你很有个性不可。

OK,所以就很需要将日期以一种我们想要的格式显示出来

另外,有时候我们需要指定一个日期,所以也需要将字符串类型转换为Date类型,我们往往会以为是这样子的:

这里写图片描述

首先我们就注意到了new Date()方法被划上了删除线,这个就表示该方法在定义的时候被@Deprecated注解注解过了,意思是该方法过期了不建议使用了可能有问题了,反正咱知道这个方法最好不用就是了。而且,确实也报错了,所以我们也需要一种将字符串转换为日期的方法

SimpleDateFormat就是为这两种需要诞生滴,类库嘛,就是前人搭棚好乘凉,而且都是牛逼的前人。

2.日期格式化显示

首先要记住一些标记:(注意大小写)

  • 年yyyy
  • 月MM
  • 日dd
  • 时HH
  • 分mm
  • 秒ss
  • 毫秒SS

然后直接看例子:

package org.maoge.common;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatDemo {
	public static void main(String[] args) {
		//默认输出格式
		Date date=new Date();
		System.out.println(date);//Fri Oct 27 16:56:37 CST 2017
		//日期格式化显示,首先定义格式
		SimpleDateFormat sdf1=new SimpleDateFormat("yyyyMMdd");//显示20171027格式
		SimpleDateFormat sdf2=new SimpleDateFormat("yyyy-MM-dd");//显示2017-10-27格式
		SimpleDateFormat sdf3=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//显示2017-10-27 10:00:00格式
		SimpleDateFormat sdf4=new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");//显示2017年10月27日10时00分00秒格式
		//将格式应用于日期
		System.out.println(sdf1.format(date));//20171027
		System.out.println(sdf2.format(date));//2017-10-27
		System.out.println(sdf3.format(date));//2017-10-27 17:11:13
		System.out.println(sdf4.format(date));//2017年10月27日17时11分13秒
	}
}

3.将字符串转换为对应日期

注意,因为可能定义的格式和实际字符串提供的格式不符合,所以会抛出异常

package org.maoge.common;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatDemo {
	public static void main(String[] args) {
		//首先定义格式
		SimpleDateFormat sdf1=new SimpleDateFormat("yyyyMMdd");
		SimpleDateFormat sdf2=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//按格式进行转换
		String strDate1="20151010";//符合sdf1格式
		String strDate2="20171027 10:00:00";//不符合格式
		try {
			Date date1=sdf1.parse(strDate1);
			System.out.println(date1);//正常输出Sat Oct 10 00:00:00 CST 2015
			Date date2=sdf2.parse(strDate2);//报错java.text.ParseException: Unparseable date: "20171027 10:00:00"
			System.out.println(date2);
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
}

SimpleDateFormat的使用及其注意事项

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

8. 线程安全的使用方法

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

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);

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java实现冒泡排序示例介绍

    Java实现冒泡排序示例介绍

    冒泡排序是一种简单的排序算法,通过不断比较相邻两个元素的大小,将较大的元素向后移动,最终将最大的元素放到了数组的末尾。Java中的实现方式是通过嵌套两层循环,外层循环控制比较的次数,内层循环控制每次比较时相邻元素的比较和交换
    2023-04-04
  • 简单了解Spring Boot及idea整合jsp过程解析

    简单了解Spring Boot及idea整合jsp过程解析

    这篇文章主要介绍了简单了解Spring Boot及idea整合jsp过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • 一文详解Java线程中的安全策略

    一文详解Java线程中的安全策略

    Java中的线程到底有哪些安全策略呢?这篇文章将详细为大家分析一下。文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的可以参考一下
    2022-05-05
  • 已有的springcloud+mybatis项目升级为mybatis-plus的方法

    已有的springcloud+mybatis项目升级为mybatis-plus的方法

    这篇文章主要介绍了已有的springcloud+mybatis项目升级为mybatis-plus,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • Java躲不过设计模式的坑之代理模式详解

    Java躲不过设计模式的坑之代理模式详解

    设计模式看来更像是一种设计思维或设计思想,为你的项目工程提供方向,让你的项目工程更加健壮、灵活,延续生命力。本文即将分享的是设计模式的其中一种:代理模式,感兴趣的可以了解一下
    2022-09-09
  • Java应用开源框架实现简易web搜索引擎

    Java应用开源框架实现简易web搜索引擎

    本篇文章主要介绍了Java应用开源框架实现简易web搜索引擎,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • Java由浅入深细数数组的操作下

    Java由浅入深细数数组的操作下

    数组对于每一门编程语言来说都是重要的数据结构之一,当然不同语言对数组的实现及处理也不尽相同。Java 语言中提供的数组是用来存储固定大小的同类型元素
    2022-04-04
  • Java并发中线程封闭知识点详解

    Java并发中线程封闭知识点详解

    在本篇文章里我们给大家整理了关于Java并发中线程封闭的知识点总结内容,需要的朋友们学习参考下。
    2019-07-07
  • 使用Zookeeper实现分布式锁

    使用Zookeeper实现分布式锁

    这篇文章主要介绍了使用Zookeeper实现分布式锁,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • IntelliJ IDEA 2019.1.1 for MAC 下载和注册码激活教程图解

    IntelliJ IDEA 2019.1.1 for MAC 下载和注

    这篇文章主要介绍了IntelliJ IDEA 2019.1.1 for MAC 下载和注册码激活,教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04

最新评论