Java calculate time difference between check in and out - java

I want to calculate the time difference hour and minute without using java dateformat
user should input like
Clock In: 23:00
Clock Out: 01:00
The expected output shall be something like 2 hours 00 minutes.
But how can I calculate them?
Scanner input = new Scanner(System.in);
//Read data
System.out.print("Clock In: ");
String sTimeIn = input.nextLine();
System.out.print("Clock Out: ");
String sTimeOut = input.nextLine();
// Process data
String sHourIn = sTimeIn.substring(0, 2);
String sMinuteIn = sTimeIn.substring(3, 5);
String sHourOut = sTimeOut.substring(0, 2);
String sMinuteOut = sTimeOut.substring(3, 5);
int iHourIn = Integer.parseInt(sHourIn);
int iMinuteIn = Integer.parseInt(sMinuteIn);
int iHourOut = Integer.parseInt(sHourOut);
int iMinuteOut = Integer.parseInt(sMinuteOut);
int sumHour =
int sumMinute =
//Display Output
System.out.print(sumHour +"Hour "+ sumMinute + " Minute");
}
}
After I have reviewed all the solutions you given. Here is what I have edited. But I still found an issue is,
if Clock in 23:00 Clock Out: 01:00 and the output is 22Hour(s) 0 Minute(s). The output should be 02 Hour(s) 0 Minute(s).
System.out.println("*Your time format must be 00:00");
System.out.print("Clock In: ");
String getTimeIn = input.nextLine();
System.out.print("Clock Out: ");
String getTimeOut = input.nextLine();
// Process data
String sHourIn = getTimeIn.substring(0, 2);
String sMinuteIn = getTimeIn.substring(3, 5);
String sHourOut = getTimeOut.substring(0, 2);
String sMinuteOut = getTimeOut.substring(3, 5);
int sumHour = Integer.parseInt(sHourIn) - Integer.parseInt(sHourOut);
int sumMinute = Integer.parseInt(sMinuteIn) - Integer.parseInt(sMinuteOut);
if(sumHour < 0) {
sumHour =-sumHour;
}
if(sumMinute < 0) {
sumMinute =- sumMinute;
}
//Display Output
System.out.print(sumHour +"Hour(s) "+ sumMinute + " Minute(s)");

If you want to use LocalTime and ChronoUnit classes of Java 8:
String sTimeIn = "23:15";
String sTimeOut = "1:30";
LocalTime timeIn = LocalTime.parse(sTimeIn, DateTimeFormatter.ofPattern("H:m"));
LocalTime timeOut = LocalTime.parse(sTimeOut, DateTimeFormatter.ofPattern("H:m"));
long dif = ChronoUnit.MINUTES.between(timeIn, timeOut);
if (dif < 0)
dif += 24 * 60;
long sumHour = dif / 60;
long sumMinute = dif % 60;
System.out.println(sumHour + ":"+ sumMinute);
or formatted to HH:mm:
System.out.println(String.format("%02d", sumHour) + ":"+ String.format("%02d", sumMinute));
will print:
02:15

As #Stultuske said the time library should be a safer option, I have provided an example below
import java.time.LocalTime;
public class HelloWorld
{
public static void main(String[] args)
{
LocalTime in = LocalTime.parse("18:20");
LocalTime out = LocalTime.parse("20:30");
int hoursDiff = (out.getHour() - in.getHour()),
minsDiff = (int)Math.abs(out.getMinute() - in.getMinute()),
secsDiff = (int)Math.abs(out.getSecond() - in.getSecond());
System.out.println(hoursDiff+":"+minsDiff+":"+secsDiff);
}
}
Update:
The solution is missing the midnight crossing as pointed by #Joakim Danielson, So I have modified the above solution to check for in > out or out < in.
import java.time.LocalTime;
public class HelloWorld
{
public static void main(String[] args)
{
LocalTime in = LocalTime.parse("16:00");
LocalTime out = LocalTime.parse("01:00");
int hOut = out.getHour(),
hIn = in.getHour();
int hoursDiff = hOut < hIn ? 24 - hIn + hOut : hOut - hIn,
minsDiff = (int)Math.abs(out.getMinute() - in.getMinute()),
secsDiff = (int)Math.abs(out.getSecond() - in.getSecond());
System.out.println(hoursDiff+":"+minsDiff+":"+secsDiff);
}
}

