My program needs to represent this date as a java.sql.date object , but it seems that when I create a new date (using the calendar) and set it to '9999-12-31' and finally convert this java.util.date object to a java.sql.date object, this date is converted to something like '000-01-31'.
Calendar calendar = Calendar.getInstance();
calendar.set(9999, 12, 31);
infinityDate = new java.sql.Date(normalizeDate(calendar.getTime()).getTime());
infinityDate should be 31-12-9999
but when my code reaches here :
if(otherDate.equals(infinityDate))
{// Do stuff}
It never goes into the if condition as the infinityDate has for some reason been changed to 31-01-000, even though otherDate is infact '31-12-9999'.
The fact that otherDate is 31-12-9999 tells me that java can represent this dates , but for some reason , when I construct it using a calendar it changes the date. (otherDate comes from a jdbc statement which fetches data from a database)
This reference date '31-12-9999' has been fixed by some client , so it cannot be changed and my program has to be able to compare some incoming date values with this.
Does anyone know why this is happening , I realize that http://en.wikipedia.org/wiki/Year_10,000_problem may be a problem for dates after year 9999 , but I should be safe by a day.
EDIT : The Normalize date method only "normalizes the given date to midnight of that day"
private static java.util.Date normalizeDate(java.util.Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
date = calendar.getTime();
return date;
}
But , this issue was appearing before I was normalizing the date , I normalized it in an attempt to fix this.
Months are zero indexed. Use 11 for December, not 12. This is why you are rolling over the year.
Calendar.MONTH is zero-based. The call
calendar.set(9999, 12, 31);
sets the date to "the 31st day in the 13th month of the year 9999", which is then implicitly converted to the 1st month of the year 10000. It would result in an exception if you first called
calendar.setLenient(false);
Check hours, minutes, seconds and milliseconds that are held into these 2 date objects. I believe they are different.
If your want to compare the date (year, month, day) only you should probably create your custom Comparator and use it.
Related
This question already has answers here:
Java Calendar adds a random number of milliseconds?
(4 answers)
Closed 4 years ago.
I'm wondering why I always get a difference between this date in milliseconds.
Any idea ?
Here is the output :
date = 1572794103293 ms
date2 = 1572794103341 ms
date3 = 1572794103341 ms
date4 = 1572794103341 ms
and here is the code :
Date date = createDate();
Date date2 = createDate();
Date date3 = createDate();
Date date4 = createDate();
System.out.println(date.getTime());
System.out.println(date2.getTime());
System.out.println(date3.getTime());
System.out.println(date4.getTime());
private static Date createDate() {
Calendar c = GregorianCalendar.getInstance();
c.set(2019, Calendar.NOVEMBER, 03, 16, 15, 03);
return c.getTime();
}
In the documentation of Calendar.set, it is said :
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.
The reason is that not all fields are set with this method, in you case, you don't have MILLISECOND set. So it keep the value when the instance was created.
The call of Calendar.clear will
Sets all the calendar field values and the time value (millisecond offset from the Epoch) of this Calendar undefined.
A quick example :
Calendar c = GregorianCalendar.getInstance();
c.clear();
c.set(2019, Calendar.NOVEMBER, 03, 16, 15, 03);
System.out.println(c.getTimeInMillis());
1572794103000
Milliseconds being undefined will give 0
In addition to the comments and AxelH's answer mentioning the fact that the milliseconds of a Calendar instance aren't changed by Calendar.set, there is still the curiosity that you get the same value for date2, date3 and date4, but a different value for date.
This is because the very first time you call createDate() the JVM has to initialize the Date class, which happens after Calendar c was initialized.
Thus on the first call c.getTime() needs more time than on the consecutive calls, which you can see as the difference between the value of date and the other 3 instances.
If you add a call to new Date() before the first call to createDate(), the difference between each value should be the same.
Please note that this does not fix your issue, it just hides it if your machine is fast enough. It's merely an explanation for the particular values you get.
I am trying to write code to find the Day difference between tow date but Calendar.getInstance() keep getting the date for previous month instead of current month
for example :Current 17/7/2014 it get 17/6/2014
my code :
TextView textview=(TextView) findViewById (R.id.textView1);
Calendar cal = Calendar.getInstance();
Calendar startDate=Calendar.getInstance();
startDate.set(Calendar.DAY_OF_MONTH, 1);
startDate.set(Calendar.MONTH,1);
startDate.set(Calendar.YEAR, 2013);
long diff=(((cal.getTimeInMillis()-startDate.getTimeInMillis())/(1000*60*60*24))+1);
String sdiff=String.valueOf(diff);
String stt=cal.get(Calendar.YEAR) +"_"+cal.get(Calendar.MONTH)+"_"+cal.get(Calendar.DAY_OF_MONTH);
textview.setText(stt);
Months start at 0, not at 1, but you really don't have to worry about this if you don't use magic numbers when getting or setting month but instead use the constants. So not this:
startDate.set(Calendar.MONTH,1); // this is February!
but rather
startDate.set(Calendar.MONTH, Calendar.JANUARY);
Months in Java's Calendar start with 0 for January, so July is 6, not 7.
Calendar.MONTH javadocs:
The first month of the year in the Gregorian and Julian calendars is JANUARY which is 0
Add 1 to the result of get.
(cal.get(Calendar.MONTH) + 1)
This also affects your set call. You can either subtract 1 when passing a month number going in, or you can use a Calendar constant, e.g. Calendar.JANUARY.
You can also use a SimpleDateFormat to convert it to your specific format, without having to worry about this quirk.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd");
String stt = sdf.format(cal.getTime());
I have Integer fields:
currentYear,currentMonth,currentDay,currentHour,currentMinute and nextYear,nextMonth,nextDay,nextHour,nextMinute.
How I can get difference between those two spots in time in milliseconds.
I found a way using Date() object, but those functions seems to be depricated, so it's little risky.
Any other way?
Use GregorianCalendar to create the date, and take the diff as you otherwise would.
GregorianCalendar currentDay=new GregorianCalendar (currentYear,currentMonth,currentDay,currentHour,currentMinute,0);
GregorianCalendar nextDay=new GregorianCalendar (nextYear,nextMonth,nextDay,nextHour,nextMinute,0);
diff_in_ms=nextDay. getTimeInMillis()-currentDay. getTimeInMillis();
Create a Calendar object for currenDay and nextDay, turn them into longs, then subtract. For example:
Calendar currentDate = Calendar.getInstance();
Calendar.set(Calendar.MONTH, currentMonth - 1); // January is 0, Feb is 1, etc.
Calendar.set(Calendar.DATE, currentDay);
// set the year, hour, minute, second, and millisecond
long currentDateInMillis = currentDate.getTimeInMillis();
Calendar nextDate = Calendar.getInstance();
// set the month, date, year, hour, minute, second, and millisecond
long nextDateInMillis = nextDate.getTimeInMillis();
return nextDateInMillis - currentDateInMillis; // this is what you want
If you don't like the confusion around the Calendar class, you can check out the Joda time library.
The date is selected by the user using a drop down for year, month and day. I have to compare the user entered date with today's date. Basically see if they are the same date. For example
the user entered 02/16/2012. And if today is 02/16/2012 then I have to display a message. How do I do it?
I tried using milliseconds but that gives out wrong results.
And what kind of object are you getting back? String, Calendar, Date? You can get that string and compare it, at least that you think you'll have problems with order YYYY MM DD /// DD MM YYY in that case I suggest to create a custom string based on your spec YYYYMMDD and then compare them.
Date d1 = new Date();
Date d2 = new Date();
String day1 = d1.getYear()+"/"+d1.getMonth()+"/"+d1.getDate();
String day2 = d2.getYear()+"/"+d2.getMonth()+"/"+d2.getDate();
if(day1.equals(day2)){
System.out.println("Same day");
}
Dates in java are moments in time, with a resolution of "to the millisecond". To compare two dates effectively, you need to first set both dates to the "same time" in hours, minutes, seconds, and milliseconds. All of the "setTime" methods in a java.util.Date are depricated, because they don't function correctly for the internationalization and localization concerns.
To "fix" this, a new class was introduced GregorianCalendar
GregorianCalendar cal1 = new GregorianCalendar(2012, 11, 17);
GregorianCalendar cal2 = new GregorianCalendar(2012, 11, 17);
return cal1.equals(cal2); // will return true
The reason that GregorianCalendar works is related to the hours, minutes, seconds, and milliseconds being initialized to zero in the year, month, day constructor. You can attempt to approximate such with java.util.Date by using deprecated methods like setHours(0); however, eventually this will fail due to a lack of setMillis(0). This means that to use the Date format, you need to grab the milliseconds and perform some integer math to set the milliseconds to zero.
date1.setHours(0);
date1.setMinutes(0);
date1.setSeconds(0);
date1.setTime((date1.getTime() / 1000L) * 1000L);
date2.setHours(0);
date2.setMinutes(0);
date2.setSeconds(0);
date2.setTime((date2.getTime() / 1000L) * 1000L);
return date1.equals(date2); // now should do a calendar date only match
Trust me, just use the Calendar / GregorianCalendar class, it's the way forward (until Java adopts something more sophisticated, like joda time.
There is two way you can do it. first one is format both the date in same date format or handle date in string format.
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
String date1 = sdf.format(selectedDate);
String date2 = sdf.format(compareDate);
if(date1.equals(date2)){
}else{
}
Or
Calendar toDate = Calendar.getInstance();
Calendar nowDate = Calendar.getInstance();
toDate.set(<set-year>,<set-month>,<set-date->);
if(!toDate.before(nowDate))
//display your report
else
// don't display the report
Above answers are correct but consider using JodaTime - its much simpler and intuitive API.
You could set DateTime using with* methods and compare them.
Look at this answer
This is a really simple request, but I am not quite sure the easiest/most efficient way of generating these two values.
I need to write a script that will check whether a given value is between two values. I am well aware of how this is done in SQL.
The way I need the values is somethign similar to the following.
Date testValue = new Date() //This represents the value we are testing
Date beginningOfDay = .... //This value would represent the date for
testValue at 12:00am
Date endOfDay = ... //This value would represent the date for
testValue at 11:59:59pm
Again, the Java Date() type may not be the best practice to do something like this. In the end I just need to generate three values that I can say
if testValue is after beginningOfDay && testValue is before endOfDay
//do logic
Personally I use the Calendar object for this. For example:
Date testDate = ??? //Replace with whatever source you are using
Calendar testDateCalendar = Calendar.getInstance();
testDateCalendar.setTime(testDate);
Date today = new Date();
Calendar endOfDay = Calendar.getInstance(); //Initiates to current time
endOfDay.setTime(today);
endOfDay.set(Calendar.HOUR_OF_DAY, 23);
endOfDay.set(Calendar.MINUTE, 59);
endOfDay.set(Calendar.SECOND, 59);
Calendar startOfDay = Calendar.getInstance();
startOfDay.setTime(today);
startOfDay.set(Calendar.HOUR_OF_DAY, 0);
startOfDay.set(Calendar.MINUTE, 0);
startOfDay.set(Calendar.SECOND, 0);
if (startOfDay.before(testDateCalendar) && endOfDay.after(testDateCalendar))
{
//Whatever
} else {
//Failure
}
You can use a calendar object to do this and by the way, the way you did the bounds check in your question is wrong (your date can match the before/after dates and still be considered in range). The following shows whether a date falls on a certain day of the year. It assumes that the timezones for the dateTime to check and the day are equal and that no time adjustments took place:
Date dateTime=...
Date day=...
// This is the date we're going to do a range check on
Calendar calDateTime=Calendar.getInstance();
calDateTime.setTime(dateTime);
// This is the day from which we will get the month/day/year to which
// we will compare it
Calendar calDay=Calendar.getInstance();
calDay.setTime(day);
// Calculate the start of day time
Calendar beginningOfDay=Calendar.getInstance();
beginningOfDay.set(calDay.Get(Calendar.YEAR),
calDay.Get(Calendar.MONTH),
calDay.Get(Calendar.DAY_OF_MONTH),
0, // hours
0, // minutes
0); // seconds
// Calculate the end of day time
Calendar endOfDay=Calendar.getInstance();
endOfDay.set(calDay.Get(Calendar.YEAR),
calDay.Get(Calendar.MONTH),
calDay.Get(Calendar.DAY_OF_MONTH),
23, // hours
59, // minutes
59); // seconds
// Now, to test your date.
// Note: You forgot about the possibility of your test date matching either
// the beginning of the day or the end of the day. The accepted answer
// got this range check wrong, as well.
if ((beginningOfDay.before(calDateTime) && endOfDay.after(calDateTime)) ||
beginningOfDay.equals(calDateTime) || endOfDay.equals(calDateTime))
{
// Date is in range...
}
This can be further simplified to:
Date dateTime=...
Date day=...
// This is the date we're going to do a range check on
Calendar calDateTime=Calendar.getInstance();
calDateTime.setTime(dateTime);
// This is the day from which we will get the month/day/year to which
// we will compare it
Calendar calDay=Calendar.getInstance();
calDay.setTime(day);
if (calDateTime.get(YEAR)==calDay.get(YEAR) &&
calDateTime.get(MONTH)==calDay.get(MONTH) &&
calDateTime.get(DAY_OF_YEAR)==calDay.get(DAY_OF_YEAR))
{
// Date is in range
}
Here's something I've used in my own code to determine if a file was modified on a certain day. Like the other answers in this thread, I used the Calendar.
// Get modified date of the current file
// and today's date
Calendar today = Calendar.getInstance();
Calendar modDate = Calendar.getInstance();
Date date = new Date(file.lastModified());
modDate.setTime(date);
// Convert dates to integers
int modDay = modDate.get(Calendar.DAY_OF_YEAR);
int todayDay = today.get(Calendar.DAY_OF_YEAR);
if (modDay == todayDay) {
// Do stuff
}
This might be closer to what you are looking for since you only need to see if the event falls on a certain day.