Calculating days between two dates in Java - java

I am new to Java and trying some practice exercises to get a better understanding of it.
I set myself the exercise to input different Strings, integers etc through the console and write the input to a textfile. All of this works fine.
Now I want to input into the textfile when the project started and when it will end. That works without any problem.
Now here is my problem. I want to calculate the time the project lasts from the beginning to the end in days.
Currently it only calculates the days, ignoring the month and the year.
For example: (dd.mm.yyyy)
Start: 07.07.2014 End: 15.07.2014 Output: 8 (almost correct :) )
Another example:
Start 07.07.2014 End: 03.08.2014 Output: -3 (not even close)
I just cannot figure out where my problem is.
Thanks for your help!
Chris
System.out.print("Start project (dd.mm.yyyy): ");
String beginn = input.nextLine();
DateFormat df = new SimpleDateFormat("dd.mm.yyyy");
Date d = null;
try {
d = df.parse(beginn);
} catch (ParseException e) {
System.out.println("Unable to parse " + beginn);
}
DateFormat df3 = DateFormat.getDateInstance(DateFormat.LONG);
String s3 = df3.format(d);
System.out.print("End of project (dd.mm.yyyy): ");
String ende = input.nextLine();
DateFormat df4 = new SimpleDateFormat("dd.mm.yyyy");
Date g = null;
try {
d = df.parse(ende);
} catch (ParseException f) {
System.out.println("Unable to parse " + ende);
}
//DateFormat df5 = DateFormat.getDateInstance(DateFormat.LONG);
//String s4 = df5.format(d);
// String dauer = input.nextLine();
diffDays = 0;
try {
DateFormat dfa = new SimpleDateFormat("dd.mm.yyyy");
Date from = dfa.parse(beginn);
Date to = dfa.parse(ende);
long diffMillis = to.getTime() - from.getTime();
//diffDays = Math.round( (double)diffMillis / (24. * 60.*60.*1000.) );
diffDays = diffMillis / (1000 * 60 * 60 * 24);
System.out.println(diffDays);
} catch (ParseException ex) {
ex.printStackTrace();
}

Your format is wrong.
DateFormat df = new SimpleDateFormat("dd.MM.yyyy");
According to the documentation, the MM specifies the months, where mm specifies minutes.

Example in Java 8 :
Get the number of days between now and java.sql.Date :
LocalDate startDate = LocalDate.now();
Instant instant = dueDate.toInstant();
LocalDate endDate = instant.atZone(ZoneId.systemDefault()).toLocalDate();
long dueDays = ChronoUnit.DAYS.between(startDate, endDate);
System.out.println("XXX is due in " + dueDays);

Related

How to convert a java double value to Date/Time format (HH:mm:ss) in Java?

