"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "log4j-core/src/main/java/org/apache/logging/log4j/core/util/datetime/FixedDateFormat.java" between
apache-log4j-2.11.1-src.tar.gz and apache-log4j-2.11.2-src.tar.gz

About: Apache Log4j 2 is a logging library for Java. Source distribution (Java).

FixedDateFormat.java  (apache-log4j-2.11.1-src):FixedDateFormat.java  (apache-log4j-2.11.2-src)
skipping to change at line 34 skipping to change at line 34
import java.util.Objects; import java.util.Objects;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* Custom time formatter that trades flexibility for performance. This formatter only supports the date patterns defined * Custom time formatter that trades flexibility for performance. This formatter only supports the date patterns defined
* in {@link FixedFormat}. For any other date patterns use {@link FastDateFormat }. * in {@link FixedFormat}. For any other date patterns use {@link FastDateFormat }.
* <p> * <p>
* Related benchmarks: /log4j-perf/src/main/java/org/apache/logging/log4j/perf/j mh/TimeFormatBenchmark.java and * Related benchmarks: /log4j-perf/src/main/java/org/apache/logging/log4j/perf/j mh/TimeFormatBenchmark.java and
* /log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadsafeDateFor matBenchmark.java * /log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadsafeDateFor matBenchmark.java
* </p>
*/ */
public class FixedDateFormat { public class FixedDateFormat {
/** /**
* Enumeration over the supported date/time format patterns. * Enumeration over the supported date/time format patterns.
* <p> * <p>
* Package protected for unit tests. * Package protected for unit tests.
* </p>
*/ */
public enum FixedFormat { public enum FixedFormat {
/** /**
* ABSOLUTE time format: {@code "HH:mm:ss,SSS"}. * ABSOLUTE time format: {@code "HH:mm:ss,SSS"}.
*/ */
ABSOLUTE("HH:mm:ss,SSS", null, 0, ':', 1, ',', 1, 3), ABSOLUTE("HH:mm:ss,SSS", null, 0, ':', 1, ',', 1, 3, null),
/** /**
* ABSOLUTE time format with microsecond precision: {@code "HH:mm:ss,nnn nnn"}. * ABSOLUTE time format with microsecond precision: {@code "HH:mm:ss,nnn nnn"}.
*/ */
ABSOLUTE_MICROS("HH:mm:ss,nnnnnn", null, 0, ':', 1, ',', 1, 6), ABSOLUTE_MICROS("HH:mm:ss,nnnnnn", null, 0, ':', 1, ',', 1, 6, null),
/** /**
* ABSOLUTE time format with nanosecond precision: {@code "HH:mm:ss,nnnn nnnnn"}. * ABSOLUTE time format with nanosecond precision: {@code "HH:mm:ss,nnnn nnnnn"}.
*/ */
ABSOLUTE_NANOS("HH:mm:ss,nnnnnnnnn", null, 0, ':', 1, ',', 1, 9), ABSOLUTE_NANOS("HH:mm:ss,nnnnnnnnn", null, 0, ':', 1, ',', 1, 9, null),
/** /**
* ABSOLUTE time format variation with period separator: {@code "HH:mm:s s.SSS"}. * ABSOLUTE time format variation with period separator: {@code "HH:mm:s s.SSS"}.
*/ */
ABSOLUTE_PERIOD("HH:mm:ss.SSS", null, 0, ':', 1, '.', 1, 3), ABSOLUTE_PERIOD("HH:mm:ss.SSS", null, 0, ':', 1, '.', 1, 3, null),
/** /**
* COMPACT time format: {@code "yyyyMMddHHmmssSSS"}. * COMPACT time format: {@code "yyyyMMddHHmmssSSS"}.
*/ */
COMPACT("yyyyMMddHHmmssSSS", "yyyyMMdd", 0, ' ', 0, ' ', 0, 3), COMPACT("yyyyMMddHHmmssSSS", "yyyyMMdd", 0, ' ', 0, ' ', 0, 3, null),
/** /**
* DATE_AND_TIME time format: {@code "dd MMM yyyy HH:mm:ss,SSS"}. * DATE_AND_TIME time format: {@code "dd MMM yyyy HH:mm:ss,SSS"}.
*/ */
DATE("dd MMM yyyy HH:mm:ss,SSS", "dd MMM yyyy ", 0, ':', 1, ',', 1, 3), DATE("dd MMM yyyy HH:mm:ss,SSS", "dd MMM yyyy ", 0, ':', 1, ',', 1, 3, n ull),
/** /**
* DATE_AND_TIME time format variation with period separator: {@code "dd MMM yyyy HH:mm:ss.SSS"}. * DATE_AND_TIME time format variation with period separator: {@code "dd MMM yyyy HH:mm:ss.SSS"}.
*/ */
DATE_PERIOD("dd MMM yyyy HH:mm:ss.SSS", "dd MMM yyyy ", 0, ':', 1, '.', 1, 3), DATE_PERIOD("dd MMM yyyy HH:mm:ss.SSS", "dd MMM yyyy ", 0, ':', 1, '.', 1, 3, null),
/** /**
* DEFAULT time format: {@code "yyyy-MM-dd HH:mm:ss,SSS"}. * DEFAULT time format: {@code "yyyy-MM-dd HH:mm:ss,SSS"}.
*/ */
DEFAULT("yyyy-MM-dd HH:mm:ss,SSS", "yyyy-MM-dd ", 0, ':', 1, ',', 1, 3), DEFAULT("yyyy-MM-dd HH:mm:ss,SSS", "yyyy-MM-dd ", 0, ':', 1, ',', 1, 3, null),
/** /**
* DEFAULT time format with microsecond precision: {@code "yyyy-MM-dd HH :mm:ss,nnnnnn"}. * DEFAULT time format with microsecond precision: {@code "yyyy-MM-dd HH :mm:ss,nnnnnn"}.
*/ */
DEFAULT_MICROS("yyyy-MM-dd HH:mm:ss,nnnnnn", "yyyy-MM-dd ", 0, ':', 1, ' ,', 1, 6), DEFAULT_MICROS("yyyy-MM-dd HH:mm:ss,nnnnnn", "yyyy-MM-dd ", 0, ':', 1, ' ,', 1, 6, null),
/** /**
* DEFAULT time format with nanosecond precision: {@code "yyyy-MM-dd HH: mm:ss,nnnnnnnnn"}. * DEFAULT time format with nanosecond precision: {@code "yyyy-MM-dd HH: mm:ss,nnnnnnnnn"}.
*/ */
DEFAULT_NANOS("yyyy-MM-dd HH:mm:ss,nnnnnnnnn", "yyyy-MM-dd ", 0, ':', 1, ',', 1, 9), DEFAULT_NANOS("yyyy-MM-dd HH:mm:ss,nnnnnnnnn", "yyyy-MM-dd ", 0, ':', 1, ',', 1, 9, null),
/** /**
* DEFAULT time format variation with period separator: {@code "yyyy-MM- dd HH:mm:ss.SSS"}. * DEFAULT time format variation with period separator: {@code "yyyy-MM- dd HH:mm:ss.SSS"}.
*/ */
DEFAULT_PERIOD("yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd ", 0, ':', 1, '.', 1, 3), DEFAULT_PERIOD("yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd ", 0, ':', 1, '.', 1, 3, null),
/** /**
* ISO8601_BASIC time format: {@code "yyyyMMdd'T'HHmmss,SSS"}. * ISO8601_BASIC time format: {@code "yyyyMMdd'T'HHmmss,SSS"}.
*/ */
ISO8601_BASIC("yyyyMMdd'T'HHmmss,SSS", "yyyyMMdd'T'", 2, ' ', 0, ',', 1, 3), ISO8601_BASIC("yyyyMMdd'T'HHmmss,SSS", "yyyyMMdd'T'", 2, ' ', 0, ',', 1, 3, null),
/** /**
* ISO8601_BASIC time format: {@code "yyyyMMdd'T'HHmmss.SSS"}. * ISO8601_BASIC time format: {@code "yyyyMMdd'T'HHmmss.SSS"}.
*/ */
ISO8601_BASIC_PERIOD("yyyyMMdd'T'HHmmss.SSS", "yyyyMMdd'T'", 2, ' ', 0, '.', 1, 3), ISO8601_BASIC_PERIOD("yyyyMMdd'T'HHmmss.SSS", "yyyyMMdd'T'", 2, ' ', 0, '.', 1, 3, null),
/** /**
* ISO8601 time format: {@code "yyyy-MM-dd'T'HH:mm:ss,SSS"}. * ISO8601 time format: {@code "yyyy-MM-dd'T'HH:mm:ss,SSS"}.
*/ */
ISO8601("yyyy-MM-dd'T'HH:mm:ss,SSS", "yyyy-MM-dd'T'", 2, ':', 1, ',', 1, ISO8601("yyyy-MM-dd'T'HH:mm:ss,SSS", "yyyy-MM-dd'T'", 2, ':', 1, ',', 1,
3), 3, null),
// TODO Do we even want a format without seconds?
// /**
// * ISO8601_OFFSET_DATE_TIME time format: {@code "yyyy-MM-dd'T'HH:mmXXX
"}.
// */
// // Would need work in org.apache.logging.log4j.core.util.datetime.Fixe
dDateFormat.writeTime(int, char[], int)
// ISO8601_OFFSET_DATE_TIME("yyyy-MM-dd'T'HH:mmXXX", "yyyy-MM-dd'T'", 2,
':', 1, ' ', 0, 0, FixedTimeZoneFormat.XXX),
/**
* ISO8601 time format: {@code "yyyy-MM-dd'T'HH:mm:ss,SSSX"} with a time
zone like {@code -07}.
*/
ISO8601_OFFSET_DATE_TIME_HH("yyyy-MM-dd'T'HH:mm:ss,SSSX", "yyyy-MM-dd'T'
", 2, ':', 1, ',', 1, 3, FixedTimeZoneFormat.HH),
/**
* ISO8601 time format: {@code "yyyy-MM-dd'T'HH:mm:ss,SSSXX"} with a tim
e zone like {@code -0700}.
*/
ISO8601_OFFSET_DATE_TIME_HHMM("yyyy-MM-dd'T'HH:mm:ss,SSSXX", "yyyy-MM-dd
'T'", 2, ':', 1, ',', 1, 3, FixedTimeZoneFormat.HHMM),
/**
* ISO8601 time format: {@code "yyyy-MM-dd'T'HH:mm:ss,SSSXXX"} with a ti
me zone like {@code -07:00}.
*/
ISO8601_OFFSET_DATE_TIME_HHCMM("yyyy-MM-dd'T'HH:mm:ss,SSSXXX", "yyyy-MM-
dd'T'", 2, ':', 1, ',', 1, 3, FixedTimeZoneFormat.HHCMM),
/** /**
* ISO8601 time format: {@code "yyyy-MM-dd'T'HH:mm:ss.SSS"}. * ISO8601 time format: {@code "yyyy-MM-dd'T'HH:mm:ss.SSS"}.
*/ */
ISO8601_PERIOD("yyyy-MM-dd'T'HH:mm:ss.SSS", "yyyy-MM-dd'T'", 2, ':', 1, '.', 1, 3); ISO8601_PERIOD("yyyy-MM-dd'T'HH:mm:ss.SSS", "yyyy-MM-dd'T'", 2, ':', 1, '.', 1, 3, null);
private static final String DEFAULT_SECOND_FRACTION_PATTERN = "SSS"; private static final String DEFAULT_SECOND_FRACTION_PATTERN = "SSS";
private static final int MILLI_FRACTION_DIGITS = DEFAULT_SECOND_FRACTION _PATTERN.length(); private static final int MILLI_FRACTION_DIGITS = DEFAULT_SECOND_FRACTION _PATTERN.length();
private static final char SECOND_FRACTION_PATTERN = 'n'; private static final char SECOND_FRACTION_PATTERN = 'n';
private final String pattern; private final String pattern;
private final String datePattern; private final String datePattern;
private final int escapeCount; private final int escapeCount;
private final char timeSeparatorChar; private final char timeSeparatorChar;
private final int timeSeparatorLength; private final int timeSeparatorLength;
private final char millisSeparatorChar; private final char millisSeparatorChar;
private final int millisSeparatorLength; private final int millisSeparatorLength;
private final int secondFractionDigits; private final int secondFractionDigits;
private final FixedTimeZoneFormat fixedTimeZoneFormat;
FixedFormat(final String pattern, final String datePattern, final int es capeCount, final char timeSeparator, FixedFormat(final String pattern, final String datePattern, final int es capeCount, final char timeSeparator,
final int timeSepLength, final char millisSeparator, final i nt millisSepLength, final int timeSepLength, final char millisSeparator, final i nt millisSepLength,
final int secondFractionDigits) { final int secondFractionDigits, final FixedTimeZoneFormat ti meZoneFormat) {
this.timeSeparatorChar = timeSeparator; this.timeSeparatorChar = timeSeparator;
this.timeSeparatorLength = timeSepLength; this.timeSeparatorLength = timeSepLength;
this.millisSeparatorChar = millisSeparator; this.millisSeparatorChar = millisSeparator;
this.millisSeparatorLength = millisSepLength; this.millisSeparatorLength = millisSepLength;
this.pattern = Objects.requireNonNull(pattern); this.pattern = Objects.requireNonNull(pattern);
this.datePattern = datePattern; // may be null this.datePattern = datePattern; // may be null
this.escapeCount = escapeCount; this.escapeCount = escapeCount;
this.secondFractionDigits = secondFractionDigits; this.secondFractionDigits = secondFractionDigits;
this.fixedTimeZoneFormat = timeZoneFormat;
} }
/** /**
* Returns the full pattern. * Returns the full pattern.
* *
* @return the full pattern * @return the full pattern
*/ */
public String getPattern() { public String getPattern() {
return pattern; return pattern;
} }
skipping to change at line 174 skipping to change at line 201
public static FixedFormat lookup(final String nameOrPattern) { public static FixedFormat lookup(final String nameOrPattern) {
for (final FixedFormat type : FixedFormat.values()) { for (final FixedFormat type : FixedFormat.values()) {
if (type.name().equals(nameOrPattern) || type.getPattern().equal s(nameOrPattern)) { if (type.name().equals(nameOrPattern) || type.getPattern().equal s(nameOrPattern)) {
return type; return type;
} }
} }
return null; return null;
} }
static FixedFormat lookupIgnoringNanos(final String pattern) { static FixedFormat lookupIgnoringNanos(final String pattern) {
final int nanoStart = nanoStart(pattern); final int[] nanoRange = nanoRange(pattern);
final int nanoStart = nanoRange[0];
final int nanoEnd = nanoRange[1];
if (nanoStart > 0) { if (nanoStart > 0) {
final String subPattern = pattern.substring(0, nanoStart) + DEFA final String subPattern = pattern.substring(0, nanoStart) + DEFA
ULT_SECOND_FRACTION_PATTERN; ULT_SECOND_FRACTION_PATTERN
+ pattern.substring(nanoEnd, pattern.length());
for (final FixedFormat type : FixedFormat.values()) { for (final FixedFormat type : FixedFormat.values()) {
if (type.getPattern().equals(subPattern)) { if (type.getPattern().equals(subPattern)) {
return type; return type;
} }
} }
} }
return null; return null;
} }
private static int nanoStart(final String pattern) { private final static int[] EMPTY_RANGE = { -1, -1 };
final int index = pattern.indexOf(SECOND_FRACTION_PATTERN);
if (index >= 0) { /**
for (int i = index + 1; i < pattern.length(); i++) { * @return int[0] start index inclusive; int[1] end index exclusive
*/
private static int[] nanoRange(final String pattern) {
final int indexStart = pattern.indexOf(SECOND_FRACTION_PATTERN);
int indexEnd = -1;
if (indexStart >= 0) {
indexEnd = pattern.indexOf('Z', indexStart);
indexEnd = indexEnd < 0 ? pattern.indexOf('X', indexStart) : ind
exEnd;
indexEnd = indexEnd < 0 ? pattern.length() : indexEnd;
for (int i = indexStart + 1; i < indexEnd; i++) {
if (pattern.charAt(i) != SECOND_FRACTION_PATTERN) { if (pattern.charAt(i) != SECOND_FRACTION_PATTERN) {
return -1; return EMPTY_RANGE;
} }
} }
} }
return index; return new int [] {indexStart, indexEnd};
} }
/** /**
* Returns the length of the resulting formatted date and time strings. * Returns the length of the resulting formatted date and time strings.
* *
* @return the length of the resulting formatted date and time strings * @return the length of the resulting formatted date and time strings
*/ */
public int getLength() { public int getLength() {
return pattern.length() - escapeCount; return pattern.length() - escapeCount;
} }
skipping to change at line 244 skipping to change at line 283
return getDatePattern() == null ? null : FastDateFormat.getInstance( getDatePattern(), tz); return getDatePattern() == null ? null : FastDateFormat.getInstance( getDatePattern(), tz);
} }
/** /**
* Returns the number of digits specifying the fraction of the second to show * Returns the number of digits specifying the fraction of the second to show
* @return 3 for millisecond precision, 6 for microsecond precision or 9 for nanosecond precision * @return 3 for millisecond precision, 6 for microsecond precision or 9 for nanosecond precision
*/ */
public int getSecondFractionDigits() { public int getSecondFractionDigits() {
return secondFractionDigits; return secondFractionDigits;
} }
/**
* Returns the optional time zone format.
* @return the optional time zone format, may be null.
*/
public FixedTimeZoneFormat getFixedTimeZoneFormat() {
return fixedTimeZoneFormat;
}
}
private static final char NONE = (char) 0;
/**
* Fixed time zone formats. The enum names are symbols from Java's <a href=
* "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeForma
tter.html">DateTimeFormatter</a>.
*
* @see <a href=
* "https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeForma
tter.html">DateTimeFormatter</a>
*/
public enum FixedTimeZoneFormat {
/**
* Offset like {@code -07}.
*/
HH(NONE, false, 3),
/**
* Offset like {@code -0700}.
*/
HHMM(NONE, true, 5),
/**
* Offset like {@code -07:00}.
*/
HHCMM(':', true, 6);
private FixedTimeZoneFormat() {
this(NONE, true, 4);
}
private FixedTimeZoneFormat(final char timeSeparatorChar, final boolean
minutes, final int length) {
this.timeSeparatorChar = timeSeparatorChar;
this.timeSeparatorCharLen = timeSeparatorChar != NONE ? 1 : 0;
this.useMinutes = minutes;
this.length = length;
}
private final char timeSeparatorChar;
private final int timeSeparatorCharLen;
private final boolean useMinutes;
// The length includes 1 for the leading sign
private final int length;
public int getLength() {
return length;
}
// Profiling showed this method is important to log4j performance. Modif
y with care!
// 262 bytes (will be inlined when hot enough: <= -XX:FreqInlineSize=325
bytes on Linux)
private int write(final int offset, final char[] buffer, int pos) {
// This method duplicates part of writeTime()
buffer[pos++] = offset < 0 ? '-' : '+';
final int absOffset = Math.abs(offset);
final int hours = absOffset / 3600000;
int ms = absOffset - (3600000 * hours);
// Hour
int temp = hours / 10;
buffer[pos++] = ((char) (temp + '0'));
// Do subtract to get remainder instead of doing % 10
buffer[pos++] = ((char) (hours - 10 * temp + '0'));
// Minute
if (useMinutes) {
buffer[pos] = timeSeparatorChar;
pos += timeSeparatorCharLen;
final int minutes = ms / 60000;
ms -= 60000 * minutes;
temp = minutes / 10;
buffer[pos++] = ((char) (temp + '0'));
// Do subtract to get remainder instead of doing % 10
buffer[pos++] = ((char) (minutes - 10 * temp + '0'));
}
return pos;
}
} }
private final FixedFormat fixedFormat; private final FixedFormat fixedFormat;
private final TimeZone timeZone; private final TimeZone timeZone;
private final int length; private final int length;
private final int secondFractionDigits; private final int secondFractionDigits;
private final FastDateFormat fastDateFormat; // may be null private final FastDateFormat fastDateFormat; // may be null
private final char timeSeparatorChar; private final char timeSeparatorChar;
private final char millisSeparatorChar; private final char millisSeparatorChar;
private final int timeSeparatorLength; private final int timeSeparatorLength;
private final int millisSeparatorLength; private final int millisSeparatorLength;
private final FixedTimeZoneFormat fixedTimeZoneFormat;
private volatile long midnightToday = 0; private volatile long midnightToday = 0;
private volatile long midnightTomorrow = 0; private volatile long midnightTomorrow = 0;
private final int[] dstOffsets = new int[25]; private final int[] dstOffsets = new int[25];
// cachedDate does not need to be volatile because // cachedDate does not need to be volatile because
// there is a write to a volatile field *after* cachedDate is modified, // there is a write to a volatile field *after* cachedDate is modified,
// and there is a read from a volatile field *before* cachedDate is read. // and there is a read from a volatile field *before* cachedDate is read.
// The Java memory model guarantees that because of the above, // The Java memory model guarantees that because of the above,
// changes to cachedDate in one thread are visible to other threads. // changes to cachedDate in one thread are visible to other threads.
skipping to change at line 285 skipping to change at line 415
* @param tz time zone * @param tz time zone
*/ */
FixedDateFormat(final FixedFormat fixedFormat, final TimeZone tz) { FixedDateFormat(final FixedFormat fixedFormat, final TimeZone tz) {
this(fixedFormat, tz, fixedFormat.getSecondFractionDigits()); this(fixedFormat, tz, fixedFormat.getSecondFractionDigits());
} }
/** /**
* Constructs a FixedDateFormat for the specified fixed format. * Constructs a FixedDateFormat for the specified fixed format.
* <p> * <p>
* Package protected for unit tests. * Package protected for unit tests.
* </p>
* *
* @param fixedFormat the fixed format * @param fixedFormat the fixed format
* @param tz time zone * @param tz time zone
* @param secondFractionDigits the number of digits specifying the fraction of the second to show * @param secondFractionDigits the number of digits specifying the fraction of the second to show
*/ */
FixedDateFormat(final FixedFormat fixedFormat, final TimeZone tz, final int secondFractionDigits) { FixedDateFormat(final FixedFormat fixedFormat, final TimeZone tz, final int secondFractionDigits) {
this.fixedFormat = Objects.requireNonNull(fixedFormat); this.fixedFormat = Objects.requireNonNull(fixedFormat);
this.timeZone = Objects.requireNonNull(tz); this.timeZone = Objects.requireNonNull(tz);
this.timeSeparatorChar = fixedFormat.timeSeparatorChar; this.timeSeparatorChar = fixedFormat.timeSeparatorChar;
this.timeSeparatorLength = fixedFormat.timeSeparatorLength; this.timeSeparatorLength = fixedFormat.timeSeparatorLength;
this.millisSeparatorChar = fixedFormat.millisSeparatorChar; this.millisSeparatorChar = fixedFormat.millisSeparatorChar;
this.millisSeparatorLength = fixedFormat.millisSeparatorLength; this.millisSeparatorLength = fixedFormat.millisSeparatorLength;
this.fixedTimeZoneFormat = fixedFormat.fixedTimeZoneFormat; // may be nu ll
this.length = fixedFormat.getLength(); this.length = fixedFormat.getLength();
this.secondFractionDigits = Math.max(1, Math.min(9, secondFractionDigits )); this.secondFractionDigits = Math.max(1, Math.min(9, secondFractionDigits ));
this.fastDateFormat = fixedFormat.getFastDateFormat(tz); this.fastDateFormat = fixedFormat.getFastDateFormat(tz);
} }
public static FixedDateFormat createIfSupported(final String... options) { public static FixedDateFormat createIfSupported(final String... options) {
if (options == null || options.length == 0 || options[0] == null) { if (options == null || options.length == 0 || options[0] == null) {
return new FixedDateFormat(FixedFormat.DEFAULT, TimeZone.getDefault( )); return new FixedDateFormat(FixedFormat.DEFAULT, TimeZone.getDefault( ));
} }
final TimeZone tz; final TimeZone tz;
if (options.length > 1) { if (options.length > 1) {
if (options[1] != null) { if (options[1] != null) {
tz = TimeZone.getTimeZone(options[1]); tz = TimeZone.getTimeZone(options[1]);
} else { } else {
tz = TimeZone.getDefault(); tz = TimeZone.getDefault();
} }
} else { } else {
tz = TimeZone.getDefault(); tz = TimeZone.getDefault();
} }
final FixedFormat withNanos = FixedFormat.lookupIgnoringNanos(options[0] final String option0 = options[0];
); final FixedFormat withNanos = FixedFormat.lookupIgnoringNanos(option0);
if (withNanos != null) { if (withNanos != null) {
final int secondFractionDigits = options[0].length() - FixedFormat.n final int[] nanoRange = FixedFormat.nanoRange(option0);
anoStart(options[0]); final int nanoStart = nanoRange[0];
final int nanoEnd = nanoRange[1];
final int secondFractionDigits = nanoEnd - nanoStart;
return new FixedDateFormat(withNanos, tz, secondFractionDigits); return new FixedDateFormat(withNanos, tz, secondFractionDigits);
} }
final FixedFormat type = FixedFormat.lookup(options[0]); final FixedFormat type = FixedFormat.lookup(option0);
return type == null ? null : new FixedDateFormat(type, tz); return type == null ? null : new FixedDateFormat(type, tz);
} }
/** /**
* Returns a new {@code FixedDateFormat} object for the specified {@code Fix edFormat} and a {@code TimeZone.getDefault()} TimeZone. * Returns a new {@code FixedDateFormat} object for the specified {@code Fix edFormat} and a {@code TimeZone.getDefault()} TimeZone.
* *
* @param format the format to use * @param format the format to use
* @return a new {@code FixedDateFormat} object * @return a new {@code FixedDateFormat} object
*/ */
public static FixedDateFormat create(final FixedFormat format) { public static FixedDateFormat create(final FixedFormat format) {
skipping to change at line 361 skipping to change at line 497
*/ */
public String getFormat() { public String getFormat() {
return fixedFormat.getPattern(); return fixedFormat.getPattern();
} }
/** /**
* Returns the time zone. * Returns the time zone.
* *
* @return the time zone * @return the time zone
*/ */
public TimeZone getTimeZone() { public TimeZone getTimeZone() {
return timeZone; return timeZone;
} }
/** /**
* <p>Returns the number of milliseconds since midnight in the time zone tha t this {@code FixedDateFormat} * <p>Returns the number of milliseconds since midnight in the time zone tha t this {@code FixedDateFormat}
* was constructed with for the specified currentTime.</p> * was constructed with for the specified currentTime.</p>
* <p>As a side effect, this method updates the cached formatted date and th e cached date demarcation timestamps * <p>As a side effect, this method updates the cached formatted date and th e cached date demarcation timestamps
* when the specified current time is outside the previously set demarcation timestamps for the start or end * when the specified current time is outside the previously set demarcation timestamps for the start or end
* of the current day.</p> * of the current day.</p>
skipping to change at line 439 skipping to change at line 574
} }
} }
public String formatInstant(final Instant instant) { public String formatInstant(final Instant instant) {
final char[] result = new char[length << 1]; // double size for locales with lengthy DateFormatSymbols final char[] result = new char[length << 1]; // double size for locales with lengthy DateFormatSymbols
final int written = formatInstant(instant, result, 0); final int written = formatInstant(instant, result, 0);
return new String(result, 0, written); return new String(result, 0, written);
} }
public int formatInstant(final Instant instant, final char[] buffer, final i nt startPos) { public int formatInstant(final Instant instant, final char[] buffer, final i nt startPos) {
int result = format(instant.getEpochMillisecond(), buffer, startPos); final long epochMillisecond = instant.getEpochMillisecond();
int result = format(epochMillisecond, buffer, startPos);
result -= digitsLessThanThree(); result -= digitsLessThanThree();
formatNanoOfMillisecond(instant.getNanoOfMillisecond(), buffer, startPos final int pos = formatNanoOfMillisecond(instant.getNanoOfMillisecond(),
+ result); buffer, startPos + result);
return result + digitsMorePreciseThanMillis(); return writeTimeZone(epochMillisecond, buffer, pos);
} }
private int digitsLessThanThree() { // in case user specified only 1 or 2 'n ' format characters private int digitsLessThanThree() { // in case user specified only 1 or 2 'n ' format characters
return Math.max(0, FixedFormat.MILLI_FRACTION_DIGITS - secondFractionDig its); return Math.max(0, FixedFormat.MILLI_FRACTION_DIGITS - secondFractionDig its);
} }
private int digitsMorePreciseThanMillis() {
return Math.max(0, secondFractionDigits - FixedFormat.MILLI_FRACTION_DIG
ITS);
}
// Profiling showed this method is important to log4j performance. Modify wi th care! // Profiling showed this method is important to log4j performance. Modify wi th care!
// 28 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes) // 28 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes)
public String format(final long epochMillis) { public String format(final long epochMillis) {
final char[] result = new char[length << 1]; // double size for locales with lengthy DateFormatSymbols final char[] result = new char[length << 1]; // double size for locales with lengthy DateFormatSymbols
final int written = format(epochMillis, result, 0); final int written = format(epochMillis, result, 0);
return new String(result, 0, written); return new String(result, 0, written);
} }
// Profiling showed this method is important to log4j performance. Modify wi th care! // Profiling showed this method is important to log4j performance. Modify wi th care!
// 31 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes) // 31 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes)
public int format(final long epochMillis, final char[] buffer, final int sta rtPos) { public int format(final long epochMillis, final char[] buffer, final int sta rtPos) {
// Calculate values by getting the ms values first and do then // Calculate values by getting the ms values first and do then
// calculate the hour minute and second values divisions. // calculate the hour minute and second values divisions.
// Get daytime in ms: this does fit into an int // Get daytime in ms: this does fit into an int
// int ms = (int) (time % 86400000); // int ms = (int) (time % 86400000);
final int ms = (int) (millisSinceMidnight(epochMillis)); final int ms = (int) (millisSinceMidnight(epochMillis));
writeDate(buffer, startPos); writeDate(buffer, startPos);
return writeTime(ms, buffer, startPos + dateLength) - startPos; final int pos = writeTime(ms, buffer, startPos + dateLength);
return pos - startPos;
} }
// Profiling showed this method is important to log4j performance. Modify wi th care! // Profiling showed this method is important to log4j performance. Modify wi th care!
// 22 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes) // 22 bytes (allows immediate JVM inlining: <= -XX:MaxInlineSize=35 bytes)
private void writeDate(final char[] buffer, final int startPos) { private void writeDate(final char[] buffer, final int startPos) {
if (cachedDate != null) { if (cachedDate != null) {
System.arraycopy(cachedDate, 0, buffer, startPos, dateLength); System.arraycopy(cachedDate, 0, buffer, startPos, dateLength);
} }
} }
skipping to change at line 533 skipping to change at line 666
ms -= 100 * temp; ms -= 100 * temp;
temp = ms / 10; temp = ms / 10;
buffer[pos++] = ((char) (temp + '0')); buffer[pos++] = ((char) (temp + '0'));
ms -= 10 * temp; ms -= 10 * temp;
buffer[pos++] = ((char) (ms + '0')); buffer[pos++] = ((char) (ms + '0'));
return pos; return pos;
} }
private int writeTimeZone(final long epochMillis, final char[] buffer, int p
os) {
if (fixedTimeZoneFormat != null) {
pos = fixedTimeZoneFormat.write(timeZone.getOffset(epochMillis), buf
fer, pos);
}
return pos;
}
static int[] TABLE = { static int[] TABLE = {
100000, // 0 100000, // 0
10000, // 1 10000, // 1
1000, // 2 1000, // 2
100, // 3 100, // 3
10, // 4 10, // 4
1, // 5 1, // 5
}; };
private void formatNanoOfMillisecond(int nanoOfMillisecond, final char[] buf fer, int pos) { private int formatNanoOfMillisecond(final int nanoOfMillisecond, final char[ ] buffer, int pos) {
int temp; int temp;
int remain = nanoOfMillisecond; int remain = nanoOfMillisecond;
for (int i = 0; i < secondFractionDigits - FixedFormat.MILLI_FRACTION_DI GITS; i++) { for (int i = 0; i < secondFractionDigits - FixedFormat.MILLI_FRACTION_DI GITS; i++) {
int divisor = TABLE[i]; final int divisor = TABLE[i];
temp = remain / divisor; temp = remain / divisor;
buffer[pos++] = ((char) (temp + '0')); buffer[pos++] = ((char) (temp + '0'));
remain -= divisor * temp; // equivalent of remain % 10 remain -= divisor * temp; // equivalent of remain % 10
} }
return pos;
} }
private int daylightSavingTime(final int hourOfDay) { private int daylightSavingTime(final int hourOfDay) {
return hourOfDay > 23 ? dstOffsets[23] : dstOffsets[hourOfDay]; return hourOfDay > 23 ? dstOffsets[23] : dstOffsets[hourOfDay];
} }
} }
 End of changes. 42 change blocks. 
44 lines changed or deleted 199 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)