Period.between only subtracting days - java

The variable dateSubtract comes out to 16 but I want to find the total number of days in between the 2 days, which should be 165. How can I do this WITHOUT JODA TIME?
String date = "06/17/2014";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
LocalDate d1 = LocalDate.parse("01/01/2014", formatter);
LocalDate d2 = LocalDate.parse(date, formatter);
int dateSubtract = Period.between(d1, d2).getDays();

Period is a combination of day, month, year. So in your case, the period is 5 months and 16 days. It is explained in the javadoc although not necessarily very clear if you read it casually.
The days unit is not automatically normalized with the months and years unit. This means that a period of "45 days" is different to a period of "1 month and 15 days" and getDays() will return 45 and 15 respectively.
To get the total number of days between two dates, you can use:
//including d1, excluding d2:
ChronoUnit.DAYS.between(d1, d2);
//or, to exclude d1 AND d2, one of these:
ChronoUnit.DAYS.between(d1.plusDays(1), d2);
ChronoUnit.DAYS.between(d1, d2) - 1;

Without JODA time:
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy");
Date dateStart = null;
Date dateEnd = null;
try {
dateStart = format.parse("01/01/2014");
dateEnd = format.parse("06/17/2014");
long diffTime = dateEnd.getTime() - dateStart.getTime();
long diffDays = diffTime / (24 * 60 * 60 * 1000);
} catch (Exception e) {
e.printStackTrace();
}

Period models a quantity or amount of time in terms of years, months and days,
such as 2 years, 3 months and 4 days.
To calculate days between two date use ChronoUnit.DAYS.between
long days = ChronoUnit.DAYS.between(LocalDate.of(2020,4,1), LocalDate.now());

Related

Java code to find difference between two time,where time is stored in date type and time is in 24 hour format [duplicate]

This question already has an answer here:
Difference in time - from before midnight to after midnight without date
(1 answer)
Closed 3 years ago.
i need java code to find difference between two times in 24 hour format
for example:
20:00:00 - 04:00:00
and the expected output is 8 hrs
but now output is 16 hrs
when i tried 12 hour format out put is coming 4.
below is the code used to parse and to find difference
SimpleDateFormat readFormat = new SimpleDateFormat("HH:mm");
Date d1 = readFormat.parse(txtshiftIn);
Date d2 = readFormat.parse(txtshiftOut);
long diff = d2.getTime() - d1.getTime();
input is just 20:00 and 04:00 no seconds and AM/PM part.
The issue with using Date is it still expects an actual date even though you are using just the time portion of it, so if you're just sending it the time it will not be correct.
Instead use LocalTime and ChronoUnit.HOURS to get the difference between the time.
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm");
LocalTime lt1 = LocalTime.parse(txtshiftIn, dtf);
LocalTime lt2 = LocalTime.parse(txtshiftOut, dtf);
long diff = ChronoUnit.HOURS.between(lt1, lt2);
This will show -16 which means that lt1 is ahead of lt2 which indicates lt2 is the next day so we can modify it to get the differences as such
if (diff < 0) {
diff += 24;
}
This will give you the 8 hour difference you're expecting.
UPDATE
To account the difference in minutes you can do the following:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm");
LocalTime lt1 = LocalTime.parse(txtshiftIn, dtf);
LocalTime lt2 = LocalTime.parse(txtshiftOut, dtf);
long diff = ChronoUnit.MINUTES.between(lt1, lt2); //get diff in minutes
if (lt2.isBefore(lt1)) {
diff += TimeUnit.DAYS.toMinutes(1); //add a day to account for day diff
}
long hours = diff / 60;
long minutes = diff % 60;
LocalTime newTime = LocalTime.parse(String.format("%02d:%02d", hours, minutes), dtf); //Format the difference to be converted to LocalTime
System.out.println(newTime);
This will produce the difference in minutes:
08:30
Update 2
Here is a cleaner method that returns a Duration
public Duration timeDifference(String txtshiftIn, String txtshiftOut) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm");
LocalTime lt1 = LocalTime.parse(txtshiftIn, dtf);
LocalTime lt2 = LocalTime.parse(txtshiftOut, dtf);
Duration between = Duration.between(lt1, lt2);
if (lt2.isBefore(lt1)) { //account for lt2 being on the next day
between = Duration.ofMinutes(TimeUnit.DAYS.toMinutes(1)).plus(between);
}
return between;
}
While it is strongly recommended you use a more up-to-date Java time library like LocalTime your logic so far actually is correct with one little caveat:
SimpleDateFormat readFormat = new SimpleDateFormat("HH:mm");
Date d1 = readFormat.parse(txtshiftIn);
Date d2 = readFormat.parse(txtshiftOut);
long diff = d2.getTime() - d1.getTime();
In your code if d1 is after d2 you will get a negativ result for long diff
So when you say
"but now output is 16 hrs"
The actual output is -16 hrs
Of course minus sixteen hours doesn't make much sense in your case, but you can easily fix that with the simple trick of just adding 24 hours in case of a negative result for diff. (And -16+24 is the 8 you expected as a result).
So just add the following lines at the end of your posted code
if(diff < 0) {
diff = 86400000 + diff;
}
And you will get the results you expect!
(86400000 is the 24h expressed in milliseconds)

get days starting from epoch

I want count of days starting from epoch(1970-01-01). I tried with joda-time
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date1 = sdf.parse("2013-05-03 07:00:00");
Date date2 = sdf.parse("2013-05-03 23:30:00");
MutableDateTime epoch = new MutableDateTime();
epoch.setDate(0); //Set to Epoch time
System.out.println("Epoch: " + epoch);
Days days1 = Days.daysBetween(epoch, new MutableDateTime(date1.getTime()));
Days days2 = Days.daysBetween(epoch, new MutableDateTime(date2.getTime()));
System.out.println("1) Days Since Epoch: " + days1.getDays());
System.out.println("2) Days Since Epoch: " + days2.getDays());
} catch (ParseException e) {
e.printStackTrace();
}
and using logic:
// Create Calendar instance
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(date);
// Set the values for the calendar fields YEAR, MONTH, and DAY_OF_MONTH.
// calendar1.set(calendar1.YEAR, calendar1.MONTH, Calendar.DAY_OF_MONTH);
calendar1.set(1970, 1, 1);
/*
* Use getTimeInMillis() method to get the Calendar's time value in
* milliseconds. This method returns the current time as UTC
* milliseconds from the epoch
*/
long miliSecondForDate1 = calendar1.getTimeInMillis();
long miliSecondForDate2 = calendar2.getTimeInMillis();
// Calculate the difference in millisecond between two dates
long diffInMilis = miliSecondForDate2 - miliSecondForDate1;
/*
* Now we have difference between two date in form of millsecond we can
* easily convert it Minute / Hour / Days by dividing the difference
* with appropriate value. 1 Second : 1000 milisecond 1 Hour : 60 * 1000
* millisecond 1 Day : 24 * 60 * 1000 milisecond
*/
long diffInSecond = diffInMilis / 1000;
long diffInMinute = diffInMilis / (60 * 1000);
long diffInHour = diffInMilis / (60 * 60 * 1000);
long diffInDays = diffInMilis / (24 * 60 * 60 * 1000);
if(logger.isInfoEnabled()) {
logger.info("Difference in Seconds : " + diffInSecond);
logger.info("Difference in Minute : " + diffInMinute);
logger.info("Difference in Hours : " + diffInHour);
logger.info("Difference in Days : " + diffInDays);
}
I am getting diff result for both of this. can somebody help where i am wrong.
thanks.
The difference between 17006 and 17007 is one day. This difference very likely comes from 7:00 and 23:30 in your time zone are on different days in some other time zone, say, UTC. Or the other way around, those times in UTC happen to be on different days in your time zone. Therefore the count is off by one. I don’t know JodaTime, so I cannot give you the precise details.
The difference between 16975 and 17006 is 31 days or a full month. I can tell you exactly where this comes from. Calendar months are 0-based: January is month 0, February is 1, etc. So calendar1.set(1970, 1, 1) sets your Calendar to February 1, 1970, 31 days after the epoch. Use calendar1.set(1970, Calendar.JANUARY, 1) instead. You will also want to control the hours, minutes and seconds of the Calendar. You may call clear() before set() to make sure the time is at midnight.
If you can use Java 8, you may do:
DateTimeFormatter format = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
OffsetDateTime t1 = LocalDateTime.parse("2013-05-03 07:00:00", format)
.atOffset(ZoneOffset.UTC);
OffsetDateTime t2 = LocalDateTime.parse("2013-05-03 23:30:00", format)
.atOffset(ZoneOffset.UTC);
System.out.println("1) Days Since Epoch: " + ChronoUnit.DAYS.between(Instant.EPOCH, t1));
System.out.println("2) Days Since Epoch: " + ChronoUnit.DAYS.between(Instant.EPOCH, t2));
This prints:
1) Days Since Epoch: 15828
2) Days Since Epoch: 15828
If you want to use a different time zone:
DateTimeFormatter format = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
ZonedDateTime t1 = LocalDateTime.parse("2013-05-03 07:00:00", format)
.atZone(ZoneId.systemDefault());
ZonedDateTime t2 = LocalDateTime.parse("2013-05-03 23:30:00", format)
.atZone(ZoneId.systemDefault());
System.out.println("1) Days Since Epoch: " + ChronoUnit.DAYS.between(Instant.EPOCH, t1));
System.out.println("2) Days Since Epoch: " + ChronoUnit.DAYS.between(Instant.EPOCH, t2));
You can fill in the desired time zone instead of ZoneId.systemDefault().

