Time Difference separating the times - java

Complete timeDifference that takes two different times and returns a
string with the difference in hours and minutes, separated by ":".
The int argument 0 represents midnight, 700 is 7:00 a.m., 1314 is 14
minutes past 1:00pm, and 2200 is 10 pm.
Leading zeros required
I know the problem requires you to convert both times to minutes, however I don't know how to separate the integers that are four characters long so I can differ between hours and minutes.

Sice your question is on the separation part only, this will do the trick:
int timeDifference(int a, int b)
{
int minsA = a % 100); //remainder
int hrsA = (a / 100);
.....
}
Edit: if you want to get the full time just in minutes you can do:
int fullMinsA = minsA + hrsA*60;

Related

Generate random time within a range of two times with condition

I'm trying to generate 10 random times within a range of two times, and there is a condition that the times generated cannot have less than 30 minutes between them. So, if i Start at 10:00am and end at 05:00pm, the times between these must be a least 30 minutes between them.
I already can get the random times, but don't know how to put the condition there, any ideas?
public LocalTime between(LocalTime startTime, LocalTime endTime) {
int startSeconds = startTime.toSecondOfDay();
int endSeconds = endTime.toSecondOfDay();
int randomTime = ThreadLocalRandom
.current()
.nextInt(startSeconds, endSeconds);
return LocalTime.ofSecondOfDay(randomTime);
}
i put this in a for loop to get 10 of them
For a good random distribution: Out of the 7 hours between your start of 10:00 and your end of 17:00 (on a 24 hour clock, “military hours”), 4 hours 30 minutes are already reserved for your minimal gaps (9 gaps # 30 minutes minimum). So subtract 4:30 from 7, this gives 2 hours 30 minutes of freedom.
Generate 10 random times within 2 hours 30 minutes, for example the way you already do.
Sort them chronologically.
Add 0 minutes to the first time, 30 minutes to the next, 1 hour to the third, etc. So you will be adding 4 hours 30 minutes to the last time. This will make sure that the gaps become at least 30 minutes each and that the last time is still within the 17:00 end time.
You can use isBefore in LocalTime, so check startTime+30 Min is before result and result is before endTime-30 Min
LocalTime result = LocalTime.ofSecondOfDay(randomTime);
if (startTime.plusMinutes(30).isBefore(result) && result.isBefore(endTime.minusMinutes(30))) {
return result;
}
Probably you can use while loop to loop until it get the valid result
while(true) {
LocalTime result = LocalTime.ofSecondOfDay(ThreadLocalRandom. current().nextInt(startSeconds, endSeconds));
if (startTime.plusMinutes(30).isBefore(result) && result.isBefore(endTime.minusMinutes(30))) {
return result;
}
}
You can not generate truly random numbers with computers, you always have to have some strategy. And if your numbers are truly random then, they can not be aware of each other. So, you can not generate truly random time 30 minutes apart separately. You have to generate them all together. You have to find a minimum distance. And start time and end time must have enough distance to generate the number of random times you want.
You can generate any number of random times by the following method in any given range if they have enough distance -
public List<LocalTime> generateRandomTimes(LocalTime startTime, LocalTime endTime, int n) {
if (n < 0) {
throw new RuntimeException("Must be greater than zero");
}
List<LocalTime> localTimeList = new ArrayList<>();
int startSeconds = startTime.toSecondOfDay();
int endSeconds = endTime.toSecondOfDay();
int minimumDistance = LocalTime.of(0, 30).toSecondOfDay();
int standardDistance = (endSeconds - startSeconds) / n;
if (standardDistance <= minimumDistance) {
throw new RuntimeException("Not enough time distance to generate the required number of random times");
}
int randomRange = (endSeconds - (n * minimumDistance)) / n;
for (int i = 1; i <= 10; i++) {
int nextInt = ThreadLocalRandom
.current()
.nextInt(startSeconds, startSeconds + randomRange);
LocalTime time = LocalTime.ofSecondOfDay(nextInt);
localTimeList.add(time);
startSeconds = nextInt + minimumDistance;
}
return localTimeList;
}

Show the format XX:00 in JAVA

I want to show a number in a format XX:00 in Java. How can I do it?
Ex: int number = 12;
show 12:00.
double i = 12;
show 12:00
Showing a double number
If 12.0 is a fractional number to be printed with colon as decimal separator:
double i = 12;
DecimalFormatSymbols dfs = new DecimalFormatSymbols();
dfs.setDecimalSeparator(':');
NumberFormat format = new DecimalFormat("00.00", dfs);
System.out.println(format.format(i));
Output:
12:00
If i was 12.75 instead of 12, the fraction would be printed too:
12:75
It rounds to the nearest number with two decimals, so 12.756 would be printed as 12:76.
Showing a duration in hours and minutes
If instead your 12:00 denotes an amount of time, a duration in hours and minutes, we want something different because there are 60 minutes in an hour, not 100. Here’s the Java 9 and later version:
long totalMinutes = (long) (i * TimeUnit.HOURS.toMinutes(1));
Duration dur = Duration.ofMinutes(totalMinutes);
System.out.format("%02d:%02d%n", dur.toHours(), dur.toMinutesPart());
This prints
12:00
or in the 12.75 case:
12:45
12.75 equals 12 and three quarters, and the 45 printed also equals three quarters of an hour, so this is what we wanted. It rounds down, so even though 12.759 equals 12 hours 45 minutes 32.4 seconds, it’s still printed as 12:45.
Java 8 and earlier:
The toMinutesPart method I have used was introduced in Java 9. In Java 8 (and earlier) you may still use the Duration class, but it’s less advantageous, so you may also do without it:
int hours = (int) i;
long minutesOnly = totalMinutes - TimeUnit.HOURS.toMinutes(hours);
System.out.format("%02d:%02d%n", hours, minutesOnly);
Now the result is the same as above.
double i = 12;
String.format("%.0f:00", i); // returns 12.00

Loss of precision - Java

Problem Statement:
Write a method whatTime, which takes an int, seconds, representing the number of seconds since midnight on some day, and returns a String formatted as "::". Here, represents the number of complete hours since midnight, represents the number of complete minutes since the last complete hour ended, and represents the number of seconds since the last complete minute ended. Each of , , and should be an integer, with no extra leading 0's. Thus, if seconds is 0, you should return "0:0:0", while if seconds is 3661, you should return "1:1:1"
My Algorithm:
Here is how my algorithm is supposed to work for the input 3661:
3661/3600 = 1.016944 -> This means the number of hours is 1
Subtract the total number of hours elapsed i.e. 1.016944-1=0.016944
Multiply this with 60 i.e. 0.016944*60=1.016666 -> The number of minutes elapsed is equal to 1
Subtract the total number of minutes elapsed i.e. 1.01666-1=0.01666. Multiply this with 60. This would yield the number of seconds elapsed.
The output produced however is 1:1:0. I tried to use a print statement and it appears that the value of 'answer3' variable is 0.999 and that is why prints the integer part (0). I tried to use the Math.ceil() function to round up the value and it produces a correct output. However I can only score about 60/250 points when I submit my code (TopCoder SRM 144 Div2) . Any insight for improving the algorithm will be helpful.
public class Time
{
public String whatTime(int seconds)
{
double answer1,answer2,answer3; int H;
answer1=(double)seconds/3600;
H=(int)answer1;
answer2=(double)((answer1-H)*60);
int M=(int)answer2;
answer3=answer2-M;
answer3=(double)answer3*60;
int S=(int)answer3;
String answer=Integer.toString(H);
answer=Integer.toString(H)+":"+Integer.toString(M)+":"+Integer.toString(S);
return answer;
}
}
public String whatTime(int seconds) {
int secondVal = seconds % 60;
int minutes = seconds / 60;
int minuteVal = minutes % 60;
int hours = minutes / 60;
int hourVal = hours % 24;
int daysVal = hours / 24;
String answer = "" + daysVal + ":" + hourVal + ":" + minuteVal + ":" + secondVal;
return answer;
}
Could do the formatting more elegantly, but that's the basic idea.
Avoid floating point values, and work entirely with ints or longs.
You could solve this by working with ints :
3661/3600 = 1.016944 -> This means the number of hours is 1
Subtract the number of hours * 3600 - i.e. 3661-(1*3600) = 61
61/60 = 1.0166666 -> The number of minutes elapsed is equal to 1
Subtract the number of minutes * 60 i.e. 61-(1*60)=1. This yields the number of seconds elapsed.

Get a less specific number - from another number

Right, sorry I can't think of the correct words to google this. So I'll have to ask.
I've got a long (System.currentTimeMillis())
Lets say
3453646345345345
I want to remove the last six (or other number of) digits and I think I can do this doing some kind of bit shift?
so I would end up with
3453646345
EDIT
I wanted to get the System.currentTimeMillis() within a time box, so if I ask for the time then ask again 29 seconds later it will return the same number but if I ask 31 seconds later it will return a different number. With the 30 second timebox being configurable.
You have to simply divide it by 1M long shorter = System.currentTimeMillis() / 1000000L;
To build on #Yob's answer, you can make the number of digits to remove configurable by creating a method like this:
public long removeDigits(long number, int digitsToRemove) {
return number / (long)Math.pow(10, digitsToRemove);
}
Depending on what you want to do (in base 10, I assume), you can do this:
int64_t radix = 1000000; // or some other power of 10
x -= x%radix; // last 6 decimal digits are now 0
// e.g: from 3453646345345345 to 3453646345000000
Or this (as in the previous answer):
x /= radix; // last 6 decimal digits are gone, the result rounded down
// e.g: from 3453646345345345 to 3453646345
Response to Edit
For your purposes, you could change radix in the modulus example to 30000:
int64_t timeInterval = 30000;
displayTime = actualTime - (actualTime % timeInterval);
Where displayTime and actualTime are in milliseonds. displayTime will, in this case, have a (rounded-down) granularity of 30 seconds while remaining a unit of milliseconds.
To have a rounded up granularity, you can do the following:
int64_t timeInterval = 30000;
int64_t modulus = actualTime % timeInterval;
displayTime = actualTime - modulus + (modulus?timeInterval:0);
Though, based on what you are asking, it seems you just want to update a display value only every few ticks. The following will work as well:
if((actualTime - displayTime) >= timeInterval){
displayTime = actualTime - (actualTime % timeInterval);
}
Pardon the C integer types, I just prefer to be unambiguous about the width of integer I'm using :P.

JodaTime Calculate total hours worked in a week

Currently I have a function which can take the start time and end time of one day, and calculate the difference between the two, giving me the hours worked in a day. What I would like to do is be able to get the hours worked for 7 days, and return a grand total, while remaining with the display format (HH:mm).
My function for a single day's total:
Period p = new Period(this.startTime[dayIndex], this.endTime[dayIndex]);
long hours = p.getHours();
long minutes = p.getMinutes();
String format = String.format("%%0%dd", 2);//Ensures that the minutes will always display as two digits.
return Long.toString(hours)+":"+String.format(format, minutes);
this.startTime[] & this.endTime[] are both arrays of DateTime objects.
Any suggestions?
You'll need something to hold a week's worth of days, and call your function once for each day.
But that means you'll want to refactor so that your calculator method doesn't format as a string, but instead returns a numeric value, so you can easily add them together.
Another simple solution:
Here is a method that receives separate the hours and minutes.The parameters are:
Start Hour
Start Minutes
End Hour
End Minutes
first, calculate the difference between hours and minutes separate:
int hours = pEndHour - pStartHour;
int minutes = ((60 - pStartMinutes) + pEndMinutes) - 60;
then, validates if the value of "minutes" variable is negative:
// If so, the "negative" value of minutes is our remnant to the next hour
if (minutes < 0) {
hours--;
minutes = 60 + minutes ;
}
Finally you can print the period of time in the hour format:
String format = String.format("%%0%dd", 2);
System.out.println( "*** " + hours + " : " + minutes);
That's all.
Solution I ended with for those interested
Period[] p=new Period[7];
long hours = 0;
long minutes =0;
for(int x=0; x<=this.daysEntered;x++)
{
p[x] = new Period(this.startTime[x], this.endTime[x]);
hours += p[x].getHours();
minutes += p[x].getMinutes();
}
hours += minutes/60;
minutes=minutes%60;
String format = String.format("%%0%dd", 2);
return Long.toString(hours)+":"+String.format(format, minutes);

Categories

Resources