I have an string array that includes some minutes like "00:05", "00:30", "00:25" etc. I want to sum the values as time format? Can anyone help me how do I do this?
Total time in minutes:
int sum = 0;
final String[] mins = new String[] { "00:05", "00:30", "00:25" };
for (String str : mins) {
String[] parts = str.split(":");
sum += Integer.parseInt(parts[1]);
}
System.out.println(sum);
You don't specify exactly how you want this output formatted.
If there may be hour elements as well, then replace the second line of the loop with this:
sum += (Integer.parseInt(parts[0]) * 60) + Integer.parseInt(parts[1]);
I'll go for quick and dirty
Split each String on the ":"
Convert both parts to integer
Multiply the first time by 60 to convert hours to minutes, and add the second part
Do this for each value in your array, and count them together
This results in the total time in minutes, which you can convert to whatever format you like
You could substring it, and then call Integer.parseInt on the result. For the hours part, do the same and multiply it by 60.
Split the strings on ':', pars the values as ints and add 'em up.
this is my suggestion. Neither compiled, ran, tested, nor guaranteed.
long seconds = 0;
for ( String min : minutes )
{
seconds += Integer.parseInt(min.substring(0,1))*60 + Integer.parseInt(min.substring(3,4));
}
return new Date ( seconds / 1000 ) ;
An object oriented approach:
public static TimeAcumm sum(final String[] times) {
final TimeAcumm c = new TimeAcumm();
for (final String time : times) {
c.incrementFromFormattedString(time);
}
return c;
}
public class TimeAcumm {
private int hours = 0;
private int minutes = 0;
private int seconds = 0;
public int getHours() {
return hours;
}
public int getMinutes() {
return minutes;
}
public int getSeconds() {
return seconds;
}
public void incrementFromFormattedString(final String time) {
final String[] parts = time.split(":");
this.minutes += Integer.parseInt(parts[0]);
this.seconds += Integer.parseInt(parts[1]);
validate();
}
private void validate() {
if (this.minutes > 59) {
this.hours++;
this.minutes -= 60;
}
if (this.seconds > 59) {
this.minutes++;
this.seconds -= 60;
}
}
#Override
public String toString() {
final String s = hours + "H:" + minutes + "M:" + seconds + "S";
return s;
}
}
Related
So I have this assignment that is asking us to take in a String format of time in the order of HH:MM:SSAM or HH:SS:MMPM. The constraint is that it cannot run if it is in wrong format, let it be missing any form of the AM or PM, missing a number, or if it is in 24 Hour Format.
I have the whole idea down, however for my statements, it is giving me the error of:
bad operand types for binary operator '>'
incomparable types: String and int
Did I convert them improperly or am I doing something else wrong?
public static void main(String args[]) {
//Test Methods
String fullTime1 = "03:21:36AM";
secondsAfterMidnight(fullTime1);
}
public static int secondsAfterMidnight(String time) {
String[] units = time.split(":");
int hours = Integer.parseInt(units[0]);
int minutes = Integer.parseInt(units[1]);
int seconds = Integer.parseInt(units[2]);
int totalSeconds = 0;
if (units[0] > 12 || units[1] > 59 || units[2] > 59) { //1st Error applies to these three, units[0] > 12 units[1] > 59 units[2] > 59
return -1;
} else if (time.equalsIgnoreCase("AM") || time.equalsIgnoreCase("PM")) {
totalSeconds = (hours * 3600) + (minutes * 60) + (seconds);
} else if (time.equalsIgnoreCase("AM") && units[0] == 12) { //2nd Error applies to this units[0] == 12
totalSeconds = (minutes * 60) + (seconds);
} else {
return -1;
}
return totalSeconds;
}
You have already parsed the String values and saved them in the variables hours , minutes, seconds. Then you can use those for the check in the if.
Also the presence of AM?PM in the Integer.parseInt() will cause NumberFormatException to avoid it remove the String part from the number by using regex.
Also for checking the presence of AM/PM you can use String.contains.
Please check the reformatted code below:
public static int secondsAfterMidnight(String time) {
String[] units = time.split(":");
int hours = Integer.parseInt(units[0]);
int minutes = Integer.parseInt(units[1]);
int seconds = Integer.parseInt(units[2].replaceAll("[^0-9]", ""));
int totalSeconds = 0;
if (hours > 12 || minutes > 59 || seconds > 59) {
return -1;
} else if (time.contains("AM") || time.contains("PM")) {
totalSeconds = (hours * 3600) + (minutes * 60) + (seconds);
} else if (time.contains("AM") && hours == 12) {
totalSeconds = (minutes * 60) + (seconds);
} else {
return -1;
}
return totalSeconds;
}
Please note that even though you have converted the String to int, you are still comparing String with int. There would also be a RuntimeException when you do this:
int seconds = Integer.parseInt(units[2]);
As units[2] will contain 36AM. So you should be using substring() to remove the "AM/PM" part.
units is of type String and you are trying to compare it with an int hence the compile time error.
You need to convert the String to an int and then compare it, as shown below :
Integer.parseInt(units[0]) > 12
so on and so forth.
Also rather than re-inventing the wheel, you can make use of the already existing java-8's LocalTime to find the number of seconds for a particular time:
public static int secondsAfterMidnight(String time) {
LocalTime localTime = LocalTime.parse(time, DateTimeFormatter.ofPattern("hh:mm:ss a"));
return localTime.toSecondOfDay();
}
I haven't verified your logic to calculate the seconds, but this code has corrections:
public static int secondsAfterMidnight(String time) {
String[] units = time.split(":");
int hours = Integer.parseInt(units[0]);
int minutes = Integer.parseInt(units[1]);
int seconds = 0;
String amPm = "";
if ( units[2].contains("AM") || units[2].contains("PM") ||
units[2].contains("am") || units[2].contains("pm") ) {
seconds = Integer.parseInt(units[2].substring(0, 2));
amPm = units[2].substring(2);
}
else {
seconds = Integer.parseInt(units[2]);
}
int totalSeconds = 0;
if (hours > 12 || minutes > 59 || seconds > 59) {
return -1;
} else if (amPm.equalsIgnoreCase("AM") || amPm.equalsIgnoreCase("PM")) {
totalSeconds = (hours * 3600) + (minutes * 60) + (seconds);
} else if (amPm.equalsIgnoreCase("AM") && hours == 12) {
totalSeconds = (minutes * 60) + (seconds);
} else {
return -1;
}
return totalSeconds;
}
java.time
static DateTimeFormatter timeFormatter
= DateTimeFormatter.ofPattern("HH:mm:ssa", Locale.ENGLISH);
public static int secondsAfterMidnight(String time) {
try {
return LocalTime.parse(time, timeFormatter).get(ChronoField.SECOND_OF_DAY);
} catch (DateTimeParseException dtpe) {
return -1;
}
}
Let’s try it out using the test code from your question:
String fullTime1 = "03:21:36AM";
System.out.println(secondsAfterMidnight(fullTime1));
12096
This is the recommended way for production code.
Only if you are doing an exercise training string manipulation, you should use one of the other answers.
Link: Oracle tutorial: Date Time explaining how to use java.time.
What I want to do?
I want to return time and display based on user's input. Say, user enters in console starthour: 23 startminute: 45 duration (in min): 30 then the period for start time will be PM offcourse and you can see below I calculated the start time based on the above things, but issue is calculating the endtime. For example, in the above start times, the end time should become 00:15 with the period AM and not PM like start hour.
What I did?
public String toString(){
int h = (getHour()==0 || getHour()==12) ? getHour() : getHour()%12;
String period = (getHour()<12)? "AM" : "PM";
return String.format("%02d:%02d %s", h, getMinute(), period);
}
What to do?
The above formula calculates the start time and its period, correctly, but I need a similar formula that can calculate the endhour correctly based on start hour, start minutes and duration entered by the user.
Basically, above mentioned code needs to be manipulated to figure out the endhour, endminute and its period.
Note: Please don't tell about local time use for getting end time and period. Thankyou
EDIT: Here is what I did now:
public String toString(){
int endh = (getEndHour()==0 || getEndHour()==12) ? getEndHour() : getEndHour()%12;
String period = ((getEndHour() + duration) <12)? "AM" : "PM";
return String.format("%02d:%02d %s", endh, getEndHour(), period);
}
you should use 60 modulo for simplicity. here it is
public class Timer {
int hour;
public int getHour() {
return hour;
}
public void setHour(int hour) {
this.hour = hour;
}
public int getMinutes() {
return minutes;
}
public void setMinutes(int minutes) {
this.minutes = minutes;
}
public void addDuration(int duration) {
hour = hour + (minutes + duration)/ 60;
minutes = (minutes + duration) % 60;
}
int minutes;
#Override
public String toString() {
int h = (getHour() == 0 || getHour() == 12) ? getHour()
: getHour() % 24;
String period = (getHour() < 12) ? "AM" : "PM";
return String.format("%02d:%02d %s", h, getMinutes(), period);
}
public static void main(String args[]) {
Timer time = new Timer();
time.setHour(23);
time.setMinutes(45);
System.out.println(time.getHour());
time.addDuration(30);
System.out.println(time.getHour());
System.out.println(time);
}
}
Suppose time is given in MM:SS(ex- 02:30) OR HH:MM:SS in String format.how can we convert this time to second.
In your case, using your example you could use something like the following:
String time = "02:30"; //mm:ss
String[] units = time.split(":"); //will break the string up into an array
int minutes = Integer.parseInt(units[0]); //first element
int seconds = Integer.parseInt(units[1]); //second element
int duration = 60 * minutes + seconds; //add up our values
If you want to include hours just modify the code above and multiply hours by 3600 which is the number of seconds in an hour.
public class TimeToSeconds {
// given: mm:ss or hh:mm:ss or hhh:mm:ss, return number of seconds.
// bad input throws NumberFormatException.
// bad includes: "", null, :50, 5:-4
public static long parseTime(String str) throws NumberFormatException {
if (str == null)
throw new NumberFormatException("parseTimeString null str");
if (str.isEmpty())
throw new NumberFormatException("parseTimeString empty str");
int h = 0;
int m, s;
String units[] = str.split(":");
assert (units.length == 2 || units.length == 3);
switch (units.length) {
case 2:
// mm:ss
m = Integer.parseInt(units[0]);
s = Integer.parseInt(units[1]);
break;
case 3:
// hh:mm:ss
h = Integer.parseInt(units[0]);
m = Integer.parseInt(units[1]);
s = Integer.parseInt(units[2]);
break;
default:
throw new NumberFormatException("parseTimeString failed:" + str);
}
if (m<0 || m>60 || s<0 || s>60 || h<0)
throw new NumberFormatException("parseTimeString range error:" + str);
return h * 3600 + m * 60 + s;
}
// given time string (hours:minutes:seconds, or mm:ss, return number of seconds.
public static long parseTimeStringToSeconds(String str) {
try {
return parseTime(str);
} catch (NumberFormatException nfe) {
return 0;
}
}
}
import org.junit.Test;
import static org.junit.Assert.*;
public class TimeToSecondsTest {
#Test
public void parseTimeStringToSeconds() {
assertEquals(TimeToSeconds.parseTimeStringToSeconds("1:00"), 60);
assertEquals(TimeToSeconds.parseTimeStringToSeconds("00:55"), 55);
assertEquals(TimeToSeconds.parseTimeStringToSeconds("5:55"), 5 * 60 + 55);
assertEquals(TimeToSeconds.parseTimeStringToSeconds(""), 0);
assertEquals(TimeToSeconds.parseTimeStringToSeconds("6:01:05"), 6 * 3600 + 1*60 + 5);
}
#Test
public void parseTime() {
// make sure all these tests fail.
String fails[] = {null, "", "abc", ":::", "A:B:C", "1:2:3:4", "1:99", "1:99:05", ":50", "-4:32", "-99:-2:4", "2.2:30"};
for (String t: fails)
{
try {
long seconds = TimeToSeconds.parseTime(t);
assertFalse("FAIL: Expected failure:"+t+" got "+seconds, true);
} catch (NumberFormatException nfe)
{
assertNotNull(nfe);
assertTrue(nfe instanceof NumberFormatException);
// expected this nfe.
}
}
}
}
int v = 0;
for (var x: t.split(":")) {
v = v * 60 + new Byte(x);
}
This snippet should support HH:MM:SS (v would result in seconds) or HH:MM (v would be in minutes)
try this
hours = totalSecs / 3600;
minutes = (totalSecs % 3600) / 60;
seconds = totalSecs % 60;
timeString = String.format("%02d",seconds);
private static final String TIME_FORMAT = "hh:mm a";//give whatever format you want.
//Function calling
long timeInMillis = TimeUtils.getCurrentTimeInMillis("04:21 PM");
long seconds = timeInMillis/1000;
//Util Function
public static long getCurrentTimeInMillis(String time) {
SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT, Locale.getDefault());
// sdf.setTimeZone(TimeZone.getTimeZone("GMT")); //getting exact milliseconds at GMT
// sdf.setTimeZone(TimeZone.getDefault());
Date date = null;
try {
date = sdf.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
return date.getTime();
}
I have written an extension function in Kotlin for converting String to seconds
fun String?.converTimeToSeconds(): Int {
if (this.isNullOrEmpty().not()) {
val units = this?.split(":")?.toTypedArray()
if (units?.isNotEmpty() == true && units.size >= 3) {
val hours = units[0].toInt()
val minutes = units[1].toInt()
val seconds = units[2].toInt()
return (3660 * hours) + (60 * minutes) + seconds
}
}
return 0
}
We are asked to build a constructor for a Stopwatch that takes a string in the format of "##:##:###" and updates minutes, seconds and milliseconds (private instance variables) accordingly. For example, "1:21:300" indicates 1 minute 21 seconds 300 milliseconds.
So I am trying to use string.split() paired with parseInt to update values. However, the program will not compile. My constructor has the correct syntax according to eclipse, but there is something wrong with what I am doing. I have never actually used split nor parseInt, so I could be using these 100% wrong. Thank you.
public StopWatch(String startTime){
String [] timeArray = startTime.split(":");
if(timeArray.length == 2){
this.minutes = Integer.parseInt(timeArray[0]);
this.seconds = Integer.parseInt(timeArray[1]);
this.milliseconds = Integer.parseInt(timeArray[2]);
}
else if(timeArray.length == 1){
this.minutes = 0;
this.seconds = Integer.parseInt(timeArray[1]);
this.milliseconds = Integer.parseInt(timeArray[2]);
}
else if(timeArray.length == 0){
this.minutes = 0;
this.seconds = 0;
this.milliseconds = Integer.parseInt(timeArray[2]);
}
else{
this.minutes = 0;
this.seconds = 0;
this.milliseconds = 0;
}
}
P.S. Junit test says "ComparisonFailue: expected 0:00:000 but was 20:10:008" when trying to do:
s = new StopWatch("20:10:8");
assertEquals(s.toString(),"20:10:008");
As mentioned in other answers, the lengths are off by 1 each each, but the index's you are using in if block are also off; eg. if the length is 1, the only index available is 0, if the length is 2, the index's available are 0 and 1.
Thus you get a constructor that looks like:
class StopWatch {
int minutes;
int seconds;
int milliseconds;
public StopWatch(String startTime) {
String[] timeArray = startTime.split(":");
if (timeArray.length == 3) {
this.minutes = Integer.parseInt(timeArray[0]);
this.seconds = Integer.parseInt(timeArray[1]);
this.milliseconds = Integer.parseInt(timeArray[2]);
} else if (timeArray.length == 2) {
this.minutes = 0;
this.seconds = Integer.parseInt(timeArray[0]);
this.milliseconds = Integer.parseInt(timeArray[1]);
} else if (timeArray.length == 1) {
this.minutes = 0;
this.seconds = 0;
this.milliseconds = Integer.parseInt(timeArray[0]);
} else {
this.minutes = 0;
this.seconds = 0;
this.milliseconds = 0;
}
}
}
Replace your toString() method with:
public String toString() {
String paddedMinutes = String.format("%02d", this.minutes);
String paddedSeconds = String.format("%02d", this.seconds);
String paddedMilliseconds = String.format("%03d", this.milliseconds);
return paddedMinutes + ":" + paddedSeconds + ":" + paddedMilliseconds;
}
Though Java arrays are zero-based, their lengths simply count the number of elements.
So, {1,2,3}.length will return 3.
As your code is written now you will be getting ArrayOutOfBounds exceptions left and right.
if(timeArray.length == 2){
should be:
if(timeArray.length == 3){
and so on.
20:10:8 split by : will give you a length of 3 ;)
Now,I have a string String time= "200hour 0minute 0second"
I want to track numbers in string and convert to second..As above string..I want to get value 200*3600..
My code:
//change from hour minute to second
public String changeSecond(String time)
{
String result;
int ind_hour=time.indexOf("hour");
int ind_minute=time.indexOf("minute");
int ind_second=time.indexOf("second");
int hour=Integer.parseInt(time.substring(0, ind_hour));
int minute=Integer.parseInt(time.substring(ind_hour+1, ind_minute));;
int second=Integer.parseInt(time.substring(ind_minute+1, ind_second));
result=String.valueOf(hour*3600+minute*60+second);
return result;
}
but when i run changeSecond(time).It don't work..How must I do.
public String changeSecond(String time)
{
String result;
int ind_hour=time.indexOf("hour");
int ind_minute=time.indexOf("minute");
int ind_second=time.indexOf("second");
int hour=Integer.parseInt(time.substring(0, ind_hour));
int minute=Integer.parseInt(time.substring(ind_hour+6, ind_minute));; // value 6 is length of minute
int second=Integer.parseInt(time.substring(ind_minute+6, ind_second));
int totalsec=((hour*60*60)+(minute*60)+second);
result=String.valueOf(totalsec);
return result;
}
You should make changes to the following lines:
int hour=Integer.parseInt(time.substring(0, ind_hour));
int minute=Integer.parseInt(time.substring(ind_hour+5, ind_minute));
int second=Integer.parseInt(time.substring(ind_minute+7, ind_second));
Its not the way to do it.But It will work.Try this,
String hour="200hour 0minute 0second";
String[] secondarray=hour.split("hour");
String second=secondarray[0]; //here "second" will have the value 200
You can split the tab into 3 parts : One will contains the hours, another the minutes and the last one the seconds.
public static String changeSecond(String time)
{
String tab[] = time.split(" ");
String result = "";
int ind_hour=tab[0].indexOf("hour");
int ind_minute=tab[1].indexOf("minute");
int ind_second=tab[2].indexOf("second");
int hour=Integer.parseInt(tab[0].substring(0, ind_hour));
int minute=Integer.parseInt(tab[1].substring(0, ind_minute));
int second=Integer.parseInt(tab[2].substring(0, ind_second));
result=String.valueOf(hour*3600+minute*60+second);
return result;
}
This is the cleanest solution I could come up with. Just split on " " then remove the text that's irrelevant.
public String changeSecond(final String time)
{
final String[] times = time.split(" ");
final int hour = Integer.parseInt(times[0].replace("hour", ""));
final int minute = Integer.parseInt(times[1].replace("minute", ""));
final int second = Integer.parseInt(times[2].replace("second", ""));
return String.valueOf(hour*3600+minute*60+second);
}
The initial code was throwing parsing errors since alpha characters were being passed to the Integer.parseInt method. The alpha characters were being included because the substring did not take into account the length of the terms hour, minute and second. I would recommend splitting the string to tidy things up.
public String changeSecond(String time) {
String[] tokens = time.split(" ");
tokens[0] = tokens[0].substring(0, tokens[0].indexOf("hour"));
tokens[1] = tokens[1].substring(0, tokens[1].indexOf("minute"));
tokens[2] = tokens[2].substring(0, tokens[2].indexOf("second"));
return String.valueOf(Integer.parseInt(tokens[0]) * 3600
+ Integer.parseInt(tokens[1]) * 60 + Integer.parseInt(tokens[2]));
}
Update your hours,minutes and seconds parsing as:
int hour=Integer.parseInt(time.substring(0, ind_hour));
int minute=Integer.parseInt(time.substring(ind_hour + "hour".length() + 1, ind_minute));
int second=Integer.parseInt(time.substring(ind_minute + "minute".length() + 1, ind_second));