I receive input in double (Eg: 12803.000000) which represents time in hours:minutes:seconds, ignore the values after the dot. All I want is to convert this double value to something like 1:28:03 as in HH:mm:ss format using java code. How to achieve the expected outcome?
Code I tried:
SimpleDateFormat df = new SimpleDateFormat("HH:mm");
String time = df.format(new Date((long) ((Double.parseDouble("12803.000000"))*60*60*1000)));
System.out.println("time>>"+time);
This code is giving me the ouput as 16:30 which is not the expected result.
TIA!!
double x = 12803.000000;
String s = String.format("%06d", (int)x);
DateFormat format = new SimpleDateFormat("HHmmss");
Date date = format.parse(s);
I don't know how your double value is representing a date, but the code can solve your example question.
This below code should give you the desired result.
public static void main (String args[]) throws ParseException {
Double value = 12803.000000;
SimpleDateFormat format = new SimpleDateFormat("HHmmss");
String intValueStr = String.valueOf(value.intValue() );
int length = intValueStr.length();
int missingDigits = 6- length;
String strForTimeParsing = intValueStr;
for(int i =0; i< missingDigits;i++){
strForTimeParsing = "0"+strForTimeParsing;
}
System.out.println("Final String after padding Zeros at the start = "+strForTimeParsing);
Date parsedDate = format.parse(strForTimeParsing);
String format1 = new SimpleDateFormat("HH:mm:ss").format(parsedDate);
System.out.println("Resulted Formatted Time = "+format1);
}
Below code worked for me. Thanks zhh for your helping hand.
double x = 12803.000000;
String s = String.format("%06d", (int)x);
System.out.println("String val>>"+s);
DateFormat format = new SimpleDateFormat("HHmmss");
DateFormat format1 = new SimpleDateFormat("HH:mm:ss");
try {
Date date = format.parse(s);
System.out.println("date>>"+date);
System.out.println("time in String format>>"+format1.format(date));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Output: time in String format>>01:28:03

Java : calculate remaining time compared to current time

I have a string in format :
2015-10-01 02:00
I want to print the remaining time compared to current time in Java, it should print in format :
It remains 1 day 4 hours 25 minutes
How could I do that ? Thanks for any ideas.
I got it working! Could you withdraw all the unvotes please ?
public static void calculateRemainTime(String scheduled_date){
// date format
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
// two dates
java.util.Date scheduledDate;
Calendar current = Calendar.getInstance();
java.util.Date currentDate;
String current_date = format.format(current.getTime());
try {
scheduledDate = format.parse(scheduled_date);
currentDate = format.parse(current_date);
long diffInMillies = scheduledDate.getTime() - currentDate.getTime();
long diffence_in_minute = TimeUnit.MINUTES.convert(diffInMillies,TimeUnit.MILLISECONDS);
System.out.println(diffence_in_minute);
} catch (ParseException e) {
e.printStackTrace();
}
}

Having trouble adding times to generate time list

I'm trying to generate a time list in Java. I've read this as to how to add two times together. I wrote the code using floats before converting to using times so I know that the general format of the code works. This is the code that I'm having difficulty with:
public class Test2 {
public static void main(String[] args){
String time = "09:00";
String quarterHour = "00:15";
String halfHour = "00:30";
String quarterHour3 = "00:45";
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
Date times;
Date temp;
long sum;
try {
times = timeFormat.parse(time);
while(times.before(timeFormat.parse("15:15"))){
System.out.println("Timelist: " + time);
if((times.equals(timeFormat.parse("10:15"))) || (times.equals(timeFormat.parse("13:45")))){
temp = timeFormat.parse(halfHour);
sum = times.getTime() + temp.getTime();
time = timeFormat.format(new Date(sum));
times = timeFormat.parse(time);
}
else if(times.equals(timeFormat.parse("11:45"))){
temp = timeFormat.parse(quarterHour3);
sum = times.getTime() + temp.getTime();
time = timeFormat.format(new Date(sum));
times = timeFormat.parse(time);
}
else{
temp = timeFormat.parse(quarterHour);
sum = times.getTime() + temp.getTime();
time = timeFormat.format(new Date(sum));
times = timeFormat.parse(time);
}
}
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
The result I get from that is simply 09:00. It goes through the loop once and ends.
I followed it through the debugger and what's happening is that when it adds the quarterHour to times it adds 12:15 and not the 00:15 as it's supposed to.
This seems to have something to do with me using 24 hour time as when I change the:
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm");
to:
SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm");
It works - except that it goes into an eternal loop.
Question: How do I get it to add only 15 minutes to the time while using 24 hour format?
Use a Calendar, or if you're using Java 8 you might use the new java.time classes like
String timeStr = "09:00";
DateFormat timeFormat = new SimpleDateFormat("HH:mm");
try {
LocalDateTime endTime = LocalDateTime.ofInstant(
Instant.ofEpochMilli(timeFormat.parse("15:15").getTime()),
ZoneOffset.ofHours(0));
Instant instant = Instant.ofEpochMilli(timeFormat.parse(timeStr)
.getTime());
LocalDateTime time = LocalDateTime.ofInstant(instant,
ZoneOffset.ofHours(0));
while (time.isBefore(endTime)) {
time = time.plus(15, ChronoUnit.MINUTES);
Instant output = time.atZone(ZoneOffset.ofHours(0)).toInstant();
System.out.println(timeFormat.format(Date.from(output)));
}
} catch (Exception e) {
e.printStackTrace();
}
or, with the Calendar like
String timeStr = "09:00";
DateFormat timeFormat = new SimpleDateFormat("HH:mm");
try {
Calendar cal = Calendar.getInstance();
cal.setTime(timeFormat.parse(timeStr));
Date when = timeFormat.parse("15:15");
while (cal.getTime().before(when)) {
cal.add(Calendar.MINUTE, 15);
System.out.println(timeFormat.format(cal.getTime()));
}
} catch (Exception e) {
e.printStackTrace();
}
Add this line to your code:
timeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
immediately after you declare timeFormat.
It fixes your problem on my computer.

I am trying to calculate difference between two dates in seconds. (Java/Android)

For someone else who might stumble here, the link refered to in this question gives misleading results
My First Date: 1986-04-08. Current Date: 2013-11-28.
Code:
public long seconds(Date date){
String formattedDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",getResources().getConfiguration().locale).format(Calendar.getInstance().getTime());
String DateStr=String.valueOf(formattedDate);
Date d = null;
try {
d = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",getResources().getConfiguration().locale).parse(DateStr);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
java.sql.Date dx = new java.sql.Date(d.getTime());
Date d1 = date;
Date d2 = dx;
t4.setText("BirthDate"+date+"\n Current Date:"+dx);
long seconds = (d2.getTime()-d1.getTime())/1000;
return seconds;
}
However when I check the results here: http://www.calculator.net/age-calculator.html?today=04%2F04%2F1986&ageat=11%2F28%2F2013&x=32&y=10 it gives me a slight different result. I am unsure where I am going wrong.
The online service you link to is wrong: it counts the age as whole days and then assumes that each day is exactly 24 hours long. Most of the time that's correct, but in most places in the world there are days with daylight savings time transitions and timezone transitions, meaning there have been days with 23, 25, or some other number of hours. The number you get from your Java code is more precise.
I think you're somehow mixing java.sql.Date and java.util.Date.
I would try simplifying the code. Something like this.
public class Test012 {
public static void main(String[] args) throws Exception {
System.out.println( seconds() );
System.out.println( seconds2() );
System.out.println( days3() );
}
public static long seconds() throws Exception {
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date d1 = sdf.parse("1986-04-08");
java.util.Date d2 = sdf.parse("2013-11-28");
return ( d2.getTime() - d1.getTime() ) / 1000;
}
public static long seconds2() throws Exception {
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date d1 = sdf.parse("1986-04-08");
java.util.Date d2 = new java.util.Date();
return ( d2.getTime() - d1.getTime() ) / 1000;
}
public static long days3() throws Exception {
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date d1 = sdf.parse("2008-01-01");
java.util.Date d2 = sdf.parse("2009-01-01");
return ( d2.getTime() - d1.getTime() ) / 1000 / 60 / 60 / 24;
}
}
I also tried
select datediff(ss, '4/8/1986', '11/28/2013') --- US date format
in SQL Server and it prints the same thing as this java program,
it prints 872294400. So this seems to be the correct value.
Are you sure the dates coming on your input are the right ones
(are equal to those I hardcoded in my test program)?
I would check that too.
Also, are you sure your dates have zero time parts? That's what the link/service you posted assumes.
Try this code:--
public static long secondsBetween(Calendar startDate, Calendar endDate) {
Calendar date = (Calendar) startDate.clone();
long daysBetween = 0;
while (date.before(endDate)) {
date.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween*24*3600;
}
Hope it helps you.. Enjoy..!

Summing time past 24 hours

I have the following method to sum time:
public static String sumTime(String date1, String date2) throws ParseException {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss.SSS");
Date d1 = formatter.parse(date1);
Date d2 = formatter.parse(date2);
calendar.setTime(d2);
d1 = DateUtils.addHours(d1, calendar.get(Calendar.HOUR_OF_DAY));
d1 = DateUtils.addMinutes(d1, calendar.get(Calendar.MINUTE));
d1 = DateUtils.addSeconds(d1, calendar.get(Calendar.SECOND));
d1 = DateUtils.addMilliseconds(d1, calendar.get(Calendar.MILLISECOND));
return formatter.format(d1);
}
DateUtils is from Apache Commons Lang 3
It works quite well for what I want, unless the sum is bigger than 24 hours.
For example:
String time = "00:00:00.000";
try {
for (int i = 0; i < 24; i++) {
time = sumTime(time, "01:00:00.123");
}
System.out.println(time);
} catch (ParseException e) {
e.printStackTrace();
}
The result is:
00:00:02.952
But this is what I'd like it to be:
24:00:02.952
Is there any (easy) way to accomplish that?
I don't mind using different libraries/methods, as long as I get the correct result.
Keep in mind that time will always start in 00:00:00.000;
Have you thought about using days to represent each set of 24 hours? You could add something in your sumTime method, and have it add days. SimpleDateFormater can use days, maybe this will help:
http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
java.util.Date is not so strong in this area. See the Joda Time for a library that handles this properly.
I don't have access to an installation just now. The code will be close to this:
DateTimeFormatter dtf = DateTimeFormat.forPattern("HH:mm:ss.SSS");
DateTime start = dtf.parseDateTime(date1);
DateTime end = dtf.parseDateTime(date2);
PeriodFormatter pf = new PeriodFormatterBuilder()
.printZeroAlways().appendHours().appendSeparator(":")
.appendMinutes().appendSeparator(":")
.appendSeconds().appendSeparator(":")
.appendMillis3Digit().toFormatter();
return pf.print(new Period(start, end, PeriodType.time()));
Date is not the right thing class to use. Date is a instant of time, not a "Date Difference".
The right thing to do will be to use a library like Joda Time as someone has already suggested. If you don't want to do so - here's a possible alternative:
Parse the string into hours, minutes and seconds yourself, and then add it yourself.
I would encourage you to look into a "well accepted" library though. There may be things I'm not thinking of in my solution. Also, you have add all the error checking.
Here's the starter code:
public class TimeInterval {
short milliSeconds;
short seconds;
short minutes;
int hours;
public TimeInterval (String dateString) {
// HHHHHH:MI:SS.SSS
Pattern pattern = Pattern.compile("(\\d+):(\\d\\d):(\\d\\d)\\.(\\d\\d\\d)");
Matcher matcher = pattern.matcher(dateString);
if ( matcher.find() ) {
hours = Integer.parseInt(dateString.substring(matcher.start(1), matcher.end(1)));
minutes = Short.parseShort(dateString.substring(matcher.start(2), matcher.end(2)));
seconds = Short.parseShort(dateString.substring(matcher.start(3), matcher.end(3)));
milliSeconds = Short.parseShort(dateString.substring(matcher.start(4), matcher.end(4)));
}
}
private TimeInterval() {
}
public TimeInterval add(TimeInterval interval) {
TimeInterval ret = new TimeInterval();
ret.milliSeconds = (short) ((interval.milliSeconds + milliSeconds)%1000);
int carry = (interval.milliSeconds + milliSeconds)/1000;
ret.seconds = (short) ((interval.seconds + seconds)%60 + carry );
carry =(interval.seconds + seconds)/60;
ret.minutes = (short) ((interval.minutes + minutes)%60 + carry);
carry = (interval.minutes + minutes)/60;
ret.hours = (interval.hours + hours + carry);
return ret;
}
#Override
public String toString() {
return String.format("%d:%02d:%02d.%03d", hours, minutes, seconds, milliSeconds);
}
}
Using this class your program will be like :
TimeInterval time = new TimeInterval("00:00:00.000");
try {
for (int i = 0; i < 24; i++) {
time = time.add(new TimeInterval("01:00:00.123"));
}
System.out.println(time.toString());
} catch (ParseException e) {
e.printStackTrace();
}
Have you tried Joda-Time which actually has direct support for this sort of thing?
PeriodFormatterBuilder builder = new PeriodFormatterBuilder();
builder.printZeroAlways()
.minimumPrintedDigits(2)
.appendHours()
.appendSeparator(":").appendMinutes()
.appendSeparator(":").appendSeconds()
.appendSeparator(".").appendMillis3Digit();
PeriodFormatter formatter = builder.toFormatter();
PeriodParser parser = builder.toParser();
String s1 = "11:00:00.111";
String s2 = "23:00:00.111";
MutablePeriod p1 = new MutablePeriod();
MutablePeriod p2 = new MutablePeriod();
parser.parseInto(p1, s1, 0, Locale.getDefault());
parser.parseInto(p2, s2, 0, Locale.getDefault());
p1.add(p2);
System.out.println(formatter.print(p1));
Prints
34:00:00.222

Categories