Merge "Remove invalid X509Certificate2Test tests"
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index eafa40d..98de1f2 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -167,19 +167,19 @@
#
#
# Run with:
-# m libcore-docs
+# mm -j32 libcore-docs
#
# Main output:
-# out/target/common/docs/libcore/reference/packages.html
+# ../out/target/common/docs/libcore/reference/packages.html
#
# All text for proofreading (or running tools over):
-# out/target/common/docs/libcore-proofread.txt
+# ../out/target/common/docs/libcore-proofread.txt
#
# TODO list of missing javadoc, etc:
-# out/target/common/docs/libcore-docs-todo.html
+# ../out/target/common/docs/libcore-docs-todo.html
#
# Rerun:
-# rm -rf out/target/common/docs/libcore-timestamp && m libcore-docs
+# rm -rf ../out/target/common/docs/libcore-timestamp && mm -j32 libcore-docs
#
include $(CLEAR_VARS)
diff --git a/include/ScopedPrimitiveArray.h b/include/ScopedPrimitiveArray.h
index 079e98c..f6626b2 100644
--- a/include/ScopedPrimitiveArray.h
+++ b/include/ScopedPrimitiveArray.h
@@ -40,6 +40,7 @@
} \
} \
const PRIMITIVE_TYPE* get() const { return mRawArray; } \
+ PRIMITIVE_TYPE ## Array getJavaArray() const { return mJavaArray; } \
const PRIMITIVE_TYPE& operator[](size_t n) const { return mRawArray[n]; } \
size_t size() const { return mEnv->GetArrayLength(mJavaArray); } \
private: \
@@ -82,6 +83,7 @@
} \
} \
const PRIMITIVE_TYPE* get() const { return mRawArray; } \
+ PRIMITIVE_TYPE ## Array getJavaArray() const { return mJavaArray; } \
const PRIMITIVE_TYPE& operator[](size_t n) const { return mRawArray[n]; } \
PRIMITIVE_TYPE* get() { return mRawArray; } \
PRIMITIVE_TYPE& operator[](size_t n) { return mRawArray[n]; } \
diff --git a/luni/src/main/java/java/text/DateFormatSymbols.java b/luni/src/main/java/java/text/DateFormatSymbols.java
index 6049fd2..d14f309c 100644
--- a/luni/src/main/java/java/text/DateFormatSymbols.java
+++ b/luni/src/main/java/java/text/DateFormatSymbols.java
@@ -58,11 +58,8 @@
String[] ampms, eras, months, shortMonths, shortWeekdays, weekdays;
- // These are used to implement ICU/Android extensions.
- transient String[] longStandAloneMonths;
- transient String[] shortStandAloneMonths;
- transient String[] longStandAloneWeekdays;
- transient String[] shortStandAloneWeekdays;
+ // This is used to implement parts of Unicode UTS #35 not historically supported.
+ transient LocaleData localeData;
// Localized display names.
String[][] zoneStrings;
@@ -107,19 +104,14 @@
public DateFormatSymbols(Locale locale) {
this.locale = locale;
this.localPatternChars = SimpleDateFormat.PATTERN_CHARS;
- LocaleData localeData = LocaleData.get(locale);
+
+ this.localeData = LocaleData.get(locale);
this.ampms = localeData.amPm;
this.eras = localeData.eras;
this.months = localeData.longMonthNames;
this.shortMonths = localeData.shortMonthNames;
this.weekdays = localeData.longWeekdayNames;
this.shortWeekdays = localeData.shortWeekdayNames;
-
- // ICU/Android extensions.
- this.longStandAloneMonths = localeData.longStandAloneMonthNames;
- this.shortStandAloneMonths = localeData.shortStandAloneMonthNames;
- this.longStandAloneWeekdays = localeData.longStandAloneWeekdayNames;
- this.shortStandAloneWeekdays = localeData.shortStandAloneWeekdayNames;
}
/**
@@ -160,12 +152,7 @@
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
-
- // The RI doesn't have these fields, so we'll have to fall back and do the best we can.
- longStandAloneMonths = months;
- shortStandAloneMonths = shortMonths;
- longStandAloneWeekdays = weekdays;
- shortStandAloneWeekdays = shortWeekdays;
+ this.localeData = LocaleData.get(locale);
}
private void writeObject(ObjectOutputStream oos) throws IOException {
diff --git a/luni/src/main/java/java/text/SimpleDateFormat.java b/luni/src/main/java/java/text/SimpleDateFormat.java
index e8aea4a..6d225c6 100644
--- a/luni/src/main/java/java/text/SimpleDateFormat.java
+++ b/luni/src/main/java/java/text/SimpleDateFormat.java
@@ -33,12 +33,12 @@
import libcore.icu.TimeZones;
/**
- * A concrete class for formatting and parsing dates in a locale-sensitive
- * manner. Formatting turns a {@link Date} into a {@link String}, and parsing turns a
- * {@code String} into a {@code Date}.
+ * Formats and parses dates in a locale-sensitive manner. Formatting turns a {@link Date} into
+ * a {@link String}, and parsing turns a {@code String} into a {@code Date}.
*
* <h4>Time Pattern Syntax</h4>
- * <p>You can supply a pattern describing what strings are produced/accepted, but almost all
+ * <p>You can supply a Unicode <a href="http://www.unicode.org/reports/tr35/#Date_Format_Patterns">UTS #35</a>
+ * pattern describing what strings are produced/accepted, but almost all
* callers should use {@link DateFormat#getDateInstance}, {@link DateFormat#getDateTimeInstance},
* or {@link DateFormat#getTimeInstance} to get a ready-made instance suitable for the user's
* locale.
@@ -57,62 +57,46 @@
* 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.
*
+ * <p>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.
+ *
* <p><table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
- * <td><B>Symbol</B></td> <td><B>Meaning</B></td> <td><B>Presentation</B></td> <td><B>Example</B></td> </tr>
+ * <td><B>Symbol</B></td> <td><B>Meaning</B></td> <td><B>Kind</B></td> <td><B>Example</B></td> </tr>
* <tr> <td>{@code D}</td> <td>day in year</td> <td>(Number)</td> <td>189</td> </tr>
- * <tr> <td>{@code E}</td> <td>day of week</td> <td>(Text)</td> <td>Tuesday</td> </tr>
+ * <tr> <td>{@code E}</td> <td>day of week</td> <td>(Text)</td> <td>{@code E}/{@code EE}/{@code EEE}:Tue, {@code EEEE}:Tuesday, {@code EEEEE}:T</td> </tr>
* <tr> <td>{@code F}</td> <td>day of week in month</td> <td>(Number)</td> <td>2 <i>(2nd Wed in July)</i></td> </tr>
* <tr> <td>{@code G}</td> <td>era designator</td> <td>(Text)</td> <td>AD</td> </tr>
* <tr> <td>{@code H}</td> <td>hour in day (0-23)</td> <td>(Number)</td> <td>0</td> </tr>
* <tr> <td>{@code K}</td> <td>hour in am/pm (0-11)</td> <td>(Number)</td> <td>0</td> </tr>
- * <tr> <td>{@code L}</td> <td>stand-alone month</td> <td>(Text/Number)</td> <td>July / 07</td> </tr>
- * <tr> <td>{@code M}</td> <td>month in year</td> <td>(Text/Number)</td> <td>July / 07</td> </tr>
+ * <tr> <td>{@code L}</td> <td>stand-alone month</td> <td>(Text)</td> <td>{@code L}:1 {@code LL}:01 {@code LLL}:Jan {@code LLLL}:January {@code LLLLL}:J</td> </tr>
+ * <tr> <td>{@code M}</td> <td>month in year</td> <td>(Text)</td> <td>{@code M}:1 {@code MM}:01 {@code MMM}:Jan {@code MMMM}:January {@code MMMMM}:J</td> </tr>
* <tr> <td>{@code S}</td> <td>fractional seconds</td> <td>(Number)</td> <td>978</td> </tr>
* <tr> <td>{@code W}</td> <td>week in month</td> <td>(Number)</td> <td>2</td> </tr>
- * <tr> <td>{@code Z}</td> <td>time zone (RFC 822)</td> <td>(Timezone)</td> <td>-0800</td> </tr>
+ * <tr> <td>{@code Z}</td> <td>time zone (RFC 822)</td> <td>(Time Zone)</td> <td>{@code Z}/{@code ZZ}/{@code ZZZ}:-0800 {@code ZZZZ}:GMT-08:00 {@code ZZZZZ}:-08:00</td> </tr>
* <tr> <td>{@code a}</td> <td>am/pm marker</td> <td>(Text)</td> <td>PM</td> </tr>
- * <tr> <td>{@code c}</td> <td>stand-alone day of week</td> <td>(Text/Number)</td> <td>Tuesday / 2</td> </tr>
+ * <tr> <td>{@code c}</td> <td>stand-alone day of week</td> <td>(Text)</td> <td>{@code c}/{@code cc}/{@code ccc}:Tue, {@code cccc}:Tuesday, {@code ccccc}:T</td> </tr>
* <tr> <td>{@code d}</td> <td>day in month</td> <td>(Number)</td> <td>10</td> </tr>
* <tr> <td>{@code h}</td> <td>hour in am/pm (1-12)</td> <td>(Number)</td> <td>12</td> </tr>
* <tr> <td>{@code k}</td> <td>hour in day (1-24)</td> <td>(Number)</td> <td>24</td> </tr>
* <tr> <td>{@code m}</td> <td>minute in hour</td> <td>(Number)</td> <td>30</td> </tr>
* <tr> <td>{@code s}</td> <td>second in minute</td> <td>(Number)</td> <td>55</td> </tr>
* <tr> <td>{@code w}</td> <td>week in year</td> <td>(Number)</td> <td>27</td> </tr>
- * <tr> <td>{@code y}</td> <td>year</td> <td>(Number)</td> <td>2010</td> </tr>
- * <tr> <td>{@code z}</td> <td>time zone</td> <td>(Timezone)</td> <td>Pacific Standard Time</td> </tr>
- * <tr> <td>{@code '}</td> <td>escape for text</td> <td>(Delimiter)</td> <td>'Date='</td> </tr>
- * <tr> <td>{@code ''}</td> <td>single quote</td> <td>(Literal)</td> <td>'o''clock'</td> </tr>
+ * <tr> <td>{@code y}</td> <td>year</td> <td>(Number)</td> <td>{@code yy}:10 {@code y}/{@code yyy}/{@code yyyy}:2010</td> </tr>
+ * <tr> <td>{@code z}</td> <td>time zone</td> <td>(Time Zone)</td> <td>{@code z}/{@code zz}/{@code zzz}:PST {@code ZZZZ}:Pacific Standard Time</td> </tr>
+ * <tr> <td>{@code '}</td> <td>escape for text</td> <td>(Delimiter)</td> <td>{@code 'Date='}:Date=</td> </tr>
+ * <tr> <td>{@code ''}</td> <td>single quote</td> <td>(Literal)</td> <td>{@code 'o''clock'}:o'clock</td> </tr>
* </table>
*
- * <p>The number of consecutive copies (the "count") of a pattern character further influences
- * the format.
- * <ul>
- * <li><b>Text</b> if the count is 4 or more, use the full form; otherwise use a short or
- * abbreviated form if one exists. So {@code zzzz} might give {@code Pacific Standard Time}
- * whereas {@code z} might give {@code PST}. Note that the count does <i>not</i> specify the
- * exact width of the field.
- *
- * <li><b>Number</b> the count is the minimum number of digits. Shorter values are
- * zero-padded to this width, longer values overflow this width.
- *
- * <p>Years are handled specially: {@code yy} truncates to the last 2 digits, but any
- * other number of consecutive {@code y}s does not truncate. So where {@code yyyy} or
- * {@code y} might give {@code 2010}, {@code yy} would give {@code 10}.
- *
- * <p>Fractional seconds are also handled specially: they're zero-padded on the
- * <i>right</i>.
- *
- * <li><b>Text/Number</b>: if the count is 3 or more, use text; otherwise use a number.
- * So {@code MM} might give {@code 07} while {@code MMM} gives {@code July}.
- * </ul>
+ * <p>Fractional seconds are handled specially: they're zero-padded on the <i>right</i>.
*
* <p>The two pattern characters {@code L} and {@code 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 distinguish between, say, "June" and "June 2010".
*
- * <p>When numeric fields are adjacent directly, with no intervening delimiter
+ * <p>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
@@ -529,8 +513,7 @@
* if the object cannot be formatted by this Format.
*/
private StringBuffer formatImpl(Date date, StringBuffer buffer,
- FieldPosition field, List<FieldPosition> fields) {
-
+ FieldPosition field, List<FieldPosition> fields) {
boolean quote = false;
int next, last = -1, count = 0;
calendar.setTime(date);
@@ -610,24 +593,24 @@
appendNumber(buffer, count, year);
}
break;
- case STAND_ALONE_MONTH_FIELD: // L
+ case STAND_ALONE_MONTH_FIELD: // 'L'
dateFormatField = Field.MONTH;
- appendMonth(buffer, count, formatData.longStandAloneMonths, formatData.shortStandAloneMonths);
+ appendMonth(buffer, count, true);
break;
- case MONTH_FIELD: // M
+ case MONTH_FIELD: // 'M'
dateFormatField = Field.MONTH;
- appendMonth(buffer, count, formatData.months, formatData.shortMonths);
+ appendMonth(buffer, count, false);
break;
case DATE_FIELD:
dateFormatField = Field.DAY_OF_MONTH;
field = Calendar.DATE;
break;
- case HOUR_OF_DAY1_FIELD: // k
+ case HOUR_OF_DAY1_FIELD: // 'k'
dateFormatField = Field.HOUR_OF_DAY1;
int hour = calendar.get(Calendar.HOUR_OF_DAY);
appendNumber(buffer, count, hour == 0 ? 24 : hour);
break;
- case HOUR_OF_DAY0_FIELD: // H
+ case HOUR_OF_DAY0_FIELD: // 'H'
dateFormatField = Field.HOUR_OF_DAY0;
field = Calendar.HOUR_OF_DAY;
break;
@@ -646,11 +629,11 @@
break;
case STAND_ALONE_DAY_OF_WEEK_FIELD:
dateFormatField = Field.DAY_OF_WEEK;
- appendDayOfWeek(buffer, count, formatData.longStandAloneWeekdays, formatData.shortStandAloneWeekdays);
+ appendDayOfWeek(buffer, count, true);
break;
case DAY_OF_WEEK_FIELD:
dateFormatField = Field.DAY_OF_WEEK;
- appendDayOfWeek(buffer, count, formatData.weekdays, formatData.shortWeekdays);
+ appendDayOfWeek(buffer, count, false);
break;
case DAY_OF_YEAR_FIELD:
dateFormatField = Field.DAY_OF_YEAR;
@@ -672,22 +655,22 @@
dateFormatField = Field.AM_PM;
buffer.append(formatData.ampms[calendar.get(Calendar.AM_PM)]);
break;
- case HOUR1_FIELD: // h
+ case HOUR1_FIELD: // 'h'
dateFormatField = Field.HOUR1;
hour = calendar.get(Calendar.HOUR);
appendNumber(buffer, count, hour == 0 ? 12 : hour);
break;
- case HOUR0_FIELD: // K
+ case HOUR0_FIELD: // 'K'
dateFormatField = Field.HOUR0;
field = Calendar.HOUR;
break;
- case TIMEZONE_FIELD: // z
+ case TIMEZONE_FIELD: // 'z'
dateFormatField = Field.TIME_ZONE;
appendTimeZone(buffer, count, true);
break;
- case RFC_822_TIMEZONE_FIELD: // Z
+ case RFC_822_TIMEZONE_FIELD: // 'Z'
dateFormatField = Field.TIME_ZONE;
- appendNumericTimeZone(buffer, false);
+ appendNumericTimeZone(buffer, count, false);
break;
}
if (field != -1) {
@@ -710,22 +693,38 @@
}
}
- private void appendDayOfWeek(StringBuffer buffer, int count, String[] longs, String[] shorts) {
- boolean isLong = (count > 3);
- String[] days = isLong ? longs : shorts;
- buffer.append(days[calendar.get(Calendar.DAY_OF_WEEK)]);
+ // See http://www.unicode.org/reports/tr35/#Date_Format_Patterns for the different counts.
+ private void appendDayOfWeek(StringBuffer buffer, int count, boolean standAlone) {
+ String[] days;
+ LocaleData ld = formatData.localeData;
+ if (count == 4) {
+ days = standAlone ? ld.longStandAloneWeekdayNames : formatData.weekdays;
+ } else if (count == 5) {
+ days = standAlone ? ld.tinyStandAloneWeekdayNames : formatData.localeData.tinyWeekdayNames;
+ } else {
+ days = standAlone ? ld.shortStandAloneWeekdayNames : formatData.shortWeekdays;
+ }
+ buffer.append(days[calendar.get(Calendar.DAY_OF_WEEK)]);
}
- private void appendMonth(StringBuffer buffer, int count, String[] longs, String[] shorts) {
- int month = calendar.get(Calendar.MONTH);
- if (count <= 2) {
- appendNumber(buffer, count, month + 1);
- return;
- }
+ // See http://www.unicode.org/reports/tr35/#Date_Format_Patterns for the different counts.
+ private void appendMonth(StringBuffer buffer, int count, boolean standAlone) {
+ int month = calendar.get(Calendar.MONTH);
+ if (count <= 2) {
+ appendNumber(buffer, count, month + 1);
+ return;
+ }
- boolean isLong = (count > 3);
- String[] months = isLong ? longs : shorts;
- buffer.append(months[month]);
+ String[] months;
+ LocaleData ld = formatData.localeData;
+ if (count == 4) {
+ months = standAlone ? ld.longStandAloneMonthNames : formatData.months;
+ } else if (count == 5) {
+ months = standAlone ? ld.tinyStandAloneMonthNames : ld.tinyMonthNames;
+ } else {
+ months = standAlone ? ld.shortStandAloneMonthNames : formatData.shortMonths;
+ }
+ buffer.append(months[month]);
}
/**
@@ -755,25 +754,24 @@
}
}
// We didn't find what we were looking for, so default to a numeric time zone.
- appendNumericTimeZone(buffer, generalTimeZone);
+ appendNumericTimeZone(buffer, count, generalTimeZone);
}
- /**
- * @param generalTimeZone "GMT-08:00" rather than "-0800".
- */
- private void appendNumericTimeZone(StringBuffer buffer, boolean generalTimeZone) {
+ // See http://www.unicode.org/reports/tr35/#Date_Format_Patterns for the different counts.
+ // @param generalTimeZone "GMT-08:00" rather than "-0800".
+ private void appendNumericTimeZone(StringBuffer buffer, int count, boolean generalTimeZone) {
int offset = calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
char sign = '+';
if (offset < 0) {
sign = '-';
offset = -offset;
}
- if (generalTimeZone) {
+ if (generalTimeZone || count == 4) {
buffer.append("GMT");
}
buffer.append(sign);
appendNumber(buffer, 2, offset / 3600000);
- if (generalTimeZone) {
+ if (generalTimeZone || count >= 4) {
buffer.append(':');
}
appendNumber(buffer, 2, (offset % 3600000) / 60000);
@@ -879,16 +877,14 @@
return position.getIndex();
}
break;
- case STAND_ALONE_MONTH_FIELD: // L
- return parseMonth(string, offset, count, absolute,
- formatData.longStandAloneMonths, formatData.shortStandAloneMonths);
- case MONTH_FIELD: // M
- return parseMonth(string, offset, count, absolute,
- formatData.months, formatData.shortMonths);
+ case STAND_ALONE_MONTH_FIELD: // 'L'
+ return parseMonth(string, offset, count, absolute, true);
+ case MONTH_FIELD: // 'M'
+ return parseMonth(string, offset, count, absolute, false);
case DATE_FIELD:
field = Calendar.DATE;
break;
- case HOUR_OF_DAY1_FIELD: // k
+ case HOUR_OF_DAY1_FIELD: // 'k'
ParsePosition position = new ParsePosition(offset);
Number result = parseNumber(absolute, string, position);
if (result == null) {
@@ -900,7 +896,7 @@
}
calendar.set(Calendar.HOUR_OF_DAY, hour);
return position.getIndex();
- case HOUR_OF_DAY0_FIELD: // H
+ case HOUR_OF_DAY0_FIELD: // 'H'
field = Calendar.HOUR_OF_DAY;
break;
case MINUTE_FIELD:
@@ -913,9 +909,9 @@
field = Calendar.MILLISECOND;
break;
case STAND_ALONE_DAY_OF_WEEK_FIELD:
- return parseDayOfWeek(string, offset, formatData.longStandAloneWeekdays, formatData.shortStandAloneWeekdays);
+ return parseDayOfWeek(string, offset, true);
case DAY_OF_WEEK_FIELD:
- return parseDayOfWeek(string, offset, formatData.weekdays, formatData.shortWeekdays);
+ return parseDayOfWeek(string, offset, false);
case DAY_OF_YEAR_FIELD:
field = Calendar.DAY_OF_YEAR;
break;
@@ -930,7 +926,7 @@
break;
case AM_PM_FIELD:
return parseText(string, offset, formatData.ampms, Calendar.AM_PM);
- case HOUR1_FIELD: // h
+ case HOUR1_FIELD: // 'h'
position = new ParsePosition(offset);
result = parseNumber(absolute, string, position);
if (result == null) {
@@ -942,12 +938,12 @@
}
calendar.set(Calendar.HOUR, hour);
return position.getIndex();
- case HOUR0_FIELD: // K
+ case HOUR0_FIELD: // 'K'
field = Calendar.HOUR;
break;
- case TIMEZONE_FIELD: // z
+ case TIMEZONE_FIELD: // 'z'
return parseTimeZone(string, offset);
- case RFC_822_TIMEZONE_FIELD: // Z
+ case RFC_822_TIMEZONE_FIELD: // 'Z'
return parseTimeZone(string, offset);
}
if (field != -1) {
@@ -956,23 +952,33 @@
return offset;
}
- private int parseDayOfWeek(String string, int offset, String[] longs, String[] shorts) {
- int index = parseText(string, offset, longs, Calendar.DAY_OF_WEEK);
- if (index < 0) {
- index = parseText(string, offset, shorts, Calendar.DAY_OF_WEEK);
- }
- return index;
+ private int parseDayOfWeek(String string, int offset, boolean standAlone) {
+ LocaleData ld = formatData.localeData;
+ int index = parseText(string, offset,
+ standAlone ? ld.longStandAloneWeekdayNames : formatData.weekdays,
+ Calendar.DAY_OF_WEEK);
+ if (index < 0) {
+ index = parseText(string, offset,
+ standAlone ? ld.shortStandAloneWeekdayNames : formatData.shortWeekdays,
+ Calendar.DAY_OF_WEEK);
+ }
+ return index;
}
- private int parseMonth(String string, int offset, int count, int absolute, String[] longs, String[] shorts) {
- if (count <= 2) {
- return parseNumber(absolute, string, offset, Calendar.MONTH, -1);
- }
- int index = parseText(string, offset, longs, Calendar.MONTH);
- if (index < 0) {
- index = parseText(string, offset, shorts, Calendar.MONTH);
- }
- return index;
+ private int parseMonth(String string, int offset, int count, int absolute, boolean standAlone) {
+ if (count <= 2) {
+ return parseNumber(absolute, string, offset, Calendar.MONTH, -1);
+ }
+ LocaleData ld = formatData.localeData;
+ int index = parseText(string, offset,
+ standAlone ? ld.longStandAloneMonthNames : formatData.months,
+ Calendar.MONTH);
+ if (index < 0) {
+ index = parseText(string, offset,
+ standAlone ? ld.shortStandAloneMonthNames : formatData.shortMonths,
+ Calendar.MONTH);
+ }
+ return index;
}
/**
diff --git a/luni/src/main/java/java/util/Formatter.java b/luni/src/main/java/java/util/Formatter.java
index 021da08..6ca8733 100644
--- a/luni/src/main/java/java/util/Formatter.java
+++ b/luni/src/main/java/java/util/Formatter.java
@@ -297,9 +297,9 @@
* </tr>
* </table>
* <p>
- * It's also possible to format dates and times with {@code Formatter}, though you should seriously
- * consider using {@link java.text.SimpleDateFormat} via the factory methods in
- * {@link java.text.DateFormat} instead.
+ * It's also possible to format dates and times with {@code Formatter}, though you should
+ * use {@link java.text.SimpleDateFormat} (probably via the factory methods in
+ * {@link java.text.DateFormat}) instead.
* The facilities offered by {@code Formatter} are low-level and place the burden of localization
* on the developer. Using {@link java.text.DateFormat#getDateInstance},
* {@link java.text.DateFormat#getTimeInstance}, and
@@ -310,11 +310,8 @@
* which you can get with {@code "%tF"} (2010-01-22), {@code "%tF %tR"} (2010-01-22 13:39),
* {@code "%tF %tT"} (2010-01-22 13:39:15), or {@code "%tF %tT%z"} (2010-01-22 13:39:15-0800).
* <p>
- * As with the other conversions, date/time conversion has an uppercase format. Replacing
- * {@code %t} with {@code %T} will uppercase the field according to the rules of the formatter's
- * locale.
- * <p>
- * This table shows the date/time conversions:
+ * This table shows the date/time conversions, but you should use {@link java.text.SimpleDateFormat}
+ * instead:
* <table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
* <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
* <TD COLSPAN=4><B>Date/time conversions</B>
@@ -349,7 +346,7 @@
* </tr>
* <tr>
* <td width="5%">{@code tc}</td>
- * <td width="25%">Locale-preferred date and time representation. (See {@link java.text.DateFormat} for more variations.)</td>
+ * <td width="25%">C library <i>asctime(3)</i>-like output. Do not use.</td>
* <td width="30%">{@code format("%tc", cal);}</td>
* <td width="30%">{@code Tue Apr 01 16:19:17 CEST 2008}</td>
* </tr>
@@ -510,6 +507,10 @@
* <td width="30%">{@code CEST}</td>
* </tr>
* </table>
+ * <p>
+ * As with the other conversions, date/time conversion has an uppercase format. Replacing
+ * {@code %t} with {@code %T} will uppercase the field according to the rules of the formatter's
+ * locale.
* <p><i>Number localization</i>. Some conversions use localized decimal digits rather than the
* usual ASCII digits. So formatting {@code 123} with {@code %d} will give 123 in English locales
* but ١٢٣ in appropriate Arabic locales, for example. This number localization
diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java
index ac8b172..4e2cf61 100644
--- a/luni/src/test/java/libcore/java/security/SignatureTest.java
+++ b/luni/src/test/java/libcore/java/security/SignatureTest.java
@@ -138,7 +138,7 @@
/* ENGINE-based private key */
NativeCryptoTest.loadTestEngine();
- OpenSSLEngine engine = OpenSSLEngine.getInstance("test");
+ OpenSSLEngine engine = OpenSSLEngine.getInstance(NativeCryptoTest.TEST_ENGINE_ID);
PrivateKey privKey = engine.getPrivateKeyById(pem_private);
assertTrue(privKey instanceof RSAPrivateKey);
diff --git a/luni/src/test/java/libcore/java/text/OldSimpleDateFormatTest.java b/luni/src/test/java/libcore/java/text/OldSimpleDateFormatTest.java
index ff24bb6..1cc7554 100644
--- a/luni/src/test/java/libcore/java/text/OldSimpleDateFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/OldSimpleDateFormatTest.java
@@ -245,7 +245,7 @@
test.test(" MM", cal, " 06", DateFormat.MONTH_FIELD);
test.test(" MMM", cal, " Jun", DateFormat.MONTH_FIELD);
test.test(" MMMM", cal, " June", DateFormat.MONTH_FIELD);
- test.test(" MMMMM", cal, " June", DateFormat.MONTH_FIELD);
+ test.test(" MMMMM", cal, " J", DateFormat.MONTH_FIELD);
test.test(" d", cal, " 2", DateFormat.DATE_FIELD);
test.test(" d", new GregorianCalendar(1999, Calendar.NOVEMBER, 12),
@@ -295,7 +295,7 @@
test.test(" EE", cal, " Wed", DateFormat.DAY_OF_WEEK_FIELD);
test.test(" EEE", cal, " Wed", DateFormat.DAY_OF_WEEK_FIELD);
test.test(" EEEE", cal, " Wednesday", DateFormat.DAY_OF_WEEK_FIELD);
- test.test(" EEEEE", cal, " Wednesday", DateFormat.DAY_OF_WEEK_FIELD);
+ test.test(" EEEEE", cal, " W", DateFormat.DAY_OF_WEEK_FIELD);
test.test(" D", cal, " 153", DateFormat.DAY_OF_YEAR_FIELD);
test.test(" DD", cal, " 153", DateFormat.DAY_OF_YEAR_FIELD);
@@ -405,7 +405,8 @@
format.setTimeZone(tz0001);
test.test(" Z", cal, " +0001", DateFormat.TIMEZONE_FIELD);
- test.test(" ZZZZ", cal, " +0001", DateFormat.TIMEZONE_FIELD);
+ test.test(" ZZZZ", cal, " GMT+00:01", DateFormat.TIMEZONE_FIELD);
+ test.test(" ZZZZZ", cal, " +00:01", DateFormat.TIMEZONE_FIELD);
format.setTimeZone(tz0130);
test.test(" Z", cal, " +0130", DateFormat.TIMEZONE_FIELD);
format.setTimeZone(tzMinus0130);
@@ -441,22 +442,18 @@
Date winterDate = new GregorianCalendar(1999, Calendar.JANUARY, 12).getTime();
FormatTester test = new FormatTester();
- test.verifyFormatTimezone("GMT-7", "GMT-07:00, GMT-07:00", "-0700, -0700", summerDate);
- test.verifyFormatTimezone("GMT-7", "GMT-07:00, GMT-07:00", "-0700, -0700", winterDate);
+ test.verifyFormatTimezone("GMT-7", "GMT-07:00, GMT-07:00", "-0700, GMT-07:00", summerDate);
+ test.verifyFormatTimezone("GMT-7", "GMT-07:00, GMT-07:00", "-0700, GMT-07:00", winterDate);
- test.verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, +1400", summerDate);
- test.verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, +1400", winterDate);
+ test.verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, GMT+14:00", summerDate);
+ test.verifyFormatTimezone("GMT+14", "GMT+14:00, GMT+14:00", "+1400, GMT+14:00", winterDate);
- test.verifyFormatTimezone("America/Los_Angeles", "PDT, Pacific Daylight Time",
- "-0700, -0700", summerDate);
- test.verifyFormatTimezone("America/Los_Angeles", "PST, Pacific Standard Time",
- "-0800, -0800", winterDate);
+ test.verifyFormatTimezone("America/Los_Angeles", "PDT, Pacific Daylight Time", "-0700, GMT-07:00", summerDate);
+ test.verifyFormatTimezone("America/Los_Angeles", "PST, Pacific Standard Time", "-0800, GMT-08:00", winterDate);
// this fails on the RI!
- test.verifyFormatTimezone("America/Detroit", "EDT, Eastern Daylight Time",
- "-0400, -0400", summerDate);
- test.verifyFormatTimezone("America/Detroit", "EST, Eastern Standard Time",
- "-0500, -0500", winterDate);
+ test.verifyFormatTimezone("America/Detroit", "EDT, Eastern Daylight Time", "-0400, GMT-04:00", summerDate);
+ test.verifyFormatTimezone("America/Detroit", "EST, Eastern Standard Time", "-0500, GMT-05:00", winterDate);
assertFalse(test.testsFailed);
}
diff --git a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
index cd54d1e..21d7302 100644
--- a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
@@ -77,6 +77,104 @@
assertEquals(Calendar.TUESDAY, parseDate(ru, "cccc", "\u0412\u0442\u043e\u0440\u043d\u0438\u043a").get(Calendar.DAY_OF_WEEK));
}
+ // The RI fails this test because it doesn't fully support UTS #35.
+ // https://code.google.com/p/android/issues/detail?id=39616
+ public void testFiveCount_parsing() throws Exception {
+ // It's pretty silly to try to parse the shortest names, because they're almost always ambiguous.
+ try {
+ parseDate(Locale.ENGLISH, "MMMMM", "J");
+ fail();
+ } catch (junit.framework.AssertionFailedError expected) {
+ }
+ try {
+ parseDate(Locale.ENGLISH, "LLLLL", "J");
+ fail();
+ } catch (junit.framework.AssertionFailedError expected) {
+ }
+ try {
+ parseDate(Locale.ENGLISH, "EEEEE", "T");
+ fail();
+ } catch (junit.framework.AssertionFailedError expected) {
+ }
+ try {
+ parseDate(Locale.ENGLISH, "ccccc", "T");
+ fail();
+ } catch (junit.framework.AssertionFailedError expected) {
+ }
+ }
+
+ // The RI fails this test because it doesn't fully support UTS #35.
+ // https://code.google.com/p/android/issues/detail?id=39616
+ public void testFiveCount_M() throws Exception {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ assertEquals("1", formatDate(Locale.ENGLISH, "M"));
+ assertEquals("01", formatDate(Locale.ENGLISH, "MM"));
+ assertEquals("Jan", formatDate(Locale.ENGLISH, "MMM"));
+ assertEquals("January", formatDate(Locale.ENGLISH, "MMMM"));
+ assertEquals("J", formatDate(Locale.ENGLISH, "MMMMM"));
+ }
+
+ // The RI fails this test because it doesn't fully support UTS #35.
+ // https://code.google.com/p/android/issues/detail?id=39616
+ public void testFiveCount_L() throws Exception {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ assertEquals("1", formatDate(Locale.ENGLISH, "L"));
+ assertEquals("01", formatDate(Locale.ENGLISH, "LL"));
+ assertEquals("Jan", formatDate(Locale.ENGLISH, "LLL"));
+ assertEquals("January", formatDate(Locale.ENGLISH, "LLLL"));
+ assertEquals("J", formatDate(Locale.ENGLISH, "LLLLL"));
+ }
+
+ // The RI fails this test because it doesn't fully support UTS #35.
+ // https://code.google.com/p/android/issues/detail?id=39616
+ public void testFiveCount_E() throws Exception {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ assertEquals("Thu", formatDate(Locale.ENGLISH, "E"));
+ assertEquals("Thu", formatDate(Locale.ENGLISH, "EE"));
+ assertEquals("Thu", formatDate(Locale.ENGLISH, "EEE"));
+ assertEquals("Thursday", formatDate(Locale.ENGLISH, "EEEE"));
+ assertEquals("T", formatDate(Locale.ENGLISH, "EEEEE"));
+ // assertEquals("Th", formatDate(Locale.ENGLISH, "EEEEEE")); // icu4c doesn't support 6.
+ }
+
+ // The RI fails this test because it doesn't fully support UTS #35.
+ // https://code.google.com/p/android/issues/detail?id=39616
+ public void testFiveCount_c() throws Exception {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ assertEquals("Thu", formatDate(Locale.ENGLISH, "c"));
+ assertEquals("Thu", formatDate(Locale.ENGLISH, "cc"));
+ assertEquals("Thu", formatDate(Locale.ENGLISH, "ccc"));
+ assertEquals("Thursday", formatDate(Locale.ENGLISH, "cccc"));
+ assertEquals("T", formatDate(Locale.ENGLISH, "ccccc"));
+ // assertEquals("Th", formatDate(Locale.ENGLISH, "cccccc")); // icu4c doesn't support 6.
+ }
+
+ // The RI fails this test because it doesn't fully support UTS #35.
+ // https://code.google.com/p/android/issues/detail?id=39616
+ public void testFiveCount_Z() throws Exception {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ assertEquals("+0000", formatDate(Locale.ENGLISH, "Z"));
+ assertEquals("+0000", formatDate(Locale.ENGLISH, "ZZ"));
+ assertEquals("+0000", formatDate(Locale.ENGLISH, "ZZZ"));
+ assertEquals("GMT+00:00", formatDate(Locale.ENGLISH, "ZZZZ"));
+ assertEquals("+00:00", formatDate(Locale.ENGLISH, "ZZZZZ"));
+ }
+
+ // The RI fails this test because it doesn't fully support UTS #35.
+ // https://code.google.com/p/android/issues/detail?id=39616
+ public void test_parsing_Z() throws Exception {
+ TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
+ assertEquals(1325421240000L, parseTime("yyyy-MM-dd' 'Z", "2012-01-01 -1234"));
+ assertEquals(1325421240000L, parseTime("yyyy-MM-dd' 'ZZ", "2012-01-01 -1234"));
+ assertEquals(1325421240000L, parseTime("yyyy-MM-dd' 'ZZZ", "2012-01-01 -1234"));
+ assertEquals(1325421240000L, parseTime("yyyy-MM-dd' 'ZZZZ", "2012-01-01 GMT-12:34"));
+ assertEquals(1325421240000L, parseTime("yyyy-MM-dd' 'ZZZZZ", "2012-01-01 -12:34"));
+ }
+
+ private static long parseTime(String fmt, String value) {
+ return parseDate(Locale.ENGLISH, fmt, value).getTime().getTime();
+ }
+
public void test2038() {
SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("UTC"));
@@ -92,13 +190,14 @@
assertEquals("Sun Feb 07 06:28:16 2106",
format.format(new Date((2L + Integer.MAX_VALUE + Integer.MAX_VALUE) * 1000L)));
}
+
private String formatDate(Locale l, String fmt) {
DateFormat dateFormat = new SimpleDateFormat(fmt, l);
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
return dateFormat.format(new Date(0));
}
- private Calendar parseDate(Locale l, String fmt, String value) {
+ private static Calendar parseDate(Locale l, String fmt, String value) {
SimpleDateFormat sdf = new SimpleDateFormat(fmt, l);
ParsePosition pp = new ParsePosition(0);
Date d = sdf.parse(value, pp);
diff --git a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
index 47ab6cc..d65dd4b 100644
--- a/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
+++ b/luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/MacTest.java
@@ -897,7 +897,7 @@
Provider p = Security.getProvider(OpenSSLProvider.PROVIDER_NAME);
NativeCryptoTest.loadTestEngine();
- OpenSSLEngine engine = OpenSSLEngine.getInstance("test");
+ OpenSSLEngine engine = OpenSSLEngine.getInstance(NativeCryptoTest.TEST_ENGINE_ID);
/*
* The "-HMAC-" prefix is a special prefix recognized by
diff --git a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java
index 41ced3e..d531596 100644
--- a/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java
+++ b/luni/src/test/java/org/apache/harmony/xnet/provider/jsse/NativeCryptoTest.java
@@ -56,7 +56,7 @@
public class NativeCryptoTest extends TestCase {
/** Corresponds to the native test library "libjavacoretests.so" */
- private static final String NATIVE_LIBRARY_NAME = "javacoretests";
+ public static final String TEST_ENGINE_ID = "javacoretests";
private static final int NULL = 0;
private static final FileDescriptor INVALID_FD = new FileDescriptor();
@@ -2007,7 +2007,7 @@
* immediately.
*/
public static void loadTestEngine() throws Exception {
- int testEngine = NativeCrypto.ENGINE_by_id("test");
+ int testEngine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
if (testEngine != 0) {
NativeCrypto.ENGINE_finish(testEngine);
return;
@@ -2035,14 +2035,14 @@
assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "LIST_ADD", "2", 0));
// Do a direct load of the ENGINE.
- assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "SO_PATH",
- NATIVE_LIBRARY_NAME, 0));
+ assertEquals(1,
+ NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "ID", TEST_ENGINE_ID, 0));
assertEquals(1, NativeCrypto.ENGINE_ctrl_cmd_string(dynEngine, "LOAD", null, 0));
} finally {
NativeCrypto.ENGINE_finish(dynEngine);
}
- testEngine = NativeCrypto.ENGINE_by_id("test");
+ testEngine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
if (testEngine == 0) {
fail("could not load test engine");
}
@@ -2052,7 +2052,7 @@
public void test_ENGINE_by_id_TestEngine() throws Exception {
loadTestEngine();
- int engine = NativeCrypto.ENGINE_by_id("test");
+ int engine = NativeCrypto.ENGINE_by_id(TEST_ENGINE_ID);
assertTrue(engine != 0);
NativeCrypto.ENGINE_add(engine);
diff --git a/luni/src/test/native/test_openssl_engine.cpp b/luni/src/test/native/test_openssl_engine.cpp
index 787f29e..9a0f3b3 100644
--- a/luni/src/test/native/test_openssl_engine.cpp
+++ b/luni/src/test/native/test_openssl_engine.cpp
@@ -26,7 +26,7 @@
#include <openssl/pem.h>
#define DYNAMIC_ENGINE
-#define TEST_ENGINE_ID "test"
+#define TEST_ENGINE_ID "javacoretests"
#define TEST_ENGINE_NAME "libcore test engine"
struct RSA_Delete {