Module java.base
Package java.text

Class SimpleDateFormat

所有已实现的接口:
Serializable, Cloneable

public class SimpleDateFormat extends DateFormat
SimpleDateFormat 是一个具体类,用于以区域敏感的方式格式化和解析日期。它允许进行格式化(日期 → 文本)、解析(文本 → 日期)和规范化操作。

SimpleDateFormat 允许您首先选择任何用户定义的日期时间格式模式。但是,建议您使用 DateFormat 中的 getTimeInstancegetDateInstancegetDateTimeInstance 创建一个日期时间格式化程序。这些类方法中的每一个都可以返回一个使用默认格式模式初始化的日期/时间格式化程序。您可以根据需要使用 applyPattern 方法修改格式模式。有关使用这些方法的更多信息,请参阅 DateFormat

日期和时间模式

日期和时间格式由日期和时间模式字符串指定。在日期和时间模式字符串中,从 'A''Z' 和从 'a''z' 的未引用字母被解释为表示日期或时间字符串组件的模式字母。文本可以使用单引号(')引用以避免解释。"''" 表示一个单引号。所有其他字符不被解释;它们在格式化期间仅被复制到输出字符串中,或在解析期间与输入字符串匹配。

以下模式字母已定义(所有其他从 'A''Z' 和从 'a''z' 的字符均保留):

图表显示模式字母、日期/时间组件、展示方式和示例。
字母 日期或时间组件 展示方式 示例
G 纪元标识符 文本 公元
y 1996; 96
Y 周年 2009; 09
M 年中的月份(上下文敏感) 七月; Jul; 07
L 年中的月份(独立形式) 七月; Jul; 07
w 年中的周 数字 27
W 月中的周 数字 2
D 年中的日 数字 189
d 月中的日 数字 10
F 月中的星期几 数字 2
E 星期几的名称 文本 星期二; 周二
u 星期的数字(1 = 星期一,..., 7 = 星期日) 数字 1
a 上午/下午标记 文本 下午
H 一天中的小时(0-23) 数字 0
k 一天中的小时(1-24) 数字 24
K 上午/下午的小时(0-11) 数字 0
h 上午/下午的小时(1-12) 数字 12
m 小时中的分钟 数字 30
s 分钟中的秒 数字 55
S 毫秒 数字 978
z 时区 通用时区 太平洋标准时间; PST; GMT-08:00
Z 时区 RFC 822 时区 -0800
X 时区 ISO 8601 时区 -08; -0800; -08:00
模式字母通常会重复,因为它们的数量决定了确切的展示方式:
  • 文本: 对于格式化,如果模式字母的数量为4或更多,则使用完整形式;否则,如果可用,则使用短形式或缩写形式。对于解析,无论模式字母的数量如何,都接受这两种形式,独立于模式字母的数量。

  • 数字: 对于格式化,模式字母的数量是最小数字位数,较短的数字将被零填充到这个数量。对于解析,除非需要将两个相邻字段分开,否则将忽略模式字母的数量。

  • 年: 如果格式化程序的Calendar是公历日历,则应用以下规则。
    • 对于格式化,如果模式字母的数量为2,则年份将被截断为2位数;否则将被解释为一个数字
    • 对于解析,如果模式字母的数量超过2,则年份将被直接解释,而不考虑数字位数。因此,使用模式"MM/dd/yyyy","01/11/12"解析为公元12年1月11日。
    • 对于使用缩写年份模式("y"或"yy")的解析,SimpleDateFormat必须相对于某个世纪解释缩写年份。它通过调整日期使其在SimpleDateFormat实例创建的时间之前80年和之后20年内。例如,使用模式"MM/dd/yy"和在1997年1月1日创建的SimpleDateFormat实例,则字符串"01/11/12"将被解释为2012年1月11日,而字符串"05/04/64"将被解释为1964年5月4日。在解析过程中,只有由Character.isDigit(char)定义的正好两位数字的字符串将被解析为默认世纪。任何其他数字字符串,例如一个数字字符串,一个三位或更多位数字字符串,或一个不全是数字的两位数字字符串(例如,"-1"),将被直接解释。因此,"01/02/3"或"01/02/003"将使用相同的模式解析为公元3年1月2日。同样,"01/02/-3"将被解释为公元前4年1月2日。
    否则,将应用特定于日历系统的形式。对于格式化和解析,如果模式字母的数量为4或更多,则使用特定于日历的长形式。否则,将使用特定于日历的短形式或缩写形式

    如果指定了周年'Y',并且日历不支持任何周年,则将使用日历年份('y')。可以通过调用getCalendar()来测试周年的支持。isWeekDateSupported()

  • 月: 如果模式字母的数量为3或更多,则月份被解释为文本;否则,将被解释为一个数字
    • 字母M生成上下文敏感的月份名称,例如嵌入式名称的形式。字母M在独立模式中使用时是上下文敏感的,例如,"MMMM",它给出月份名称的独立形式,当它在包含其他字段的模式中使用时,例如,"d MMMM",它给出月份名称的格式形式。例如,加泰罗尼亚语中的一月在格式形式中是"de gener",而在独立形式中是"gener"。在这种情况下,"MMMM"将生成"gener","d MMMM"的月份部分将生成"de gener"。如果使用构造函数SimpleDateFormat(String,DateFormatSymbols)或方法setDateFormatSymbols(DateFormatSymbols)明确设置了DateFormatSymbols,则将使用DateFormatSymbols给出的月份名称。
    • 字母L生成月份名称的独立形式。

  • 通用时区: 如果时区具有名称,则将其解释为文本。对于表示GMT偏移值的时区,使用以下语法:
         GMTOffsetTimeZone:
                 GMT Sign Hours : Minutes
         Sign: 其中之一
                 + -
         Hours:
                 Digit
                 Digit Digit
         Minutes:
                 Digit Digit
         Digit: 其中之一
                 0 1 2 3 4 5 6 7 8 9
    Hours必须在0和23之间,Minutes必须在00和59之间。该格式与语言环境无关,数字必须取自Unicode标准的基本拉丁文块。

    对于解析,还接受RFC 822时区

  • RFC 822时区: 对于格式化,使用RFC 822的4位数字时区格式:
         RFC822TimeZone:
                 Sign TwoDigitHours Minutes
         TwoDigitHours:
                 Digit Digit
    TwoDigitHours必须在00和23之间。其他定义与通用时区相同。

    对于解析,还接受通用时区

  • ISO 8601时区: 模式字母的数量指定了格式化和解析的格式,如下所示:
         ISO8601TimeZone:
                 OneLetterISO8601TimeZone
                 TwoLetterISO8601TimeZone
                 ThreeLetterISO8601TimeZone
         OneLetterISO8601TimeZone:
                 Sign TwoDigitHours
                 Z
         TwoLetterISO8601TimeZone:
                 Sign TwoDigitHours Minutes
                 Z
         ThreeLetterISO8601TimeZone:
                 Sign TwoDigitHours : Minutes
                 Z
    其他定义与通用时区RFC 822时区相同。

    对于格式化,如果与GMT的偏移值为0,则生成"Z"。如果模式字母的数量为1,则忽略任何小时的小数部分。例如,如果模式是"X",时区是"GMT+05:30",则生成"+05"

    对于解析,"Z"被解析为UTC时区标识符。不接受通用时区

    如果模式字母的数量为4或更多,在构造SimpleDateFormat应用模式时抛出IllegalArgumentException

SimpleDateFormat还支持本地化日期和时间模式字符串。在这些字符串中,上述描述的模式字母可以被其他依赖于语言环境的模式字母替换。 SimpleDateFormat不处理除模式字母之外的文本的本地化;这由类的客户端处理。

示例

以下示例展示了日期和时间模式在美国语言环境中的解释。给定的日期和时间是2001年7月4日12:08:56在美国太平洋时间时区的本地时间。
在美国语言环境中解释的日期和时间模式示例
日期和时间模式 结果
"yyyy.MM.dd G 'at' HH:mm:ss z" 2001.07.04 公元 at 12:08:56 PDT
"EEE, MMM d, ''yy" 周三, 7月 4, '01
"h:mm a" 12:08 下午
"hh 'o''clock' a, zzzz" 下午12点, 太平洋夏令时间
"K:mm a, z" 下午0:08, PDT
"yyyyy.MMMMM.dd GGG hh:mm aaa" 02001.七月.04 公元 12:08 下午
"EEE, d MMM yyyy HH:mm:ss Z" 周三, 7 月 2001 12:08:56 -0700
"yyMMddHHmmssZ" 010704120856-0700
"yyyy-MM-dd'T'HH:mm:ss.SSSZ" 2001-07-04T12:08:56.235-0700
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX" 2001-07-04T12:08:56.235-07:00
"YYYY-'W'ww-u" 2001-W27-3

同步

日期格式不是同步的。建议为每个线程创建单独的格式实例。如果多个线程同时访问一个格式,必须在外部进行同步。

API注释:
考虑使用DateTimeFormatter作为不可变且线程安全的替代方案。
自版本:
1.1
参见:
  • Constructor Details

    • SimpleDateFormat

      public SimpleDateFormat()
      使用默认模式和默认FORMAT区域设置的日期格式符号构造SimpleDateFormat注意:此构造函数可能不支持所有区域设置。要获得完整覆盖范围,请使用DateFormat类中的工厂方法。
    • SimpleDateFormat

      public SimpleDateFormat(String pattern)
      使用给定模式和默认FORMAT区域设置的日期格式符号构造SimpleDateFormat注意:此构造函数可能不支持所有区域设置。要获得完整覆盖范围,请使用DateFormat类中的工厂方法。

      这相当于调用SimpleDateFormat(pattern, Locale.getDefault(Locale.Category.FORMAT))

      参数:
      pattern - 描述日期和时间格式的模式
      抛出:
      NullPointerException - 如果给定的模式为null
      IllegalArgumentException - 如果给定的模式无效
      参见:
    • SimpleDateFormat

      public SimpleDateFormat(String pattern, Locale locale)
      使用给定模式和给定区域设置的默认日期格式符号构造SimpleDateFormat注意:此构造函数可能不支持所有区域设置。要获得完整覆盖范围,请使用DateFormat类中的工厂方法。
      参数:
      pattern - 描述日期和时间格式的模式
      locale - 应使用其日期格式符号的区域设置
      抛出:
      NullPointerException - 如果给定的模式或区域设置为null
      IllegalArgumentException - 如果给定的模式无效
    • SimpleDateFormat

      public SimpleDateFormat(String pattern, DateFormatSymbols formatSymbols)
      使用给定模式和日期格式符号构造SimpleDateFormat
      参数:
      pattern - 描述日期和时间格式的模式
      formatSymbols - 用于格式化的日期格式符号
      抛出:
      NullPointerException - 如果给定的模式或formatSymbols为null
      IllegalArgumentException - 如果给定的模式无效
  • Method Details

    • set2DigitYearStart

      public void set2DigitYearStart(Date startDate)
      设置将被解释为开始日期的100年周期,其中2位数年份将被解释为属于用户指定的日期。
      参数:
      startDate - 在解析过程中,两位数年份将放置在startDatestartDate + 100年的范围内。
      抛出:
      NullPointerException - 如果startDatenull
      自版本:
      1.2
      参见:
    • get2DigitYearStart

      public Date get2DigitYearStart()
      返回100年周期的开始日期,其中两位数年份被解释为属于其中的日期。
      返回:
      解析为两位数年份的100年周期的开始日期
      自版本:
      1.2
      参见:
    • format

      public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos)
      将给定的Date格式化为日期/时间字符串并将结果附加到给定的StringBuffer
      指定者:
      format 在类 DateFormat
      参数:
      date - 要格式化为日期/时间字符串的日期时间值。
      toAppendTo - 要附加新日期/时间文本的位置。
      pos - 跟踪返回字符串中字段的位置。例如,给定日期/时间文本"1996.07.10 AD at 15:08:56 PDT",如果给定的fieldPositionDateFormat.YEAR_FIELD,则fieldPosition的开始索引和结束索引将分别设置为0和4。请注意,如果相同的日期/时间字段在模式中出现多次,则fieldPosition将设置为该日期/时间字段的第一次出现。例如,使用模式"h a z (zzzz)"和对齐字段DateFormat.TIMEZONE_FIELDDate格式化为日期/时间字符串"1 PM PDT (Pacific Daylight Time)"fieldPosition的开始索引和结束索引将分别设置为5和8,用于时区模式字符'z'的第一次出现。
      返回:
      格式化的日期/时间字符串。
      抛出:
      NullPointerException - 如果任何参数为null
    • formatToCharacterIterator

      public AttributedCharacterIterator formatToCharacterIterator(Object obj)
      格式化一个对象,生成一个AttributedCharacterIterator。您可以使用返回的AttributedCharacterIterator来构建生成的字符串,以及确定有关生成的字符串的信息。

      AttributedCharacterIterator的每个属性键将是DateFormat.Field类型,相应的属性值将与属性键相同。

      覆盖:
      formatToCharacterIterator 在类 Format
      参数:
      obj - 要格式化的对象
      返回:
      描述格式化值的AttributedCharacterIterator。
      抛出:
      NullPointerException - 如果obj为null。
      IllegalArgumentException - 如果Format无法格式化给定对象,或者如果Format的模式字符串无效。
      自版本:
      1.4
    • parse

      public Date parse(String text, ParsePosition pos)
      解析字符串以生成Date

      该方法尝试解析从pos指定的索引开始的文本。如果解析成功,则更新pos的索引为最后一个使用的字符之后的索引(解析不一定使用直到字符串末尾的所有字符),并返回解析的日期。更新后的pos可以用于指示下一次调用此方法的起始点。如果发生错误,则不更改pos的索引,将pos的错误索引设置为发生错误的字符的索引,并返回null。

      此解析操作使用calendar生成Date。在解析之前,将清除calendar的所有日期时间字段,并对任何缺少的日期时间信息使用calendar的日期时间字段的默认值。例如,如果从解析操作中未提供年份值,则使用GregorianCalendar的1970年作为解析的Date的年份值。可能会覆盖TimeZone值,具体取决于给定的模式和text中的时区值。任何之前通过调用setTimeZone设置的TimeZone值可能需要在后续操作中恢复。

      指定者:
      parse 在类中 DateFormat
      参数:
      text - 应解析其中一部分的String
      pos - 一个带有索引和错误索引信息的ParsePosition对象,如上所述。
      返回:
      从字符串解析的Date。如果出现错误,则返回null。
      抛出:
      NullPointerException - 如果textpos为null。
    • toPattern

      public String toPattern()
      返回描述此日期格式的模式字符串。
      返回:
      描述此日期格式的模式字符串。
    • toLocalizedPattern

      public String toLocalizedPattern()
      返回描述此日期格式的本地化模式字符串。
      返回:
      描述此日期格式的本地化模式字符串。
    • applyPattern

      public void applyPattern(String pattern)
      将给定的模式字符串应用于此日期格式。
      参数:
      pattern - 此日期格式的新日期和时间模式
      抛出:
      NullPointerException - 如果给定的模式为null
      IllegalArgumentException - 如果给定的模式无效
    • applyLocalizedPattern

      public void applyLocalizedPattern(String pattern)
      将给定的本地化模式字符串应用于此日期格式。
      参数:
      pattern - 要映射到此格式的新日期和时间格式模式的字符串
      抛出:
      NullPointerException - 如果给定的模式为null
      IllegalArgumentException - 如果给定的模式无效
    • getDateFormatSymbols

      public DateFormatSymbols getDateFormatSymbols()
      获取此日期格式的日期和时间格式符号的副本。
      返回:
      此日期格式的日期和时间格式符号
      参见:
    • setDateFormatSymbols

      public void setDateFormatSymbols(DateFormatSymbols newFormatSymbols)
      设置此日期格式的日期和时间格式符号。
      参数:
      newFormatSymbols - 新的日期和时间格式符号
      抛出:
      NullPointerException - 如果给定的newFormatSymbols为null
      参见:
    • clone

      public Object clone()
      创建此SimpleDateFormat的副本。这也会克隆格式的日期格式符号。
      覆盖:
      clone 在类中 DateFormat
      返回:
      SimpleDateFormat的克隆
      参见:
    • hashCode

      public int hashCode()
      返回此SimpleDateFormat对象的哈希码值。
      覆盖:
      hashCode 在类中 DateFormat
      返回:
      SimpleDateFormat对象的哈希码值。
      参见:
    • equals

      public boolean equals(Object obj)
      将给定对象与此SimpleDateFormat进行比较以检查是否相等。
      覆盖:
      equals 在类中 DateFormat
      参数:
      obj - 要比较的参考对象。
      返回:
      如果给定对象等于此SimpleDateFormat,则返回true
      参见: