|
Java example source code file (BaseDateTimeField.java)
The BaseDateTimeField.java Java example source code/* * Copyright 2001-2005 Stephen Colebourne * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.joda.time.field; import java.util.Locale; import org.joda.time.DateTimeField; import org.joda.time.DateTimeFieldType; import org.joda.time.DurationField; import org.joda.time.IllegalFieldValueException; import org.joda.time.ReadablePartial; /** * BaseDateTimeField provides the common behaviour for DateTimeField * implementations. * <p> * This class should generally not be used directly by API users. The * DateTimeField class should be used when different kinds of DateTimeField * objects are to be referenced. * <p> * BaseDateTimeField is thread-safe and immutable, and its subclasses must * be as well. * * @author Brian S O'Neill * @since 1.0 * @see DecoratedDateTimeField */ public abstract class BaseDateTimeField extends DateTimeField { /** The field type. */ private final DateTimeFieldType iType; /** * Constructor. */ protected BaseDateTimeField(DateTimeFieldType type) { super(); if (type == null) { throw new IllegalArgumentException("The type must not be null"); } iType = type; } public final DateTimeFieldType getType() { return iType; } public final String getName() { return iType.getName(); } /** * @return true always */ public final boolean isSupported() { return true; } // Main access API //------------------------------------------------------------------------ /** * Get the value of this field from the milliseconds. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to query * @return the value of the field, in the units of the field */ public abstract int get(long instant); //----------------------------------------------------------------------- /** * Get the human-readable, text value of this field from the milliseconds. * If the specified locale is null, the default locale is used. * <p> * The default implementation returns getAsText(get(instant), locale). * * @param instant the milliseconds from 1970-01-01T00:00:00Z to query * @param locale the locale to use for selecting a text symbol, null means default * @return the text value of the field */ public String getAsText(long instant, Locale locale) { return getAsText(get(instant), locale); } /** * Get the human-readable, text value of this field from the milliseconds. * <p> * The default implementation calls {@link #getAsText(long, Locale)}. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to query * @return the text value of the field */ public final String getAsText(long instant) { return getAsText(instant, null); } /** * Get the human-readable, text value of this field from a partial instant. * If the specified locale is null, the default locale is used. * <p> * The default implementation returns getAsText(fieldValue, locale). * * @param partial the partial instant to query * @param fieldValue the field value of this field, provided for performance * @param locale the locale to use for selecting a text symbol, null for default * @return the text value of the field */ public String getAsText(ReadablePartial partial, int fieldValue, Locale locale) { return getAsText(fieldValue, locale); } /** * Get the human-readable, text value of this field from a partial instant. * If the specified locale is null, the default locale is used. * <p> * The default implementation calls {@link ReadablePartial#get(DateTimeFieldType)} * and {@link #getAsText(ReadablePartial, int, Locale)}. * * @param partial the partial instant to query * @param locale the locale to use for selecting a text symbol, null for default * @return the text value of the field */ public final String getAsText(ReadablePartial partial, Locale locale) { return getAsText(partial, partial.get(getType()), locale); } /** * Get the human-readable, text value of this field from the field value. * If the specified locale is null, the default locale is used. * <p> * The default implementation returns Integer.toString(get(instant)). * <p> * Note: subclasses that override this method should also override * getMaximumTextLength. * * @param fieldValue the numeric value to convert to text * @param locale the locale to use for selecting a text symbol, null for default * @return the text value of the field */ public String getAsText(int fieldValue, Locale locale) { return Integer.toString(fieldValue); } //----------------------------------------------------------------------- /** * Get the human-readable, short text value of this field from the milliseconds. * If the specified locale is null, the default locale is used. * <p> * The default implementation returns getAsShortText(get(instant), locale). * * @param instant the milliseconds from 1970-01-01T00:00:00Z to query * @param locale the locale to use for selecting a text symbol, null means default * @return the text value of the field */ public String getAsShortText(long instant, Locale locale) { return getAsShortText(get(instant), locale); } /** * Get the human-readable, short text value of this field from the milliseconds. * <p> * The default implementation calls {@link #getAsShortText(long, Locale)}. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to query * @return the text value of the field */ public final String getAsShortText(long instant) { return getAsShortText(instant, null); } /** * Get the human-readable, short text value of this field from a partial instant. * If the specified locale is null, the default locale is used. * <p> * The default implementation returns getAsShortText(fieldValue, locale). * * @param partial the partial instant to query * @param fieldValue the field value of this field, provided for performance * @param locale the locale to use for selecting a text symbol, null for default * @return the text value of the field */ public String getAsShortText(ReadablePartial partial, int fieldValue, Locale locale) { return getAsShortText(fieldValue, locale); } /** * Get the human-readable, short text value of this field from a partial instant. * If the specified locale is null, the default locale is used. * <p> * The default implementation calls {@link ReadablePartial#get(DateTimeFieldType)} * and {@link #getAsText(ReadablePartial, int, Locale)}. * * @param partial the partial instant to query * @param locale the locale to use for selecting a text symbol, null for default * @return the text value of the field */ public final String getAsShortText(ReadablePartial partial, Locale locale) { return getAsShortText(partial, partial.get(getType()), locale); } /** * Get the human-readable, short text value of this field from the field value. * If the specified locale is null, the default locale is used. * <p> * The default implementation returns getAsText(fieldValue, locale). * <p> * Note: subclasses that override this method should also override * getMaximumShortTextLength. * * @param fieldValue the numeric value to convert to text * @param locale the locale to use for selecting a text symbol, null for default * @return the text value of the field */ public String getAsShortText(int fieldValue, Locale locale) { return getAsText(fieldValue, locale); } //----------------------------------------------------------------------- /** * Adds a value (which may be negative) to the instant value, * overflowing into larger fields if necessary. * <p> * The value will be added to this field. If the value is too large to be * added solely to this field, larger fields will increase as required. * Smaller fields should be unaffected, except where the result would be * an invalid value for a smaller field. In this case the smaller field is * adjusted to be in range. * <p> * For example, in the ISO chronology:<br> * 2000-08-20 add six months is 2001-02-20<br> * 2000-08-20 add twenty months is 2002-04-20<br> * 2000-08-20 add minus nine months is 1999-11-20<br> * 2001-01-31 add one month is 2001-02-28<br> * 2001-01-31 add two months is 2001-03-31<br> * * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to * @param value the value to add, in the units of the field * @return the updated milliseconds */ public long add(long instant, int value) { return getDurationField().add(instant, value); } /** * Adds a value (which may be negative) to the instant value, * overflowing into larger fields if necessary. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to * @param value the long value to add, in the units of the field * @return the updated milliseconds * @throws IllegalArgumentException if value is too large * @see #add(long,int) */ public long add(long instant, long value) { return getDurationField().add(instant, value); } /** * Adds a value (which may be negative) to the partial instant, * throwing an exception if the maximum size of the instant is reached. * <p> * The value will be added to this field, overflowing into larger fields * if necessary. Smaller fields should be unaffected, except where the * result would be an invalid value for a smaller field. In this case the * smaller field is adjusted to be in range. * <p> * Partial instants only contain some fields. This may result in a maximum * possible value, such as TimeOfDay being limited to 23:59:59:999. If this * limit is breached by the add an exception is thrown. * <p> * For example, in the ISO chronology:<br> * 2000-08-20 add six months is 2000-02-20<br> * 2000-08-20 add twenty months is 2000-04-20<br> * 2000-08-20 add minus nine months is 2000-11-20<br> * 2001-01-31 add one month is 2001-02-28<br> * 2001-01-31 add two months is 2001-03-31<br> * * @param instant the partial instant * @param fieldIndex the index of this field in the partial * @param values the values of the partial instant which should be updated * @param valueToAdd the value to add, in the units of the field * @return the passed in values * @throws IllegalArgumentException if the value is invalid or the maximum instant is reached */ public int[] add(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd) { if (valueToAdd == 0) { return values; } // there are more efficient algorithms than this (especially for time only fields) // trouble is when dealing with days and months, so we use this technique of // adding/removing one from the larger field at a time DateTimeField nextField = null; while (valueToAdd > 0) { int max = getMaximumValue(instant, values); long proposed = values[fieldIndex] + valueToAdd; if (proposed <= max) { values[fieldIndex] = (int) proposed; break; } if (nextField == null) { if (fieldIndex == 0) { throw new IllegalArgumentException("Maximum value exceeded for add"); } nextField = instant.getField(fieldIndex - 1); // test only works if this field is UTC (ie. local) if (getRangeDurationField().getType() != nextField.getDurationField().getType()) { throw new IllegalArgumentException("Fields invalid for add"); } } valueToAdd -= (max + 1) - values[fieldIndex]; // reduce the amount to add values = nextField.add(instant, fieldIndex - 1, values, 1); // add 1 to next bigger field values[fieldIndex] = getMinimumValue(instant, values); // reset this field to zero } while (valueToAdd < 0) { int min = getMinimumValue(instant, values); long proposed = values[fieldIndex] + valueToAdd; if (proposed >= min) { values[fieldIndex] = (int) proposed; break; } if (nextField == null) { if (fieldIndex == 0) { throw new IllegalArgumentException("Maximum value exceeded for add"); } nextField = instant.getField(fieldIndex - 1); if (getRangeDurationField().getType() != nextField.getDurationField().getType()) { throw new IllegalArgumentException("Fields invalid for add"); } } valueToAdd -= (min - 1) - values[fieldIndex]; // reduce the amount to add values = nextField.add(instant, fieldIndex - 1, values, -1); // subtract 1 from next bigger field values[fieldIndex] = getMaximumValue(instant, values); // reset this field to max value } return set(instant, fieldIndex, values, values[fieldIndex]); // adjusts smaller fields } /** * Adds a value (which may be negative) to the partial instant, * wrapping the whole partial if the maximum size of the partial is reached. * <p> * The value will be added to this field, overflowing into larger fields * if necessary. Smaller fields should be unaffected, except where the * result would be an invalid value for a smaller field. In this case the * smaller field is adjusted to be in range. * <p> * Partial instants only contain some fields. This may result in a maximum * possible value, such as TimeOfDay normally being limited to 23:59:59:999. * If ths limit is reached by the addition, this method will wrap back to * 00:00:00.000. In fact, you would generally only use this method for * classes that have a limitation such as this. * <p> * For example, in the ISO chronology:<br> * 10:20:30 add 20 minutes is 10:40:30<br> * 10:20:30 add 45 minutes is 11:05:30<br> * 10:20:30 add 16 hours is 02:20:30<br> * * @param instant the partial instant * @param fieldIndex the index of this field in the partial * @param values the values of the partial instant which should be updated * @param valueToAdd the value to add, in the units of the field * @return the passed in values * @throws IllegalArgumentException if the value is invalid or the maximum instant is reached */ public int[] addWrapPartial(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd) { if (valueToAdd == 0) { return values; } // there are more efficient algorithms than this (especially for time only fields) // trouble is when dealing with days and months, so we use this technique of // adding/removing one from the larger field at a time DateTimeField nextField = null; while (valueToAdd > 0) { int max = getMaximumValue(instant, values); long proposed = values[fieldIndex] + valueToAdd; if (proposed <= max) { values[fieldIndex] = (int) proposed; break; } if (nextField == null) { if (fieldIndex == 0) { valueToAdd -= (max + 1) - values[fieldIndex]; values[fieldIndex] = getMinimumValue(instant, values); continue; } nextField = instant.getField(fieldIndex - 1); // test only works if this field is UTC (ie. local) if (getRangeDurationField().getType() != nextField.getDurationField().getType()) { throw new IllegalArgumentException("Fields invalid for add"); } } valueToAdd -= (max + 1) - values[fieldIndex]; // reduce the amount to add values = nextField.addWrapPartial(instant, fieldIndex - 1, values, 1); // add 1 to next bigger field values[fieldIndex] = getMinimumValue(instant, values); // reset this field to zero } while (valueToAdd < 0) { int min = getMinimumValue(instant, values); long proposed = values[fieldIndex] + valueToAdd; if (proposed >= min) { values[fieldIndex] = (int) proposed; break; } if (nextField == null) { if (fieldIndex == 0) { valueToAdd -= (min - 1) - values[fieldIndex]; values[fieldIndex] = getMaximumValue(instant, values); continue; } nextField = instant.getField(fieldIndex - 1); if (getRangeDurationField().getType() != nextField.getDurationField().getType()) { throw new IllegalArgumentException("Fields invalid for add"); } } valueToAdd -= (min - 1) - values[fieldIndex]; // reduce the amount to add values = nextField.addWrapPartial(instant, fieldIndex - 1, values, -1); // subtract 1 from next bigger field values[fieldIndex] = getMaximumValue(instant, values); // reset this field to max value } return set(instant, fieldIndex, values, values[fieldIndex]); // adjusts smaller fields } /** * Adds a value (which may be negative) to the instant value, * wrapping within this field. * <p> * The value will be added to this field. If the value is too large to be * added solely to this field then it wraps. Larger fields are always * unaffected. Smaller fields should be unaffected, except where the * result would be an invalid value for a smaller field. In this case the * smaller field is adjusted to be in range. * <p> * For example, in the ISO chronology:<br> * 2000-08-20 addWrapField six months is 2000-02-20<br> * 2000-08-20 addWrapField twenty months is 2000-04-20<br> * 2000-08-20 addWrapField minus nine months is 2000-11-20<br> * 2001-01-31 addWrapField one month is 2001-02-28<br> * 2001-01-31 addWrapField two months is 2001-03-31<br> * <p> * The default implementation internally calls set. Subclasses are * encouraged to provide a more efficient implementation. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to add to * @param value the value to add, in the units of the field * @return the updated milliseconds */ public long addWrapField(long instant, int value) { int current = get(instant); int wrapped = FieldUtils.getWrappedValue (current, value, getMinimumValue(instant), getMaximumValue(instant)); return set(instant, wrapped); } /** * Adds a value (which may be negative) to the partial instant, * wrapping within this field. * <p> * The value will be added to this field. If the value is too large to be * added solely to this field then it wraps. Larger fields are always * unaffected. Smaller fields should be unaffected, except where the * result would be an invalid value for a smaller field. In this case the * smaller field is adjusted to be in range. * <p> * For example, in the ISO chronology:<br> * 2000-08-20 addWrapField six months is 2000-02-20<br> * 2000-08-20 addWrapField twenty months is 2000-04-20<br> * 2000-08-20 addWrapField minus nine months is 2000-11-20<br> * 2001-01-31 addWrapField one month is 2001-02-28<br> * 2001-01-31 addWrapField two months is 2001-03-31<br> * <p> * The default implementation internally calls set. Subclasses are * encouraged to provide a more efficient implementation. * * @param instant the partial instant * @param fieldIndex the index of this field in the instant * @param values the values of the partial instant which should be updated * @param valueToAdd the value to add, in the units of the field * @return the passed in values * @throws IllegalArgumentException if the value is invalid */ public int[] addWrapField(ReadablePartial instant, int fieldIndex, int[] values, int valueToAdd) { int current = values[fieldIndex]; int wrapped = FieldUtils.getWrappedValue (current, valueToAdd, getMinimumValue(instant), getMaximumValue(instant)); return set(instant, fieldIndex, values, wrapped); // adjusts smaller fields } //----------------------------------------------------------------------- /** * Computes the difference between two instants, as measured in the units * of this field. Any fractional units are dropped from the result. Calling * getDifference reverses the effect of calling add. In the following code: * * <pre> * long instant = ... * int v = ... * int age = getDifference(add(instant, v), instant); * </pre> * * The value 'age' is the same as the value 'v'. * * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to * subtract from * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to * subtract off the minuend * @return the difference in the units of this field */ public int getDifference(long minuendInstant, long subtrahendInstant) { return getDurationField().getDifference(minuendInstant, subtrahendInstant); } /** * Computes the difference between two instants, as measured in the units * of this field. Any fractional units are dropped from the result. Calling * getDifference reverses the effect of calling add. In the following code: * * <pre> * long instant = ... * long v = ... * long age = getDifferenceAsLong(add(instant, v), instant); * </pre> * * The value 'age' is the same as the value 'v'. * * @param minuendInstant the milliseconds from 1970-01-01T00:00:00Z to * subtract from * @param subtrahendInstant the milliseconds from 1970-01-01T00:00:00Z to * subtract off the minuend * @return the difference in the units of this field */ public long getDifferenceAsLong(long minuendInstant, long subtrahendInstant) { return getDurationField().getDifferenceAsLong(minuendInstant, subtrahendInstant); } /** * Sets a value in the milliseconds supplied. * <p> * The value of this field will be set. * If the value is invalid, an exception if thrown. * <p> * If setting this field would make other fields invalid, then those fields * may be changed. For example if the current date is the 31st January, and * the month is set to February, the day would be invalid. Instead, the day * would be changed to the closest value - the 28th/29th February as appropriate. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to set in * @param value the value to set, in the units of the field * @return the updated milliseconds * @throws IllegalArgumentException if the value is invalid */ public abstract long set(long instant, int value); /** * Sets a value using the specified partial instant. * <p> * The value of this field (specified by the index) will be set. * If the value is invalid, an exception if thrown. * <p> * If setting this field would make other fields invalid, then those fields * may be changed. For example if the current date is the 31st January, and * the month is set to February, the day would be invalid. Instead, the day * would be changed to the closest value - the 28th/29th February as appropriate. * * @param partial the partial instant * @param fieldIndex the index of this field in the instant * @param values the values to update * @param newValue the value to set, in the units of the field * @return the updated values * @throws IllegalArgumentException if the value is invalid */ public int[] set(ReadablePartial partial, int fieldIndex, int[] values, int newValue) { FieldUtils.verifyValueBounds(this, newValue, getMinimumValue(partial, values), getMaximumValue(partial, values)); values[fieldIndex] = newValue; // may need to adjust smaller fields for (int i = fieldIndex + 1; i < partial.size(); i++) { DateTimeField field = partial.getField(i); if (values[i] > field.getMaximumValue(partial, values)) { values[i] = field.getMaximumValue(partial, values); } if (values[i] < field.getMinimumValue(partial, values)) { values[i] = field.getMinimumValue(partial, values); } } return values; } /** * Sets a value in the milliseconds supplied from a human-readable, text value. * If the specified locale is null, the default locale is used. * <p> * This implementation uses <code>convertText(String, Locale) and * {@link #set(long, int)}. * <p> * Note: subclasses that override this method should also override * getAsText. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to set in * @param text the text value to set * @param locale the locale to use for selecting a text symbol, null for default * @return the updated milliseconds * @throws IllegalArgumentException if the text value is invalid */ public long set(long instant, String text, Locale locale) { int value = convertText(text, locale); return set(instant, value); } /** * Sets a value in the milliseconds supplied from a human-readable, text value. * <p> * This implementation uses {@link #set(long, String, Locale)}. * <p> * Note: subclasses that override this method should also override getAsText. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to set in * @param text the text value to set * @return the updated milliseconds * @throws IllegalArgumentException if the text value is invalid */ public final long set(long instant, String text) { return set(instant, text, null); } /** * Sets a value in the milliseconds supplied from a human-readable, text value. * If the specified locale is null, the default locale is used. * <p> * This implementation uses <code>convertText(String, Locale) and * {@link #set(ReadablePartial, int, int[], int)}. * * @param instant the partial instant * @param fieldIndex the index of this field in the instant * @param values the values of the partial instant which should be updated * @param text the text value to set * @param locale the locale to use for selecting a text symbol, null for default * @return the passed in values * @throws IllegalArgumentException if the text value is invalid */ public int[] set(ReadablePartial instant, int fieldIndex, int[] values, String text, Locale locale) { int value = convertText(text, locale); return set(instant, fieldIndex, values, value); } /** * Convert the specified text and locale into a value. * * @param text the text to convert * @param locale the locale to convert using * @return the value extracted from the text * @throws IllegalArgumentException if the text is invalid */ protected int convertText(String text, Locale locale) { try { return Integer.parseInt(text); } catch (NumberFormatException ex) { throw new IllegalFieldValueException(getType(), text); } } // Extra information API //------------------------------------------------------------------------ /** * Returns the duration per unit value of this field. For example, if this * field represents "hour of day", then the unit duration is an hour. * * @return the duration of this field, or UnsupportedDurationField if field * has no duration */ public abstract DurationField getDurationField(); /** * Returns the range duration of this field. For example, if this field * represents "hour of day", then the range duration is a day. * * @return the range duration of this field, or null if field has no range */ public abstract DurationField getRangeDurationField(); /** * Returns whether this field is 'leap' for the specified instant. * <p> * For example, a leap year would return true, a non leap year would return * false. * <p> * This implementation returns false. * * @return true if the field is 'leap' */ public boolean isLeap(long instant) { return false; } /** * Gets the amount by which this field is 'leap' for the specified instant. * <p> * For example, a leap year would return one, a non leap year would return * zero. * <p> * This implementation returns zero. */ public int getLeapAmount(long instant) { return 0; } /** * If this field were to leap, then it would be in units described by the * returned duration. If this field doesn't ever leap, null is returned. * <p> * This implementation returns null. */ public DurationField getLeapDurationField() { return null; } /** * Get the minimum allowable value for this field. * * @return the minimum valid value for this field, in the units of the * field */ public abstract int getMinimumValue(); /** * Get the minimum value for this field evaluated at the specified time. * <p> * This implementation returns the same as {@link #getMinimumValue()}. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to query * @return the minimum value for this field, in the units of the field */ public int getMinimumValue(long instant) { return getMinimumValue(); } /** * Get the minimum value for this field evaluated at the specified instant. * <p> * This implementation returns the same as {@link #getMinimumValue()}. * * @param instant the partial instant to query * @return the minimum value for this field, in the units of the field */ public int getMinimumValue(ReadablePartial instant) { return getMinimumValue(); } /** * Get the minimum value for this field using the partial instant and * the specified values. * <p> * This implementation returns the same as {@link #getMinimumValue(ReadablePartial)}. * * @param instant the partial instant to query * @param values the values to use * @return the minimum value for this field, in the units of the field */ public int getMinimumValue(ReadablePartial instant, int[] values) { return getMinimumValue(instant); } /** * Get the maximum allowable value for this field. * * @return the maximum valid value for this field, in the units of the * field */ public abstract int getMaximumValue(); /** * Get the maximum value for this field evaluated at the specified time. * <p> * This implementation returns the same as {@link #getMaximumValue()}. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to query * @return the maximum value for this field, in the units of the field */ public int getMaximumValue(long instant) { return getMaximumValue(); } /** * Get the maximum value for this field evaluated at the specified instant. * <p> * This implementation returns the same as {@link #getMaximumValue()}. * * @param instant the partial instant to query * @return the maximum value for this field, in the units of the field */ public int getMaximumValue(ReadablePartial instant) { return getMaximumValue(); } /** * Get the maximum value for this field using the partial instant and * the specified values. * <p> * This implementation returns the same as {@link #getMaximumValue(ReadablePartial)}. * * @param instant the partial instant to query * @param values the values to use * @return the maximum value for this field, in the units of the field */ public int getMaximumValue(ReadablePartial instant, int[] values) { return getMaximumValue(instant); } /** * Get the maximum text value for this field. The default implementation * returns the equivalent of Integer.toString(getMaximumValue()).length(). * * @param locale the locale to use for selecting a text symbol * @return the maximum text length */ public int getMaximumTextLength(Locale locale) { int max = getMaximumValue(); if (max >= 0) { if (max < 10) { return 1; } else if (max < 100) { return 2; } else if (max < 1000) { return 3; } } return Integer.toString(max).length(); } /** * Get the maximum short text value for this field. The default * implementation returns getMaximumTextLength(). * * @param locale the locale to use for selecting a text symbol * @return the maximum short text length */ public int getMaximumShortTextLength(Locale locale) { return getMaximumTextLength(locale); } // Calculation API //------------------------------------------------------------------------ /** * Round to the lowest whole unit of this field. After rounding, the value * of this field and all fields of a higher magnitude are retained. The * fractional millis that cannot be expressed in whole increments of this * field are set to minimum. * <p> * For example, a datetime of 2002-11-02T23:34:56.789, rounded to the * lowest whole hour is 2002-11-02T23:00:00.000. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to round * @return rounded milliseconds */ public abstract long roundFloor(long instant); /** * Round to the highest whole unit of this field. The value of this field * and all fields of a higher magnitude may be incremented in order to * achieve this result. The fractional millis that cannot be expressed in * whole increments of this field are set to minimum. * <p> * For example, a datetime of 2002-11-02T23:34:56.789, rounded to the * highest whole hour is 2002-11-03T00:00:00.000. * <p> * The default implementation calls roundFloor, and if the instant is * modified as a result, adds one field unit. Subclasses are encouraged to * provide a more efficient implementation. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to round * @return rounded milliseconds */ public long roundCeiling(long instant) { long newInstant = roundFloor(instant); if (newInstant != instant) { instant = add(newInstant, 1); } return instant; } /** * Round to the nearest whole unit of this field. If the given millisecond * value is closer to the floor or is exactly halfway, this function * behaves like roundFloor. If the millisecond value is closer to the * ceiling, this function behaves like roundCeiling. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to round * @return rounded milliseconds */ public long roundHalfFloor(long instant) { long floor = roundFloor(instant); long ceiling = roundCeiling(instant); long diffFromFloor = instant - floor; long diffToCeiling = ceiling - instant; if (diffFromFloor <= diffToCeiling) { // Closer to the floor, or halfway - round floor return floor; } else { return ceiling; } } /** * Round to the nearest whole unit of this field. If the given millisecond * value is closer to the floor, this function behaves like roundFloor. If * the millisecond value is closer to the ceiling or is exactly halfway, * this function behaves like roundCeiling. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to round * @return rounded milliseconds */ public long roundHalfCeiling(long instant) { long floor = roundFloor(instant); long ceiling = roundCeiling(instant); long diffFromFloor = instant - floor; long diffToCeiling = ceiling - instant; if (diffToCeiling <= diffFromFloor) { // Closer to the ceiling, or halfway - round ceiling return ceiling; } else { return floor; } } /** * Round to the nearest whole unit of this field. If the given millisecond * value is closer to the floor, this function behaves like roundFloor. If * the millisecond value is closer to the ceiling, this function behaves * like roundCeiling. * <p> * If the millisecond value is exactly halfway between the floor and * ceiling, the ceiling is chosen over the floor only if it makes this * field's value even. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to round * @return rounded milliseconds */ public long roundHalfEven(long instant) { long floor = roundFloor(instant); long ceiling = roundCeiling(instant); long diffFromFloor = instant - floor; long diffToCeiling = ceiling - instant; if (diffFromFloor < diffToCeiling) { // Closer to the floor - round floor return floor; } else if (diffToCeiling < diffFromFloor) { // Closer to the ceiling - round ceiling return ceiling; } else { // Round to the instant that makes this field even. If both values // make this field even (unlikely), favor the ceiling. if ((get(ceiling) & 1) == 0) { return ceiling; } return floor; } } /** * Returns the fractional duration milliseconds of this field. In other * words, calling remainder returns the duration that roundFloor would * subtract. * <p> * For example, on a datetime of 2002-11-02T23:34:56.789, the remainder by * hour is 34 minutes and 56.789 seconds. * <p> * The default implementation computes * <code>instant - roundFloor(instant). Subclasses are encouraged to * provide a more efficient implementation. * * @param instant the milliseconds from 1970-01-01T00:00:00Z to get the * remainder * @return remainder duration, in milliseconds */ public long remainder(long instant) { return instant - roundFloor(instant); } /** * Get a suitable debug string. * * @return debug string */ public String toString() { return "DateTimeField[" + getName() + ']'; } } Other Java examples (source code examples)Here is a short list of links related to this Java BaseDateTimeField.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.