Statically created dates are not equal? - java

I'm testing the equality of dates that I create using constants and for some reason the tests are all failing.
public static Date date(int year, int month, int date, int hour, int minute) {
Calendar working = GregorianCalendar.getInstance();
working.set(year, month, date, hour, minute, 1);
return working.getTime();
}
If I create that with the same year, month, date, hour etc then I expect it to be equal. Except that it inconsistantly isn't. I use this function in two different classes and the objects aren't equal - except only sometimes.
What's the issue? The epoch it gives me is occasionally 1 second behind the other and I'm not entirely sure why.

getTime is millisecond precision, you are only setting to second precision. So when you compare the Dates using the .equals() method it will return false.
Stop using the abomination of the java date time api and use jodatime instead.
DateTime dateTime = new DateTime().secOfDay().roundFloorCopy();
dateTime.equals(myOtherDateTimeCreatedSameway);
Or if you are just worried about date, not time, use LocalDate.

The old calendar-API is undoubtedly horrible in general but I show a possible solution which suppresses the millisecond part generated in constructor. This will work as long as you don't change the timezone. So sometimes the Calendar-API is underestimated while JodaTime is often overestimated.
public static Date date(int year, int month, int date, int hour, int minute) {
// current time in system timezone
GregorianCalendar working = new GregorianCalendar();
// assuming you rather want second set to zero
working.set(year, month, date, hour, minute, 0);
// no millisecond part
working.set(Calendar.MILLISECOND, 0);
return working.getTime();
}

Related

Java: How can I create method that works on my date class

