Java SimpleDateFormat

时间:2020-01-09 10:35:37  来源:igfitidea点击:

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类通过使用DateStringBufferFieldPosition实例作为参数的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

我们可以创建一个针对特定JavaLocaleSimpleDateFormat实例。这样做将在相关时根据该"语言环境"格式化日期。例如,包含星期几名称的格式化模式将以给定的"语言环境"的语言来写星期几。这是一个例子:

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)
aAM / PM标记
k小时(1-24,与HH的0-23不同)
K小时,上午/下午(0-11)
z时区
'转义文本定界符
'单引号

除这些字符外的其他字符将被视为普通文本,以插入到模式中,并因此插入格式化的日期中。

某些字符可以使用不同的数字。例如,我们可以为年份的2个字符版本(例如12)写" yy",也可以为年份的4个字符版本写" yyyy"(例如2012)。有关接受的模式的更多信息,请参见SimpleDateFormat类的JavaDoc。

模式范例

以下是一些JavaSimpleDateFormat日期模式示例:

模式示例
dd-MM-yy31-01-12
dd-MM-yyyy2012年1月31日
MM-dd-yyyy2012年1月31日
yyyy-MM-dd2012-01-31
yyyy-MM-dd HH:mm:ss2012-01-31 23:59:59
yyyy-MM-dd HH:mm:ss.SSS2012-01-31 23:59:59.999
yyyy-MM-dd HH:mm:ss.SSSZ2012-01-31 23:59:59.999 + 0100
EEEEE MMMMM yyyy HH:mm:ss.SSSZ2012年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.SUNDAYCalendar.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