so from this :
1459245759880
to this
1459245759000
Usual integer rounding?
long millis = 1459245759880L;
long rounded = millis / 1000 * 1000;
Using Java time (convenient if you need to do date/time operations on the result - in that case you can work with the instant):
Instant i = Instant.ofEpochMilli(millis).truncatedTo(ChronoUnit.SECONDS);
long rounded = i.toEpochMilli();
More convoluted (and probably not very clear):
long rounded = 1000 * TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS);
//OR
long rounded = TimeUnit.MILLISECONDS.convert(TimeUnit.SECONDS.convert(millis, TimeUnit.MILLISECONDS), TimeUnit.SECONDS);
long x = 1459245759880;
long y = x - (x % 1000);
Use simply the modulo operator to get reminder and then subtract it from the actual value.
Why not this
long value = 1459245759880L;
System.out.println(1000 * (value / 1000));
Related
I'm trying to type out a code that outputs random words from a list, the user must type back as many words as possible before 60 seconds has elapsed I am using currentTimeMillis() to keep track of time so this is difficult for me to figure out I tried the code below and it said 6000000000000 is too large of a number but when I output the current/start time, it output 1512409897444 so this doesn't make sense to me.
long currentTime = System.currentTimeMillis();
long startTime = System.currentTimeMillis();
System.out.println(currentTime);
System.out.println(startTime);
while (startTime <= 6000000000000)
{
(etc. ect.)
}
What you want to do is compare the current time against the time you started and check if their difference is below 60 seconds, aka 60000 milli seconds:
long startTime = System.currentTimeMillis();
while ((System.currentTimeMillis() - startTime) <= 60000) {
// still under 60 seconds...
}
System.currentTimeMillis() returns a value that increases from an "epoch". You must subtract two time values to determine the amount of time that has elapsed.
long startTime = System.currentTimeMillis();
long elapsedTime = 0;
while (elapsedTime <= 60000) {
// etc, etc, etc
elapsedTime = System.currentTimeMillis() - startTime;
}
As others have already answered you have to subtract the starting time to the current time to determine if the difference is greather than 60 seconds (60,000 milliseconds). Also you can use TimeUnit to get a more readeable code:
long startTime = System.currentTimeMillis();
while (TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - startTime) <= 60) {
//do stuff
}
EDIT
If you are wondering why 6000000000000 gives you an error and the result of currentTimeMillis() (1512409897444) doesn't, is because they are different datatypes: int (32 bits) vs long (64 bits). The literal value 6000000000000 is interpreted as an int value which is greather than the max supported 32-bit signed int value (2,147,483,647) and the compiler doesn't allow that. It would work if you use a long literal instead 6000000000000L (note the L at the end). Signed long's max supported value is 9,223,372,036,854,775,807. The result of System.currentTimeMillis() is a long value hence 1512409897444 is valid. Read Primitive Data Types for further information.
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;
Is it possible to lose precision in this case?
int X = (some integer number);
Date D = new Date(X * 1000);
int Y = (int)(D.getTime())/1000;
I would believe that Y would always be the same as X as long as X is some integer value. Is that correct?
No!you're not correct!
replace the line Date D = new Date(X * 1000);
with Date D = new Date(X * 1000L);
Use long (64 bit) numbers not integers (32 bit) numbers. If you use integers it may overflow (go from positive to negative). See this link for details https://www.securecoding.cert.org/confluence/display/java/NUM00-J.+Detect+or+prevent+integer+overflow
i want to make a simple progressbar showing me how much time some process takes. At the moment of creation of it I have only actual percentage (as int) and time that is left(as String formatted HH:mm:ss). I want it to update every second and show me the actual state of process. I've tried everything and it doesn't work. Current version looks like this - tell me please what I'm doing wrong...
int initialProgress = 35; // %
// time to finish process
Date endDate = new SimpleDateFormat("HH:mm:ss").parse("07:07:07");
Date now = new Date();
long totalDuration = (long) (((double)(endDate.getTimeInMillis()
- now.getTimeInMillis()) * 100.0 / (double)initialProgress);
and then every second I repeat:
now = new Date();
int currentProgress = (totalDuration - endDate.getTimeInMillis()
+ now.getTimeInMillis())/totalDuration;
It simply is not working. Total duration is even something strange...
The issue seems to be that you have a time remaining String and you want to parse it to percentage of work done.
The first thing you need, obviously, is the total expected time. Lets assume that this is also a String.
First write a method for parsing your HH:mm:ss String to a long representing time remaining in seconds.
public long parseToSeconds(final String duration) throws ParseException {
final MessageFormat durationFormat = new MessageFormat("{0,number,#}:{1,number,#}:{2,number,#}");
final Object[] parsedTimeRemaining = durationFormat.parse(duration);
final long totalDuration = TimeUnit.HOURS.toSeconds((Long) parsedTimeRemaining[0])
+ TimeUnit.MINUTES.toSeconds((Long) parsedTimeRemaining[1])
+ (Long) parsedTimeRemaining[2];
return totalDuration;
}
What we do here is use a MessageFormat to parse your String into an array of Object. As we have told the MessageFormat that these are numbers, it will automagically convert (or try to convert, hence the exception) to Long.
Once we have those numbers we scale them all to seconds using the (very useful) TimeUnit class.
A couple of quick tests to ensure we're on the right track:
System.out.println(parseToSeconds("00:00:01"));
System.out.println(parseToSeconds("00:01:00"));
System.out.println(parseToSeconds("01:00:00"));
System.out.println(parseToSeconds("01:01:01"));
Output:
1
60
3600
3661
Looks good.
Lets assume that right as the start of the process we get a time remaining, for simplicity, of "04:04:04", this gives 14644. Now we just need to store that and calculate the percentage against any new duration String. This should do the trick:
public int asPercentage(final long totalTime, final long remaining) {
final double percentage = remaining / ((double) totalTime);
return (int) (percentage * 100);
}
Note the fact that I cast (seemingly pointlessly) one of the items to a double. This is because in Java any operation on an integral type always returns another integral type. Casting to a double forces it to return a double.
Lets do a quick check again:
final long totalDuration = 14644;
System.out.println(asPercentage(totalDuration, parseToSeconds("03:03:03")));
System.out.println(asPercentage(totalDuration, parseToSeconds("02:02:02")));
System.out.println(asPercentage(totalDuration, parseToSeconds("01:01:01")));
Output:
75
50
25
Looks good, that is the time remaining as a percentage of the total. Maybe to quite what we want for a progress bar. Lets invert it:
public static int asPercentage(final long totalTime, final long remaining) {
final double percentage = remaining / ((double) totalTime);
return 100 - (int) (percentage * 100);
}
Output:
25
50
75
Ah-ha. Much better.
I have problem with java then i want to divade big long type numerics for example if i divide 165600139 / 86400000 = 1.9, but my method return 1 without rounding :/
public static long calcDaysBefore(Date date) {
int MILISECONDS_IN_DAY = 24 * 60 * 60 * 1000;
long days = 0;
if (date != null) {
long current = getCurrentDate().getTime() - date.getTime();
days = current / MILISECONDS_IN_DAY;
}
return days;
}
It is rounding down and is similar to doing
days = Math.floor((double) current / MILISECONDS_IN_DAY);
If you want to round half up you can write
days = (current + MILISECONDS_IN_DAY/2) / MILISECONDS_IN_DAY;
Using floating point you could use the following which is much slower.
days = Math.round((double) current / MILISECONDS_IN_DAY);
if you want to round up you can do
days = (current + MILISECONDS_IN_DAY-1) / MILISECONDS_IN_DAY;
or
days = Math.ceil((double) current / MILISECONDS_IN_DAY);
btw milli-seconds has two l's
actually the result is rounded, there are several rounding modes, see http://docs.oracle.com/javase/1.5.0/docs/api/java/math/RoundingMode.html, in your case you are getting the number of full days. For rounding to the closest long we can use
long days = Math.round(current / 8640000.0);
cast to double.
days = (double)current / (double)MILISECONDS_IN_DAY;