Java SimpleDateFormat
java.text.SimpleDateFormat
类用于根据我们指定的格式设置模式解析日期并设置日期格式。解析日期时,JavaSimpleDateFormat
通常从Java字符串解析日期。在格式化日期时,SimpleDateFormat
通常会将"日期"对象格式化为字符串,尽管它也可以将日期格式化为" StringBuffer"。
本文介绍了如何使用SimpleDateFormat
类设置日期格式。
创建一个SimpleDateFormat
我们可以这样创建SimpleDateFormat
实例:
String pattern = "yyyy-MM-dd"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
传递给SimpleDateFormat
构造函数的pattern
参数是用于解析和格式化日期的模式。模式语法将在本文后面介绍。该模式只是一个常规的Java字符串。
格式化日期
一旦创建了一个" SimpleDateFormat"实例,就可以使用其" format()"方法格式化日期。这是一个例子:
String pattern = "yyyy-MM-dd"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); String date = simpleDateFormat.format(new Date()); System.out.println(date);
传递给format()方法的Date实例是java.util.Date实例。
上面的SimpleDateFormat
示例输出的输出为:
2016-09-09
请注意,格式化的日期字符串如何以年份,然后是月份,然后是日期开头。日期字段的顺序由传递给SimpleDateFormat
构造函数的日期模式确定。如前所述,此格式将在本JavaSimpleDateFormat
教程中稍后解释。
将日期格式化为StringBuffer
JavaSimpleDateFormat
类也能够将Date对象格式化为StringBuffer,而不用返回格式化日期的单个String。 SimpleDateFormat
类通过使用Date
,StringBuffer
和FieldPosition
实例作为参数的format()
方法的版本来实现的。
这是使用JavaSimpleDateFormat
将日期格式化为StringBuffer的示例:
StringBuffer stringBuffer = new StringBuffer(); Date now = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ"); simpleDateFormat.format(now, stringBuffer, new FieldPosition(0));
目前尚不清楚如何使用FieldPosition实例。看来,无论传递给FieldPosition构造函数的int值是什么,format()方法都会将格式化的字符串添加到StringBuffer的末尾。
解析日期
我们可以使用SimpleDateFormat实例的parse()方法将String解析为java.util.Date实例。这是一个例子:
String pattern = "yyyy-MM-dd"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); Date date = simpleDateFormat.parse("2016-09-09");
执行此代码后,date
变量将指向代表2016年9月9日的Date
实例。
为特定语言环境创建SimpleDateFormat
我们可以创建一个针对特定JavaLocale
的SimpleDateFormat
实例。这样做将在相关时根据该"语言环境"格式化日期。例如,包含星期几名称的格式化模式将以给定的"语言环境"的语言来写星期几。这是一个例子:
String pattern = "EEEEE dd MMMMM yyyy HH:mm:ss.SSSZ"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern, new Locale("da", "DK")); String date = simpleDateFormat.format(new Date()); System.out.println(date);
此代码输出的输出可能是:
søndag 09 september 2016 09:53:17.013+0200
注意周日(sndag =星期日)和月(11月)是用丹麦语写的。
模式语法
我们可以在格式设置模式中使用以下符号:
G | 时代代号(在基督之前,在基督之后) |
y | 年(例如12或者2012年)。使用yy或者yyyy。 |
M | 一年中的月份。 M的数量决定格式的长度(例如MM,MMM或者MMMMM) |
d | 每月的一天。 d的数量决定格式的长度(例如d或者dd) |
h | 一天中的12:00(AM / PM)(通常是hh) |
H | 一天中的0-23(通常是HH) |
m | 以分钟为单位,通常为0-59(毫米) |
s | 以分钟为单位,秒为0-59(通常为ss) |
S | 毫秒,0-999(通常为SSS) |
E | 星期几(例如星期一,星期二等) |
D | 一年中的一天(1-366) |
F | 每月的星期几(例如,12月的第一个星期四) |
w | 一年中的一周(1-53) |
W | 每月的一周(0-5) |
a | AM / PM标记 |
k | 小时(1-24,与HH的0-23不同) |
K | 小时,上午/下午(0-11) |
z | 时区 |
' | 转义文本定界符 |
' | 单引号 |
除这些字符外的其他字符将被视为普通文本,以插入到模式中,并因此插入格式化的日期中。
某些字符可以使用不同的数字。例如,我们可以为年份的2个字符版本(例如12)写" yy",也可以为年份的4个字符版本写" yyyy"(例如2012)。有关接受的模式的更多信息,请参见SimpleDateFormat类的JavaDoc。
模式范例
以下是一些JavaSimpleDateFormat
日期模式示例:
模式 | 示例 |
dd-MM-yy | 31-01-12 |
dd-MM-yyyy | 2012年1月31日 |
MM-dd-yyyy | 2012年1月31日 |
yyyy-MM-dd | 2012-01-31 |
yyyy-MM-dd HH:mm:ss | 2012-01-31 23:59:59 |
yyyy-MM-dd HH:mm:ss.SSS | 2012-01-31 23:59:59.999 |
yyyy-MM-dd HH:mm:ss.SSSZ | 2012-01-31 23:59:59.999 + 0100 |
EEEEE MMMMM yyyy HH:mm:ss.SSSZ | 2012年11月星期六10:45:42.720 + 0100 |
DateFormatSymbols
可以针对特定的"区域设置"来自定义格式化输出中使用的日期符号。我们可以使用java.text.DateFormatSymbols实例来实现。这是一个例子:
Locale locale = new Locale("en", "UK"); DateFormatSymbols dateFormatSymbols = new DateFormatSymbols(locale); dateFormatSymbols.setWeekdays(new String[]{ "Unused", "Sad Sunday", "Manic Monday", "Thriving Tuesday", "Wet Wednesday", "Total Thursday", "Fat Friday", "Super Saturday", }); String pattern = "EEEEE MMMMM yyyy"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern, dateFormatSymbols); String date = simpleDateFormat.format(new Date()); System.out.println(date);
首先,为英国" Locale"创建一个新的" DateFormatSymbols"实例。
其次,设置一组新的工作日名称。注意,第一个字符串" unused"从未使用过。该数组中的索引必须从1开始,以便可以通过Calendar.SUNDAY
,Calendar.MONDAY
等常量进行索引。 " Calendar.SUNDAY"常量为1," Calendar.MONDAY"常量为2,依此类推。
第三,使用DateFormatSymbols
创建SimpleDateFormat
,并用其格式化日期。由此输出的输出可能看起来像这样:
Super Saturday November 2012
请注意如何使用自定义的星期几名称。
我们可以在DateFormatSymbols
实例上设置更多日期格式符号。以下是可用于设置其他符号的方法:
dateFormatSymbols.setWeekdays(); dateFormatSymbols.setAmPmStrings(); dateFormatSymbols.setEras(); dateFormatSymbols.setLocalPatternChars(); dateFormatSymbols.setMonths(); dateFormatSymbols.setShortMonths(); dateFormatSymbols.setShortWeekdays(); dateFormatSymbols.setZoneStrings();
有关这些方法和符号的更多详细信息,请参见JavaDoc中的java.text.DateFormatSymbols类。
设置SimpleDateFormat的时区
到目前为止,本教程中显示的示例均使用系统默认时区。这意味着,如果我们要格式化日期,SimpleDateFormat
将假定我们要根据系统的时区格式化该日期。但是,这可能并不总是我们想要的。
我们可以使用setTimeZone()方法设置SimpleDateFormat的时区。 setTimeZone()方法采用Java TimeZone实例(java.util.TimeZone)作为参数。这是显示如何设置JavaSimpleDateFormat
实例的时区的示例:
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ"); simpleDateFormat1.setTimeZone(TimeZone.getTimeZone("Europe/Paris"));
设置时区后,SimpleDateFormat
将更改其格式。这是一个将时区设置为两个不同时区,并为每个时区设置相同日期格式的示例:
Date now = new Date(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ"); simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Europe/London")); System.out.println(simpleDateFormat.format(now)); simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Paris")); System.out.println(simpleDateFormat.format(now));
该示例输出的输出类似于:
2016-09-09 10:43:54+0100 2016-09-09 11:43:54+0200
注意格式化日期的" +0100"和" +0200"部分。这些指示时间的格式设置为哪个时区。顺便说一句,伦敦之所以比UTC / GMT早1小时,而巴黎比UTC / GMT早2小时,是因为夏季。在冬季,时区偏移量将为" +0000"和" +0100"。
ISO日期格式
有时我们可能想根据ISO日期格式格式化"日期"。更具体地说,ISO 8601日期格式。 ISO 8601日期格式(以下简称为ISO日期格式)如下所示:
yyyy-MM-ddTHH:mm:ss:sssZ
ISO 8601日期格式的优点在于,如果我们对使用ISO 8601格式格式化的日期字符串进行排序,则实际上这些字符串将按日期顺序进行排序。换句话说,字母顺序与日期时间顺序相同。
上述格式中唯一的新字符是日期和时间之间的" T",以及表示时区的模式末尾的" Z"。两者都将在下面说明。请注意,ISO 8601日期格式似乎未在其日期格式中包含毫秒。
" T"实际上是一个文字字符,必须位于ISO 8601日期字符串的日期和时间部分之间。例如:
2016-09-24T17:48:00
代表时区的Z
字符可以是:
- 文字" Z"字符。在那种情况下," Z"代表UTC时区。
- 使用以下模式之一编码的时区字符串:hh:mm
- 嗯
- h
在这些ISO时区格式中,JavaSimpleDateFormat
类仅支持第二种格式(+ hhmm
)或者以Z
字符结尾的格式。
为了使用以UTC时区的Z
字符结尾的ISO 8601格式创建JavaSimpleDateFormat
实例,我们需要使用以下日期模式String:
yyyy-MM-dd'T'HH:mm:ss'Z'
注意" T"和" Z"字符如何都用单引号引起来。这是为了使SimpleDateFormat
类将它们视为要插入的文字字符,而不是试图将它们解释为代表日期的某些部分。如果我们没有在单引号中包含T和Z字符,则在创建SimpleDateFormat实例时会出现异常。这是使用上述ISO 8601日期格式模式创建JavaSimpleDateFormat
的示例:
String isoDatePattern = "yyyy-MM-dd'T'HH:mm:ss'Z'"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(isoDatePattern); String dateString = simpleDateFormat.format(new Date());
这是一个使用上述模式由SimpleDateFormat
格式化的日期的示例:
2016-09-24T18:01:24Z
为了按照ISO 8601日期格式设置日期格式,并且使用不同于UTC的时区,请在创建JavaSimpleDateFormat
实例时使用以下日期格式:
yyyy-MM-dd'T'HH:mm:ssZ
注意,Z
字符不再用单引号引起来。这是使用上述日期格式创建JavaSimpleDateFormat
的示例:
String isoDatePattern = "yyyy-MM-dd'T'HH:mm:ssZ"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(isoDatePattern); String dateString = simpleDateFormat.format(new Date());
从上面的代码示例生成的日期字符串将类似于以下内容:
2016-09-24T18:09:24+0200