Java.Text.SimpleDateFormat Class
Formats and parses dates in a locale-sensitive manner.

See Also: SimpleDateFormat Members

Syntax

[Android.Runtime.Register("java/text/SimpleDateFormat", DoNotGenerateAcw=true)]
public class SimpleDateFormat : DateFormat

Remarks

Formats and parses dates in a locale-sensitive manner. Formatting turns a Java.Util.Date into a Java.Lang.String, and parsing turns a String into a Date.

Time Pattern Syntax

You can supply a Unicode pattern describing what strings are produced/accepted, but almost all callers should use DateFormat.DateInstance, DateFormat.DateTimeInstance, or DateFormat.TimeInstance to get a ready-made instance suitable for the user's locale. In cases where the system does not provide a suitable pattern, see Android.Text.Format.DateFormat.GetBestDateTimePattern(Java.Util.Locale, System.String) which lets you specify the elements you'd like in a pattern and get back a pattern suitable for any given locale.

The main reason you'd create an instance this class directly is because you need to format/parse a specific machine-readable format, in which case you almost certainly want to explicitly ask for Java.Util.Locale.Us to ensure that you get ASCII digits (rather than, say, Arabic digits). (See "Be wary of the default locale".) The most useful non-localized pattern is "yyyy-MM-dd HH:mm:ss.SSSZ", which corresponds to the ISO 8601 international standard date format.

To specify the time format, use a time pattern string. In this string, any character from 'A' to 'Z' or 'a' to 'z' is treated specially. All other characters are passed through verbatim. The interpretation of each of the ASCII letters is given in the table below. ASCII letters not appearing in the table are reserved for future use, and it is an error to attempt to use them.

The number of consecutive copies (the "count") of a pattern character further influences the format, as shown in the table. For fields of kind "number", the count is the minimum number of digits; shorter values are zero-padded to the given width and longer values overflow it.

SymbolMeaningKindExample
Dday in year(Number)189
Eday of week(Text)E/EE/EEE:Tue, EEEE:Tuesday, EEEEE:T
Fday of week in month(Number)2 (2nd Wed in July)
Gera designator(Text)AD
Hhour in day (0-23)(Number)0
Khour in am/pm (0-11)(Number)0
Lstand-alone month(Text)L:1 LL:01 LLL:Jan LLLL:January LLLLL:J
Mmonth in year(Text)M:1 MM:01 MMM:Jan MMMM:January MMMMM:J
Sfractional seconds(Number)978
Wweek in month(Number)2
Ztime zone (RFC 822)(Time Zone)Z/ZZ/ZZZ:-0800 ZZZZ:GMT-08:00 ZZZZZ:-08:00
aam/pm marker(Text)PM
cstand-alone day of week(Text)c/cc/ccc:Tue, cccc:Tuesday, ccccc:T
dday in month(Number)10
hhour in am/pm (1-12)(Number)12
khour in day (1-24)(Number)24
mminute in hour(Number)30
ssecond in minute(Number)55
wweek in year(Number)27
yyear(Number)yy:10 y/yyy/yyyy:2010
ztime zone(Time Zone)z/zz/zzz:PST zzzz:Pacific Standard Time
'escape for text(Delimiter)'Date=':Date=
''single quote(Literal)'o''clock':o'clock

Fractional seconds are handled specially: they're zero-padded on the right.

The two pattern characters L and c are ICU-compatible extensions, not available in the RI or in Android before Android 2.3 (Gingerbread, API level 9). These extensions are necessary for correct localization in languages such as Russian that make a grammatical distinction between, say, the word "June" in the sentence "June" and in the sentence "June 10th"; the former is the stand-alone form, the latter the regular form (because the usual case is to format a complete date). The relationship between E and c is equivalent, but for weekday names.

Five-count patterns (such as "MMMMM") used for the shortest non-numeric representation of a field were introduced in Android 4.3 (Jelly Bean MR2, API level 18).