Here is my suggested solution including some simple (not perfect) validation of the input, I have put the solution inside a method so asking user for input is not handled
public static void calcTime(String sTimeIn, String sTimeOut) {
final String timePattern = "[0-2][0-9]:[0-5][0-9]";
if (sTimeIn == null || sTimeOut == null || !sTimeIn.matches(timePattern) || !sTimeIn.matches(timePattern)) {
throw new IllegalArgumentException();
}
String[] timeIn = sTimeIn.split(":");
String[] timeOut = sTimeOut.split(":");
int inMinutes = 60 * Integer.valueOf(timeIn[0]) + Integer.valueOf(timeIn[1]);
int outMinutes = 60 * Integer.valueOf(timeOut[0]) + Integer.valueOf(timeOut[1]);
int diff = 0;
if (outMinutes > inMinutes) {
diff = outMinutes - inMinutes;
} else if (outMinutes < inMinutes) {
diff = outMinutes + 24 * 60 - inMinutes;
}
System.out.printf("Time difference between %s and %s is %d hours and %d minutes\n", sTimeIn, sTimeOut, diff / 60, diff % 60);
}
Update
Here is a solution based on LocalTime and Duration
public static void calcTime2(String sTimeIn, String sTimeOut) {
final String timePattern = "[0-2][0-9]:[0-5][0-9]";
if (sTimeIn == null || sTimeOut == null || !sTimeIn.matches(timePattern) || !sTimeIn.matches(timePattern)) {
throw new IllegalArgumentException();
}
String[] timeIn = sTimeIn.split(":");
String[] timeOut = sTimeOut.split(":");
LocalTime localTimeIn = LocalTime.of(Integer.valueOf(timeIn[0]), Integer.valueOf(timeIn[1]));
LocalTime localTimeOut = LocalTime.of(Integer.valueOf(timeOut[0]), Integer.valueOf(timeOut[1]));
Duration duration;
if (localTimeOut.isAfter(localTimeIn)) {
duration = Duration.between(localTimeIn, localTimeOut);
} else {
Duration prevDay = Duration.ofHours(24).minusHours(localTimeIn.getHour()).minusMinutes(localTimeIn.getMinute());
Duration nextDay = Duration.between(LocalTime.MIDNIGHT, localTimeOut);
duration = prevDay.plus(nextDay);
}
System.out.printf("Time difference between %s and %s is %d hours and %d minutes\n", sTimeIn, sTimeOut,
duration.toHours(), duration.minusHours(duration.toHours()).toMinutes());
}

try this :
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//Read data
System.out.println("Clock In: ");
String sTimeIn = "20:30";
System.out.println("Clock Out: ");
String sTimeOut = "18:20";
// Process data
String sHourIn = sTimeIn.substring(0, 2);
String sMinuteIn = sTimeIn.substring(3, 5);
String sHourOut = sTimeOut.substring(0, 2);
String sMinuteOut = sTimeOut.substring(3, 5);
int iHourIn = Integer.parseInt(sHourIn);
int iMinuteIn = Integer.parseInt(sMinuteIn);
int iHourOut = Integer.parseInt(sHourOut);
int iMinuteOut = Integer.parseInt(sMinuteOut);
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY,iHourIn);
cal.set(Calendar.MINUTE,iMinuteIn);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
Long timeIn = cal.getTime().getTime();
cal.set(Calendar.HOUR_OF_DAY,iHourOut);
cal.set(Calendar.MINUTE,iMinuteOut);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
Long timeOut = cal.getTime().getTime();
Long finaltime= timeIn-timeOut;
// Convert the result to Hours and Minutes
Long temp = null;
// get hours
temp = finaltime % 3600000 ;
int sumHour = (int) ((finaltime - temp) / 3600000 );
finaltime = temp;
int sumMinute = (int) (finaltime/ 60000);
//Display Output
System.out.println(sumHour +" Hour "+ sumMinute + " Minute");
}

I have added some code in addition to your code. Please check and let me know if this is enough for your requirement
public class MainClass1 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//Read data
System.out.print("Clock In: ");
String[] sTimeIn = input.nextLine().split(":");
System.out.print("Clock Out: ");
String[] sTimeOut = input.nextLine().split(":");
int iHourIn = Integer.parseInt(sTimeIn[0]);
int iMinuteIn = Integer.parseInt(sTimeIn[1]);
int iHourOut = Integer.parseInt(sTimeOut[0]);
int iMinuteOut = Integer.parseInt(sTimeOut[1]);
if(iMinuteIn < iMinuteOut) {
iMinuteIn = 60 + iMinuteIn;
iHourIn--;
}
int sumHour = iHourIn - iHourOut;
int sumMinute = iMinuteIn - iMinuteOut;
//Display Output
System.out.print(sumHour +"Hour "+ sumMinute + " Minute");
}
}

Related

Java Format Timestamp

