A DESCRIPTION OF THE REQUEST :
SimpleDateFormat accepts:
z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
Z Time zone RFC 822 time zone -0800
From ISO 8601:2004 section 4.2.5.1, the SimpleDateFormat pattern Z matches the basic format (without delimiters, as in 20010704T120856.235-0700, which is produced by the SDF pattern "yyyyMMdd'T'HHmmss.SSSZ").
However, the pattern Z does not match the extended format (±hh:mm), hence
"yyyy-MM-dd'T'HH:mm:ss.SSSZ" does not produce an ISO formatted datetime representation, because it yields 2001-07-04T12:08:56.235-0700
instead of 2001-07-04T12:08:56.235-07:00.
JUSTIFICATION :
ISO 8601 Extended format should be supported out-of-the box.
It is unnecessarily non-trivial to produce a correct ISO 8601 datetime representation in Extended format.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A new pattern (lets say T) such that formatting a date with the "yyyy-MM-dd'T'HH:mm:ss.SSST" patter produces a string like "2001-07-04T12:08:56.235-07:00"
ACTUAL -
There is no such pattern. Formatting a date with the "yyyy-MM-dd'T'HH:mm:ss.SSSZ" pattern produces a string like "2001-07-04T12:08:56.235-0700" which is not ISO 8601 compliant
CUSTOMER SUBMITTED WORKAROUND :
/*this example defines an utility class which uses SimpleDateFormat to format/parse datetime representations in ISO 8601 extended format.
The idea behind the implementation is that such representations have fixed length (when fraction of a second is not present, and assuming a year between 0001 and 9999), thus we can use simple string operations in order to fix the result (after SDF.parse) or preparing the result so that SDF.format will accept it */
public final class IsoDateFormat {
private IsoDateFormat() {}
private final static DateFormat dateFormat;
static {
try {dateFormat=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");}
catch (RuntimeException e) {throw e;}
catch (Exception e) {throw (Error) new InstantiationError().initCause(e);}
}
public static synchronized String format(long date) {
String s = dateFormat.format(date);
if (s.length()>22) {
char c = s.charAt(19);
if (c=='-'||c=='+') s=s.substring(0,22)+":"+s.substring(22,24);
}
return s;
}
public static synchronized String format(Date date) {return date==null?"null":dateFormat.format(date);}
/**Parses text from the beginning of the given string to produce a date.
* Parsing may or may not be {@link DateFormat#setLenient(boolean) lenient}
*
* @param string the String representation of a date.
* @param lenient whether date/time parsing is to be lenient.
* @return a {@link Date}.
* #see @link DateFormat#parse(String)
*/
public static synchronized Date parse(String string,boolean lenient) throws ParseException {
dateFormat.setLenient(lenient);
string=string.trim();
if (string.length()>22) {
char c = string.charAt(19);
if (c=='-'||c=='+') string=string.substring(0,22)+string.substring(23);
}
return dateFormat.parse(string);
}
}
SimpleDateFormat accepts:
z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
Z Time zone RFC 822 time zone -0800
From ISO 8601:2004 section 4.2.5.1, the SimpleDateFormat pattern Z matches the basic format (without delimiters, as in 20010704T120856.235-0700, which is produced by the SDF pattern "yyyyMMdd'T'HHmmss.SSSZ").
However, the pattern Z does not match the extended format (±hh:mm), hence
"yyyy-MM-dd'T'HH:mm:ss.SSSZ" does not produce an ISO formatted datetime representation, because it yields 2001-07-04T12:08:56.235-0700
instead of 2001-07-04T12:08:56.235-07:00.
JUSTIFICATION :
ISO 8601 Extended format should be supported out-of-the box.
It is unnecessarily non-trivial to produce a correct ISO 8601 datetime representation in Extended format.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
A new pattern (lets say T) such that formatting a date with the "yyyy-MM-dd'T'HH:mm:ss.SSST" patter produces a string like "2001-07-04T12:08:56.235-07:00"
ACTUAL -
There is no such pattern. Formatting a date with the "yyyy-MM-dd'T'HH:mm:ss.SSSZ" pattern produces a string like "2001-07-04T12:08:56.235-0700" which is not ISO 8601 compliant
CUSTOMER SUBMITTED WORKAROUND :
/*this example defines an utility class which uses SimpleDateFormat to format/parse datetime representations in ISO 8601 extended format.
The idea behind the implementation is that such representations have fixed length (when fraction of a second is not present, and assuming a year between 0001 and 9999), thus we can use simple string operations in order to fix the result (after SDF.parse) or preparing the result so that SDF.format will accept it */
public final class IsoDateFormat {
private IsoDateFormat() {}
private final static DateFormat dateFormat;
static {
try {dateFormat=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");}
catch (RuntimeException e) {throw e;}
catch (Exception e) {throw (Error) new InstantiationError().initCause(e);}
}
public static synchronized String format(long date) {
String s = dateFormat.format(date);
if (s.length()>22) {
char c = s.charAt(19);
if (c=='-'||c=='+') s=s.substring(0,22)+":"+s.substring(22,24);
}
return s;
}
public static synchronized String format(Date date) {return date==null?"null":dateFormat.format(date);}
/**Parses text from the beginning of the given string to produce a date.
* Parsing may or may not be {@link DateFormat#setLenient(boolean) lenient}
*
* @param string the String representation of a date.
* @param lenient whether date/time parsing is to be lenient.
* @return a {@link Date}.
* #see @link DateFormat#parse(String)
*/
public static synchronized Date parse(String string,boolean lenient) throws ParseException {
dateFormat.setLenient(lenient);
string=string.trim();
if (string.length()>22) {
char c = string.charAt(19);
if (c=='-'||c=='+') string=string.substring(0,22)+string.substring(23);
}
return dateFormat.parse(string);
}
}
- duplicates
-
JDK-4919632 RFE: SimpleDateFormat should fully support ISO8601 standard for timezone
-
- Closed
-