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.
Related
I am trying to divide two time durations (java.time.Duration) and to perform that there are two methods
java.time.Duration#dividedBy(long) which returns an object of type Duration itself but due to some API restrictions I can not use this version.
java.time.Duraiton#dividedBy(Duration) which returns a long and returns number of times one duration occurs within other duration but here we lose the precision as it does not care about the remainder.
Is there any way out to perform this division and get the result with remainder.
Duration.ofHours(1).dividedBy(7L); //returns 8M34.28571 seconds
Duration.ofHours(1).dividedBy(Duration.ofSeconds(7L)) // returns 514 seconds
I have a restriction not to use the first way. Can I get the results using some other way?
EDIT: (from comments) I am not allowed to convert a Duration instance to an ordinal value, e.g. milliseconds.
Convert to milliseconds/nanoseconds, then divide their ordinal value(s), then create a new Duration object from the result.
When the easy ways are forbidden, you can of course do it the more cumbersome way. The following is similar to how we learned to do division by hand in school.
Duration dividend = Duration.ofHours(1);
long divisor = 7;
long minutes = dividend.toMinutes() / divisor;
dividend = dividend.minusMinutes(minutes * divisor);
long seconds = dividend.toSeconds() / divisor;
dividend = dividend.minusSeconds(seconds * divisor);
long nanoseconds = dividend.toNanos() / divisor;
Duration result = Duration.ofMinutes(minutes)
.plusSeconds(seconds)
.plusNanos(nanoseconds);
System.out.println(result);
Result output:
PT8M34.285714285S
Your requirements are not that precise, so I can’t be sure I haven’t used a forbidden method, though.
I want to parse a timestamp, a Long number like 14655**56648041**. I want to create from this Long number two other Long numbers, One with the last four numbers 8041 and the second with 5664. I can convert the number to String, use substring and then convert it again to Long, but I want to know if there is a cleaner way? I tried using % and / but didn't succeed.
The last 4 digits are num % 1E4 and the four previous ones are (num % 1E8 - (num % 1E4)) / 1E4
There is. You can obtain the last four numbers by performing a modulo 10000 on the number:
long last4 = all%10000;
You can furthermore obtain the middle four digits by first dividing by 10000 and the again perform modulo:
long midl4 = (all/10000)%10000;
Or putting it all together:
long all = 1465556648041L;
long last4 = all%10000;
long midl4 = (all/10000)%10000;
System.out.println("all="+all);
System.out.println("last4="+last4);
System.out.println("midl4="+midl4);
jDoodle demo
I'm reading Java: The Complete Reference by Herbert Schildt right now and here is one thing that is not really clear for me. In the chapter about Integers it says that the long type should be used when big, whole numbers are needed. The code example from the book:
// Compute distance light travels using long variables
class Light {
public static void main(String args[]) {
int lightspeed;
long days;
long seconds;
long distance;
// approximate speed of light in miles per second
lightspeed = 18600;
days = 1000; // specify number of days here
seconds = days * 24 * 60 * 60; // convert to seconds
distance = lightspeed * seconds; // compute distance
System.out.print("In " + days + " days light will travel about " + distance + " miles.");
}
}
Upon execution console provides me with such the result:
"In 1000 days light will travel about 16070400000000 miles."
According by my logic, days and seconds vars should be int too, while their values are less than 2 147 483 647.
At this example days = 1000 and seconds = 86 400 000, so the values aren't that big.
But when I declare variables like this:
int lightspeed, days, seconds;
long distance;
I've strange result and for now I can accept it at no way.
"In 1000 days light will travel about -1367621632 miles."
Help me please.
When both seconds and lightspeed are declared as int, lightspeed * seconds is computed as the multiplication of ints, which causes an overflow (since 16070400000000 > 2147483647).
You can still leave them as int if you cast lightspeed or seconds to long, which will force the multiplication to be performed on longs :
distance = (long)lightspeed * seconds;
or
distance = lightspeed * (long)seconds;
Yes, only the distance is relevant, as Eran pointed out.
This behaviour is quite easy to remember if you just think of divison.
as above a / b performs integer division (truncation) given that a and b are integers whereas
(double) a / b
would return a double.
Note that the cast always refers to what follows after it. so in the case of an expression comprising of two integers only the first integer is casted to double.
`
Lets say i have long currentMillis and long oldMillis. The difference between the two timestamps is very tiny and always less than 1 second.
If i want to know the difference between the timestamps in milleseconds, i can do the following:
long difference = currentmillis-oldmillis;
And if i want to convert difference to seconds, i can just divide it by 1000. However if the difference in milliseconds is less than 1000 milliseconds(<1 second), dividing it by 1000 will result in 0.
How can i get the difference between the two timestamps if the difference is less than a second? For example, if the difference is 500 milliseconds, the desired output is 0.5 seconds.
Using float/double instead of long always returns 0.0 for some reason i don't understand.
My code:
private long oldmillis = 0, difference = 0;
private long calculateDifference()
{
long currentMillis = System.currentTimeMillis();
if (oldMillis == 0) oldMillis = currentMillis;
difference = currentMillis - oldMillis;
oldMillis = currentMillis;
return difference;
}
The method calculateDifference is called randomly with a small random time interval.
It sounds like you just need to convert the results into double before the division:
// This will work
double differenceMillis = currentMillis - oldMillis;
double differenceSeconds = differenceMillis / 1000;
// This will *not* work
double differenceSecondsBroken = (currentMillis - oldMillis) / 1000;
In the latter code, the division is performed using integer arithmetic, so you'll end up with a result of 0 that is then converted to a double.
An alternative which would work is to divide by 1000.0, which would force the arithmetic to be done using floating point:
double differenceSeconds = (currentMillis - oldMillis) / 1000.0;
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.