I have below Java code to convert string format to Timestamp object
public class TestUtil{
Object result;
Public Object convertFormat(String format, String value, String type){
String format = "yyyyMMddHHmmss";
String value = "20050225144824";
SimpleDateFormat dformat = new SimpleDateFormat(format);
java.util.Date date = dformat.parse(value);
result = new Timestamp(date.getTime);
System.out.println("Result::"+ result);
}
}
Expected outcome:
I was expecting the outcome should be like below
20050225144824
Actual outcome:
2005-02-25 14:48:24.0
Could anyone tell me what I am missing here? To get "20050225144824" this result
The below code runs fine for me.
Adding few print statements to explain the different behaviors.
import java.util.Date;
import java.text.SimpleDateFormat;
import java.sql.Timestamp;
public class Main
{
public static void main(String[] args) {
String myFormat = "yyyyMMddHHmmss";
String value = "20050225144824";
try {
SimpleDateFormat dformat = new SimpleDateFormat("yyyyMMddHHmmss");
Date date = dformat.parse(value);
Timestamp ts = new Timestamp(date.getTime());
Object result = new Timestamp(date.getTime());
System.out.println("Timestamp Format with yyyyMMddHHmmss : " +dformat.format(ts));
System.out.println("Object Format with yyyyMMddHHmmss : " +result);
System.out.println("Object Format with yyyyMMddHHmmss : " +dformat.format(result));
} catch(Exception e) {
e.printStackTrace();
}
}
}
Here is the output of the different behaviors :
Timestamp Format with yyyyMMddHHmmss : 20050225144824
Object Format with yyyyMMddHHmmss : 2005-02-25 14:48:24.0
Object Format with yyyyMMddHHmmss : 20050225144824
If you expect Timestamp to return your custom output then you need to override the default Timestamp library.
Here I create CustomTimestamp.java to extend Timestamp and override its toString() method. I modified the changes according to your requirement.
public class CustomTimestamp extends Timestamp {
private int nanos;
public CustomTimestamp(long time) {
super(time);
}
#Override
public String toString () {
int year = super.getYear() + 1900;
int month = super.getMonth() + 1;
int day = super.getDate();
int hour = super.getHours();
int minute = super.getMinutes();
int second = super.getSeconds();
String yearString;
String monthString;
String dayString;
String hourString;
String minuteString;
String secondString;
String nanosString;
String zeros = "000000000";
String yearZeros = "0000";
StringBuffer timestampBuf;
if (year < 1000) {
// Add leading zeros
yearString = "" + year;
yearString = yearZeros.substring(0, (4-yearString.length())) +
yearString;
} else {
yearString = "" + year;
}
if (month < 10) {
monthString = "0" + month;
} else {
monthString = Integer.toString(month);
}
if (day < 10) {
dayString = "0" + day;
} else {
dayString = Integer.toString(day);
}
if (hour < 10) {
hourString = "0" + hour;
} else {
hourString = Integer.toString(hour);
}
if (minute < 10) {
minuteString = "0" + minute;
} else {
minuteString = Integer.toString(minute);
}
if (second < 10) {
secondString = "0" + second;
} else {
secondString = Integer.toString(second);
}
if (nanos == 0) {
nanosString = "";
} else {
nanosString = Integer.toString(nanos);
// Add leading zeros
nanosString = zeros.substring(0, (9-nanosString.length())) +
nanosString;
// Truncate trailing zeros
char[] nanosChar = new char[nanosString.length()];
nanosString.getChars(0, nanosString.length(), nanosChar, 0);
int truncIndex = 8;
while (nanosChar[truncIndex] == '0') {
truncIndex--;
}
nanosString = new String(nanosChar, 0, truncIndex + 1);
}
// do a string buffer here instead.
timestampBuf = new StringBuffer(20+nanosString.length());
timestampBuf.append(yearString);
timestampBuf.append(monthString);
timestampBuf.append(dayString);
timestampBuf.append(hourString);
timestampBuf.append(minuteString);
timestampBuf.append(secondString);
timestampBuf.append(nanosString);
return (timestampBuf.toString());
}
}
Your main class should use CustomTimestamp to get the output
try {
String format = "yyyyMMddHHmmss";
String value = "20050225144824";
SimpleDateFormat dformat = new SimpleDateFormat(format);
java.util.Date date;
date = dformat.parse(value);
Timestamp result = new CustomTimestamp(date.getTime());
System.out.println("Result::" + result);
} catch (ParseException e) {
e.printStackTrace();
}

Excel finance app Exception in thread "main" java.lang.NumberFormatException: For input string: ""

I'm making an excel finance calculator and the columns I've chosen are the ones I need in my calculation, the app takes the start date and the end date from the user and then calculate all the transaction amount between those dates and I get this error that stops the app
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at Input.ExcelReader.main(ExcelReader.java:81)
package Input;
public class ExcelReader {
public static final String SAMPLE_XLSX_FILE_PATH = "C:\\Users\\abdo\\Downloads\\Sample File.xlsx";
static double CreditTRX = 0 ;
static double DebitTRX = 0.0 ;
static int noDebitTRX = 0 ;
static int cashAtHand = 0 ;
static double agentComm = 0.0 ;
static double Amount = 0.0 ;
public static void main(String[] args) throws IOException, InvalidFormatException {
Workbook workbook = WorkbookFactory.create(new File(SAMPLE_XLSX_FILE_PATH));
Sheet sheet = workbook.getSheetAt(0);
DataFormatter dataFormatter = new DataFormatter();
Iterator<Row> rowIterator = sheet.rowIterator();
//entering dates
Scanner in = new Scanner(System.in);
System.out.print("Please enter the start date ");
String d1 = in.next();
System.out.print("Please enter the end date ");
String d2 = in.next();
int M1 = 0 ; int D1 = 0 ;
int M2 = 0 ; int D2 = 0 ;
String date1[] = d1.split("/");
M1 = Integer.parseInt(date1[0]);
D1 = Integer.parseInt(date1[1]);
String date2[] = d2.split("/");
M2 = Integer.parseInt(date2[0]);
D2 = Integer.parseInt(date2[1]);
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Cell trxType = row.getCell(3) ;
String Type = dataFormatter.formatCellValue(trxType);
Cell trxAmount = row.getCell(8) ;
String sAmount = dataFormatter.formatCellValue(trxAmount) ;
Cell trxDate = row.getCell(13) ;
String Date = dataFormatter.formatCellValue(trxDate);
//date equalizer
Date = Date.replaceAll("/18", "/2018");
Date = Date.replaceAll("2018/", "18/") ;
if (!Date.equals("Trx Date")) {
String tempDate[] = Date.split("/");
int tempMonth = Integer.parseInt(tempDate[0]);
int tempDay = Integer.parseInt(tempDate[1]);
if ( M2 == M1 ) {
if ((tempDay <= D1) && (tempDay >= D2) ) {
total(sAmount,Type) ;
}
}else if (M2 > M1) {
if ((tempMonth <= M1) && (tempMonth >= M2) && tempMonth!= M2 ) {
total(sAmount,Type) ;
}else if (tempMonth == M2 ) {
if ((tempDay <= D1) && (tempDay >= D2) ) {
total(sAmount,Type) ;
}
}
}
}
}
double CashAtHand = DebitTRX ;
agentComm = noDebitTRX *0.75 ;
System.out.println("Total number of DebitTRX =" + noDebitTRX);
System.out.println("Total CreditTRX Amount =" + CreditTRX);
System.out.println("Total DebitTRX Amount =" + DebitTRX);
System.out.println("Cash at hand =" + cashAtHand);
System.out.println("Total agent commssion =" + agentComm);
}
public static void total ( String s , String t ) {
if(s.equals("Amount") ){
System.out.println(s);
}
else if(!s.equals("Amount") && !s.equals(null) ) {
s=s.replaceAll("," , "") ;
System.out.println(s);
Amount = Double.valueOf(s) ;
}
if (t.equals("Debit")) {
noDebitTRX++ ;
DebitTRX = DebitTRX + Amount ;
}
else if (t.equals("Reverse Debit")) {
noDebitTRX--;
DebitTRX = DebitTRX - Amount ;
}
else if (t.equals("Notify Credit")) {
CreditTRX = CreditTRX + Amount ;
}
}
}
I think the errors comes from the while loop ( .hasnext() ) but I couldn't solve it
Sorry If the post isn't proper cause I'm new to the site and coding in general