Calculating time difference bug

I am trying to calculate the difference between two dates. The difference consist of remaining Days, Hours, Minutes, Seconds.
I'm using this method:
public static void computeDiff(Date date2) {
Date date1 = new Date();
long diffInMillies = date2.getTime() - date1.getTime();
long milliesRest = diffInMillies;
for ( TimeUnit unit : timeUnitsArrayList ) {
long diff = unit.convert(milliesRest, TimeUnit.MILLISECONDS);
long diffInMilliesForUnit = unit.toMillis(diff);
milliesRest -= diffInMilliesForUnit;
result.put(unit, diff);
}
}
/*
TimeUnit = java.util.concurrent.TimeUnit
timeUnitsArrayList = A list with units: DAYS, HOURS, MINUTES, SECONDS
date1 = java.util.Date (date now)
date2 = java.util.Date (a date with time 00:00:00)
*/
I'm giving an example: If i want the difference between today and and 20 March 2015, the difference will be ok (8 days, X hours, Y minutes, Z seconds), but if i choose an older date like 20 April 2015 the difference will be 39 days (ok), X - 1 hours (which isn't ok because is calculating wrong), Y minutes (ok), Z seconds(ok).
Is a Java bug or a bug in my code? Because if i choose an earlier date, the hours are ok, but if i choose an older date i get the hours wrong (one less hour)
Thank you
This is most probably an issue with the switch to daylight saving time - in central europe the change is on 29 March, so in your timezone (wherever that is) it might be similar and would account for the 1 hour.

Unable to find difference between two dates w.r.t time,seconds,months and years?

This is my java class
public class dateparse {
public static void main(String args[]) throws ParseException
{
Date dd=new Date();
int year = Calendar.getInstance().get(Calendar.YEAR);
int month=0;
int calc_days=0;
String d1 = dd.getDate()+"/"+dd.getMonth()+"/"+year;
String d2 = "19/1/2014";
SimpleDateFormat s1 = new SimpleDateFormat("dd/mm/yyyy");
SimpleDateFormat s2 = new SimpleDateFormat("dd/mm/yyyy");
Date dateOne = new SimpleDateFormat("dd/mm/yyyy").parse(d1);
Date dateTwo = s2.parse(d2);
long diff = dateOne.getTime() - dateTwo.getTime();
calc_days= (int) (diff / 1000 / 60 / 60 / 24 / 1);
}
}
I am trying to find the difference between current date and the date specified with respect to seconds,minutes,hours,days,months and years.Here my input date is 19th Feb 2014.I want to show the difference in no of days(e.g. 10 days) or months+days(e.g.1 month and 2 days) or year+month+days(e.g. 1 year and 2 months and 4 days).But when I run this code it returns difference as -10 days.
Your error is your parsing. Lowercase m means minutes, not month:
SimpleDateFormat s2 = new SimpleDateFormat("dd/mm/yyyy");
should be:
SimpleDateFormat s2 = new SimpleDateFormat("dd/MM/yyyy");
Here's a simplified example:
String d1 = "21/1/2014";
String d2 = "19/1/2014";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date dateOne = sdf.parse(d1);
Date dateTwo = sdf.parse(d2);
long diff = dateOne.getTime() - dateTwo.getTime();
int differenceInDays = (int) (diff / 1000 / 60 / 60 / 24 / 1);
System.out.println(differenceInDays);
Prints: 2
This is a classic error caused by the horrible API that Java has provided:
date.getMonth() returns 0 for January, 1 for february... and 11 for December. If you can, try to avoid java.util.Date and Calendar :P
Attention - Accepted answer is wrong! Prove:
Use as input the dates 2014-03-19 and 2014-04-01 in my timezone "Europe/Berlin". The true answer is 13 days as everyone can easily veryify using standard calendars, but the accepted code of #Duncan produces 12 days because in my timezone there was a dst-jump which breaks the basis of calculation formular (1 day = 24 hours). On 30th of March the day was only 23 hours long.
The JDK pre 8 does not offer a built-in generic solution for this problem. Please also note that your input is just a pair of two plain dates with no time. Therefore it is silly to ask for the difference in seconds, etc. Only asking for the difference in days, months, weeks or years is sensible. In Java 8 you can do following:
// only days
LocalDate start = LocalDate.of(2014, 3, 19); // start in March
LocalDate end = LocalDate.of(2014, 4, 1);
int days = ChronoUnit.DAYS.between(start, end); // 13
// period in years, months and days
LocalDate start = LocalDate.of(2014, 2, 19); // start in February
LocalDate end = LocalDate.of(2014, 4, 1);
Period period = Period.between(start, end); // P1M13D = 1 month + 13 days
Unfortunately you are not free to choose in which calendar units you like to get the difference expressed. JodaTime (and my library) has a more flexible approach using PeriodType.

