关于日期转换的知识点(SimpleDateFormat)
这篇文章不是系统的学习,是阅读一些文章,然后总结汇总的。
一:SimpleDateFormat类
1.介绍
SimpleDateFormat 是一个以国别敏感的方式格式化和分析数据的具体类。 它允许格式化 (date -> text)、语法分析 (text -> date)和标准化。
SimpleDateFormat 允许以为日期-时间格式化选择任何用户指定的方式启动。
但是,希望用 DateFormat 中的 getTimeInstance、 getDateInstance 或 getDateTimeInstance 创建一个日期-时间格式化程序。 每个类方法返回一个以缺省格式化方式初始化的日期/时间格式化程序。 可以根据需要用 applyPattern 方法修改格式化方式。
2.继承关系
java.lang.Object
|
+----java.text.Format
|
+----java.text.DateFormat
|
+----java.text.SimpleDateFormat
3.语法
G 年代标志符
y 年
M 月
d 日
h 时 在上午或下午 (1~12)
H 时 在一天中 (0~23)
m 分
s 秒
S 毫秒
E 星期
D 一年中的第几天
F 一月中第几个星期几
w 一年中第几个星期
W 一月中第几个星期
a 上午 / 下午 标记符
k 时 在一天中 (1~24)
K 时 在上午或下午 (0~11)
z 时区
二:案例一
1.format
日期对象产生日期字符串。
package com.cao.it; import java.text.SimpleDateFormat;
import java.util.Date; public class Test1 {
public static void main(String[] args) {
SimpleDateFormat myFmt = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
SimpleDateFormat myFmt1 = new SimpleDateFormat("yy/MM/dd HH:mm");
SimpleDateFormat myFmt2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 等价于now.toLocaleString()
SimpleDateFormat myFmt3 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 E");
SimpleDateFormat myFmt4 = new SimpleDateFormat("一年中的第 D 天 一年中第w个星期 一月中第W个星期 在一天中k时 z时区"); Date now = new Date(); System.out.println(myFmt.format(now));
System.out.println(myFmt1.format(now));
System.out.println(myFmt2.format(now));
System.out.println(myFmt3.format(now));
System.out.println(myFmt4.format(now)); System.out.println("======"); System.out.println(now.toGMTString());
System.out.println(now.toLocaleString()); //这个方法产生的效果和上面的一样,不建议使用这个方法
System.out.println(now.toString());
}
}
2.效果

3.对上面的一个补充
format后返回的是String。
package com.cao.it;
import java.text.SimpleDateFormat;
import java.util.Date; public class Test2 {
public static String toLongDateString(Date dt){
SimpleDateFormat myFmt=new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 E ");
return myFmt.format(dt);
} public static String toLongTimeString(Date dt){
SimpleDateFormat myFmt=new SimpleDateFormat("HH mm ss SSSS");
return myFmt.format(dt);
} public static void main(String[] args) {
Date now=new Date();
System.out.println(toLongDateString(now));
System.out.println(toLongTimeString(now));
}
}
4.效果

三:案例二
1.parse
字符串中提取日期。
package com.cao.it; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; class Test3 {
public static void main(String[] args) throws Exception {
String str = "2009-02-15 09:21:35.345";
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日 hh时mm分ss秒SSS毫秒"); //必须使用相同的格式才好进行解析
Date date = sdf1.parse(str); // 提取格式中的日期
System.out.println("转换之前的日期:" + date); String newStr1 = sdf1.format(date); // 改变格式
System.out.println("转换之后的日期:" + newStr1); String newStr2 = sdf2.format(date); // 改变格式
System.out.println("转换之后的日期:" + newStr2);
}
}
2.效果

四:Calendar
1.程序
package com.cao.it;
import java.util.Calendar;
public class Test4 {
public static void main(String[] args) {
Calendar date=Calendar.getInstance();
int day=date.get(Calendar.HOUR_OF_DAY ); //得到24小时机制的
int hour=date.get(Calendar.HOUR); //得到12小时机制的
System.out.println(day);
System.out.println(hour);
}
}
2.效果

