This is general programming, but I'm working in Java.
Given a date dd-mm-yy or dd-mm-yyyy (e.g. 13-01-2011) I want to convert this into a unique number such that any two dates have a different number. And the year isin't important. So just converting dd-mm into one unique int is acceptable. Does anyone know an algorithm for doing this?
I'm SOrry: I want to be more specific:
The unique numbers should be from 1 to 365 (or 0 to 364), or should break down uniquely modulo 365. (I'm ignoring the case of leap years at the moment).
So concatenating "ddmm" might be a unique 4 digit number. But modulo 365 probably wouldnt be unique.
So you basically want to get the day of year? That's not the same as "an unique int from date".
Use Calendar#get(Calendar.DAY_OF_YEAR) (which is 1-based).
Date date = getItSomehow();
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
As you already admitted, comparing this on leap/non-leap years will fail.
Use the number of days since the beginning of the year.
new Date().getTime()
The number of milliseconds since 1970 should be unique to each date. Just convert the string to a date object and use getTime()
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
Date date = formatter.format( myInput );
Use unix timestamp see java.util.Date.getTime()
If you just need a unique key, Calendar's hashCode() should do the trick.
Alternately, you can concatenate the two digit month and day, and four digit year.
Update: the OP clarified the question to want a unique value in the range 1-364. In that case I would convert the date into a Calendar object and call get (Calendar.DAY_OF_YEAR) on it - this will return the number of the day within the year, which is exactly what the OP is after it seems.
Original answer:
There about as many ways to do this as there are bits of string. If you want to be able to use the unique numbers for relative comparison of dates then the most obvious solution is to do what most computers do anyway, namely convert the date into some lowest common denominator, like the number of seconds from a particular epoch. Java provides ways for doing this with both the Date and Calendar classes. If you only care about days and months, you could achieve the same with something like int v = (month * 120) + day. If you don't care about comparisons and just want a unique value, you could come up with a digest of the date using a hashing algorithm of some kind. In Java you could, for example, take a String representation of the date and call hashCode() on it.
Related
So Im working on an Calendar programm and to change the Months im asking for the int of the month.
If I type calendar.get(Calendar.JANUARY) i get 1 as return, which is correct because first month. But if I type calendar.get(Calendar.FEBUARY) i get 2018 in respond which of course is wrong. Does anyone know what the problem could be?
Calendar cal1 = new GregorianCalendar();
int month = cal1.get(Calendar.JANUARY);
int month2 = cal1.get(Calendar.FEBRUARY);
int year = cal1.get(Calendar.YEAR);
java.time
T.J. Crowder’s answer is correct. Allow me to supply the real, good and modern solution to your problem.
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Atlantic/Stanley"));
// 2018-05-21T05:02:23.942763-03:00[Atlantic/Stanley]
Month monthEnum = zdt.getMonth(); // MAY
int monthNumber = zdt.getMonthValue(); // 5
int year = zdt.getYear(); // 2018
I ran the code just now and have given results in comments after each code line. Please put your desired time zone where I have put Atlantic/Stanley since the month does not change at the same point in time in different time zones. Do you agree with me that this code is clearer and more natural and leaves less room for confusion? BTW, if you’re only interested in the date, not the time of day, use LocalDate instead of ZonedDateTime, the rest of the code will be the same.
To get the numbers of specific months:
int januaryNumber = Month.JANUARY.getValue(); // 1
int februaryNumber = Month.FEBRUARY.getValue(); // 2
What happened in your code?
As T.J. Crowder has already said, Calendar.get expects a field number, for example Calendar.MONTH or Calendar.YEAR. Calendar.JANUARY is 0. Zero?! It’s another confusing thing about Calendar, month numbers are 0-based, that is, they go from 0 for January through 11 for December. Anyway, 0 is also the field number of Calendar.ERA. GregorianCalendar uses 0 for BC (or more religion neutral: BCE for before common era) and 1 for AD (CE, common era). Since your date is in the common era, you get 1. Which, by the way, would have been incorrect for month of January since months are 0-based.
Similarly, Calendar.FEBRUARY equals 1 and coincides with field number Calendar.YEAR, which I why you got the year.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Question: Why is January month 0 in Java Calendar?
Calendar#get gets a field value. Calendar.JANUARY is not a field number, it's a potential field value. The only static fields in Calendar that you use with get (and set) are the ones whose descriptions start with "Field number for get and set...".
To get the month, use cal1.get(Calendar.MONTH).
The Calendar API is...unfortunate, not least because it predates enums and so int was used for get/set's field identifier parameter where an enum was really needed. While get takes an int, and Calendar.JANUARY is an int, they're ints in different domains. See Ole V.V.'s answer for the modern, dramatically-improved alternative: java.time.
This question already has answers here:
How to check if 2 dates are on the same day in Java
(4 answers)
Closed 8 years ago.
I have two calendar objects, they seems to contain same dates but the compareTo() method is returning -1 as result, Can any one explain the reason behind this.
On debugging the two Calendar objects, the result is shown as :
2014-06-01T00:00:00.000Z
for both calendar objects but the compareTo() is returning -1. Even the long time in millis for both dates are different.
Well, have a look at the Calendar code (this is from JDK 1.7.0-13):
public int compareTo(Calendar anotherCalendar) {
return compareTo(getMillisOf(anotherCalendar));
}
private int compareTo(long t) {
long thisTime = getMillisOf(this);
return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1;
}
It should be obvious that if the two Calendar's have different millis, then they're different as per the second method.
In any case, the millis in your example should not both represent 2014-06-01T00:00:00.000Z so there's another problem in your code. Try this:
Timestamp ts1 = new Timestamp( 1401561000000L );
Timestamp ts2 = new Timestamp( 1401595200000L );
System.err.println( ts1 );
System.err.println( ts2 );
Outputs:
2014-05-31 20:30:00.0
2014-06-01 06:00:00.0
Cheers,
The milliseconds number is the "offical" time in Java. However, for a variety or reasons, there are numbers with the same date/time which have different numbers of milliseconds. Then normal reason is clock adjustments. E.g. Sometimes you have to add a second or two to account for irregularities in the earth's orbit. The other big source is when regions were first brought into the UTC, then some time zones moved hours.
THere is also the common source for these things: DST.
This will happen twice a year when you move to daylight saving time, on the one hand there are date/times which do not exists, as they were "skipped", and there are other times which happened twice, as the clock gets reset at midnight, so 11pm-midnight happens twice on the same day.
If you want to just compare the minutes and ignore the milliseconds or seconds do this:
You need to use
cal.set(Calendar.MILLISECOND, 0);
and possibly as well
cal.set(Calendar.SECOND, 0);
if you just need the minutes to match.
Quick explanation of what is going on:
The JavaDoc for Calendar states:
Compares the time values (millisecond offsets from the Epoch)
represented by two Calendar objects.
So you acknowledge that ".. long time in millis for both dates are different .."
#JonSkeet says in this question:
Calendar.setTime takes a java.util.Date, which is just a wrapper
around a long indicating the number of milliseconds since midnight Jan
1st 1970, UTC. It's not "in the format MM/dd/yyy" - that's a string
representation, not a java.util.Date. If it happens to print something
out in the format MM/dd/yyyy, that's just what Date.toString is doing
for you - it's not inherently part of the format.
This should answer your question about what is going on.
Note: java.util.Date has the same problem.
PS. A lot of people say use Joda Time, which I have heard is going to be in Java 8, but I have not personally tried it. If you are going to be using a lot of date code, I'd recommend you use it.
I invoked compareTo on Date instead of Calendar and got the correct result. It might be because of the fact that Calendar stores Timezone information but Date object does not.
Thanks
I retrieve a Date from the database using the ResultSet rsExpid.
Date joindate = rsExpid.getDate("join_date_ad");
System.out.println(joindate);
int year = joindate.getYear();
System.out.println(year);
int month =joindate.getMonth();
System.out.println(month);
int day = joindate.getDay();
System.out.println(day);
dateTimeJoin4.setDate(year, month, day);
When I print joindate to the console it shows correctly as 2011-08-03, but when I print the year to the console I was amazed to see 111. Similarly printing the month produced 7 and the day resulted in 3.
The variable dateTimeJoin4 is my SWT DateTime. It is not setting any value and it is also not giving any error message. Could please anybody help me on this?
Chances are you haven't read the documentation for Date.getYear and Date.getMonth:
Returns a value that is the result of subtracting 1900 from the year that contains or begins with the instant in time represented by this Date object, as interpreted in the local time zone.
and
Returns a number representing the month that contains or begins with the instant in time represented by this Date object. The value returned is between 0 and 11, with the value 0 representing January.
respectively. Likewise Date.getDay returns the day of the week, not the day of the month - you want Date.getDate() for that (or preferrably a different API entirely, either Calendar or Joda Time).
This has nothing to do with SWT's DateTime type - after all, you only use that in the last line. When something behaves unusually, your first port of call should be the documentation. SWT's DateTime.setDate method is documented to require a year between 1752 and 9999, so 111 will be confusing it. Admittedly it would have been nice if it had thrown an exception, but even so...
The fact that you're calling deprecated methods should have been a hint to you, although Calendar also uses 0-11 for its months.
Personally I would strongly encourage you to use Joda Time for as much of your date and time work as you can. It's a far superior date and time API to the one built into Java. It's not immediately clear whether it's worth you using it here (if this is all you have to do) but if you're doing anything at all significant (including parsing, formatting or any kind of arithmetic) you should be using it.
I tried using this method and it worked correctly so this method can be useful to other.
Calendar startCal = Calendar.getInstance();
startCal.setTime(joindate);
int months= startCal.get(Calendar.MONTH);
int years= startCal.get(Calendar.YEAR);
int days= startCal.get(Calendar.DAY_OF_MONTH);
System.out.println(months+1);
System.out.println(years);
System.out.println(days);
dateTimeJoin4.setDate(years, months+1, days);
getDay() return the position of the day not the date like suppose today is Monday it will return 1, it start from the sunday with 0 value.
as well as the getMonth() return the position as starting value is 0 for january at now you getting the 7 instead of 8.
for getting date you can use the SimpleDateFormat or DateFormat by passing the format string in that you can get it
example links
http://www.roseindia.net/java/javadate/date-format.shtml
http://www.java-examples.com/java-simpledateformat-class-example
I need to compare two dates along with time portion.
I need to check it upto hh:mm:ss only.
Can any one suggest any util i can use for it or any suggestion for doing programatically.
Thanks,
Narendra
To compare just the date portion, the simplest thing to do is
int cmp = date1.substring(0, 10).compareTo(date2.substring(0,10));
You don't need to convert them into a true date object as the strings will be in the same order. This is like #rodion's answer except his will compare the time as well.
If performance IS important to you I suggest you leave the strings as strings, converting them to a date object is relatively expensive.
You could use a java.text.SimpleDateFormat to parse your dates into Date objects, then use getTime to do the comparison. Date also implements Comparable so you can use that directly if you prefer.
You can use string comparison like: "2010:01:01 00:00:01".compareTo("2010:01:01 00:00:02"). This will return -1, 0 or 1 for when the first date is before, same or after the second date respectively
If you have the Date or Calendar object available you can compare dates using Calendar.before(date) and Calendar.after(date) methods, but this will take into account milliseconds so you have to be careful to reset milliseconds to 0 before comparing.
If performance is not so important to you I would suggest string comparison above.
I am using SimpleDateFormat to display a Calendar like this :
public String getDate()
{
String DATE_FORMAT = "EEEE, dd/MM/yyyy HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
System.err.println(date.getTime().getMonth());
return sdf.format(date.getTime());
}
The shell returns 6 and the display : mardi, 06/07/2010 12:44:52
It can't be possible ? Why ?
Thanks
From the Java API:
public int getMonth()
Returns a number representing the month that contains or begins with the instant in time represented by this Date object. The value returned is between 0 and 11, with the value 0 representing January.
Unfortunately, months in class Date and class Calendar are zero-based. (In my opinion, this was a huge design mistake in those classes, and it's just one of the many design mistakes in Java's date and time API).
Note that class Calendar has constants to represent the months: Calendar.JANUARY, Calendar.FEBRUARY etc. Use those instead of the raw numbers.
An often mentioned, much better date and time API for Java is Joda Time. Note that there is a proposal to add a new date and time API to the next version of Java that will be based on Joda Time.
the getMonth method in Date is 0 indexed. from the JavaDoc:
Returns a number representing the month that contains or begins with the instant in time represented by this Date object. The value returned is between 0 and 11, with the value 0 representing January.
month index starts from 0 just like array index
that's your locale set to france DD/MM/YY so it is tuesday, July, 2010.
the 6th month is july if it starts at 0.