add string time with overflow hour in java - java

I want to add string time with format HH:mm:ss and special hour field. Example :
"20:15:30" (string) add "13:50:35" (string) -> result i want : "34:06:05" (string).
I have search similar code :
String time1="20:15:30";
String time2="13:50:35";
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
timeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date1 = timeFormat.parse(time1);
Date date2 = timeFormat.parse(time2);
long sum = date1.getTime() + date2.getTime();
String date3 = timeFormat.format(new Date(sum));
System.out.println("The sum is "+ date3);
And result of above code : The sum is 10:06:05 not i want. How is easy way to do this ?

You could simply take advantage of either Java 8's or Joda Time's duration capabilities.
For example, this simply creates a duration which is the sum of the number of seconds of the two times
LocalTime lt1 = LocalTime.parse("20:15:30", DateTimeFormatter.ofPattern("HH:mm:ss"));
LocalTime lt2 = LocalTime.parse("13:50:35", DateTimeFormatter.ofPattern("HH:mm:ss"));
//long t = lt1.toSecondOfDay() + lt2.toSecondOfDay();
//Duration duration = Duration.ofSeconds(t);
Duration duration = Duration.between(lt2, lt1);
System.out.println(formatDuration(duration));
Which prints out 34:06:05
formatDuration method
public static String formatDuration(Duration duration) {
long hours = duration.toHours();
duration = duration.minusHours(hours);
long minutes = duration.toMinutes();
duration = duration.minusMinutes(minutes);
long seconds = duration.getSeconds();
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
}

SimpleDateFormat can't do that, but you can do it yourself, by parsing the input with a regular expression, and formatting the output with the format method.
private static String addTime(String ... times) {
if (times.length < 2)
throw new IllegalArgumentException("At least 2 times are required");
Pattern timePattern = Pattern.compile("([0-9]+):([0-5][0-9]):([0-5][0-9])");
// Parse times and sum hours, minutes, and seconds
int hour = 0, minute = 0, second = 0;
for (String time : times) {
Matcher m = timePattern.matcher(time);
if (! m.matches())
throw new IllegalArgumentException("Invalid time: " + time);
hour += Integer.parseInt(m.group(1));
minute += Integer.parseInt(m.group(2));
second += Integer.parseInt(m.group(3));
}
// Handle overflow
minute += second / 60; second %= 60;
hour += minute / 60; minute %= 60;
// Format and return result
return String.format("%02d:%02d:%02d", hour, minute, second);
}
Test
System.out.println(addTime("20:15:30", "13:50:35"));
System.out.println(addTime("20:15:30", "13:50:35", "20:15:30", "13:50:35"));
System.out.println(addTime("98765:43:21", "12:34:56"));
Output
34:06:05
68:12:10
98778:18:17

Related

How to compare timing?