五:安全问题
参考文档:https://www.cnblogs.com/peida/archive/2013/05/31/3070790.html
1.问题
DateFormat 和 SimpleDateFormat 类不都是线程安全的,在多线程环境下调用 format() 和 parse() 方法应该使用同步代码来避免问题。
2.下面是解决方法一
在需要用到SimpleDateFormat 的地方新建一个实例,不管什么时候,将有线程安全问题的对象由共享变为局部私有都能避免多线程问题,不过也加重了创建对象的负担。
在一般情况下,这样其实对性能影响比不是很明显的。
package com.cao.it; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; public class Test5 {
/**
* 两个静态方法
* 在要使用SimpleDateFormat的时候才创建类对象
*/
public static String formatDate(Date date,String parent)throws ParseException{
SimpleDateFormat sdf = new SimpleDateFormat(parent);
return sdf.format(date);
} public static Date parse(String strDate,String parent) throws ParseException{
SimpleDateFormat sdf = new SimpleDateFormat(parent);
return sdf.parse(strDate);
}
/**
* 测试主类
*/
public static void main(String[] args) throws ParseException {
String parent="yyyy-MM-dd HH:mm:ss";
//
Date date=new Date();
String dateStr=formatDate(date,parent);
System.out.println(dateStr);
//
String strDate="2017-12-27 21:56:36";
Date mydate=parse(strDate, parent);
System.out.println(date);
System.out.println(date.toLocaleString()); }
}
3.效果

4.下面是解决方法二
当线程较多时,当一个线程调用该方法时,其他想要调用此方法的线程就要block,多线程并发量大的时候会对性能有一定的影响。
我认为,这个不适合写成工具类,因为sdf中的格式被固定了。
package com.cao.it; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; public class Test6 {
private static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static String format(Date date) {
synchronized (sdf) {
return sdf.format(date);
}
}
public static Date parse(String dateStr) throws ParseException {
synchronized(sdf) {
return sdf.parse(dateStr);
}
}
/**
* 测试主方法
*/
public static void main(String[] args) {
Date date=new Date();
String datestr=format(date);
System.out.println(datestr);
}
}
5.下面是解决方法三
使用ThreadLocal, 也是将共享变量变为独享,线程独享肯定能比方法独享在并发环境中能减少不少创建对象的开销。如果对性能要求比较高的情况下,一般推荐使用这种方法。
package com.cao.it; import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; public class Test7 {
// private static final String date_format = "yyyy-MM-dd HH:mm:ss";
private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(); /**
*获取SimpleDateFormat
*/
public static DateFormat getFormat(String date_format)
{
DateFormat df = threadLocal.get();
if(df==null){
df = new SimpleDateFormat(date_format);
threadLocal.set(df);
}
return df;
} public static String formatDate(Date date,String date_format) throws ParseException {
return getFormat(date_format).format(date);
} public static Date parse(String strDate,String date_format) throws ParseException {
return getFormat(date_format).parse(strDate);
} /**
* 测试主类
* @throws ParseException
*/
public static void main(String[] args) throws ParseException {
Date date=new Date();
String parent="yyyy--mm--dd HH:mm:ss";
String dateStr=formatDate(date, parent);
System.out.println(dateStr); } }
6.效果

