Since getActualMinimum()
and getGreatestMinimum()
are going to return the same value for every field what's the exact difference?
What's the difference between Calendar's getActualMinimum and getGreatestMinimum methods?
608 views Asked by Sangita Elango AtThere are 3 answers
There is no such method as leastminimum . The methods are getActualMaximum(), getActualMinimum(), getLeastMaximum(),getMaximum() and getMinimum()
getLeastMaximum() would return 28, getMaximum() would return 31, getMinimum() would return 1 for input as Calendar.DAY_OF_WEEK
The methods with 'Actual' will return the corresponding least or max values specific to the calendar instance value being used. ( Some calendars have 13 months in a year)
So the Actuals are relative and the other 3 methods are absolute.
I just read through the java doc and the below 2 links to arrive at this conclusion
I recommend you stop using the outdated and error-prone java.util
date-time API. In the modern date-time API, the smallestMaximum
refers to the smallest of the maximum values e.g. the maximum number of days for the month ranges from 28
(for Feb
) to 31
and therefore the smallestMaximum
is 28
.
Similar is the case with largestMinimum
whose name is self-descriptive. However, unlike the smallestMaximum
which holds the smallest value from the range of maximum values, I haven't been able to find the range of minimum values from which the largest value has to be held by the largestMinimum
. In other words, the values held by minimum
and largestMinimum
are same for all the ChronoField
s.
With the modern date-time API:
import java.time.temporal.ChronoField;
public class Main {
public static void main(String[] args) {
// e.g. Value range for ChronoField.DAY_OF_MONTH
System.out.println("Stats of ChronoField.DAY_OF_MONTH:");
System.out.println("Supported value range: " + ChronoField.DAY_OF_MONTH.range());
System.out.println("Maximum supported value: " + ChronoField.DAY_OF_MONTH.range().getMaximum());
System.out.println("Minimum supported value: " + ChronoField.DAY_OF_MONTH.range().getMinimum());
System.out.println("Largest minimum supported value: " + ChronoField.DAY_OF_MONTH.range().getLargestMinimum());
System.out
.println("Smallest maximum supported value: " + ChronoField.DAY_OF_MONTH.range().getSmallestMaximum());
// e.g. Value range for ChronoField.DAY_OF_YEAR
System.out.println("\nStats of ChronoField.DAY_OF_YEAR:");
System.out.println("Supported value range: " + ChronoField.DAY_OF_YEAR.range());
System.out.println("Maximum supported value: " + ChronoField.DAY_OF_YEAR.range().getMaximum());
System.out.println("Minimum supported value: " + ChronoField.DAY_OF_YEAR.range().getMinimum());
System.out.println("Largest minimum supported value: " + ChronoField.DAY_OF_YEAR.range().getLargestMinimum());
System.out.println("Smallest maximum supported value: " + ChronoField.DAY_OF_YEAR.range().getSmallestMaximum());
}
}
Output:
Stats of ChronoField.DAY_OF_MONTH:
Supported value range: 1 - 28/31
Maximum supported value: 31
Minimum supported value: 1
Largest minimum supported value: 1
Smallest maximum supported value: 28
Stats of ChronoField.DAY_OF_YEAR:
Supported value range: 1 - 365/366
Maximum supported value: 366
Minimum supported value: 1
Largest minimum supported value: 1
Smallest maximum supported value: 365
Check TemporalAccessor#range
for more details. Learn more about the modern date-time API from Trail: Date Time.
The
getActualMinimum()
method returns the minimum possible value that an attribute could possibly have. For example,Calendar.DAY_OF_MONTH
is never less than 1, since no month starts with a day numbered 0 or less.The
getGreatestMinimum()
method returns the maximum possible value thatgetActualMinimum()
could ever have. While in most cases these values will always be the same (months nearly always start with 1), the code allows for them to be different in some rare circumstances. UsinggetGreatestMinimum()
is appropriate for data validation scenarios.One place this can (and does) occur is when there are skipped dates or discontinuities in a calendar. Java's
GregorianCalendar
, for example implements dates in the Julian calendar before a cutover date, and the Gregorian calendar after that date, and thus has a gap of several days where dates in the calendar simply don't exist.The
Calendar
classgetGreatestMinimum()
method is abstract, so it is required to be implemented by a subclass. The JRE's implementation forGregorianCalendar
shows that it could differ on theDAY_OF_MONTH
field if the "skipped days" on the cutover month don't include the first of the month:Using this as a cue, you can use
setGregorianChange()
to set the cutover date for Julian-to-Gregorian change. By default it is 15 October 1582 (having skipped 10 days from 4 October 1582). Different Locales switched at different times, for example Great Britain switched on 14 September 1752 (the day after 2 September).By setting this cutover to a date in a month that makes the skipped days overlap the first of the month, we can generate these edge cases.
An actual locale-based discontinuity with a real cutover date is probably Romania, in which the day after 31 March 1919 was 14 April 1919. So in a Romanian locale, the month of April 1919 would only include days from 14 to 30, and
getGreatestMin()
will return 14.Since I don't have that locale installed I can change the cutover date to simulate what would happen:
Output:
Another edge case exists if you use
Date(Long.MIN_VALUE)
as the cutover, giving a "pure Gregorian" calendar with no gaps. But in that case, the "beginning of time" is on the 16th of the month (in the Gregorian calendar), so greatest min in that case is 16.Other calendar systems may have similar discontinuities and edge cases.