So my method receives a time in 24 hour format ("HH:MM:SS") and returns a string the difference time. If it's 2:00PM local time I should be able to send it "16:30:00"(4:30PM) and get the output "2 hours, 30 mins". But the code has some problem, and I am just a beginner and I need help to fix it.
The problem is if the time is 4:40PM, and I sent it "17:00:00"(5:00PM) it returns the message:
12 hours, 20 minutes instead of 0 hours, 20 minutes.
The other problem is if I sent it the current time, it would return "12 hours" away, and not 24 like it should.
Please keep in mind I am only a beginner at java and math really isn't my thing, so any help is highly appreciated. Thanks.
private static String timeUntil(String distanceTime) {
String returnMsg = null;
try {
SimpleDateFormat sdfDate = new SimpleDateFormat("hh:mm:ss");
Date now = new Date();
java.text.DateFormat df = new java.text.SimpleDateFormat("hh:mm:ss");
Date date1 = df.parse(sdfDate.format(now));
Date date2 = df.parse(distanceTime);
long diff = date2.getTime() - date1.getTime();
int timeInSeconds = (int) (diff / 1000);
int hours, minutes;
hours = timeInSeconds / 3600;
timeInSeconds = timeInSeconds - (hours * 3600);
minutes = timeInSeconds / 60;
if (hours >= 0) {
returnMsg = hours + " hours" +
"\n" + minutes + " mins";
} else {
returnMsg = minutes + " mins";
}
} catch (Exception e) {
e.printStackTrace();
}
return returnMsg;
}
In your date format, hh is used for 12-hour time. Use HH for 24-hour time:
new SimpleDateFormat("HH:mm:ss");
Code review comments...
Most of the Date class' methods are deprecated. You should consider using Calendar (GregorianCalendar) instead of Date.
Your variable names often lack meaning - you have to know the purpose of the variable to know its meaning. Your code will be more maintainable if you use better variable names. df could be renamed "format" or "dateFormat".
You create a Date object 'now', then you pass it through your df DateFormat instance, hten through your sdfDate instance, to convert it back to a Date. This is unnecessary. Replace this with Date date1 = new Date(); and remove Date now = new Date();. Simiilarly, I've seen very difficult to diagnose errors when converting between units, so you should change diff to indicate that it's milliseconds, like diff_ms. And you should keep names consistent - you change from "different" (diff) to "timeInSeconds". They should both be "timeInXxx" or "diff_xx". the distanceTime parameter should be renamed something like futureTime
You do a bunch of math to determine the difference between two times, but there are libraries that will do this for you. Google for "java difference between two dates" and find many answers.
Your code always assumes that the second time occurs after "now". This should be included in a comment at the top of your method.
When you instantiate date1 and date2, they're both probably for the same day. Try debugging or at least printing the objects to stdout immediately after they're created to see if this is the case. Is this what you really want?
Your code doesn't handle leap year.
Instead of handling all of the time conversions yourself, why don't you look for a library that does it for you?
This is your fixed code. I have changed the date format to HH:mm:ss and also your calculation logic. Try it and let us know
private static String timeUntil(String distanceTime) {
String returnMsg = null;
try {
SimpleDateFormat sdfDate = new SimpleDateFormat("HH:mm:ss");
Date now = new Date();
java.text.DateFormat df = new java.text.SimpleDateFormat("HH:mm:ss");
Date date1 = df.parse(sdfDate.format(now));
Date date2 = df.parse(distanceTime);
long diff = date2.getTime() - date1.getTime();
int timeInSeconds = (int) (diff / 1000);
int hours, minutes;
hours = timeInSeconds / 3600;
timeInSeconds = timeInSeconds - (hours * 3600);
minutes = timeInSeconds / 60;
if (hours != 0) {
returnMsg = hours + " hours" +
"\n" + minutes + " mins";
} else {
returnMsg = minutes + " mins";
}
} catch (Exception e) {
e.printStackTrace();
}
return returnMsg;
}
Here is an example which is more robust and uses Java more modern date functions. I could go point by point and point at all the thing you could have done better in your example, but sometimes its easier to give you a good example and let you glean what you can from other people code as far as good style.
import java.util.Calendar;
public class testSpace {
public static void main (String ... args){
System.out.println(timeUntil("00:12:12"));
}
private static String timeUntil(String distanceTime){
String[] times = distanceTime.split(":");
Calendar now = Calendar.getInstance();
Calendar then = Calendar.getInstance();
then.set(Calendar.SECOND, Integer.parseInt(times[2]));
then.set(Calendar.MINUTE, Integer.parseInt(times[1]));
then.set(Calendar.HOUR, Integer.parseInt(times[0]) % 12);
then.set(Calendar.AM_PM, (Integer.parseInt(times[0]) >= 12 ) ? Calendar.PM : Calendar.AM);
boolean isFuture = (then.getTimeInMillis() > now.getTimeInMillis());
long interval = (isFuture)
? then.getTimeInMillis() - now.getTimeInMillis()
: now.getTimeInMillis() - then.getTimeInMillis();
return ((isFuture) ? "" : "-") + millToTime(interval);
}
public static long MILLISECOND_PER_HOUR = 1000*60*60;
public static long MILLISECOND_PER_MIN = 1000*60;
public static long MILLISECOND_PER_SECOND = 1000;
public static String millToTime(long mill){
long hours = mill / MILLISECOND_PER_HOUR;
long mins = (mill % MILLISECOND_PER_HOUR) / MILLISECOND_PER_MIN;
long sec = ((mill % MILLISECOND_PER_HOUR) % MILLISECOND_PER_MIN) / MILLISECOND_PER_SECOND;
return String.format("%d:%d:%d", hours, mins, sec);
}
}
tl;dr
For time-of-day only, without a date or time zone.
LocalTime start = LocalTime.of( "16:40" ) ;
LocalTime stop = LocalTime.of( "17:00" ) ;
Duration d = Duration.between( start , stop ) ;
PT20M
Or, for date-time in a zone.
ZoneId z = ZoneId.of( "America/Montreal" )
ZonedDateTime zdtNow = ZonedDateTime.now( z );
ZonedDateTime zdtThen =
ZonedDateTime.of( // Pass a LocalDate, LocalTime, ZoneId.
zdtNow.toLocalDate() , // Same date…
LocalTime.parse( "16:30:00" ) , // … but different time-of-day.
z
)
Duration d = Duration.between( zdtNow , zdtThen ) ;
PT2H30M
Details
You are using old date-time classes, now legacy, supplanted by the java.time classes.
LocalTime
You are incorrectly using a date-time class for a time-of-day-only value. Instead use the LocalTime class. And use a span-of-time class when calculating elapsed time.
String input = "16:30:00" ;
LocalTime lt = LocalTime.parse( input );
Instant
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now();
ZonedDateTime
Determining a wall-clock time requires a time zone. Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtNow = instant.atZone( z ); // Adjusted into your time zone.
Now construct a ZonedDateTime for your given input time-of-day.
ZonedDateTime zdtTarget = ZonedDateTime.of( zdtNow.toLocalDate() , lt , z );
Duration
Use Duration to represent elapsed time not attached to the timeline.
Duration d = Duration.between( zdtNow , zdtTarget );
Note that the duration will be a negative amount if the specified time-of-day is earlier than the current time-of-day.
ISO 8601 string for duration
To get a String describing the hours, minutes, etc. of that span of time, simply call toString to generate a String in standard ISO 8601 format of PnYnMnDTnHnMnS where P marks the beginning and T separates the years-month-days from hours-minutes-seconds.
If the current time were 14:00:00 in the same zone, the output would be:
PT2H30M
Getter methods
Oddly, in Java 8 this class Duration lacks any getter methods for the parts such as 2 for hours and 30 for minutes. Remedied in Java 9 with methods such as toHoursPart and toMinutesPart.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Related
I want hours and minutes will start from the current date will be October 10, 2016 end of days
package com.mkyong.date;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateDifferentExample
{
public static void main(String[] args)
{
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
//get current date time with Date()
Date date = new Date();
System.out.println(dateFormat.format(date));
//get current date time with Calendar()
Calendar cal = Calendar.getInstance();
System.out.println(dateFormat.format(cal.getTime()));
String dateStart = "01/14/2012 09:29:58";
String dateStop = "01/15/2012 10:31:48";
//HH converts hour in 24 hours format (0-23), day calculation
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date d1 = null;
Date d2 = null;
try
{
d1 = format.parse(dateStart);
d2 = format.parse(dateStop);
//in milliseconds
long diff = d2.getTime() - d1.getTime();
long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.print(diffDays + " days, ");
System.out.print(diffHours + " hours, ");
System.out.print(diffMinutes + " minutes, ");
System.out.print(diffSeconds + " seconds.");
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Results :
2016/08/15 18:54:03
2016/08/15 18:54:03
1097 Days1 Hours 1 Minute 50 Second
My want to result for example :
100 days 5 hours 2 minutes
Avoid old date-time classes
You are using troublesome old legacy date-time classes bundled with the earliest versions of Java. Use java.time classes instead.
Parsing
Your input strings are almost in standard ISO 8601 format. Replace the SPACE in the middle with a T. The java.time classes parse/generate strings using ISO 8601 formats by default. So no need to specify a formatting pattern.
String startInput = "01/14/2012 09:29:58".replace( " " , "T" );
String stopInput = "01/15/2012 10:31:48".replace( " " , "T" );
LocalDateTime
Your inputs lack any information about offset-from-UTC or time zone. So we parse as LocalDateTime objects.
LocalDateTime startLdt = LocalDateTime.parse( startInput );
LocalDateTime stopLdt = LocalDateTime.parse( stopInput );
If you work further with these types you will get results based on generic 24-hour days while ignoring anomalies such as Daylight Saving Time (DST).
If you know the context of this data is a particular time zone, apply the zone to get ZonedDateTime.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime start = startLdt.atZone( zoneId );
ZonedDateTime stop = stopLdt.atZone( zoneId );
If you want the current moment as the start or the stop, call now. Pass the desired/expected time zone rather than relying on the JVM’s current default time zone.
ZonedDateTime now = ZonedDateTime.now( zoneId );
Duration
The Duration class represents a span of time as a total of seconds plus a fraction of a second in nanoseconds resolution.
Duration duration = Duration.between( start , stop );
Oddly, in Java 8 this class lacks methods to get the number of days, hours, etc. making up this span of time. Java 9 adds to…Part methods.
long days = duration.toDaysPart();
int hours = duration.toHoursPart();
int minutes = duration.toMinutesPart();
Until Java 9 you can do the math yourself.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
public final void set(int year,int month,int date) - this method of Calendar class can be used to set date .
public final void set(int year, int month,int date,int hourOfDay,int minute,int second) can be used to set time too.
Calendar.getInstance() by default set current date and time.`
Looking at the source code here for this example project:
https://github.com/quakig/sunrisesunsettime/tree/master/SunriseSunsetTime
It calculates the sunrise/sunset time. Looking at the code, I cannot see where they determine if the time is returned in 12hour or 24 hours format. Running the sample apk on my phone, it gets returned in 24 hour format.
Where in the code is this determined? or would I be looking in the layout file properties instead of the javascript?
It's located in the transitTime method that is located in the MainActivity :
protected String transitTime(String endtime, String starttime) {
SimpleDateFormat dt = new SimpleDateFormat("hh:mm");
Date startTime;
Date endTime;
long timdedifferencemillis = 0;
try {
startTime = dt.parse(starttime);
endTime = dt.parse(endtime);
timdedifferencemillis = endTime.getTime() - startTime.getTime(); // in
// milliseconds
} catch (ParseException e) {
e.printStackTrace();
}
int minutes = Math
.abs((int) ((timdedifferencemillis / (1000 * 60)) % 60));
int hours = Math
.abs((int) ((timdedifferencemillis / (1000 * 60 * 60)) % 24));
String hm = String.format("%02d h %02d min", hours, minutes);
return hm;
}
You will have to tweak it yourself to return the 12hr format.
Joda-Time
You can use the Joda-Time library to alter a time-of-day string from 24-hour format to a 12-hour format.
LocalTime
Unlike the java.util.Date & .Calendar classes bundled with Java, Joda-Time offers a class to represent the time-of-day without a date or time zone. The class is called LocalTime.
In Java 8, the new java.time package (inspired by Joda-Time) also has such a class. But Java 8 technology has not yet been copied in Android. Joda-Time does work in Android.
Example Code
LocalTime localTime = LocalTime.parse( "15:43:21" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "h:m a" ); // Truncate seconds and fractional seconds.
String output = formatter.print( localTime );
Dump to console.
System.out.println( "output: " + output ); // output: 3:43 PM
I am trying to compare two calendars in java to decide if one of them is >= 24 hours ago. I am unsure on the best approach to accomplish this.
// get today's date
Date today = new Date();
Calendar currentDate = Calendar.getInstance();
currentDate.setTime(today);
// get last update date
Date lastUpdate = profile.getDateLastUpdated().get(owner);
Calendar lastUpdatedCalendar = Calendar.getInstance();
lastUpdatedCalendar(lastUpdate);
// compare that last hotted was < 24 hrs ago from today?
tl;dr
Instant now = Instant.now();
Boolean isWithinPrior24Hours =
( ! yourJUDate.toInstant().isBefore( now.minus( 24 , ChronoUnit.HOURS) ) )
&&
( yourJUDate.toInstant().isBefore( now )
) ;
Details
The old date-time classes (java.util.Date/.Calendar, java.text.SimpleDateFormat, etc.) have proven to be be confusing and flawed. Avoid them.
For Java 8 and later, use java.time framework built into Java. For earlier Java, add the Joda-Time framework to your project.
You can easily convert between a java.util.Date and either framework.
java.time
The java.time framework built into Java 8 and later supplants the troublesome old java.util.Date/.Calendar classes. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.
The Instant class represents a moment on the timeline in UTC. If you meant to ask for literally 24 hours rather than "a day", then Instant is all we need.
Instant then = yourJUDate.toInstant();
Instant now = Instant.now();
Instant twentyFourHoursEarlier = now.minus( 24 , ChronoUnit.HOURS );
// Is that moment (a) not before 24 hours ago, AND (b) before now (not in the future)?
Boolean within24Hours = ( ! then.isBefore( twentyFourHoursEarlier ) ) && then.isBefore( now ) ;
If you meant "a day" rather than 24 hours, then we need to consider time zone. A day is determined locally, within a time zone. Daylight Saving Time (DST) and other anomalies mean a day is not always 24 hours long.
Instant then = yourJUDate.toInstant();
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
ZonedDateTime oneDayAgo = now.minusDays( 1 );
Boolean within24Hours = ( ! then.isBefore( oneDayAgo ) ) && then.isBefore( now ) ;
Another approach would use the Interval class found in the ThreeTen-Extra project. That class represents a pair of Instant objects. The class offers methods such as contains to perform comparisons.
Joda-Time
The Joda-Time library works in a similar fashion to java.time, having been its inspiration.
DateTime dateTime = new DateTime( yourDate ); // Convert java.util.Date to Joda-Time DateTime.
DateTime yesterday = DateTime.now().minusDays(1);
boolean isBeforeYesterday = dateTime.isBefore( yesterday );
Or, in one line:
boolean isBeforeYesterday = new DateTime( yourDate).isBefore( DateTime.now().minusDays(1) );
you could use Date.getTime(), here's an example:
public final static long MILLIS_PER_DAY = 24 * 60 * 60 * 1000L;
public static void main(String args[]) throws Exception {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = sdf.parse("2009-12-31");
Date date2 = sdf.parse("2010-01-31");
boolean moreThanDay = Math.abs(date1.getTime() - date2.getTime()) > MILLIS_PER_DAY;
System.out.println(moreThanDay);
}
You can check localDateTime whether its in 24 hours or not, depending on zone offset parameter like following the example.
#Test
public void checkIsWithin24Hours() {
final ZoneOffset zoneOffset = ZoneOffset.UTC;
final LocalDateTime now = LocalDateTime.now(zoneOffset);
final LocalDateTime after = LocalDateTime.now(zoneOffset).plusHours(5);
final long nowHours = TimeUnit.MILLISECONDS.toHours(now.toInstant(zoneOffset).toEpochMilli());
final long afterFiveHours = TimeUnit.MILLISECONDS.toHours(after.toInstant(zoneOffset).toEpochMilli());
assertThat(afterFiveHours - nowHours <= 24).isTrue();
}
I have this date object:
SimpleDateFormat df = new SimpleDateFormat("yyyy-mm-dd HH:mm");
Date d1 = df.parse(interviewList.get(37).getTime());
value of d1 is Fri Jan 07 17:40:00 PKT 2011
Now I am trying to add 10 minutes to the date above.
Calendar cal = Calendar.getInstance();
cal.setTime(d1);
cal.add(Calendar.MINUTE, 10);
String newTime = df.format(cal.getTime());
Value of newTime changes to 2011-50-07 17:50
but it should be 07-01-2011 17:50.
It adds minutes correctly but it also changes month, don't know why!
The issue for you is that you are using mm. You should use MM. MM is for month and mm is for minutes. Try with yyyy-MM-dd HH:mm
Other approach:
It can be as simple as this (other option is to use joda-time)
static final long ONE_MINUTE_IN_MILLIS=60000;//millisecs
Calendar date = Calendar.getInstance();
long t= date.getTimeInMillis();
Date afterAddingTenMins=new Date(t + (10 * ONE_MINUTE_IN_MILLIS));
you can use DateUtils class in org.apache.commons.lang3.time package
int addMinuteTime = 5;
Date targetTime = new Date(); //now
targetTime = DateUtils.addMinutes(targetTime, addMinuteTime); //add minute
Convenience method for implementing #Pangea's answer:
/*
* Convenience method to add a specified number of minutes to a Date object
* From: http://stackoverflow.com/questions/9043981/how-to-add-minutes-to-my-date
* #param minutes The number of minutes to add
* #param beforeTime The time that will have minutes added to it
* #return A date object with the specified number of minutes added to it
*/
private static Date addMinutesToDate(int minutes, Date beforeTime){
final long ONE_MINUTE_IN_MILLIS = 60000;//millisecs
long curTimeInMs = beforeTime.getTime();
Date afterAddingMins = new Date(curTimeInMs + (minutes * ONE_MINUTE_IN_MILLIS));
return afterAddingMins;
}
In order to avoid any dependency you can use java.util.Calendar as follow:
Calendar now = Calendar.getInstance();
now.add(Calendar.MINUTE, 10);
Date teenMinutesFromNow = now.getTime();
In Java 8 we have new API:
LocalDateTime dateTime = LocalDateTime.now().plus(Duration.of(10, ChronoUnit.MINUTES));
Date tmfn = Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
This is incorrectly specified:
SimpleDateFormat df = new SimpleDateFormat("yyyy-mm-dd HH:mm");
You're using minutes instead of month (MM)
tl;dr
LocalDateTime.parse(
"2016-01-23 12:34".replace( " " , "T" )
)
.atZone( ZoneId.of( "Asia/Karachi" ) )
.plusMinutes( 10 )
java.time
Use the excellent java.time classes for date-time work. These classes supplant the troublesome old date-time classes such as java.util.Date and java.util.Calendar.
ISO 8601
The java.time classes use standard ISO 8601 formats by default for parsing/generating strings of date-time values. To make your input string comply, replace the SPACE in the middle with a T.
String input = "2016-01-23 12:34" ;
String inputModified = input.replace( " " , "T" );
LocalDateTime
Parse your input string as a LocalDateTime as it lacks any info about time zone or offset-from-UTC.
LocalDateTime ldt = LocalDateTime.parse( inputModified );
Add ten minutes.
LocalDateTime ldtLater = ldt.plusMinutes( 10 );
ldt.toString(): 2016-01-23T12:34
ldtLater.toString(): 2016-01-23T12:44
See live code in IdeOne.com.
That LocalDateTime has no time zone, so it does not represent a point on the timeline. Apply a time zone to translate to an actual moment. Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland, or Asia/Karachi. Never use the 3-4 letter abbreviation such as EST or IST or PKT as they are not true time zones, not standardized, and not even unique(!).
ZonedDateTime
If you know the intended time zone for this value, apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "Asia/Karachi" );
ZonedDateTime zdt = ldt.atZone( z );
zdt.toString(): 2016-01-23T12:44+05:00[Asia/Karachi]
Anomalies
Think about whether to add those ten minutes before or after adding a time zone. You may get a very different result because of anomalies such as Daylight Saving Time (DST) that shift the wall-clock time.
Whether you should add the 10 minutes before or after adding the zone depends on the meaning of your business scenario and rules.
Tip: When you intend a specific moment on the timeline, always keep the time zone information. Do not lose that info, as done with your input data. Is the value 12:34 meant to be noon in Pakistan or noon in France or noon in Québec? If you meant noon in Pakistan, say so by including at least the offset-from-UTC (+05:00), and better still, the name of the time zone (Asia/Karachi).
Instant
If you want the same moment as seen through the lens of UTC, extract an Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = zdt.toInstant();
Convert
Avoid the troublesome old date-time classes whenever possible. But if you must, you can convert. Call new methods added to the old classes.
java.util.Date utilDate = java.util.Date.from( instant );
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
There's an error in the pattern of your SimpleDateFormat. it should be
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
use this format,
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
mm for minutes and MM for mounth
Once you have you date parsed, I use this utility function to add hours, minutes or seconds:
public class DateTimeUtils {
private static final long ONE_HOUR_IN_MS = 3600000;
private static final long ONE_MIN_IN_MS = 60000;
private static final long ONE_SEC_IN_MS = 1000;
public static Date sumTimeToDate(Date date, int hours, int mins, int secs) {
long hoursToAddInMs = hours * ONE_HOUR_IN_MS;
long minsToAddInMs = mins * ONE_MIN_IN_MS;
long secsToAddInMs = secs * ONE_SEC_IN_MS;
return new Date(date.getTime() + hoursToAddInMs + minsToAddInMs + secsToAddInMs);
}
}
Be careful when adding long periods of time, 1 day is not always 24 hours (daylight savings-type adjustments, leap seconds and so on), Calendar is recommended for that.
Can be done without the constants (like 3600000 ms is 1h)
public static Date addMinutesToDate(Date date, int minutes) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.MINUTE, minutes);
return calendar.getTime();
}
public static Date addHoursToDate(Date date, int hours) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.HOUR_OF_DAY, hours);
return calendar.getTime();
}
example of usage:
System.out.println(new Date());
System.out.println(addMinutesToDate(new Date(), 5));
Tue May 26 16:16:14 CEST 2020
Tue May 26 16:21:14 CEST 2020
Work for me DateUtils
//import
import org.apache.commons.lang.time.DateUtils
...
//Added and removed minutes to increase current range dates
Date horaInicialCorteEspecial = DateUtils.addMinutes(new Date(corteEspecial.horaInicial.getTime()),-1)
Date horaFinalCorteEspecial = DateUtils.addMinutes(new Date(corteEspecial.horaFinal.getTime()),1)
For android developers, here's a kotlin implementation using an extension of #jeznag's answer
fun Date.addMinutesToDate(minutes: Int): Date {
val minuteMillis: Long = 60000 //millisecs
val curTimeInMs: Long = this.time
val result = Date(curTimeInMs + minutes * minuteMillis)
this.time = result.time
return this
}
an unit test to check functionality works as expected
#Test
fun `test minutes are added to date`() {
//given
val date = SimpleDateFormat("dd-MM-yyyy hh:mm").parse("29-04-2021 23:00")
//when
date?.addMinutesToDate(45)
//then
val calendar = Calendar.getInstance()
calendar.time = date
assertEquals(29, calendar[Calendar.DAY_OF_MONTH])
assertEquals(23, calendar[Calendar.HOUR_OF_DAY])
assertEquals(45, calendar[Calendar.MINUTE])
}
Just for anybody who is interested. I was working on an iOS project that required similar functionality so I ended porting the answer by #jeznag to swift
private func addMinutesToDate(minutes: Int, beforeDate: NSDate) -> NSDate {
var SIXTY_SECONDS = 60
var m = (Double) (minutes * SIXTY_SECONDS)
var c = beforeDate.timeIntervalSince1970 + m
var newDate = NSDate(timeIntervalSince1970: c)
return newDate
}
I have time data split in two strings - one string for date, and one for time.
I want to calculate the diff. of such two times in Java.
e.g.
time 1:"26/02/2011" and "11:00 AM"
time 2:"27/02/2011" and "12:15 AM"
Difference would be like 13 hours 15 minutes.
String str_date1 = "26/02/2011";
String str_time1 = "11:00 AM";
String str_date2 = "27/02/2011";
String str_time2 = "12:15 AM" ;
DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy hh:mm a");
Date date1 = formatter.parse(str_date1 + " " + str_time1);
Date date2 = formatter.parse(str_date2 + " " + str_time2);
// Get msec from each, and subtract.
long diff = date2.getTime() - date1.getTime();
System.out.println("Difference In Days: " + (diff / (1000 * 60 * 60 * 24)));
Obs: This is only valid as an aproximation. See Losing Time on the Garden Path.)
try {
String date1 = "26/02/2011";
String time1 = "11:00 AM";
String date2 = "27/02/2011";
String time2 = "12:15 AM";
String format = "dd/MM/yyyy hh:mm a";
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date dateObj1 = sdf.parse(date1 + " " + time1);
Date dateObj2 = sdf.parse(date2 + " " + time2);
System.out.println(dateObj1);
System.out.println(dateObj2);
long diff = dateObj2.getTime() - dateObj1.getTime();
double diffInHours = diff / ((double) 1000 * 60 * 60);
System.out.println(diffInHours);
System.out.println("Hours " + (int)diffInHours);
System.out.println("Minutes " + (diffInHours - (int)diffInHours)*60 );
} catch (ParseException e) {
e.printStackTrace();
}
output
Sat Feb 26 11:00:00 EST 2011
Sun Feb 27 00:15:00 EST 2011
13.25
Hours 13
Minutes 15.0
You need to first convert the strings to java.util.Date objects (using SimpleDateFormat.parse(String) for instance). Then you can use Date.getTime() for each of the two Date instances that you parsed and compute the difference in milliseconds or make use of a java.util.Calendar or the joda time API for advanced computations.
Have a look at DateFormat, you can use it to parse your strings with the parse(String source) method and the you can easily manipulate the two Dates object to obtain what you want.
DateFormat df = DateFormat.getInstance();
Date date1 = df.parse(string1);
Date date2 = df.parse(string2);
long difference = date1.getTime() - date2.getTime();
Date myDate = new Date(difference);
The to show the Date :
String diff = df.format(myDate);
tl;dr
Duration.between(
ZonedDateTime.of(
LocalDate.parse( "26/02/2011" , DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ) ,
LocalTime.parse( "11:00 AM" , DateTimeFormatter.ofPattern( "hh:mm a" ) ) ,
ZoneId.of( "America/Montreal" )
)
,
ZonedDateTime.of(
LocalDate.parse( "27/02/2011" , DateTimeFormatter.ofPattern( "dd/MM/uuuu" ) ) ,
LocalTime.parse( "12:15 AM" , DateTimeFormatter.ofPattern( "hh:mm a" ) ) ,
ZoneId.of( "America/Montreal" )
)
).toString()
See live code in IdeOne.com.
Time zone
The Question and the other Answers all ignore the crucial issue of time zone. You cannot calculate elapsed time between two date-time strings without knowing the intended time zone. For example, in places with Daylight Saving Time (DST), on the night of the cut-over, a day may be 23 hours long or 25 hours long rather than 24 hours long.
java.time
The modern way to do date-time work is with the java.time classes. These supplant the troublesome old date-time classes such as java.util.Date and java.util.Calendar.
Local…
First parse the input strings. These lack any indication of time zone, so we parse them as Local… types.
Define a DateTimeFormatter to match your string inputs. By the way, in the future, use standard ISO 8601 formats when serializing date-time values to text.
DateTimeFormatter df = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
LocalDate ld = LocalDate.parse( "26/02/2011" , df ) ;
ld.toString(): 2011-02-2011
DateTimeFormatter tf = DateTimeFormatter.ofPattern( "hh:mm a" );
LocalTime lt = LocalTime.parse( "11:00 AM" , tf ) ;
lt.toString(): 11:00:00
ZoneId
You need to know the time zone intended by your business scenario. I will arbitrarily choose one.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime
Apply the zone to get a ZonedDateTime.
ZonedDateTime zdtStart = ZonedDateTime.of( ld , lt , z );
zdtStart.toString(): 2011-02-26T11:00:00-05:00[America/Montreal]
Duration
Do the same to get a zdtStop. Calculate the elapsed time as a span of time not attached to the timeline, in a Duration.
Duration d = Duration.between( zdtStart , zdtStop );
Call toString to generate a String in standard ISO 8601 format for durations: PnYnMnDTnHnMnS. The P marks the beginning while the T separates the two portions.
String output = d.toString();
d.toString(): PT13H15M
In Java 9 and later, call the to…Part methods to access each component.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
try this one
you can calculate days,hours and minutes
public class TimeUtils {
public static final String HOURS = "hours";
public static final String MINUTES = "minutes";
public static final String DAYS = "days";
public static int findTheNumberBetween(String type, Date day1, Date day2) {
long diff = day2.getTime() - day1.getTime();
switch (type) {
case DAYS:
return (int) TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
case HOURS:
return (int) TimeUnit.HOURS.convert(diff, TimeUnit.MILLISECONDS);
case MINUTES:
return (int) TimeUnit.MINUTES.convert(diff, TimeUnit.MILLISECONDS);
}
return 0;
}
}
and the use it like
Date day1= TimeUtils.getDateTime("2016-12-08 02:06:14");
Date day2 = TimeUtils.getDateTime("2016-12-08 02:10:14");
Log.d(TAG, "The difference: "+TimeUtils.findTheNumberBetween(TimeUtils.MINUTES,day1,day2));