I want to make a function to compare with the estimated time and actual time.
if estimated time = actual time + 15 minutes
return delay
for example:
estimated time = "09:00"
actual time = "09:15" late
How can i do it in android java ?
Quick solution to be able to use parameters easily is to use Duration.
You can get the duration between to "time". From this, you can easily check of this is in a valid delay or not comparing two Duration.
Using Duration.between with two LocalTime, you will get the duration between the two. Then you just need to compare this with a specific duration of time, something like this :
//Our times for this test.
LocalTime lt1 = LocalTime.of(9, 0);
LocalTime lt2 = LocalTime.of(9, 10);
//A duration of 15minutes, used to validate the difference between the two times
Duration delay = Duration.ofMinutes(15);
//A duration between two times
Duration d = Duration.between(lt1, lt2);
//Is less than, or equal to the duration.
boolean isValid = d.compareTo(delay) <= 0;
Using :
import java.time.Duration;
import java.time.LocalTime;
A more complete test code
LocalTime lt1 = LocalTime.of(9, 0);
LocalTime lt2 = LocalTime.of(9, 10);
LocalTime lt3 = LocalTime.of(9, 15);
LocalTime lt4 = LocalTime.of(9, 20);
Duration delay = Duration.ofMinutes(15);
System.out.format("%s and %s as more than %s delay : %s%n", lt1, lt2, delay, Duration.between(lt1, lt2).compareTo(delay));
System.out.format("%s and %s as more than %s delay : %s%n", lt1, lt3, delay, Duration.between(lt1, lt3).compareTo(delay));
System.out.format("%s and %s as more than %s delay : %s%n", lt1, lt4, delay, Duration.between(lt1, lt4).compareTo(delay));
Output :
09:00 and 09:10 as more than PT15M delay : -1
09:00 and 09:15 as more than PT15M delay : 0
09:00 and 09:20 as more than PT15M delay : 1
You can easily use different Duration values and it is not complicated to get a LocalTime from a String, a LocalDateTime or even a Date.
private void compareTime(String lastTime) {
SimpleDateFormat format = new SimpleDateFormat("hh:mm:ss aa", Locale.US);
String currentTime = format.format(new Date(System.currentTimeMillis()));
Date date2 = null;
Date date1 = null;
try {
date1 = format.parse(lastTime);
date2 = format.parse(currentTime);
} catch (ParseException e) {
e.printStackTrace();
}
assert date2 != null;
long difference = (date2.getTime() - date1.getTime()) / 1000;
long hours = difference % (24 * 3600) / 3600; // Calculating Hours
long minute = difference % 3600 / 60; // Calculating minutes if there is any minutes difference
long min = minute + (hours * 60);
if (min > 24 || min < -24) {
}
}
Your lastTime should be in "hh:mm:ss aa" this format as same to currentTime.

How to sum total number of hours ,minutes,seconds in java?

