Forum Stats

  • 3,728,152 Users
  • 2,245,559 Discussions
  • 7,853,357 Comments

Discussions

Bug Detection in Calendar.getDisplayName

L.D.L.
L.D.L. Member Posts: 19
edited March 2015 in Java 8 Questions

Operating System = Windows 7 version 6.1 running on amd64

Java; VM; Vendor = 1.8.0

Runtime = Java HotSpot(TM) 64-Bit Server VM 25.0-b70

Detect a bug in Java, specifically in the Calendar class will getDisplayName method. I put in the message code showing the error. If the code is executed you can see that the month March be repeated 2 times jumping the month of February.

Code Example:

import java.util.Calendar;

import java.util.Locale;

public class BugInCalendarDisplayName {

  public static void main(String[] args) {

    Calendar aMonth = Calendar.getInstance();

    aMonth.set(Calendar.MONTH, 0);

    System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

    aMonth = Calendar.getInstance();

    aMonth.set(Calendar.MONTH, 1);

    System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

    aMonth = Calendar.getInstance();

    aMonth.set(Calendar.MONTH, 2);

    System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

    aMonth = Calendar.getInstance();

    aMonth.set(Calendar.MONTH, 3);

    System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

    aMonth = Calendar.getInstance();

    aMonth.set(Calendar.MONTH, 4);

    System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

    aMonth = Calendar.getInstance();

    aMonth.set(Calendar.MONTH, 5);

    System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

    aMonth = Calendar.getInstance();

    aMonth.set(Calendar.MONTH, 6);

    System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

    aMonth = Calendar.getInstance();

    aMonth.set(Calendar.MONTH, 7);

    System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

    aMonth = Calendar.getInstance();

    aMonth.set(Calendar.MONTH, 8);

    System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

    aMonth = Calendar.getInstance();

    aMonth.set(Calendar.MONTH, 9);

    System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

    aMonth = Calendar.getInstance();

    aMonth.set(Calendar.MONTH, 10);

    System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

    aMonth = Calendar.getInstance();

    aMonth.set(Calendar.MONTH, 11);

    System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

  }

}

Obtained results of the code execution:

ENERO

MARZO

MARZO

ABRIL

MAYO

JUNIO

JULIO

AGOSTO

SEPTIEMBRE

OCTUBRE

NOVIEMBRE

DICIEMBRE

Answers

  • Rogerl-Oracle
    Rogerl-Oracle Member Posts: 214
    edited March 2015

    Can I ask that you file a bug at Report a Bug or Request a Feature?

    Thank you,

    Roger

  • Unknown
    edited March 2015
    Rogerl-Oracle wrote:
    
    Can I ask that you file a bug at Report a Bug or Request a Feature?
    
    

    That is NOT a bug.

  • Unknown
    edited March 2015
    Detect a bug in Java, specifically in the Calendar class will getDisplayName method.

    No - that is NOT a bug. That is the way the Calendar class works.

    If the code is executed you can see that the month March be repeated 2 times jumping the month of February.  

    Yes - that is the CORRECT behavior.

    You are ONLY changing the month and NOT the day so the day will stay the same, temporarily until you call a method that actually needs the correct value of a component. Then the entire value will be regenerated.

    Let's assume you executed that code today, March 30, 2015:

        aMonth.set(Calendar.MONTH, 0);

    That will set the month to January and the day will remain UNCHANGED at 30.

        aMonth.set(Calendar.MONTH, 1);
    

    That will set the month to February and the day will remain UNCHANGED at 30. Note that there IS NO day 30 in February but that is just an interim value.

        System.out.println(aMonth.getDisplayName(Calendar.MONTH, Calendar.LONG, Locale.getDefault()).toUpperCase());

    That will attempt to get a value so the actual date components will be resolved. The 'interim' value is Month=February and Day=30 which will get resolved to Month=March and Day=2.

    So that line print 'March' which is correct.

        aMonth.set(Calendar.MONTH, 2);
    

    That will set the month to March and the day will remain UNCHANGE at 2.

    The Java API for the Calendar class explains how the class uses LAZY computation to determine certain component values when other component values are changed. See the 'set' method also.

    Calendar (Java Platform SE 8 )

    set(f, value) changes calendar field f to value. In addition, it sets an internal member variable to indicate that calendar field f has been changed. Although calendar field f is changed immediately, the calendar's time value in milliseconds is not recomputed until the next call to get(), getTime(), getTimeInMillis(), add(), or roll() is made. Thus, multiple calls to set() do not trigger multiple, unnecessary computations. As a result of changing a calendar field using set(), other calendar fields may also change, depending on the calendar field, the calendar field value, and the calendar system. In addition, get(f) will not necessarily return value set by the call to the set method after the calendar fields have been recomputed. The specifics are determined by the concrete calendar class.
     
    Example: Consider a GregorianCalendar originally set to August 31, 1999. Calling set(Calendar.MONTH, Calendar.SEPTEMBER) sets the date to September 31, 1999. This is a temporary internal representation that resolves to October 1, 1999 if getTime()is then called. However, a call to set(Calendar.DAY_OF_MONTH, 30) before the call to getTime() sets the date to September 30, 1999, since no recomputation occurs after set() itself.
    

    See that example at the end? That is the SAME effect that you are seeing.

    You will see that effect when the day value is greater than the day value of the month you change to.

Sign In or Register to comment.