Need to check for available dates in a for loop and schedule a sale order

I have a MS SQL server table having these columns - Date_Allotted, Sale_Order_No, Time_Available.
The contents are like -
Date_Allotted | Sale_Order_No | Time_Available | Time_Needed
-------------------------------------------------------------------
02-02-2015 | 123456 | 90 mins | 50 mins
08-02-2015 | 123457 | 70 mins | 30 mins
09-02-2015 | 123458 | 120 mins | 200 mins
10-02-2015 | 123459 | 320 mins | 100 mins
11-02-2015 | 123455 | 40 mins | 20 mins
15-02-2015 | 123454 | 30 mins | 15 mins
Time_Available says, how many minutes are available from morning 9 to evening 6:30.
Time_Needed says, number of minutes the sale order needs to get executed.
When a new sale order is added, I want to schedule it when the dates are free, i.e., when on the date there is no sale order scheduled. I need to check the dates in between and check if time is available on that day in a loop.
I am using the following code to get the dates which are not in the series and the dates between them.
I mean, in the above dates, 8th and 9th are in series and dates are available between 2nd and 8th, 9th and 11th and 11th and 15th.
The code is -
To find dates between 2 dates..........
Declare #Date1 DATETIME, #Date2 DATETIME
set #Date1 = '01/25/2015 12:00:00 AM';
set #Date2 = '02/05/2015 12:00:00 AM';
with daterange as
( select dt = DATEADD(dd, 1, #Date1)
where DATEADD(dd, 1, #Date1) <= #Date2
union all
select DATEADD(dd, 1, dt)
from daterange
where DATEADD(dd, 1, dt) <= #Date2 )
select *
from daterange
To find the dates not in series or the dates that have a gap............
select l.DateAllotted as start
from [DCP].[dbo].[TimeAllotted] as l
left outer join [DCP].[dbo].[TimeAllotted] as r on l.DateAllotted + 1 = r.DateAllotted
where r.DateAllotted is null
My function in java is something like this........
try
{
String tl = "";
SimpleDateFormat sdft = new SimpleDateFormat("HH:mm:ss");
st5 = con.createStatement();
ResultSet rs5 = st5.executeQuery("Select TimeLeft from DCP.dbo.TimeAllotted where DateAllotted = '"+lir.trim()+"'");
while(rs5.next())
{
tl = rs5.getString("TimeLeft"); // it is the time left on that day
System.out.println("TimeLeft : " + tl);
}
rs5.close();
st5.close();
if((("").equals(tl.trim())) || ((" ").equals(tl.trim())))
tl = "960";
int ftl = 0, frt = 0;
tl = tl.trim();
RoutingTime = RoutingTime.trim(); // it is the time needed to execute a sale order
ftl = Integer.parseInt(tl);
System.out.println("ftl: " + ftl);
frt = Integer.parseInt(RoutingTime);
System.out.println("frt: " + frt);
if(ftl >= frt)
{
Calendar calb = Calendar.getInstance();
Calendar calc = Calendar.getInstance();
Calendar cald = Calendar.getInstance();
String cdatet = "18:30:00";
calb.setTime(sdft.parse(cdatet));
cdatet = sdft.format(calb.getTime());
System.out.println("Fixed Date Time: " + cdatet);
String cdateta = "09:00:00";
cald.setTime(sdft.parse(cdateta));
cdateta = sdft.format(cald.getTime());
System.out.println("Fixed Date Time 1: " + cdateta);
String cdatetc = sdft.format(calc.getTime());
calc.setTime(sdft.parse(cdatetc));
cdatetc = sdft.format(calc.getTime());
System.out.println("Current Date Time: " + cdatetc);
java.util.Date cdatetd = calb.getTime();
java.util.Date cdatetcd = calc.getTime();
java.util.Date cdatetcd1 = cald.getTime();
int mins = (int) ((calb.getTime().getTime() - calc.getTime().getTime()) / (60000));
System.out.println("mins : " + mins);
int TimeLeft = 0;
if((cdatetcd1.before(cdatetcd)) && (cdatetcd.before(cdatetd)) && (mins >= frt))
TimeLeft = ftl - frt;
Statement st3 = con.createStatement();
String dd = "";
String sql1 = "SELECT datediff(dd, LastItemReceiptDate, CustomerRequestDate) as 'ddiff' FROM DCP.dbo.DCPDate where SONo = '"+jtfSONo.getText().trim()+"' and LineItemNo = '"+jtfLineItemNo.getText().trim()+"'";
ResultSet rs2 = st2.executeQuery(sql1);
while(rs2.next())
{
dd = rs2.getString("ddiff");
}
rs2.close();
st3.close();
int datediff = 0;
datediff = Integer.parseInt(dd);
System.out.println("datediff : " + datediff);
tl = "" + TimeLeft;
if(datediff >= 10)
{
if(TimeLeft <= frt)
{
Statement st6 = con.createStatement();
ArrayList<String> solist = new ArrayList<String>();
String sql2i = "select l.DateAllotted as start from [DCP].[dbo].[TimeAllotted] as l left outer join [DCP].[dbo].[TimeAllotted] as r on l.DateAllotted + 1 = r.DateAllotted where r.DateAllotted is null and l.DateAllotted > '"+lir.trim()+"'"; // check which date are not in series
ResultSet rs6 = st6.executeQuery(sql2i);
while(rs6.next())
{
solist.add(rs6.getString("Start").trim());
}
rs6.close();
st6.close();
for(int i = 0; i < solist.size(); i++)
{
for(int j = i; j <= (i+1); j++)
{
Statement st7 = con.createStatement();
ArrayList<String> linelist = new ArrayList<String>();
String sql3 = "Declare #sDate DATETIME, #eDate DATETIME select #sDate = '"+solist.get(i).toString().trim()+"'; select #eDate = '"+solist.get(i+1).toString().trim()+"'; ;with DATE(Date1) as ( select DATEADD(day, datediff(day, '19000101', #sDate), '19000101') union all select DATEADD(day, 1, Date1) from DATE where Date1 <= #eDate ) select convert(varchar(15),d1.DATE1,110) as [Working Date], datename(weekday,d1.Date1)[Working Day] from DATE d1 where (datename(weekday,d1.Date1))not in ('Saturday','Sunday')"; // check free dates using the dates not in series and consider only working dates
ResultSet rs7 = st7.executeQuery(sql3);
while(rs7.next())
{
linelist.add(rs7.getString("Working Date").trim());
}
for(int k = 0; k < linelist.size(); k++)
{
Statement st8 = con.createStatement();
String lefttime = "";
ResultSet rs8 = st8.executeQuery("Select TimeLeft from DCP.dbo.TimeAllotted where DateAllotted = '"+linelist.get(k).toString().trim()+"'"); // take up one date, if time is available, come out of the loop and schedule the sale order on that date.....
while(rs8.next())
{
lefttime = rs8.getString("TimeLeft");
System.out.println("TimeLeft : " + lefttime);
}
if((("").equals(lefttime.trim())) || ((" ").equals(lefttime.trim())))
lefttime = "960";
int ftla = 0, frta = 0;
lefttime = lefttime.trim();
RoutingTime = RoutingTime.trim();
ftla = Integer.parseInt(lefttime);
System.out.println("ftla: " + ftla);
frta = Integer.parseInt(RoutingTime);
System.out.println("frta: " + frta);
if(ftla >= frta)
{
Calendar calbi = Calendar.getInstance();
Calendar calci = Calendar.getInstance();
Calendar caldi = Calendar.getInstance();
String cdateti = "18:30:00";
calbi.setTime(sdft.parse(cdateti));
cdateti = sdft.format(calbi.getTime());
System.out.println("Fixed Date Timei: " + cdateti);
String cdatetai = "09:00:00";
caldi.setTime(sdft.parse(cdatetai));
cdatetai = sdft.format(caldi.getTime());
System.out.println("Fixed Date Time 1i: " + cdatetai);
String cdatetci = sdft.format(calci.getTime());
calci.setTime(sdft.parse(cdatetci));
cdatetci = sdft.format(calci.getTime());
System.out.println("Current Date Timei: " + cdatetci);
java.util.Date cdatetdi = calbi.getTime();
java.util.Date cdatetcdi = calci.getTime();
java.util.Date cdatetcd1i = caldi.getTime();
int minsi = (int) ((calbi.getTime().getTime() - calci.getTime().getTime()) / (60000));
System.out.println("minsi : " + minsi);
int TimeLefti = 0;
if((cdatetcd1i.before(cdatetcdi)) && (cdatetcdi.before(cdatetdi)) && (minsi >= frta))
TimeLefti = ftla - frta;
lefttime = "" + TimeLefti;
if(TimeLefti >= frta)
{
EDCDate = linelist.get(k).toString().trim();
break;
}
}
}
}
}
calca.add(Calendar.DATE, 1);
// check if the date is free
lir = sdf1.format(calca.getTime());
System.out.println("lir : " + lir);
EDCDate = lir.trim();
}
else
{
EDCDate = lir.trim();
}
}
else
{
if(TimeLeft <= frt)
{
calda.add(Calendar.DATE, 1);
cr = sdf1.format(calda.getTime());
System.out.println("cr : " + cr);
EDCDate = cr.trim();
}
else
{
EDCDate = cr.trim();
}
}
}
else
{
Calendar cala = Calendar.getInstance();
String cdate = sdf.format(cala.getTime());
cala.setTime(sdf.parse(cdate));
cdate = sdf1.format(cala.getTime());
System.out.println("Current Date : " + cdate);
cala.add(Calendar.DATE, 1);
cdate = sdf1.format(cala.getTime());
System.out.println("cdate : " + cdate);
EDCDate = cdate.trim();
}
}
else
{
SimpleDateFormat sdft = new SimpleDateFormat("HH:mm:ss");
st5 = con.createStatement();
ResultSet rs5 = st5.executeQuery("Select TimeLeft from DCP.dbo.TimeAllotted where DateAllotted = '"+lir.trim()+"'");
while(rs5.next())
{
tl = rs5.getString("TimeLeft");
System.out.println("TimeLeft : " + tl);
}
rs5.close();
st5.close();
if((("").equals(tl.trim())) || ((" ").equals(tl.trim())))
tl = "960";
int ftl = 0, frt = 0;
tl = tl.trim();
RoutingTime = RoutingTime.trim();
ftl = Integer.parseInt(tl);
System.out.println("ftl: " + ftl);
frt = Integer.parseInt(RoutingTime);
System.out.println("frt: " + frt);
if(ftl >= frt)
{
Calendar calb = Calendar.getInstance();
Calendar calc = Calendar.getInstance();
Calendar cald = Calendar.getInstance();
String cdatet = "18:30:00";
calb.setTime(sdft.parse(cdatet));
cdatet = sdft.format(calb.getTime());
System.out.println("Fixed Date Time: " + cdatet);
String cdateta = "09:00:00";
cald.setTime(sdft.parse(cdateta));
cdateta = sdft.format(cald.getTime());
System.out.println("Fixed Date Time 1: " + cdateta);
String cdatetc = sdft.format(calc.getTime());
calc.setTime(sdft.parse(cdatetc));
cdatetc = sdft.format(calc.getTime());
System.out.println("Current Date Time: " + cdatetc);
java.util.Date cdatetd = calb.getTime();
java.util.Date cdatetcd = calc.getTime();
java.util.Date cdatetcd1 = cald.getTime();
int mins = (int) ((calb.getTime().getTime() - calc.getTime().getTime()) / (60000));
System.out.println("mins : " + mins);
int TimeLeft = 0;
if((cdatetcd1.before(cdatetcd)) && (cdatetcd.before(cdatetd)) && (mins >= frt))
TimeLeft = ftl - frt;
if(TimeLeft <= frt)
{
calca.add(Calendar.DATE, 1);
lir = sdf1.format(calca.getTime());
System.out.println("lir : " + lir);
EDCDate = lir.trim();
}
else
{
EDCDate = lir.trim();
}
}
else
{
Calendar cala = Calendar.getInstance();
String cdate = sdf.format(cala.getTime());
cala.setTime(sdf.parse(cdate));
cdate = sdf1.format(cala.getTime());
System.out.println("Current Date : " + cdate);
cala.add(Calendar.DATE, 1);
cdate = sdf1.format(cala.getTime());
System.out.println("cdate : " + cdate);
EDCDate = cdate.trim();
}
}
Please guide me.......... I am not sure about the loops. I need to first check for the dates not in series or the dates that have gap in between. And, then, using those dates, check which all dates are free. Then, check if time is available on that date. If yes, break the loop and schedule the order, else go to next date. Please tell me if the loops are correct or can they be improved on.
Create a calendar table in SQL. A table that has every date in it. Then join to it, so you can return all dates, even if they don't appear in your TimeAllotted table.

Given first chrono time, calculate value of next results given the gaps

I have some sports time results returned by an xml feed.
Result time for the first arrived is returned and converted like this:
String time = "00:01:00:440";
String gap = "";
for the other partecipants I get back only the gap:
String time = "";
String gap = "00:00:00:900";
How can I calculate the time of others partecipants given the gap from the first?
I have tried with java Date object but it uses calendar days too and I get strange result:
String firstTime = "00:01:00:440";
String gapOne = "00:00:00:900";
SimpleDateFormat formatter = new SimpleDateFormat("hh:mm:ss:SSS");
Date d1 = null;
Date d2 = null;
long diff = 0;
String timeResult = "";
try {
d1 = formatter.parse(firstTime);
d2 = formatter.parse(gapOne);
diff = d2.getTime() + d1.getTime();
timeResult = formatter.format(new Date(diff));
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(timeResult);
But prints out:
11:01:01:340
I came up with this solution:
String firstTime = "00:01:00:440";
String gapOne = "00:00:00:900";
String firstTimeSplit[] = firstTime.split(":");
String gapSplit[] = gapOne.split(":");
int millisecSum = Integer.parseInt(firstTimeSplit[3]) + Integer.parseInt(gapSplit[3]);
int secsSum = Integer.parseInt(firstTimeSplit[2]) + Integer.parseInt(gapSplit[2]);
int minSum = Integer.parseInt(firstTimeSplit[1]) + Integer.parseInt(gapSplit[1]);
int hrsSum = Integer.parseInt(firstTimeSplit[0]) + Integer.parseInt(gapSplit[0]);
String millisec = String.format("%03d", millisecSum % 1000);
int mathSec = millisecSum / 1000 + secsSum;
String secs = String.format("%02d", mathSec % 60);
int mathMins = mathSec / 60 + minSum;
String mins = String.format("%02d", mathMins % 60);
int mathHrs = mathMins / 60 + hrsSum;
String hrs = String.format("%02d", mathHrs % 60);
String format = "%s:%s:%s:%s";
String result = String.format(format, hrs, mins, secs, millisec);
This way I get returned the value this way:
00:01:01:340

Clipping mp4s with mp4parser. Can't get past timeCorrected with SyncSample

I am writing an Android app and I have a bunch of 5-15 second .mp4 files that I want to clip. I have been trying to use Sebastian Annies' mp4parser to do so, following the example code given here: ShortenExample.
Here is the code I am using (heavily resembles the example code above):
public static void clip(Sprinkle sprinkle, double start, double end) throws IOException {
Movie movie = MovieCreator.build(sprinkle.getLocalVideoPath());
// Save all tracks then remove them from movie
List<Track> tracks = movie.getTracks();
movie.setTracks(new LinkedList<Track>());
boolean timeCorrected = false;
// Here we try to find a track that has sync samples. Since we can only start decoding
// at such a sample we SHOULD make sure that the start of the new fragment is exactly
// such a frame
for (Track track : tracks) {
if (track.getSyncSamples() != null && track.getSyncSamples().length > 0) {
if (timeCorrected) {
// This exception here could be a false positive in case we have multiple tracks
// with sync samples at exactly the same positions. E.g. a single movie containing
// multiple qualities of the same video (Microsoft Smooth Streaming file)
Log.v("clip", "track.getSyncSamples().length: " + track.getSyncSamples().length);
throw new RuntimeException("The startTime has already been corrected by another track with SyncSample. Not Supported.");
}
Log.v("syncSample", "start before: " + start);
Log.v("syncSample", "end before: " + end);
start = correctTimeToSyncSample(track, start, false);
end = correctTimeToSyncSample(track, end, true);
Log.v("syncSample", "start after: " + start);
Log.v("syncSample", "end after: " + end);
timeCorrected = true;
}
}
for (Track track : tracks) {
long currentSample = 0;
double currentTime = 0;
double lastTime = 0;
long startSample = -1;
long endSample = -1;
for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
for (int j = 0; j < entry.getCount(); j++) {
if (currentTime > lastTime && currentTime <= start) {
// current sample is still before the new starttime
startSample = currentSample;
}
if (currentTime > lastTime && currentTime <= end) {
// current sample is after the new start time and still before the new endtime
endSample = currentSample;
}
lastTime = currentTime;
currentTime += (double) entry.getDelta() / (double) track.getTrackMetaData().getTimescale();
currentSample++;
}
}
movie.addTrack(new AppendTrack(new CroppedTrack(track, startSample, endSample)));
}
long start1 = System.currentTimeMillis();
Container out = new DefaultMp4Builder().build(movie);
long start2 = System.currentTimeMillis();
File file = Constants.getEditsDir();
FileOutputStream fos = new FileOutputStream(file.getPath() + String.format("output-%f-%f.mp4", start, end));
FileChannel fc = fos.getChannel();
out.writeContainer(fc);
fc.close();
fos.close();
long start3 = System.currentTimeMillis();
System.err.println("Building IsoFile took : " + (start2 - start1) + "ms");
System.err.println("Writing IsoFile took : " + (start3 - start2) + "ms");
System.err.println("Writing IsoFile speed : " + (new File(String.format("output-%f-%f.mp4", start, end)).length() / (start3 - start2) / 1000) + "MB/s");
}
private static double correctTimeToSyncSample(Track track, double cutHere, boolean next) {
double[] timeOfSyncSamples = new double[track.getSyncSamples().length];
long currentSample = 0;
double currentTime = 0;
for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
for (int j = 0; j < entry.getCount(); j++) {
if (Arrays.binarySearch(track.getSyncSamples(), currentSample + 1) >= 0) {
// samples always start with 1 but we start with zero therefore +1
timeOfSyncSamples[Arrays.binarySearch(track.getSyncSamples(), currentSample + 1)] = currentTime;
}
currentTime += (double) entry.getDelta() / (double) track.getTrackMetaData().getTimescale();
currentSample++;
}
}
double previous = 0;
for (double timeOfSyncSample : timeOfSyncSamples) {
if (timeOfSyncSample > cutHere) {
if (next) {
return timeOfSyncSample;
} else {
return previous;
}
}
previous = timeOfSyncSample;
}
return timeOfSyncSamples[timeOfSyncSamples.length - 1];
}
I can't seem to prevent the error "The startTime has already been corrected by another track with SyncSample. Not Supported." from occurring. When I log the tracks that I am looping through, getHandler() returns "vide", "soun", and then crashes when it comes to "hint". If I comment this part out:
if (timeCorrected) {
// This exception here could be a false positive in case we have multiple tracks
// with sync samples at exactly the same positions. E.g. a single movie containing
// multiple qualities of the same video (Microsoft Smooth Streaming file)
Log.v("clip", "track.getSyncSamples().length: " + track.getSyncSamples().length);
throw new RuntimeException("The startTime has already been corrected by another track with SyncSample. Not Supported.");
}
then the program just crashes with an index out of bounds error when it gets to the line
Container out = new DefaultMp4Builder().build(movie);
What am I doing wrong?
You are getting an IndexOutOfBoundsException, because either your startSample or your endSample has a wrong value (e.g. still -1) when reaching
Container out = new DefaultMp4Builder().build(movie);
In my example using a start value for the clipping process of smaller than 2 seconds resulted in the effect that if (currentTime > lastTime && currentTime <= start) never reached a true value and thus startSample was not updated from it's initial value of -1. One solution for this is to change the initial value of startSample from -1 to 0.
use this iso-parser library.https://code.google.com/p/mp4parser/downloads/detail?name=isoviewer-1.0-RC-28.jar&can=2&q=
private void doShorten(final int _startTime, final int _endTime) {
try {
File folder = new File(VideoPath);
Movie movie = MovieCreator.build(VideoPath);
List<Track> tracks = movie.getTracks();
movie.setTracks(new LinkedList<Track>());
// remove all tracks we will create new tracks from the old
double startTime = _startTime;
double endTime = _endTime;// (double) getDuration(tracks.get(0)) /
// tracks.get(0).getTrackMetaData().getTimescale();
boolean timeCorrected = false;
// Here we try to find a track that has sync samples. Since we can
// only start decoding
// at such a sample we SHOULD make sure that the start of the new
// fragment is exactly
// such a frame
for (Track track : tracks) {
if (track.getSyncSamples() != null
&& track.getSyncSamples().length > 0) {
if (timeCorrected) {
// This exception here could be a false positive in case
// we have multiple tracks
// with sync samples at exactly the same positions. E.g.
// a single movie containing
// multiple qualities of the same video (Microsoft
// Smooth Streaming file)
throw new RuntimeException(
"The startTime has already been corrected by another track with SyncSample. Not Supported.");
}
startTime = correctTimeToSyncSample(track, startTime, false);
endTime = correctTimeToSyncSample(track, endTime, true);
timeCorrected = true;
}
}
for (Track track : tracks) {
long currentSample = 0;
double currentTime = 0;
long startSample = -1;
long endSample = -1;
for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
TimeToSampleBox.Entry entry = track
.getDecodingTimeEntries().get(i);
for (int j = 0; j < entry.getCount(); j++) {
// entry.getDelta() is the amount of time the current
// sample covers.
if (currentTime <= startTime) {
// current sample is still before the new starttime
startSample = currentSample;
}
if (currentTime <= endTime) {
// current sample is after the new start time and
// still before the new endtime
endSample = currentSample;
} else {
// current sample is after the end of the cropped
// video
break;
}
currentTime += (double) entry.getDelta()
/ (double) track.getTrackMetaData()
.getTimescale();
currentSample++;
}
}
movie.addTrack(new CroppedTrack(track, startSample, endSample));
}
long start1 = System.currentTimeMillis();
Container out = new DefaultMp4Builder().build(movie);
long start2 = System.currentTimeMillis();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
String filename = "TrimVideo"+System.currentTimeMillis()+".mp4";
RandomAccessFile fc = new RandomAccessFile(
Environment.getExternalStorageDirectory()+"/myfolder/"+filename,
"rw");
FileChannel fc2 = fc.getChannel();
out.writeContainer(fc2);
fc2.close();
AddVideoInfo(filename);
long start3 = System.currentTimeMillis();
System.err.println("Building IsoFile took : " + (start2 - start1)
+ "ms");
System.err.println("Writing IsoFile took : " + (start3 - start2)
+ "ms");
System.err.println("Writing IsoFile speed : "
+ (new File(String.format("TMP4_APP_OUT-%f-%f", startTime,
endTime)).length() / (start3 - start2) / 1000)
+ "MB/s");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void AddVideoInfo(String filename) {
// TODO Auto-generated method stub
File f = new File(Environment.getExternalStorageDirectory()
+ "/TotalRecall/"+filename);
EvientVideosListActivity.mVideoNamesList.add(f.getAbsolutePath());
Date lastModDate = new Date(f.lastModified());
SimpleDateFormat sdf = new SimpleDateFormat(
"MMM dd, yyyy hh:mm");
String date = sdf.format(lastModDate);
EvientVideosListActivity.mVideoDateList.add(date);
Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(
f.getAbsolutePath(),
MediaStore.Video.Thumbnails.MINI_KIND);
EvientVideosListActivity.mVideoThumbsList.add(bitmap);
Global.mVideoCheckList.add(false);
}
long getDuration(Track track) {
long duration = 0;
for (TimeToSampleBox.Entry entry : track.getDecodingTimeEntries()) {
duration += entry.getCount() * entry.getDelta();
}
return duration;
}
double correctTimeToSyncSample(Track track, double cutHere, boolean next) {
double[] timeOfSyncSamples = new double[track.getSyncSamples().length];
long currentSample = 0;
double currentTime = 0;
for (int i = 0; i < track.getDecodingTimeEntries().size(); i++) {
TimeToSampleBox.Entry entry = track.getDecodingTimeEntries().get(i);
for (int j = 0; j < entry.getCount(); j++) {
if (Arrays.binarySearch(track.getSyncSamples(),
currentSample + 1) >= 0) {
// samples always start with 1 but we start with zero
// therefore +1
timeOfSyncSamples[Arrays.binarySearch(
track.getSyncSamples(), currentSample + 1)] = currentTime;
}
currentTime += (double) entry.getDelta()
/ (double) track.getTrackMetaData().getTimescale();
currentSample++;
}
}
double previous = 0;
for (double timeOfSyncSample : timeOfSyncSamples) {
if (timeOfSyncSample > cutHere) {
if (next) {
return timeOfSyncSample;
} else {
return previous;
}
}
previous = timeOfSyncSample;
}
return timeOfSyncSamples[timeOfSyncSamples.length - 1];
}

Categories