< prev index next >
src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java
Print this page
*** 864,874 ****
//-----------------------------------------------------------------------
/**
* Appends the zone offset, such as '+01:00', to the formatter.
* <p>
* This appends an instruction to format/parse the offset ID to the builder.
! * This is equivalent to calling {@code appendOffset("+HH:MM:ss", "Z")}.
*
* @return this, for chaining, not null
*/
public DateTimeFormatterBuilder appendOffsetId() {
appendInternal(OffsetIdPrinterParser.INSTANCE_ID_Z);
--- 864,876 ----
//-----------------------------------------------------------------------
/**
* Appends the zone offset, such as '+01:00', to the formatter.
* <p>
* This appends an instruction to format/parse the offset ID to the builder.
! * This is equivalent to calling {@code appendOffset("+HH:mm:ss", "Z")}.
! * See {@link #appendOffset(String, String)} for details on formatting
! * and parsing.
*
* @return this, for chaining, not null
*/
public DateTimeFormatterBuilder appendOffsetId() {
appendInternal(OffsetIdPrinterParser.INSTANCE_ID_Z);
*** 884,896 ****
* to querying the temporal with {@link TemporalQueries#offset()}.
* It will be printed using the format defined below.
* If the offset cannot be obtained then an exception is thrown unless the
* section of the formatter is optional.
* <p>
! * During parsing, the offset is parsed using the format defined below.
! * If the offset cannot be parsed then an exception is thrown unless the
! * section of the formatter is optional.
* <p>
* The format of the offset is controlled by a pattern which must be one
* of the following:
* <ul>
* <li>{@code +HH} - hour only, ignoring minute and second
--- 886,908 ----
* to querying the temporal with {@link TemporalQueries#offset()}.
* It will be printed using the format defined below.
* If the offset cannot be obtained then an exception is thrown unless the
* section of the formatter is optional.
* <p>
! * When parsing in strict mode, the input must contain the mandatory
! * and optional elements are defined by the specified pattern.
! * If the offset cannot be parsed then an exception is thrown unless
! * the section of the formatter is optional.
! * <p>
! * When parsing in lenient mode, only the hours are mandatory - minutes
! * and seconds are optional.
! * The colons are required if the specified pattern contains a colon.
! * If the specified pattern is "+HH", the presence of colons is
! * determined by whether the character after the hour digits is a colon
! * or not.
! * If the offset cannot be parsed then an exception is thrown unless
! * the section of the formatter is optional.
* <p>
* The format of the offset is controlled by a pattern which must be one
* of the following:
* <ul>
* <li>{@code +HH} - hour only, ignoring minute and second
*** 900,909 ****
--- 912,925 ----
* <li>{@code +HH:MM} - hour and minute, ignoring second, with colon
* <li>{@code +HHMMss} - hour and minute, with second if non-zero, no colon
* <li>{@code +HH:MM:ss} - hour and minute, with second if non-zero, with colon
* <li>{@code +HHMMSS} - hour, minute and second, no colon
* <li>{@code +HH:MM:SS} - hour, minute and second, with colon
+ * <li>{@code +HHmmss} - hour, with minute if non-zero or with minute and
+ * second if non-zero, no colon
+ * <li>{@code +HH:mm:ss} - hour, with minute if non-zero or with minute and
+ * second if non-zero, with colon
* </ul>
* The "no offset" text controls what text is printed when the total amount of
* the offset fields to be output is zero.
* Example values would be 'Z', '+00:00', 'UTC' or 'GMT'.
* Three formats are accepted for parsing UTC - the "no offset" text, and the
*** 3313,3323 ****
/**
* Prints or parses an offset ID.
*/
static final class OffsetIdPrinterParser implements DateTimePrinterParser {
static final String[] PATTERNS = new String[] {
! "+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS",
}; // order used in pattern builder
static final OffsetIdPrinterParser INSTANCE_ID_Z = new OffsetIdPrinterParser("+HH:MM:ss", "Z");
static final OffsetIdPrinterParser INSTANCE_ID_ZERO = new OffsetIdPrinterParser("+HH:MM:ss", "0");
private final String noOffsetText;
--- 3329,3339 ----
/**
* Prints or parses an offset ID.
*/
static final class OffsetIdPrinterParser implements DateTimePrinterParser {
static final String[] PATTERNS = new String[] {
! "+HH", "+HHmm", "+HH:mm", "+HHMM", "+HH:MM", "+HHMMss", "+HH:MM:ss", "+HHMMSS", "+HH:MM:SS", "+HHmmss", "+HH:mm:ss",
}; // order used in pattern builder
static final OffsetIdPrinterParser INSTANCE_ID_Z = new OffsetIdPrinterParser("+HH:MM:ss", "Z");
static final OffsetIdPrinterParser INSTANCE_ID_ZERO = new OffsetIdPrinterParser("+HH:MM:ss", "0");
private final String noOffsetText;
*** 3360,3374 ****
int absSeconds = Math.abs(totalSecs % 60);
int bufPos = buf.length();
int output = absHours;
buf.append(totalSecs < 0 ? "-" : "+")
.append((char) (absHours / 10 + '0')).append((char) (absHours % 10 + '0'));
! if (type >= 3 || (type >= 1 && absMinutes > 0)) {
buf.append((type % 2) == 0 ? ":" : "")
.append((char) (absMinutes / 10 + '0')).append((char) (absMinutes % 10 + '0'));
output += absMinutes;
! if (type >= 7 || (type >= 5 && absSeconds > 0)) {
buf.append((type % 2) == 0 ? ":" : "")
.append((char) (absSeconds / 10 + '0')).append((char) (absSeconds % 10 + '0'));
output += absSeconds;
}
}
--- 3376,3390 ----
int absSeconds = Math.abs(totalSecs % 60);
int bufPos = buf.length();
int output = absHours;
buf.append(totalSecs < 0 ? "-" : "+")
.append((char) (absHours / 10 + '0')).append((char) (absHours % 10 + '0'));
! if ((type >= 3 && type < 9) || (type >= 9 && absSeconds > 0) || (type >= 1 && absMinutes > 0)) {
buf.append((type % 2) == 0 ? ":" : "")
.append((char) (absMinutes / 10 + '0')).append((char) (absMinutes % 10 + '0'));
output += absMinutes;
! if (type == 7 || type == 8 || (type >= 5 && absSeconds > 0)) {
buf.append((type % 2) == 0 ? ":" : "")
.append((char) (absSeconds / 10 + '0')).append((char) (absSeconds % 10 + '0'));
output += absSeconds;
}
}
*** 3382,3391 ****
--- 3398,3414 ----
@Override
public int parse(DateTimeParseContext context, CharSequence text, int position) {
int length = text.length();
int noOffsetLen = noOffsetText.length();
+ int parseType = type;
+ if (context.isStrict() == false) {
+ parseType = 9;
+ if ((length > position + 3) && (text.charAt(position + 3) == ':')) {
+ parseType = 10;
+ }
+ }
if (noOffsetLen == 0) {
if (position == length) {
return context.setParsedField(OFFSET_SECONDS, 0, position, position);
}
} else {
*** 3402,3422 ****
if (sign == '+' || sign == '-') {
// starts
int negative = (sign == '-' ? -1 : 1);
int[] array = new int[4];
array[0] = position + 1;
! if ((parseNumber(array, 1, text, true) ||
! parseNumber(array, 2, text, type >=3) ||
! parseNumber(array, 3, text, false)) == false) {
// success
long offsetSecs = negative * (array[1] * 3600L + array[2] * 60L + array[3]);
return context.setParsedField(OFFSET_SECONDS, offsetSecs, position, array[0]);
}
}
// handle special case of empty no offset text
if (noOffsetLen == 0) {
! return context.setParsedField(OFFSET_SECONDS, 0, position, position + noOffsetLen);
}
return ~position;
}
/**
--- 3425,3445 ----
if (sign == '+' || sign == '-') {
// starts
int negative = (sign == '-' ? -1 : 1);
int[] array = new int[4];
array[0] = position + 1;
! if ((parseNumber(array, 1, text, true, parseType) ||
! parseNumber(array, 2, text, parseType >= 3 && parseType < 9, parseType) ||
! parseNumber(array, 3, text, parseType == 7 || parseType == 8, parseType)) == false) {
// success
long offsetSecs = negative * (array[1] * 3600L + array[2] * 60L + array[3]);
return context.setParsedField(OFFSET_SECONDS, offsetSecs, position, array[0]);
}
}
// handle special case of empty no offset text
if (noOffsetLen == 0) {
! return context.setParsedField(OFFSET_SECONDS, 0, position, position);
}
return ~position;
}
/**
*** 3424,3441 ****
*
* @param array the array of parsed data, 0=pos,1=hours,2=mins,3=secs, not null
* @param arrayIndex the index to parse the value into
* @param parseText the offset ID, not null
* @param required whether this number is required
* @return true if an error occurred
*/
! private boolean parseNumber(int[] array, int arrayIndex, CharSequence parseText, boolean required) {
! if ((type + 3) / 2 < arrayIndex) {
return false; // ignore seconds/minutes
}
int pos = array[0];
! if ((type % 2) == 0 && arrayIndex > 1) {
if (pos + 1 > parseText.length() || parseText.charAt(pos) != ':') {
return required;
}
pos++;
}
--- 3447,3465 ----
*
* @param array the array of parsed data, 0=pos,1=hours,2=mins,3=secs, not null
* @param arrayIndex the index to parse the value into
* @param parseText the offset ID, not null
* @param required whether this number is required
+ * @param parseType the offset pattern type
* @return true if an error occurred
*/
! private boolean parseNumber(int[] array, int arrayIndex, CharSequence parseText, boolean required, int parseType) {
! if ((parseType + 3) / 2 < arrayIndex) {
return false; // ignore seconds/minutes
}
int pos = array[0];
! if ((parseType % 2) == 0 && arrayIndex > 1) {
if (pos + 1 > parseText.length() || parseText.charAt(pos) != ':') {
return required;
}
pos++;
}
< prev index next >