7.总结
如果在必要的时候,追求那么一点性能提升的话,可以考虑用方法三,用ThreadLocal做缓存。
关于日期转换的知识点(SimpleDateFormat)的更多相关文章
- 使用DateUtils和DateFormatUtils处理时间日期转换与SimpleDateFormat的区别
在Apache Commons项目的Lang里面,有两个类:DateUtils和DateFormatUtils,专门用于处理时间日期转换.它们在 org.apache.commons.lang.tim ...
- springMvc的日期转换之二
方式一:使用@InitBinder注解实现日期转换 前台页面: 后台打印: 方式二:处理多种日期格式类型之间的转换 采用方式:由于binder.registerCustomEditor(Date.cl ...
- Struts2中Date日期转换的问题
今天跑程序的时候莫名其妙的出现了下面的一个异常: java.lang.NoSuchMethodException:com.ca.agent.model.mybatis.ApprovalInforC ...
- struts1日期转换处理
问题场景 最近在维护公司旧的系统(用的struts1框架)的时候,在日期处理的时候,我将日期设定为Date类型,结果报以下错误: javax.servlet.ServletException: Bea ...
- java中的日期转换
在java中有两种Date对象,一种是java.sql.Date,另一种是java.util.Date 一.java.sql.Date对象: 这种Date对象使用了进行数据库操作的,它对应了数据库中的 ...
- 日期转换工具类 CommUtil.java
package com.util; import java.text.ParseException; import java.text.SimpleDateFormat; import java.ut ...
- 日期转换类 DateConverter.java
package com.util; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.D ...
- java日期格式大全 format SimpleDateFormat(转)
java日期格式大全 format SimpleDateFormat /** * 字符串转换为java.util.Date<br> * 支持格式为 yyyy.MM.dd G ...
- java日期转换
在java开发过程中,时间的转换时必须掌握的=========下面把时间转换做个总结,有可能不是很全面 时间格式只有两种 yyyy-MM-DD yyyy/MM/DD 时间的类型:字符串类型.sql类型 ...
随机推荐
- 洛谷 P4284 [SHOI2014]概率充电器 解题报告
P4284 [SHOI2014]概率充电器 题目描述 著名的电子产品品牌SHOI 刚刚发布了引领世界潮流的下一代电子产品-- 概率充电器: "采用全新纳米级加工技术,实现元件与导线能否通电完 ...
- Python之旅:并发编程之协程
一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...
- C# 基于MySQL的数据层基类(MySQLHelper)
这里介绍下比较简单的方式,引用MySql.Data.dll然后添加一个MySqlHelper类来对MySql数据库进行访问和操作. 1.将MySql.Data.dll引用到你的项目中 下载地址:MyS ...
- SqlServer在视图上创建索引
在视图上创建索引需要三个条件: 一.视图必须绑定到架构. 要做到这点,在 CREATE VIEW 语句中,必须加上 WITH SCHEMABINDING,如果是使用企业管理器,则在设计界面的空白处点击 ...
- MySQL的DML常用语法格式
MySQL的DML常用语法格式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们知道MySQL的查询大致分为单表查询,多表查询以及联合查询.多表查询,顾名思义,就是查询的结果可能 ...
- websocket使用nginx作为反向代理
需要nginx作为websocket的反向代理,没有nginx反向代理时候没有问题,通过nginx反向代理后会报400错误,查后台调试信息: tornado.general – DEBUG – Can ...
- 介绍C++11标准的变长参数模板
目前大部分主流编译器的最新版本均支持了C++11标准(官方名为ISO/IEC14882:2011)大部分的语法特性,其中比较难理解的新语法特性可能要属变长参数模板(variadic template) ...
- ifconfig不显示网卡eth0
参考资料:http://blog.itpub.net/25851087/viewspace-1700568/ 在/etc/sysconfig/network-script/ifcfg-eth0网卡配置 ...
- bzoj千题计划293:bzoj3142: [Hnoi2013]数列
http://www.lydsy.com/JudgeOnline/problem.php?id=3142 如果已知数列的差分数列a[1]~a[k-1] 那么这种差分方式对答案的贡献为 N-Σ a[i] ...
- History of Monte Carlo Methods - Part 1
History of Monte Carlo Methods - Part 1 Some time ago in June 2013 I gave a lab tutorial on Monte Ca ...