简体   繁体   中英

JAVA - Is it a bug in java.util.Calendar class or what?

I have faced the same problem many times.

The Same Problem was With This Question and Got Solution Like the Same, How to compare known hours ad current hour in android?

Problem:

When I use Calendar calCurr = Calendar.getInstance(); to get the Calendar object of current date and time, It always return me wrong.

I have put logs and checked it and to make it correct I had to add in years and months and then I got the correct object for Current Date and Time.

See My Example:

    Calendar calCurr = Calendar.getInstance();
    Log.i("Time in mili of Current - Normal", ""+calCurr.getTimeInMillis()); 
                // see what it gives? dont know why?

    Date date = new Date();
    calCurr.set(date.getYear()+1900, date.getMonth()+1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
                // so added one month to it

    Log.i("Time in mili of Current - after update", ""+calCurr.getTimeInMillis()); 
                // now get correct

Question:

  • Why it's giving the wrong output?
  • Is it a bug in there or My concept about the Calendar class is wrong?
  • tell me what should have been done for that?

It works perfectly as expected if you change to getDate() it outputs:

Time in mili of Current - Normal Wed Apr 04 11:34:34 BST 2012

Time in mili of Current - after update Fri May 04 11:34:34 BST 2012

What do you expect? And in milleseconds it also equals 30 days:

Time in mili of Current - Normal 1333535834557

Time in mili of Current - after update 1336127834557

and the calculation is (difference, divided by milliseconds in a day):

1336127834557 - 1333535834557 = 2 592 000 000

2592000000 / 86400000 = 30

And todays date in milliseconds after 1970 is 1333536754 ... which fits, I don't see a problem.

EDIT

Your Problem is you are setting Month like 3 for march...there you need to set 2..cause months are indexed from 0 to 11.

Do not use date.getXXX() . Do not use any setter or getter except Date.getTime() . They are all deprecated. Using them would cause unexpected results.

If you call Calendar.getInstance() , it is already set to the current date. If you want to set or add days, months, whatever, set them on the calendar.

Eg calCurr.set(Calendar.MONTH,2) or calCurr.add(Calendar.DAY,1) .

Calendar months are zero-indexed. So when want to set for March its 2 not 3

Also, Don't set year, month and date from the Date object. If you must initialise a Calendar to a date, do it like this:

   Calendar cal = Calendar.getInstance();
   cal.setTime(date);

be aware that your Date object might be a different locale to what you think it is.

It is NOT a bug, the Calendar is returning what it should (at least here it is).

Calendar calCurr = Calendar.getInstance();
Log.i("Time in mili of Current - Normal", ""+calCurr.getTimeInMillis()); 
            // see what it gives? dont know why?

I got 1333546375707 milliseconds, which is the correct value (also calculated by hand).
Which value are you expecting here? How you know it is wrong?


Date date = new Date();
calCurr.set(date.getYear()+1900, date.getMonth()+1, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());
            // so added one month to it

Why adding ONE to the month? Month of both Date and Calendar are zero-based - no need to add 1.


EDIT
Calculating by hand (approximated):

2012  - 42 years * 365.24 days/year * 86400 seconds/day
April - (31 + 29 + 31) days * 86400
4th   - 3 days * 86400
13:30 - 13.5 hours * 3600 seconds/hour
        ====================
        1333553112 seconds

When Calendar object is created by using Calendar.getInstance() the instance variable "time" in the Calendar object is set and this value will get changed only if you use Calendar.setTimeInMillis() function.
Code snippet from Calendar object:

public long getTimeInMillis() {
        if (!isTimeSet) {
        updateTime();
    }
        return time;
    }

Here "isTimeSet" will become "true" when Calendar.getInstance() is called and it returns "time" every time without updating the time.

This is the reason you get the same value of time every time you call calCurr.getTimeInMillis();

Hope this helps.

It's the weird implementation of Calendar . For some reasons January is month 0, and years are not very logical as well.

I recommend Joda time library.

We are using below lines of code for finding current date and time It's working fine our side.

            java.util.Calendar calc = java.util.Calendar.getInstance();

        int day = calc.get(java.util.Calendar.DATE);
        int month = calc.get(java.util.Calendar.MONTH)+1;
        int year = calc.get(java.util.Calendar.YEAR);

        String dayStr,monthStr;
        if(day<10){
            dayStr = "0"+day;
        }else{
            dayStr = ""+day;
        }
        if(month<10){
            monthStr = "0"+month;
        }else{
            monthStr = ""+month;
        }
        /*String currentdate = monthStr+"/"+dayStr+"/"+year+" ";*/
        String currentdate = dayStr+"/"+monthStr+"/"+year+" ";

        /*String currenttime = currentdate + String.valueOf(calc.get(java.util.Calendar.HOUR_OF_DAY))+ ":"+
        String.valueOf(calc.get(java.util.Calendar.MINUTE))+":"+String.valueOf(calc.get(java.util.Calendar.SECOND));*/

        return currentdate;

Java Date Based API is not properly designed. in future versions I think some problems of The API are planned to address.

I would recommend to use JodaTime .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM