Possible bug in Calendar

Discussion in 'Java' started by Harold Yarmouth, Oct 27, 2008.

  1. Calendar calendar = Calendar.getInstance();
    calendar.set(2003,9,10,13,8,42);
    Date date = calendar.getTime();



    When the above code is run twice with some time passing in between, the
    resulting Date objects compare unequal!


    The getTime methods returned the following values from two runs of the
    above code:

    1065805722140
    1065805722828

    As you can see, the last three digits appear to vary randomly.


    Clearly, this should not be the case. Calling calendar.set with the
    maximal precision (six values) should completely determine the resulting
    Date object. It looks like it uses the last three digits of the current
    millisecond value of the system clock to "fill in the blanks" when it
    really ought to use zeros.
     
    Harold Yarmouth, Oct 27, 2008
    #1
    1. Advertising

  2. Harold Yarmouth wrote:
    > Calendar calendar = Calendar.getInstance();
    > calendar.set(2003,9,10,13,8,42);
    > Date date = calendar.getTime();
    >
    >
    >
    > When the above code is run twice with some time passing in between, the
    > resulting Date objects compare unequal!
    >
    >
    > The getTime methods returned the following values from two runs of the
    > above code:
    >
    > 1065805722140
    > 1065805722828
    >
    > As you can see, the last three digits appear to vary randomly.
    >
    >
    > Clearly, this should not be the case. Calling calendar.set with the
    > maximal precision (six values) should completely determine the resulting
    > Date object. It looks like it uses the last three digits of the current
    > millisecond value of the system clock to "fill in the blanks" when it
    > really ought to use zeros.


    The JDK documentation says this:

    "Sets the values for the fields YEAR, MONTH, DAY_OF_MONTH, HOUR, MINUTE,
    and SECOND. Previous values of other fields are retained. If this is not
    desired, call clear() first."

    So the behaviour you have noted is by design.

    Mark Thornton
     
    Mark Thornton, Oct 27, 2008
    #2
    1. Advertising

  3. Mon, 27 Oct 2008 16:42:21 -0400, /Harold Yarmouth/:

    > Calendar calendar = Calendar.getInstance();
    > calendar.set(2003,9,10,13,8,42);
    > Date date = calendar.getTime();
    >
    > When the above code is run twice with some time passing in between, the
    > resulting Date objects compare unequal!


    I think it is o.k. as you're not setting the field for the
    milliseconds which is left at what it got set during the time of the
    calendar construction. The documentation for the Calendar.set(int,
    int, int, int, int, int) method
    <http://java.sun.com/javase/6/docs/api/java/util/Calendar.html#set%28int,%20int,%20int,%20int,%20int,%20int%29>
    says:

    > Sets the values for the fields YEAR, MONTH, DAY_OF_MONTH, HOUR,
    > MINUTE, and SECOND. Previous values of other fields are retained.
    > If this is not desired, call clear() first.


    So you may either call clear() or set(MILLISECOND, 0):

    Calendar calendar = Calendar.getInstance();
    calendar.clear();
    calendar.set(2003,9,10,13,8,42);
    Date date = calendar.getTime();
    System.out.println(date.getTime());

    calendar = Calendar.getInstance();
    calendar.set(Calendar.MILLISECOND, 0);
    calendar.set(2003,9,10,13,8,42);
    Date date2 = calendar.getTime();
    System.out.println(date2.getTime());

    System.out.println(date.equals(date2));

    --
    Stanimir
     
    Stanimir Stamenkov, Oct 27, 2008
    #3
  4. Mark Thornton wrote:
    > The JDK documentation says this:
    >
    > "Sets the values for the fields YEAR, MONTH, DAY_OF_MONTH, HOUR, MINUTE,
    > and SECOND. Previous values of other fields are retained. If this is not
    > desired, call clear() first."
    >
    > So the behaviour you have noted is by design.


    Nope.

    If Calendar lacks a hidden, seventh milliseconds field, the six-argument
    set method sets all of the fields and retains no old values, contrary to
    what's observed.

    If, on the other hand, Calendar has a hidden, seventh milliseconds
    field, since this value is not being set by the second call to set, it
    should retain the previous value, i.e. the value it had when the first
    Date object was constructed. The second Date value should therefore have
    the same milliseconds last-three-digits as the first Date value, again
    contrary to what's observed.

    So, this still looks like a bug to me.
     
    Harold Yarmouth, Oct 27, 2008
    #4
  5. Stanimir Stamenkov wrote:
    > Mon, 27 Oct 2008 16:42:21 -0400, /Harold Yarmouth/:
    >
    >> Calendar calendar = Calendar.getInstance();
    >> calendar.set(2003,9,10,13,8,42);
    >> Date date = calendar.getTime();
    >>
    >> When the above code is run twice with some time passing in between,
    >> the resulting Date objects compare unequal!

    >
    > I think it is o.k. as you're not setting the field for the milliseconds


    If there is such a field, it should either be zero or the
    previously-used value, not something random.

    I have the feeling that Calendar.getInstance() is not returning a
    singleton, and that it is also not zeroing out newly-created instances.

    (And since Calendar is really a mutable Date mainly used to get
    immutable Dates, perhaps they should have called it DateBuilder?)
     
    Harold Yarmouth, Oct 27, 2008
    #5
  6. Mon, 27 Oct 2008 17:26:40 -0400, /Harold Yarmouth/:
    > Stanimir Stamenkov wrote:
    >> Mon, 27 Oct 2008 16:42:21 -0400, /Harold Yarmouth/:
    >>
    >>> Calendar calendar = Calendar.getInstance();
    >>> calendar.set(2003,9,10,13,8,42);
    >>> Date date = calendar.getTime();
    >>>
    >>> When the above code is run twice with some time passing in between,
    >>> the resulting Date objects compare unequal!

    >>
    >> I think it is o.k. as you're not setting the field for the milliseconds

    >
    > If there is such a field, it should either be zero or the
    > previously-used value, not something random.


    Nope, it is not random. Calendar.getInstance()
    <http://java.sun.com/javase/6/docs/api/java/util/Calendar.html#getInstance()>:

    > ... The Calendar returned is based on the current time...


    So you're ending up with a calendar with milliseconds set based on
    the current time.

    Mon, 27 Oct 2008 17:26:40 -0400, /Harold Yarmouth/:

    > I have the feeling that Calendar.getInstance() is not returning a
    > singleton, and that it is also not zeroing out newly-created instances.


    It is not returning a singleton for sure, why should it? There's no
    mention for a singleton in the documentation nor it sounds logical
    to be the case as you're probably realizing next.

    > (And since Calendar is really a mutable Date mainly used to get
    > immutable Dates, perhaps they should have called it DateBuilder?)


    --
    Stanimir
     
    Stanimir Stamenkov, Oct 27, 2008
    #6
  7. Harold Yarmouth

    Mark Space Guest

    Stanimir Stamenkov wrote:

    > It is not returning a singleton for sure, why should it? There's no



    Yeah, not a singleton. It's just a plain old factory method.
     
    Mark Space, Oct 27, 2008
    #7
  8. Harold Yarmouth wrote:
    > Mark Thornton wrote:
    >> The JDK documentation says this:
    >>
    >> "Sets the values for the fields YEAR, MONTH, DAY_OF_MONTH, HOUR,
    >> MINUTE, and SECOND. Previous values of other fields are retained. If
    >> this is not desired, call clear() first."
    >>
    >> So the behaviour you have noted is by design.

    >
    > Nope.


    Yep.

    >
    > If, on the other hand, Calendar has a hidden, seventh milliseconds
    > field, since this value is not being set by the second call to set, it
    > should retain the previous value, i.e. the value it had when the first
    > Date object was constructed.


    Calendar.getInstance() returns a Calendar representing "now", so each time
    it's called you will see a different milliseconds value. To get the
    behavior you're looking for, you need

    Calendar calendar = Calendar.getInstance();
    calendar.set(2003,9,10,13,8,42);
    calendar.set(Calendar.MILLISECOND, 0);

    Yes, this is obnoxious.
     
    Mike Schilling, Oct 27, 2008
    #8
  9. Stanimir Stamenkov wrote:
    >
    >> I have the feeling that Calendar.getInstance() is not returning a
    >> singleton, and that it is also not zeroing out newly-created instances.

    >
    > It is not returning a singleton for sure, why should it? There's no
    > mention for a singleton in the documentation nor it sounds logical to be
    > the case as you're probably realizing next.
    >


    Given that Calendar is not thread safe and that users might wish to use
    Calendar objects concurrently in different threads it would be broken if
    it were a singleton.

    Mark Thornton
     
    Mark Thornton, Oct 27, 2008
    #9
  10. Harold Yarmouth

    Arne Vajhøj Guest

    Harold Yarmouth wrote:
    > Mark Thornton wrote:
    >> The JDK documentation says this:
    >>
    >> "Sets the values for the fields YEAR, MONTH, DAY_OF_MONTH, HOUR,
    >> MINUTE, and SECOND. Previous values of other fields are retained. If
    >> this is not desired, call clear() first."
    >>
    >> So the behaviour you have noted is by design.

    >
    > Nope.
    >
    > If Calendar lacks a hidden, seventh milliseconds field, the six-argument
    > set method sets all of the fields and retains no old values, contrary to
    > what's observed.
    >
    > If, on the other hand, Calendar has a hidden, seventh milliseconds
    > field, since this value is not being set by the second call to set, it
    > should retain the previous value, i.e. the value it had when the first
    > Date object was constructed. The second Date value should therefore have
    > the same milliseconds last-three-digits as the first Date value, again
    > contrary to what's observed.


    Why should a second object inherit a value from the first object ??

    Arne
     
    Arne Vajhøj, Oct 28, 2008
    #10
  11. Harold Yarmouth

    Wojtek Guest

    Harold Yarmouth wrote :
    > Calendar calendar = Calendar.getInstance();
    > calendar.set(2003,9,10,13,8,42);
    > Date date = calendar.getTime();
    >
    >
    >
    > When the above code is run twice with some time passing in between, the
    > resulting Date objects compare unequal!
    >
    >
    > The getTime methods returned the following values from two runs of the above
    > code:
    >
    > 1065805722140
    > 1065805722828
    >
    > As you can see, the last three digits appear to vary randomly.
    >
    >
    > Clearly, this should not be the case. Calling calendar.set with the maximal
    > precision (six values) should completely determine the resulting Date object.
    > It looks like it uses the last three digits of the current millisecond value
    > of the system clock to "fill in the blanks" when it really ought to use
    > zeros.


    calendar.getTime() always returns the current time regardless of the
    value wihin the Calendar object.

    Yes, this is a pain.

    --
    Wojtek :)
     
    Wojtek, Oct 28, 2008
    #11
  12. Harold Yarmouth

    Arne Vajhøj Guest

    Harold Yarmouth wrote:
    > Stanimir Stamenkov wrote:
    >> Mon, 27 Oct 2008 16:42:21 -0400, /Harold Yarmouth/:
    >>
    >>> Calendar calendar = Calendar.getInstance();
    >>> calendar.set(2003,9,10,13,8,42);
    >>> Date date = calendar.getTime();
    >>>
    >>> When the above code is run twice with some time passing in between,
    >>> the resulting Date objects compare unequal!

    >>
    >> I think it is o.k. as you're not setting the field for the milliseconds

    >
    > If there is such a field, it should either be zero or the
    > previously-used value, not something random.
    >
    > I have the feeling that Calendar.getInstance() is not returning a
    > singleton, and that it is also not zeroing out newly-created instances.


    Have you read the documentation ?

    http://java.sun.com/javase/6/docs/api/java/util/Calendar.html

    public static Calendar getInstance()

    Gets a calendar using the default time zone and locale. The
    Calendar returned is based on the current time in the default time zone
    with the default locale.

    The keywords are "current time".

    And even though a singleton implies a getInstance method, then a
    getInstance method does not imply a singleton.

    Arne
     
    Arne Vajhøj, Oct 28, 2008
    #12
  13. Harold Yarmouth

    Arne Vajhøj Guest

    Wojtek wrote:
    > calendar.getTime() always returns the current time regardless of the
    > value wihin the Calendar object.


    It does not. It returns value within the Calendar object.

    Arne
     
    Arne Vajhøj, Oct 28, 2008
    #13
  14. Harold Yarmouth

    Wojtek Guest

    Arne Vajhøj wrote :
    > Wojtek wrote:
    >> calendar.getTime() always returns the current time regardless of the value
    >> wihin the Calendar object.

    >
    > It does not. It returns value within the Calendar object.
    >
    > Arne


    Sigh.

    My opinion was based on a series of test I did when I was using an
    earlier Java version. I could never get the Calendar object to return
    the date within it. It always seemed to return the current time rather
    than the set time.

    And now a quick test shows it returns the Calendar time.

    I remember this specifically as I was getting quite frustrated with it.

    --
    Wojtek :)
     
    Wojtek, Oct 28, 2008
    #14
  15. Wojtek wrote:
    > Arne Vajhøj wrote :
    >> Wojtek wrote:
    >>> calendar.getTime() always returns the current time regardless of
    >>> the value wihin the Calendar object.

    >>
    >> It does not. It returns value within the Calendar object.
    >>
    >> Arne

    >
    > Sigh.
    >
    > My opinion was based on a series of test I did when I was using an
    > earlier Java version. I could never get the Calendar object to
    > return
    > the date within it. It always seemed to return the current time
    > rather
    > than the set time.
    >
    > And now a quick test shows it returns the Calendar time.
    >
    > I remember this specifically as I was getting quite frustrated with
    > it.


    A newly created Calendar contains the current time. Perhaps your test
    was inadvertently creating a new Calendar object and doing the
    getTime() on that?
     
    Mike Schilling, Oct 28, 2008
    #15
  16. Mike Schilling wrote:
    > Harold Yarmouth wrote:
    >> Mark Thornton wrote:
    >>> The JDK documentation says this:
    >>>
    >>> "Sets the values for the fields YEAR, MONTH, DAY_OF_MONTH, HOUR,
    >>> MINUTE, and SECOND. Previous values of other fields are retained. If
    >>> this is not desired, call clear() first."
    >>>
    >>> So the behaviour you have noted is by design.

    >> Nope.

    >
    > Yep.


    Nope. Or, at least, not what was implied elsewhere.

    > Calendar.getInstance() returns a Calendar representing "now", so each time
    > it's called you will see a different milliseconds value.


    Well, there's the problem, right there. Most other places, having a
    no-arguments "getInstance" method instead of a constructor means some
    sort of singleton. (Although I can see why this wouldn't work for
    Calendar, which is mutable; it wouldn't be thread-safe.)

    It leads one to expect that any milliseconds value wouldn't be changing.
     
    Harold Yarmouth, Oct 28, 2008
    #16
  17. Arne Vajhøj wrote:
    > Why should a second object inherit a value from the first object ??


    That depends on there being a second object. Ordinarily, having no
    constructor but a no-arguments "getInstance" method signals a singleton,
    or something with singleton-like behavior (such as one instance per
    calling thread).
     
    Harold Yarmouth, Oct 28, 2008
    #17
  18. Stanimir Stamenkov wrote:
    > So you're ending up with a calendar with milliseconds set based on the
    > current time.


    Why is the "most specific" set method missing a field for this? And
    surely it should set that field to zero, since there's no reason to set
    everything else but have those last three digits vary randomly.


    > It is not returning a singleton for sure, why should it?


    It shouldn't, but having no public constructor and having instead a
    no-arguments "getInstance" method suggests it, or a similar thing such
    as fetching a per-thread instance.
     
    Harold Yarmouth, Oct 28, 2008
    #18
  19. Arne Vajhøj wrote:
    > Harold Yarmouth wrote:
    >> Stanimir Stamenkov wrote:
    >>> Mon, 27 Oct 2008 16:42:21 -0400, /Harold Yarmouth/:
    >>>
    >>>> Calendar calendar = Calendar.getInstance();
    >>>> calendar.set(2003,9,10,13,8,42);
    >>>> Date date = calendar.getTime();
    >>>>
    >>>> When the above code is run twice with some time passing in between,
    >>>> the resulting Date objects compare unequal!
    >>>
    >>> I think it is o.k. as you're not setting the field for the milliseconds

    >>
    >> If there is such a field, it should either be zero or the
    >> previously-used value, not something random.
    >>
    >> I have the feeling that Calendar.getInstance() is not returning a
    >> singleton, and that it is also not zeroing out newly-created instances.

    >
    > Have you read the documentation ?


    Have you forgotten yet again to check your confrontational attitude at
    the door?

    > And even though a singleton implies a getInstance method, then a
    > getInstance method does not imply a singleton.


    It usually implies something of the sort, if it takes no arguments and
    there's no public constructor. In this case, a per-thread instance might
    have made sense. With the semantics of producing a new instance every
    time, there's no apparent reason not to have a public constructor.

    To be more exact, use of a factory method instead of any public
    constructors usually means one of two things: the exact type is dynamic
    (and why would it be in this case?) or it may return a pre-existing
    instance.

    Since there's no obvious reason for polymorphism here (any
    locale/timezone stuff can be done by way of private fields and
    delegation, with generic behavior) that leaves pre-existing instances.
    Or perversity, I suppose.
     
    Harold Yarmouth, Oct 28, 2008
    #19
  20. Tue, 28 Oct 2008 02:42:21 -0400, /Harold Yarmouth/:
    > Stanimir Stamenkov wrote:
    >
    >> So you're ending up with a calendar with milliseconds set based on the
    >> current time.

    >
    > Why is the "most specific" set method missing a field for this? And
    > surely it should set that field to zero, since there's no reason to set
    > everything else but have those last three digits vary randomly.


    Whether the "most specific" method should automatically set the
    milliseconds to 0 is subjective. Probably many would come up with
    cases they would not want that method doing so. At least the
    present behavior is ever since the Calendar has been introduced
    (Java 1.1), thus changing it would break existing applications. You
    can only hope an even more specific method will be introduced in
    future Java versions, but I don't think it worths it.

    >> It is not returning a singleton for sure, why should it?

    >
    > It shouldn't, but having no public constructor and having instead a
    > no-arguments "getInstance" method suggests it, or a similar thing such
    > as fetching a per-thread instance.


    You've already been given the most exact answer by Mark Space: "It's
    just a plain old factory method."

    --
    Stanimir
     
    Stanimir Stamenkov, Oct 28, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Shevek
    Replies:
    3
    Views:
    6,128
    Shevek
    Jun 23, 2004
  2. =?Utf-8?B?TWFyaWFubyBQYWRpbGxh?=

    Possible Bug In the Calendar Control on web forms.

    =?Utf-8?B?TWFyaWFubyBQYWRpbGxh?=, Jan 28, 2006, in forum: ASP .Net
    Replies:
    2
    Views:
    478
    Otis Mukinfus
    Jan 28, 2006
  3. Steve Holden
    Replies:
    1
    Views:
    421
    Behrang Dadsetan
    Jul 2, 2003
  4. Abraham Andres Luna

    possible calendar bug

    Abraham Andres Luna, Oct 25, 2006, in forum: ASP .Net Web Controls
    Replies:
    1
    Views:
    101
    Abraham Andres Luna
    Oct 26, 2006
  5. Michael Fellinger
    Replies:
    3
    Views:
    187
    Michael Fellinger
    Dec 27, 2007
Loading...

Share This Page