Find total hours between two Dates

I have two Date objects and I need to get the time difference so I can determine the total hours between them. They happen to be from the same day. The result I would like would have the hours and minutes.
When I use .toString() on my Date object I get this: Fri Dec 18 08:08:10 CST 2009
I've tried the following:
long diff = (this.endDate.getTime() - this.startDate.getTime()) / (60 * 60 * 1000);
But this only gives me hours, not the minutes.
I know this is a simple problem, but I can't figure it out atm.
Edits:
Final solution for those interested. Thanks to Michael Brewer-Davis
Period p = new Period(this.startDate, this.endDate);
long hours = p.getHours();
long minutes = p.getMinutes();
String format = String.format("%%0%dd", 2);
return Long.toString(hours) + ":" + String.format(format, minutes);
This should work.
long secs = (this.endDate.getTime() - this.startDate.getTime()) / 1000;
int hours = secs / 3600;
secs = secs % 3600;
int mins = secs / 60;
secs = secs % 60;
Here's how it works with Joda time:
DateTime startTime, endTime;
Period p = new Period(startTime, endTime);
int hours = p.getHours();
int minutes = p.getMinutes();
You could format with Joda's formatters, e.g., PeriodFormat, but I'd suggest using Java's. See this question for more details.
EDIT: be careful using this method to check hours between. This function don't respect days between. It get just hours between two times. 2022-07-20 11.00 and 2022-07-21 12.00 will return 1 hour, not 25 hours.
Here's simple way:
private static int hoursDifference(Date date1, Date date2) {
final int MILLI_TO_HOUR = 1000 * 60 * 60;
return (int) (date1.getTime() - date2.getTime()) / MILLI_TO_HOUR;
}
java.time.Duration
I should like to contribute the modern (java 8+) answer. The solutions using Joda-Time are fine. The Joda-Time project is in maintenance mode, so for new code we should not use it. I follow the official recommendation from the Joda-Time project and use java.time, the modern Java date and time API:
Duration dur = Duration.between(startDate, endDate);
String result = String.format("%d:%02d", dur.toHours(), dur.toMinutesPart());
System.out.println(result);
This works if startDate and endDate both have type Instant or OffsetDateTime or ZonedDateTime or LocalDateTime or LocalTime. All of the mentioned types are from java.time package. If starting with LocalDate, call either of the atStartOfDay methods.
The toMinutesPart methof was introduced in Java 9. If you are using Java 8 (ot ThreeTen Backport), search for java format duration or similar to learn how to format the duration into hours and minutes.
Two quotes from the Joda-Time home page:
Users are now asked to migrate to java.time (JSR-310).
Note that Joda-Time is considered to be a largely “finished” project.
No major enhancements are planned. If using Java SE 8, please migrate
to java.time (JSR-310).
Links
Oracle tutorial: Date Time explaining how to use java.time.
Joda-Time home page
Please follow Somaiah's suggestion in a comment, use Hours instead:
Hours hours = Hours.hoursBetween(startTime, endTime);
The call to getHours() will only return the hour section of the time difference and ignore all year, month differences so it would not be correct in some cases.
If you use Period.toStandardHours() to try to convert the time difference into hours the calculation will throw an exception if the time difference between the two dates includes difference in either year or month, since the length of month is unknown.
So the getTime() method, I presume, returns an integer.
In which case, the left set of parentheses has type int, right?
and
(60*60*1000)
is also an int.
Which means you get long diff = ((int)/(int)) so the integer division is done BEFORE you cast stuff to long. And hence you lose your minutes.
Try casting them BEFORE you divide.
for kotlin, you can use below function and get hours between two date
private val dateFormat: String = "yyyy-MM-dd # hh:mm a"
val startDate = SimpleDateFormat(dateFormat).parse("2018-10-01 # 12:33 PM")
val endDate = SimpleDateFormat(dateFormat).parse("2018-10-01 # 02:46 PM")
private fun hoursDifference(date1: Date, date2: Date): Int {
val milliToHour : Long = 1000 * 60 * 60
return ((date1.time - date2.time) / milliToHour).toInt()
}
println(hoursDifference(endDate,startDate).toString())
Output:
2
Even though there's already an accepted answer, this is what worked for me using the Joda time library.
/**
*
* #param date1
* #param date2
* #return hours between two dates rounded down
*/
public static int hoursBetween(DateTime date1, DateTime date2) {
if(date1 == null || date2 == null) return NOT_FOUND;
return Math.abs(Hours.hoursBetween(date1.toLocalDateTime(), date2.toLocalDateTime()).getHours());
}
private void getHours(Date d1, Date d2){
long diff = d2.getTime() - d1.getTime();
long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffDays = diff / (24 * 60 * 60 * 1000);
long diffHours = diff / (60 * 60 * 1000) % 24;
System.out.print(diffDays + " days, ");
System.out.print(diffHours + " hours, ");
System.out.print(diffMinutes + " minutes, ");
System.out.print(diffSeconds + " seconds.\n");
}`
//Displays:
/* 1 days, 1 hours, 1 minutes, 50 seconds. */
Here's a pure Java 8+ solution that does not involve Joda or mathematical operations
import java.time.*;
import java.time.temporal.*;
// given two java.util.Dates
Date startDate ...
Date endDate ...
// convert them to ZonedDateTime instances
ZonedDateTime start = ZonedDateTime.ofInstant(startDate.toInstant(), ZoneId.systemDefault());
ZonedDateTime end = ZonedDateTime.ofInstant(endDate.toInstant(), ZoneId.systemDefault());
// get the total duration of minutes between them
Duration total = Duration.ofMinutes(ChronoUnit.MINUTES.between(start, end));
// use the duration to determine the hours and minutes values
long hours = total.toHours();
long minutes = total.minusHours(hours).toMinutes();
Here is the simple method :-
Check your Date format,if your date not in this format then change it and pass to this method it will give you a String which is your result. Modify the method as per the requirement.
private String getDateAsTime(String datePrev) {
String daysAsTime = "";
long day = 0, diff = 0;
String outputPattern = "yyyy:MM:dd HH:mm:ss";
SimpleDateFormat outputFormat = new SimpleDateFormat(outputPattern);
Calendar c = Calendar.getInstance();
String dateCurrent = outputFormat.format(c.getTime());
try {
Date date1 = outputFormat.parse(datePrev);
Date date2 = outputFormat.parse(dateCurrent);
diff = date2.getTime() - date1.getTime();
day = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
} catch (ParseException e) {
e.printStackTrace();
}
if (day == 0) {
long hour = TimeUnit.HOURS.convert(diff, TimeUnit.MILLISECONDS);
if (hour == 0)
daysAsTime = String.valueOf(TimeUnit.MINUTES.convert(diff, TimeUnit.MILLISECONDS)).concat(" minutes ago");
else
daysAsTime = String.valueOf(hour).concat(" hours ago");
} else {
daysAsTime = String.valueOf(day).concat(" days ago");
}
return daysAsTime;
}
Hope this will help,

Categories

Resources