一.需求介绍
在实际开发过程中经常会需要将Date类型的数据封装成XML或Json格式在网络上进行传输,这样就面临这String 类型的日期和Date类型日期互转的情况。在JDK1.1之前可以使用newDate(“”)来将String类型的日期转换成Date类型的对象。但自JDK1.1开始已将不建议这样做了。本文主要介绍一下用SimpleDateFormat类来将String类型的日期与Date对象的互转.
二.SimpleDateFormat 使用说明
java.text.SimpleDateFormat >> java.text.DateFormat >> java.text.Format >> java.lang.Object
1.SimpleDateFormat 介绍
SimpleDateFormat 是一个以与语言环境有关的方式来格式化和解析日期的具体类。它允许进行格式化format(日期 -> 文本)、解析parse(文本 -> 日期)和规范化。
SimpleDateFormat 使得可以选择任何用户定义的日期-时间格式的模式。但是,仍然建议通过 DateFormat 中的 getTimeInstance、getDateInstance 或 getDateTimeInstance 来创建日期-时间格式器。每一个这样的类方法都能够返回一个以默认格式模式初始化的日期/时间格式器。可以根据需要使用 applyPattern 方法来修改格式模式.
2.日期和时间模式
日期和时间格式由日期和时间模式 字符串指定。在日期和时间模式字符串中,未加引号的字母 ‘A’
到 ‘Z’
和 ‘a’
到 ‘z’
被解释为模式字母,用来表示日期或时间字符串元素。文本可以使用单引号 (’
) 引起来,以免进行解释。"’’"
表示单引号。所有其他字符均不解释;只是在格式化时将它们简单复制到输出字符串,或者在解析时与输入字符串进行匹配。
定义了以下模式字母(所有其他字符 'A'
到 'Z'
和 'a'
到 'z'
都被保留):
字母 | 日期或时间元素 | 表示 | 示例 |
---|---|---|---|
G | Era 标志符 | Text | AD |
y | 年 | Year | 1996 ; 96 |
M | 年中的月份 | Month | July ; Jul ; 07 |
w | 年中的周数 | Number | 27 |
W | 月份中的周数 | Number | 2 |
D | 年中的天数 | Number | 189 |
d | 月份中的天数 | Number | 10 |
F | 月份中的星期 | Number | 2 |
E | 星期中的天数 | Text | Tuesday ; Tue |
a | Am/pm 标记 | Text | PM |
H | 一天中的小时数(0-23) | Number | 0 |
k | 一天中的小时数(1-24) | Number | 24 |
K | am/pm 中的小时数(0-11) | Number | 0 |
h | am/pm 中的小时数(1-12) | Number | 12 |
m | 小时中的分钟数 | Number | 30 |
s | 分钟中的秒数 | Number | 55 |
S | 毫秒数 | Number | 978 |
z | 时区 | General time zone | Pacific Standard Time ; PST ; GMT-08:00 |
Z | 时区 | RFC 822 time zone | -0800 |
- Text: 对于格式化来说,如果模式字母的数量大于等于 4,则使用完全形式;否则,在可用的情况下使用短形式或缩写形式。对于解析来说,两种形式都是可接受的,与模式字母的数量无关。
- Number: 对于格式化来说,模式字母的数量是最小的数位,如果数位不够,则用 0 填充以达到此数量。对于解析来说,模式字母的数量被忽略,除非必须分开两个相邻字段。
- Year: 如果格式器的
Calendar
是格里高利历,则应用以下规则。
- 对于格式化来说,如果模式字母的数量为 2,则年份截取为 2 位数,否则将年份解释为 number。
- 对于解析来说,如果模式字母的数量大于 2,则年份照字面意义进行解释,而不管数位是多少。因此使用模式 "MM/dd/yyyy",将 "01/11/12" 解析为公元 12 年 1 月 11 日。
- 在解析缩写年份模式("y" 或 "yy")时,
SimpleDateFormat
必须相对于某个世纪来解释缩写的年份。这通过将日期调整为SimpleDateFormat
实例创建之前的 80 年和之后 20 年范围内来完成。例如,在 "MM/dd/yy" 模式下,如果SimpleDateFormat
实例是在 1997 年 1 月 1 日创建的,则字符串 "01/11/12" 将被解释为 2012 年 1 月 11 日,而字符串 "05/04/64" 将被解释为 1964 年 5 月 4 日。在解析时,只有恰好由两位数字组成的字符串(如Character.isDigit(char)
所定义的)被解析为默认的世纪。其他任何数字字符串将照字面意义进行解释,例如单数字字符串,3 个或更多数字组成的字符串,或者不都是数字的两位数字字符串(例如"-1")。因此,在相同的模式下, "01/02/3" 或 "01/02/003" 解释为公元 3 年 1 月 2 日。同样,"01/02/-3" 解析为公元前 4 年 1 月 2 日。
- Month: 如果模式字母的数量为 3 或大于 3,则将月份解释为 text;否则解释为 number。
- General time zone: 如果时区有名称,则将它们解释为 text。对于表示 GMT 偏移值的时区,使用以下语法:
GMTOffsetTimeZone:
Hours 必须在 0 到 23 之间,Minutes 必须在 00 到 59 之间。格式是与语言环境无关的,并且数字必须取自 Unicode 标准的 Basic Latin 块。GMT
Sign Hours:
Minutes Sign: one of+ -
Hours: Digit Digit Digit Minutes: Digit Digit Digit: one of0 1 2 3 4 5 6 7 8 9
对于解析来说,RFC 822 time zones 也是可接受的。
- RFC 822 time zone: 对于格式化来说,使用 RFC 822 4-digit 时区格式:
RFC822TimeZone: Sign TwoDigitHours Minutes TwoDigitHours: Digit Digit
TwoDigitHours 必须在 00 和 23 之间。对于解析来说,general time zones 也是可接受的。
SimpleDateFormat
还支持
本地化日期和时间模式 字符串。在这些字符串中,以上所述的模式字母可以用其他与语言环境有关的模式字母来替换。
SimpleDateFormat
不处理除模式字母之外的文本本地化;而由类的客户端来处理。
**示例**
以下示例显示了如何在美国语言环境中解释日期和时间模式。给定的日期和时间为美国太平洋时区的本地时间 2001-07-04 12:08:56。
日期和时间模式 | 结果 |
---|---|
"yyyy.MM.dd G 'at' HH:mm:ss z" | 2001.07.04 AD at 12:08:56 PDT |
"EEE, MMM d, ''yy" | Wed, Jul 4, '01 |
"h:mm a" | 12:08 PM |
"hh 'o''clock' a, zzzz" | 12 o'clock PM, Pacific Daylight Time |
"K:mm a, z" | 0:08 PM, PDT |
"yyyyy.MMMMM.dd GGG hh:mm aaa" | 02001.July.04 AD 12:08 PM |
"EEE, d MMM yyyy HH:mm:ss Z" | Wed, 4 Jul 2001 12:08:56 -0700 |
"yyMMddHHmmssZ" | 010704120856-0700 |
"yyyy-MM-dd'T'HH:mm:ss.SSSZ" | 2001-07-04T12:08:56.235-0700 |
同步
日期格式是不同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,则它必须是外部同步的。
3.常用的匹配模式
EEE MMM dd HH:mm:ss zzz yyyy
yyyy年MM月dd日 HH时mm分ss秒
yyyy-MM-dd HH:mm:ss E
SimpleDateFormat实例化参数说明:
在实例化SimpleDateFormat类的时候需要指定两个参数,第一个参数是要解析的日期模式,第二个参数是指定语言环境的。在有些时候第二参数是可以省略的,但在解析String类型的GMT或GST日期的时候需要将第二个参数指定为Locale.US或Locale.UK或Locale.ENGLISH否则会出现编译错误。
关于第一个参数日期模式是要根据要解析的String类型日期格式不同而不同,其中EEE代表星期 ,MM代表月份,dd代表天,HH代表小时,mm代表分钟,ss代表秒,这里要特别注意的是’GMT’,它代表你要解析的String是GMT格式的时间,如果GST格式可以使用’ GST’来代替’GMT’。GMT是指格林尼标准时间.
4.SimpleDateFormat常用代码
SimpleDateFormat 是一个以与语言环境有关的方式来格式化和解析日期的具体类。它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)和规范化。
在将Date转成String时需要用到format方法,而将文本解析成Date时要用到的方法是parse方法.
Date转String:
/* 默认的toString的格式 */
System.out.println(new Date()); // Fri Sep 22 10:40:07 CST 2017
Calendar calendar = Calendar.getInstance();
System.out.println(calendar.getTime()); // Fri Sep 22 10:40:07 CST 2017
/* 模式匹配一 */
String pattern = "yyyy-MM-dd HH:mm:ss E";
SimpleDateFormat format = new SimpleDateFormat(pattern);
String dateStr = format.format(new Date());
System.out.println(dateStr);// 2017-09-22 10:26:22 星期五
/* 模式匹配二 */
SimpleDateFormat format2 = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒 E ");
String dateStr2 = format2.format(new Date());
System.out.println(dateStr2); // 2017年09月22日 10时29分08秒 星期五
/* 模式匹配三 */
SimpleDateFormat format3 = new SimpleDateFormat(" MM dd HH:mm:ss zzz yy");
String dateStr3 = format3.format(new Date());
System.out.println(dateStr3); // 2017年09月22日 10时29分08秒 星期五
String转Date:
转换的时候,如果是格式不能完全匹配会出现异常,只允许需要转换的文本比pattern有更加多的格式.
比如:
pattern = "yyyy-MM-dd HH:mm:ss E";
source = "2017-09-22 13:55:60";时会出现异常
pattern = "yyyy-MM-dd"; source = "2017-09-22 13:55:60";是不会出现异常.
String转Date简单例子:
try {
/* 模式匹配一 */
String pattern = "yyyy-MM-dd HH:mm";
String source = "2017-09-22 13:55:60";
SimpleDateFormat format = new SimpleDateFormat(pattern);
Date parse = format.parse(source);
System.out.println(parse);// Fri Sep 22 13:55:00 CST 2017
} catch (ParseException e) {
e.printStackTrace();
}
//打印的是默认的toString格式.