I have a date class and it has the following
public class Date {
public int month;
public int day;
public int year;
public Date(int m, int d, int y)
{
month = m;
day = d;
year = y;
}
public Date increase(int numberOfDays)
{
day += numberOfDays;
return this;
}
My question is what is the easiest way to do increasing of number of days to that given instance of Date? Like for example I have a created an instance of new Date(4,20,2016).increase(30); which would increase the given date addition 30 days. That would be sometime in May 19 I think. The method above should work if it's less than the max day of the month. But I haven't figure out how to do the calculation including the month and year. Like I added 365 days to that date would be 4/20/2017. Just an idea would be helpful. Thanks
use Java Calendar object instead. https://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DATE, 30); // add 30 days
date = cal.getTime();
using jcalendar you can add the dates try this example
Implementing this yourself is a suprisingly tricky task. More so since you are storing your Date as a separate month, year and day. You would have to store information about the number of days in every month, along with information about leap years. In short, trying to re-implement Date is not easy.
One solution to storing a "day, month, year" date before Java 8 came along was to use Joda. Using Joda's LocalDate class, you can do:
LocalDate date = LocalDate.now();
date = date.plusDays(30);
This functionality is now available in Java 8's java.time package, using the same LocalDate class name. Take a look at the source code for either package to see how it's implemented.
In short, LocalDate.plusDays() first converts the "month, day, year" date to a single number of days since the "epoch", using an algorithm that's around twenty lines long. Then, it adds the requested number of days to that number. Finally, it converts that number back to a "day, month, year" using another algorithm that's even longer.

Gregorian calendar midnight time not giving a round number

This code snippet
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
cal.set(2013, Calendar.NOVEMBER, 6, 0, 0, 0);
long time = cal.getTimeInMillis();
results in time == 1383696000628.
Where the heck is it getting those last 628 milliseconds from?
I'm using Java 6.
Calendar.set(int year, int month, int date, int hourOfDay, int minute, int second) does not change MILLISECOND field, its API 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.
cal.set(int, int, int, int, int, int) does not set the milliseconds.
Therefore, the Calendar instance still contains the milliseconds from its creation time.
You can use GregorianCalendar(int year, int month, int dayOfMonth), although you would loose the locale, or cal.set(Calendar.MILLISECOND, 0) to remove the millis.
Edit
As suggested by Jonathan Drapeau in the comment below, you can also call cal.clear() to remove all fields before calling set

Android get difference in milliseconds between two dates

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.

Java - GregorianCalendar outputting wrong year?

When I instantiate a new date using GregorianCalendar like this:
GregorianCalendar myCal = new GregorianCalendar(29,5,2011);
Then, finally, I carry out the following code (expecting it to return 2011), and it returns 35. I'm wondering why this is, as I will need to compare it to the passed date (2011).
System.out.println(myCal.get(Calendar.YEAR));
Are you even reading the documentation/method signatures?
public GregorianCalendar(int year, int month, int dayOfMonth)
Try this:
GregorianCalendar myCal = new GregorianCalendar(2011, Calendar.MAY, 29);
And BTW: 5th month is actually June, I guess you wanted May (months are 0-based). To avoid confusion use constants like Calendar.MAY (equal to 4...)
The GregorianCalendar constructor you are using does not expect dayOfMonth, month, year as arguments, but year, month, dayOfMonth. See the JavaDoc for details.

Android java datetime values from String to Long to String issue

Long time reader, first time poster.
In Android, capturing date from datepicker and storing as string in sqlite. Sorting by date doesn't work because they're strings (unless I'm doing it wrong.
I've googled this issue for ~5 days, and it looks like there should be a way to capture the date from the date picker, convert it to a Long, store it in sqlite as a Long, select and sort on the Long date value, then convert the Long back to a "mm/dd/yyyy" string for display. I've tried various combinations of parse statements, Date, FormatDate, etc. with no luck at all.
My actual application flow would be:
On activity start, get today's date and display it in button which calls the datepicker.
Capture new date from datepicker (if one is entered), save it as a long to sqlite.
On opening an activity showing a listview of records, select from sqlite with orderby on date (Long), convert Long to "mm/dd/yyyy" string for display in ListView.
If someone could point me at a code sample, it would be greatly appreciated - thanks!
Evan
Hours of hair-pulling later, the solution is sort of a mix of the answers given, and some other things:
// variables declared
private int mYear;
private int mMonth;
private int mDay;
// datepicker declared and listened for
private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
mYear = year;
mMonth = monthOfYear;
mDay = dayOfMonth;
updateDisplay();
}
};
// converting the datestring from the picker to a long:
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, mDay);
c.set(Calendar.MONTH, mMonth);
c.set(Calendar.YEAR, mYear);
Long lDate = c.getTime().getTime();
//The formatting that worked on the trip back from long to string
// (I spent hours with SimpleDateFormat strings, years that were off by 1500, etc.):
String DateFormatted = DateFormat.getDateFormat(getApplicationContext()).format(helper.getDate(c)); // helper.getDate(c) is just the passing back of the Long date from my SELECT statement
New to the forum - I tried to vote up as useful, but I don't have enough reputation points yet.
All Date objects in java are just Long values behind the scenes. You can get the Long value from a java Date object using getTime(), storing the resulting long value, and then initializing a new Date object using that long value in the constructor. Since the DatePicker gives interfaces to Day, Month and Year you should use the java Calendar class as an interim by creating a new Calendar object, setting the day, month and year before extracting a Date object and then a long value from the Date object.
I would say something along these lines:
DatePicker dp = blah blah;
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, dp.getDayOfMonth());
c.set(Calendar.MONTH, dp.getMonth());;
c.set(Calendar.YEAR, dp.getYear());
long l = c.getTime().getTime();
From here you can serialize your long value. Obviously then to reverse the process you pull the long value out, construct a Date object with the long value and then use a Calendar.setTime(Date) call before using the Calendar.get function to get the values to use on the DatePicker.init function, or utilizing a SimpleDateFormat object to get it prepped for display in a format like you described.
I'd just use a date as I think Calendar objects are a bit heavy for this task. Get your values from your DatePicker :
public void onDateSet(DatePicker view, int year,
int monthOfYear, int dayOfMonth) {
mYear = year;
mMonth = monthOfYear;
mDay = dayOfMonth;
updateDisplay();
}
Use the integers provide to the DatePicker to create a Date:
Date date = new Date(mYear, mMonth, mDay);
Then store and sort by the long value : date.getTime().
Alternatively, if you really must use strings for sorting dates, format them in yyyy/mm/dd format to ensure proper sorting, even then you need to watch out. I've just done some tests with SimpleDateFormat and it parses inappropriate date strings e.g. 2010/09/31 is interpreted as 2010/10/01.
When checking stuff like this I would always recommend running up some JUnit tests.

Categories