Am having a doubt on how to sum total number of hours minutes seconds in java for example i have 160:00:00 and 24:00:00 and 13:50:00 and 00:10:00 i need to get grand sum like 198:00:00 how can i calculate this so far what i have tried is
for(int i=0;i<addnoteobj.size();i++){
String s = addnoteobj.get(i).getDuration();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String[] tokens = s.split(":");
int hours = Integer.parseInt(tokens[0]);
int minutes = Integer.parseInt(tokens[1]);
int seconds = Integer.parseInt(tokens[2]);
duration = 3600 * hours + 60 * minutes + seconds;
int j = duration/3600;
int h= (duration%3600) / 60;
int m = (duration % 60);
hourss=hourss+j;
mm=mm+h;
sss=sss+m;
date3 = hourss + ":" + mm + ":" + ss;
String time = simpleDateFormat.format(new Date(duration*1000L));
Log.d("dat",time);
try {
date=simpleDateFormat.parse(s);
ss=ss+date.getTime();
date3 = simpleDateFormat.format(new Date(ss));
// total=dates.getTime();
Log.d("time",date3);
} catch (ParseException e) {
e.printStackTrace();
}
}
But i cannot achieve this how to do this am having total hours in list how to get total hours thanks in advance
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
Solution using java.time, the modern Date-Time API:
You can use java.time.Duration which is modelled on ISO-8601 standards and was introduced with Java-8 as part of JSR-310 implementation. With Java-9 some more convenient methods were introduced.
Assuming all the string are in the form of HH:mm:ss format, you can split them on : and then combine the parts to form a string in the ISO 8601 pattern for a duration which can be parsed using Duration#parse.
Demo:
import java.time.Duration;
public class Main {
public static void main(String[] args) {
String[] strDurationArr = {
"160:00:00",
"24:00:00",
"13:50:00",
"00:10:00"
};
Duration sum = Duration.ZERO;
for (String strDuration : strDurationArr) {
sum = sum.plus(parseStrDuration(strDuration));
}
System.out.println(formatDurationJava8Plus(sum));
System.out.println(formatDurationJava9Plus(sum));
}
static Duration parseStrDuration(String strDuration) {
String[] arr = strDuration.split(":");
String strIsoDuration = "PT" + arr[0] + "H" + arr[1] + "M" + arr[2] + "S";
return Duration.parse(strIsoDuration);
}
static String formatDurationJava8Plus(Duration duration) {
return String.format("%d:%02d:%02d", duration.toHours(), duration.toMinutes() % 60, duration.toSeconds() % 60);
}
static String formatDurationJava9Plus(Duration duration) {
return String.format("%d:%02d:%02d", duration.toHours(), duration.toMinutesPart(), duration.toSecondsPart());
}
}
Output:
198:00:00
198:00:00
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
I have intentionally left the println so that you can see the code flow. hope this helps you...
public static void main(String[] args) {
String time[] = { "160:00:00", "24:00:00", "13:50:00", "00:10:00" };
int hours = 0, minutes = 0, seconds = 0;
for (String string : time) {
String temp[] = string.split(":");
hours = hours + Integer.valueOf(temp[0]);
minutes = minutes + Integer.valueOf(temp[1]);
seconds = seconds + Integer.valueOf(temp[2]);
}
System.out.println(hours + ":" + minutes + ":" + seconds);
if (seconds == 60) {
minutes = minutes + 1;
seconds = 0;
} else if (seconds > 59) {
minutes = minutes + (seconds / 60);
seconds = seconds % 60;
}
System.out.println(hours + ":" + minutes + ":" + seconds);
if (minutes == 60) {
hours = hours + 1;
minutes = 0;
} else if (minutes > 59) {
hours = hours + (minutes / 60);
minutes = minutes % 60;
}
System.out.println(hours + ":" + minutes + ":" + seconds);
String output = "";
output = String.valueOf(hours);
output = output.concat(":" + (String.valueOf(minutes).length() == 1 ? "0" + String.valueOf(minutes) : String.valueOf(minutes)));
output = output.concat(":" + (String.valueOf(seconds).length() == 1 ? "0" + String.valueOf(seconds) : String.valueOf(seconds)));
System.out.println(output);
}
I didn't test it but I'm pretty sure it's something like this:
private static String sumTime(String t1, String t2){
byte extraMinutes=0;
byte extraHours=0;
String arrt1[] = t1.split(":");
String arrt2[] = t2.split(":");
int seconds = Integer.valueOf(arrt1[2]) + Integer.valueOf(arrt2[2]);
if(seconds>=60) {
extraMinutes = 1;
seconds = seconds % 60;
}
int minutes = Integer.valueOf(arrt1[1]) + Integer.valueOf(arrt2[1]) + extraMinutes;
if(minutes>=60){
extraHours = 1;
minutes = minutes % 60;
}
int hours = Integer.valueOf(arrt1[0]) + Integer.valueOf(arrt2[0]) + extraHours;
if(hours>=24) hours = hours%24;
return hours+":"+minutes+":"+seconds;
}

When time difference gets calculated the values is off

I have a timepicker for a start time and an end time. It's in Sweden so here is 24 hour clock. If I set the start time at 23:00 and the end time at 02:00 it should be 3 hours difference. But in this case its 22 hours.
I calculate the difference lite this:
String a =""+Math.abs(diff/(60*60*1000)%24);
String b =""+Math.abs(diff/(60*1000)%60);
How can this be fixed?
UPDATE
Here is some more code:
DateFormat formatter = new SimpleDateFormat("HH:mm");
Date date1 = formatter.parse(str_time1);
Date date2 = formatter.parse(str_time2);
long diff = date2.getTime() - date1.getTime();
String a =""+Math.abs(diff/(60*60*1000)%24);
String b =""+Math.abs(diff/(60*1000)%60);
UPDATE 2
Here is my timepickerdialog and maybe the error start even here:
final Calendar c = Calendar.getInstance();
mHour = c.get(Calendar.HOUR_OF_DAY);
mMinute = c.get(Calendar.MINUTE);
// Launch Time Picker Dialog
final TimePickerDialog timePickerDialog = new TimePickerDialog(this,
new TimePickerDialog.OnTimeSetListener() {
#Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
startworkFrom.setText(hourOfDay + ":" + minute);
}
}, mHour, mMinute, true);
timePickerDialog.show();
Here is a solution to the problem I had:
public int theTimeMachineHours(EditText a, EditText b) throws Exception{
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
Date startDate = simpleDateFormat.parse(a.getText().toString());
Date endDate = simpleDateFormat.parse(b.getText().toString());
long difference = endDate.getTime() - startDate.getTime();
if(difference<0)
{
Date dateMax = simpleDateFormat.parse("24:00");
Date dateMin = simpleDateFormat.parse("00:00");
difference=(dateMax.getTime() -startDate.getTime() )+(endDate.getTime()-dateMin.getTime());
}
int days = (int) (difference / (1000*60*60*24));
int hours = (int) ((difference - (1000*60*60*24*days)) / (1000*60*60));
int min = (int) (difference - (1000*60*60*24*days) - (1000*60*60*hours)) / (1000*60);
return hours;
}
this might help:
result_time = (end_time - start_time +24) % 24;
// +24 to avoid the result from going to negative
where end_time is your ending time i.e 02:00
start_time is starting time i.e 23:00
and % is modulo operator
Try using kk:mm instead HH:mm
So change the code to:
DateFormat formatter = new SimpleDateFormat("kk:mm");

