Java 8 进阶手册(XX):使用简单日期对象 SimpleDateFormat

目录

  1. 开始使用简单日期对象 SimpleDateFormat
  2. 格式化日期和时间
  3. 常规用法
  4. 格式支持列表
  5. 更改时区
  6. 不是线程安全的 SimpleDateFormat
  7. 小结
  8. 附:完整示例

1.开始使用简单日期对象 SimpleDateFormat

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

例如,我们通常这样解析日期:

public static void main(String[] args) {
	//构建一个简单日起对象,并输入要解析的格式
	SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
	Date date = null;
	try {
		//开始解析,必须捕获异常
		date = dateFormat.parse("2019-09-29");
	} catch (ParseException e) {
		e.printStackTrace();
	}
	System.out.println(date);
}
//打印:Sun Sep 29 00:00:00 CST 2019

2.格式化日期和时间

格式化一个日期时,可以使用方法:format()。只需要传入Date 实例中传递,就会自动生生成有格式的输出,比如:

System.out.println(dateFormat.format(new Date()));
//打印:2019-09-29

2.1 使用 String.format()

在格式化日期时,还有另一种选择:String.format()。它提供了同样简单的格式,有点类似C语言的替换字符,比如

//只显示年
String str = String.format("%1$tY", new Date());
// 打印: 2019
//完整日期
String str = String.format("%1$tY-%1$tm-%1$td", new Date());
// 打印: 2019-09-29
// 或者:
String str = String.format("%1$tF", new Date());
// 打印: 2019-09-29
//日期和时间
String str = String.format("%1$tY-%1$tm-%1$tdT%1$tH:%1$tM:%1$tS", new Date());
// 打印: 2019-09-29T15:56:09
//使用时区的日期和时间
String str = String.format("%1$tY-%1$tm-%1$tdT%1$tH:%1$tM:%1$tS%1$tz", new Date());
// 打印: 2019-09-29T15:56:09+0800

3.常规用法

Let us now look at some commonly used formats.These formats are based on ISO-8601.

3.1 只显示年

SimpleDateFormat df = new SimpleDateFormat("yyyy");
// 打印: 2019

3.2 显示年、月

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM");
// 打印: 2019-09

3.3 显示年、月、日

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
// 打印: 2019-09-29

3.4 显示日期、时间和时区

//显示到分钟数
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZZZZ");
// 打印: 2019-09-29T16:00+0800
//或者 加入秒数
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZ");
// 打印: 2019-09-29T16:00:54+0800

3.5 显示日期、时间(秒数)和十进制分数

SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ");
// 打印: 2019-09-29T16:00:54.225+0800

3.6 显示第几周

SimpleDateFormat df = new SimpleDateFormat("yyyy-'W'ww");
// 打印: 2019-W40

3.7 显示第几周的第几天

SimpleDateFormat df = new SimpleDateFormat("yyyy-'W'ww-F");
// 打印: 2019-W40-5

3.8 显示一年的第几天

SimpleDateFormat df = new SimpleDateFormat("yyyy-DDD");
// 打印: 2019-272

3.9 显示本地时间

SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
// 打印: 16:00:54

3.9 显示本地时间、时区

SimpleDateFormat df = new SimpleDateFormat("HH:mm:ssZZZZ");
// 打印: 16:00:54+0800

格式支持列表

日期格式,可以查看完整支持列表官方文档

字符日期或时间组件类型标示示例
GEra designatorTextAD
yYearYear1996; 96
YWeek yearYear2009; 09
MMonth in year (context sensitive)MonthJuly; Jul; 07
LMonth in year (standalone form)MonthJuly; Jul; 07
wWeek in yearNumber27
WWeek in monthNumber2
DDay in yearNumber189
dDay in monthNumber10
FDay of week in monthNumber2
EDay name in weekTextTuesday; Tue
uDay number of week (1 = Monday, …, 7 = Sunday)Number1
aAm/pm markerTextPM
HHour in day (0-23)Number0
kHour in day (1-24)Number24
KHour in am/pm (0-11)Number0
hHour in am/pm (1-12)Number12
mMinute in hourNumber30
sSecond in minuteNumber55
SMillisecond Number978
zTime zoneGeneral time zonePacific Standard Time; PST; GMT-08:00
ZTime zoneRFC 822 time zone-0800
XTime zoneISO 8601 time zone-08; -0800; -08:00