When two numeric fields are directly adjacent with no intervening delimiter characters, they constitute a run of adjacent numeric fields. Such runs are parsed specially. For example, the format "HHmmss" parses the input text "123456" to 12:34:56, parses the input text "12345" to 1:23:45, and fails to parse "1234". In other words, the leftmost field of the run is flexible, while the others keep a fixed width. If the parse fails anywhere in the run, then the leftmost field is shortened by one character, and the entire run is parsed again. This is repeated until either the parse succeeds or the leftmost field is one character in length. If the parse still fails at that point, the parse of the run fails.

See SimpleDateFormat.Set2DigitYearStart(Java.Util.Date) for more about handling two-digit years.

Sample Code

If you're formatting for human use, you should use an instance returned from Java.Text.DateFormat as described above. This code:

java Example

 DateFormat[] formats = new DateFormat[] {
   DateFormat.getDateInstance(),
   DateFormat.getDateTimeInstance(),
   DateFormat.getTimeInstance(),
 };
 for (DateFormat df : formats) {
   System.out.println(df.format(new Date(0)));
 }
 

Produces this output when run on an en_US device in the America/Los_Angeles time zone:

java Example

 Dec 31, 1969
 Dec 31, 1969 4:00:00 PM
 4:00:00 PM
 
And will produce similarly appropriate localized human-readable output on any user's system.

If you're formatting for machine use, consider this code:

java Example

 String[] formats = new String[] {
   "yyyy-MM-dd",
   "yyyy-MM-dd HH:mm",
   "yyyy-MM-dd HH:mmZ",
   "yyyy-MM-dd HH:mm:ss.SSSZ",
   "yyyy-MM-dd'T'HH:mm:ss.SSSZ",
 };
 for (String format : formats) {
   SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);
   System.out.format("%30s %s\n", format, sdf.format(new Date(0)));
   sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
   System.out.format("%30s %s\n", format, sdf.format(new Date(0)));
 }
 

Which produces this output when run in the America/Los_Angeles time zone:

java Example

                     yyyy-MM-dd 1969-12-31
                     yyyy-MM-dd 1970-01-01
               yyyy-MM-dd HH:mm 1969-12-31 16:00
               yyyy-MM-dd HH:mm 1970-01-01 00:00
              yyyy-MM-dd HH:mmZ 1969-12-31 16:00-0800
              yyyy-MM-dd HH:mmZ 1970-01-01 00:00+0000
       yyyy-MM-dd HH:mm:ss.SSSZ 1969-12-31 16:00:00.000-0800
       yyyy-MM-dd HH:mm:ss.SSSZ 1970-01-01 00:00:00.000+0000
     yyyy-MM-dd'T'HH:mm:ss.SSSZ 1969-12-31T16:00:00.000-0800
     yyyy-MM-dd'T'HH:mm:ss.SSSZ 1970-01-01T00:00:00.000+0000
 

As this example shows, each SimpleDateFormat instance has a Java.Util.TimeZone. This is because it's called upon to format instances of Date, which represents an absolute time in UTC. That is, Date does not carry time zone information. By default, SimpleDateFormat will use the system's default time zone. This is appropriate for human-readable output (for which, see the previous sample instead), but generally inappropriate for machine-readable output, where ambiguity is a problem. Note that in this example, the output that included a time but no time zone cannot be parsed back into the original Date. For this reason it is almost always necessary and desirable to include the timezone in the output. It may also be desirable to set the formatter's time zone to UTC (to ease comparison, or to make logs more readable, for example). It is often best to avoid formatting completely when writing dates/times in machine-readable form. Simply sending the "Unix time" as a long or as the string corresponding to the long is cheaper and unambiguous, and can be formatted any way the recipient deems appropriate.

Synchronization

SimpleDateFormat is not thread-safe. Users should create a separate instance for each thread.

See Also

[Android Documentation]

Requirements

Namespace: Java.Text
Assembly: Mono.Android (in Mono.Android.dll)
Assembly Versions: 0.0.0.0
Since: Added in API level 1