How to correct calculate the running time

I want to calculate the total running time of my program from start to end and refresh running time in JFrame, but when I run my program I get excess 70 years, 1 day and 2 hours. Why ? What wrong ?
private void setMachineTime(){
Timer timer = new Timer();
long startTime = new Date().getTime();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
long endTime = new Date().getTime();
long diffTime = endTime - startTime ;
String time = new SimpleDateFormat("yy:mm:dd:HH:mm:ss").format(diffTime);
System.out.println(time);
}
}, 0, 1000);
}
actual result
UPD:
I rewrote code with my own format time method. Now I got what I want. Thanks to all of you.
private void setMachineTime(){
Timer timer = new Timer();
long startTime = new Date().getTime();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
long endTime = new Date().getTime();
long diffTime = endTime - startTime;
String diffSeconds = formatTime(diffTime / 1000 % 60);
String diffMinutes = formatTime(diffTime / (60 * 1000) % 60);
String diffHours = formatTime(diffTime / (60 * 60 * 1000) % 24);
System.out.println(diffHours + ":" + diffMinutes + ":" + diffSeconds);
}
}, 0, 1000);
}
private String formatTime(long diff){
long t;
t = diff;
if(t < 10){
return String.valueOf("0"+t);
} else {
return String.valueOf(t);
}
}
You are formatting the time difference as yy:mm:dd:HH:mm:ss. Just printing out diffTime would give you the milliseconds, divide by 1000 if you need seconds.
EDIT: I think i see what you are trying to do, but you are dealing with a time interval, which cannot be formatted as a date. You'll need to roll your own formatting for displaying the time as seconds, minutes, hours etc. or use an external library.
getTime return number of milliseconds from 1.1.1970...and same is for SimpleDateFormat converting number to date (and then formating it). It means when your diffTime = 0, SimpleDateFormat will try to format Date 1.1.1970 0:00:00 and with your formating string it will be 70:01:01:00:00:00. Try to use http://joda-time.sourceforge.net/api-release/org/joda/time/Interval.html instead.
And by the way, your formating string is wrong anyway...you use mm where I supouse you wanted month...but mm are minutes.

How define the proper Day for Date variable

There are two times such as "startTime" = 23:57 and "endTime" = 00:50. How can I define that startTime belongs to the day that is before "endTime"?
Date min = date("23:57");
Date max = date("00:50");
private static Date date(final String time) {
final Calendar calendar = Calendar.getInstance();
String[] hm = time.split(":");
int hour = Integer.parseInt(hm[0]);
int minute = Integer.parseInt(hm[1]);
calendar.set(Calendar.HOUR,hour);
calendar.set(Calendar.MINUTE,minute);
final Date result = calendar.getTime();
return result;
}
you could append a token of some kind, like + to the end your time:
Date max = date("00:50+");
and when parsing the time:
if time.endsWith("+") {
calendar.add(Calendar.HOUR, 24);
}
if you needed to handle periods of longer than 24 hours you could use +1, +2 etc.

Categories