更改时区

修改时区可以使用方法:setTimeZone()

SimpleDateFormat df = new SimpleDateFormat(..);
df.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));

默认时区是来自 JVM 的,我们可以以编程方式更改 JVM 的时区,如下:

TimeZone.setDefault(TimeZone.getTimeZone("PST"));

或者通过指定系统属性(system property)里的用户时区选项(user.timezone.)来更改程序外的时区,比如:

java -Duser.timezone=EST ...

想要进行系统范围的更改?在 ubuntu 上,这需要更改 /etc/本地文件。执行以下操作(作为根):

// ubuntu
# dpkg-reconfigure tzdata
// centos
# tzselect
// macos
#先迁移老时区
sudo mv /etc/localtime /etc/localtime-old
#再更改时区
sudo ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

不是线程安全的 SimpleDateFormat

SimpleDateFormat 类不是线程安全的。

这意味着我们不能在多线程里使用相同的实例。有点无奈,毕竟应用程序的各个部分中经常使用相同的日期/时间格式。

此问题的一个解决方案是:使用 Apache Commons 的 FastDate 格式。此类被播发为"线程安全"和"可用作静态成员"。如果您不介意添加对 Apache Commons 的依赖关系(或者您的应用程序已经具有依赖关系),那么这就是要走的路。

小结

本文重点介绍了 SimpleDateFormat 的常规用法,在分析和格式化日期时,SimpleDate 非常有用,它提供了各种格式指令,涵盖处理日期和时间的所有方面。但是,它不是线程安全的,在并发编程下,需要考虑别的替代方案。

附:完整例子

public static void main(String[] args) {
      SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
      Date date = null;
      try {
          date = dateFormat.parse("2019-09-29");
      } catch (ParseException e) {
          e.printStackTrace();
      }
      System.out.println(date);
      System.out.println(dateFormat.format(new Date()));
      String str = String.format("%1$tY", new Date());
      System.out.println(str);
      str = String.format("%1$tY-%1$tm-%1$td", new Date());
      System.out.println(str);
      str = String.format("%1$tF", new Date());
      System.out.println(str);
      str = String.format("%1$tY-%1$tm-%1$tdT%1$tH:%1$tM:%1$tS", new Date());
      System.out.println(str);
      str = String.format("%1$tY-%1$tm-%1$tdT%1$tH:%1$tM:%1$tS%1$tz", new Date());
      System.out.println(str);
      //
      SimpleDateFormat df = new SimpleDateFormat("yyyy");
      System.out.println(df.format(new Date()));
      df = new SimpleDateFormat("yyyy-MM");
      System.out.println(df.format(new Date()));
      df = new SimpleDateFormat("yyyy-MM-dd");
      System.out.println(df.format(new Date()));
      df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZZZZ");
      System.out.println(df.format(new Date()));
      df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZ");
      System.out.println(df.format(new Date()));
      df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ");
      System.out.println(df.format(new Date()));
      df = new SimpleDateFormat("yyyy-'W'ww");
      System.out.println(df.format(new Date()));
      df = new SimpleDateFormat("yyyy-'W'ww-F");
      System.out.println(df.format(new Date()));
      df = new SimpleDateFormat("yyyy-DDD");
      System.out.println(df.format(new Date()));
      df = new SimpleDateFormat("HH:mm:ss");
      System.out.println(df.format(new Date()));
      df = new SimpleDateFormat("HH:mm:ssZZZZ");
      System.out.println(df.format(new Date()));
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值