Is there a possibility to convert a time format which is represented as a string (00:00:000) to long variable.
I'm not sure what do you mean by Convert to currentTimeMillis() or some float variable., but if you are simply looking to convert the given time to long then you can do something like this using simple split:
String timeString = "01:00:100";
int multiplier[] = {3600000, 60000, 100};
String splits[] = timeString.split(":");
long time = 0;
for (int x = 0; x < splits.length; x++) {
time += (Integer.parseInt(splits[x]) * multiplier[x]);
}
System.out.println(time);
Here, the time is being represented in Milliseconds.
Also, this is plain Java and nothing Android specific.
That simply doesn't make much sense.
currentTimeMillis() returns the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.
In other words: the result of a call to that method represents a full blown time stamp; not only hh::mm:sss as in your example; but all of that plus year, month, ...
Thus the answer here: you should step back and clarify for yourself what your actual requirements are.
Related
I have been trying to figured out an algorithm to return a list of time based on a start time and end time and how many loop. For example the start time at 6 am and the end time at 10 pm and the looping number is 5 so I need to return 22-6 = 16 and 16/5 = 3.2 so I need to return
6:00:00
9:20:00
12:40:00
15:60:00
18:20:00
21:40:00
I need to return such these values. (Note, the return value I wrote are not accurate but just for the purpose of demonstration)
The current code:
// List<Time> times(int looping){
long test(){
List<Time> result = new ArrayList<Time>();
String start = "06:00:00";
String finish = "22:00:00";
Time startTime = Time.valueOf(start);
Time endTime = Time.valueOf(finish);
long totalHours = endTime.getTime() - startTime.getTime();
return totalHours;
// return result;
}
Note: the long totalHours return a strange number not 16 and I'm not sure how to loop throw time and return the wanted values.
java.time
This is one of the places where java.time, the modern Java date and time API, excels. The method Duration::dividedBy does just want you want, dividing a span of time into a certain number of chunks.
List<LocalTime> result = new ArrayList<>();
String start = "06:00:00";
String finish = "22:00:00";
LocalTime startTime = LocalTime.parse(start);
LocalTime endTime = LocalTime.parse(finish);
Duration totalTime = Duration.between(startTime, endTime);
int subintervalCount = 5;
Duration subintervalLength = totalTime.dividedBy(subintervalCount);
LocalTime currentTime = startTime;
for (int i = 0; i < subintervalCount; i++) {
result.add(currentTime);
currentTime = currentTime.plus(subintervalLength);
}
System.out.println(result);
This outputs:
[06:00, 09:12, 12:24, 15:36, 18:48]
Where did the strange number of total hours come from?
the long totalHours return a strange number not 16 and I'm not sure
how to loop throw time and return the wanted values.
The Time class doesn’t define a getTime method. Instead you are calling the getTime method of the superclass java.util.Date, another poorly designed and long outdated class that we should no longer use. This getTime retunrs the count of milliseconds since the epoch of 1970-01-01T00:00:00 UTC, something that does not make sense for a time of day. I consider it likely that your subtraction yielded the number of milliseconds rather than the number of hours between your two times.
Edit: In case you’re curious and want to check: 16 hours equals 57 600 000 milliseconds. I obtained the number from TimeUnit.HOURS.toMillis(16).
Link
Oracle tutorial: Date Time explaining how to use java.time.
Suppose I have a System.currentTimeMillis() value as a long number.
How do I modify it to match the instant when last minute started? I.e., zero out seconds and milliseconds.
I would prefer to not use magic constants. Using java.time is fine.
I agree with the answers recommending java.time, but it can be done yet simpler as in those answers:
long lastWholeMinute = Instant.now().truncatedTo(ChronoUnit.MINUTES).toEpochMilli();
This just gave 1517940060000. Of course, if it makes sense for you to keep the Instant object, by all means do that rather than converting to a naked primitive long.
If your long value was one you had stored rather than the time now, it’s quite similar:
long someEpochMilliValue = 1_517_941_234_567L;
long lastWholeMinute = Instant.ofEpochMilli(someEpochMilliValue)
.truncatedTo(ChronoUnit.MINUTES)
.toEpochMilli();
Using java.time is probably the easiest way. You could use withNano and withSecond, like
java.time.ZonedDateTime zdt = java.time.ZonedDateTime.now().withNano(0).withSecond(0);
long millis = zdt.toInstant().toEpochMilli();
Since the value is in milliseconds, if we assume an idealized day (no leap seconds, etc.), then given l you could do it by simply removing the value of l % 60000L from it. I realize that's a magic constant, but it's truly a constant, there are always going to be 60,000 milliseconds in a minute. I'd give it symbolic name:
private static long SIXTY_SECONDS_IN_MS = 60000L;
and not worry about it. Then it's:
long l = /*...your number...*/;
l = l - (l % SIXTY_SECONDS_IN_MS);
Why this works: The Epoch value is from midnight Jan 1st 1970, and so at 0L, 60000L, 120000L, etc., the seconds and milliseconds of an idealized day based on that value are 0. So we use the remainder operator (%) to isolate the part of the value that would remain if we divided by 60000L and remove it. Thus the resulting value, again assuming idealized days, has 0 for seconds and milliseconds. It also works across timezones if we assume all timezones are going to be at whole-minute offsets to UTC. I've only ever heard of timezones that were multiples of hours or half-hours offset from UTC ("GMT plus five hours", "GMT plus 5.5 hours"), never (say) "GMT plus five hours seven minutes and 20 seconds". (And indeed, the standard notation for timezome offsets, +0600 or similar, only includes hours and minutes, not fractional minutes.)
Live Example:
import java.time.*;
public class Example
{
private static long SIXTY_SECONDS_IN_MS = 60000L;
public static void main (String[] args) throws java.lang.Exception
{
long l = System.currentTimeMillis();
l = l - (l % SIXTY_SECONDS_IN_MS);
System.out.println("l = " + l);
// Checking the result
LocalDateTime dt = Instant.ofEpochMilli(l).atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(dt);
System.out.println(dt.getSecond()); // 0
System.out.println(dt.getNano()); // 0
}
}
Still, though, if that constant violates the terms of the question such that you think I shouldn't have answered, let me know and I'll delete the answer. :-)
I am trying to calculate the difference between two times, which are represented as longs in the Format HHmm 24 hour time. E.g 4:30pm is represented by the long 0430.
I am happy for the difference to be in minutes.
Is there a simple calculation that can be done to achieve this? I am aware of Java's Date class, however I want to avoid having to store dummy date information just for a calculation on time.
Thanks!
Putting aside the fact that this is a really, really bad way to store times, the easiest way to do this is to convert the HHMM time to minutes since the start of the day:
long strangeTimeFormatToMinutes(long time) {
long minutes = time % 100;
long hours = time / 100;
return minutes + 60 * hours;
}
Then just use plain old subtraction to get the difference.
You may also want to add validation that minutes and hours are in the ranges you expect, i.e. 0-59 and 0-23.
You mentioned that you didn't want to use the Date class because it required you to use a dummy date. The LocalTime class does not require that.
LocalTime start = LocalTime.of(6,15,30,200); // h, m, s, nanosecs
LocalTime end = LocalTime.of(6,30,30,320);
Duration d = Duration.between(start, end);
System.out.println(d.getSeconds()/60);
Pad zeros
First convert your integer to a 4-character string, padding with leading zeros.
For example, 430 becomes 0430 and parsed as 04:30. Or, 15 becomes 0015 and parsed as quarter past midnight, 00:15.
String input = String.format( "%04d", yourTimeAsInteger );
LocalDate
The LocalTime class represents a time-of-day value with no date and no time zone.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "HHmm" );
LocalTime ld = LocalTime.parse( input , f ) ;
I'm trying to make a timing mechanism using threads, and I'm having a problem in getting the time difference between two Dates, and using that difference to get a current percentage of the time left. Here is the concept I'm trying to prototype:
And here is my implementation:
long startMilisecs = System.currentTimeMillis();
long currentMilisecs;
long endDateMilisecs = getEndDate().getTime();
int diffMillisecs = ((int)(endDateMilisecs - startMilisecs) / 1000) / 60;
int currPerc;
while (startMilisecs <= endDateMilisecs)
{
currentMilisecs = (int) System.currentTimeMillis();
currPerc = ((int)currentMilisecs * 100) / diffMillisecs;
System.out.println(" Current Percentage: " + currPerc);
}
The problem with this code is that the percentage is not starting from 0 but rather in the 20's to 40 percent.
Can you tell me what is wrong with this? and for this problem I have been restricted to using only threads.
check below:
public static int getPercentageLeft(Date start, Date end) {
long now = System.currentTimeMillis();
long s = start.getTime();
long e = end.getTime();
if (s >= e || now >= e) {
return 0;
}
if (now <= s) {
return 100;
}
return (int) ((e - now) * 100 / (e - s));
}
You need to subtract the starting time like this
currPerc = ((currentMilisecs - startMilisecs) * 100) / diffMillisecs;
to get the correct percentage.
The problem is with the System.currentTimeMillis();. Taken from the javadoc:
public static long currentTimeMillis()
Returns the current time in milliseconds. Note that while the unit of
time of the return value is a millisecond, the granularity of the
value depends on the underlying operating system and may be larger.
For example, many operating systems measure time in units of tens of
milliseconds.
See the description of the class Date for a discussion of slight
discrepancies that may arise between "computer time" and coordinated
universal time (UTC).
Returns:
the difference, measured in milliseconds, between the current time and midnight, January 1, 1970 UTC.
So your current time in milliseconds is based on January 1, 1970 UTC, not on your start date.
You need to calculate current time by subtracting start time from the value that is given by System.currentTimeMillis();.
I am basically formulating your linked image here. Other alternative calculations can also be carried out.
I have the following code that normally would take some instances of time, convert them to milliseconds to make some fairly precise computations, and produce the equivalent day(s) between those times OR hour(s) between them as the case may be. I think the code best explains what I am trying to achieve. Following are some snippets...
private int hours = 0;
/* This is intended to get the days between 'startDate' and 'endDate'
* and ensure it is between zero & the specified 'range' of days, inclusive*/
public int getPeriodBtw(Date startDate, Date endDate, int range)
{
int daysBtw = 0;
Calendar constantDate = Calendar.getInstance();
constantDate.setTime(startDate);
Calendar currentDate = Calendar.getInstance();
currentDate.setTime(endDate);
long rangePeriod = Period.ConvertDaysToMillis(range);
long duration = (constantDate.getTimeInMillis() + rangePeriod) - currentDate.getTimeInMillis();
daysBtw = (int)Period.ConvertMillisToDays(duration);
if(duration >= 0 && duration <= rangePeriod)
{
if(daysBtw == 0){
hours = (int)Period.ConvertMillisToHours(duration);
}
}
return daysBtw;
}
Now, the logic above seems all knit tight and good to me, but surprisingly, I get odd results as currentDate changes. I mean, normally I would expect something like this... See the following Illustration;
If constantDate = 10:00am
If range = 1 day starting from constantDate
and lets say currentDate = 2:00pm on the same day (i.e within range),
then daysBtw should return = 0
hours between constantDate and currentDate is 4hrs
Now this means currentDate is 4hrs Less range,
Thus duration should be 1day(24hrs) - 4hrs = 20hrs
Of course I think handling this in Millisecond offset from epoch wld be something like so;
10:00am(millis) + 1day(millis) - 2:00pm(millis) = 20hrs
long duration = (constantDate.getTimeInMillis() + rangePeriod) - currentDate.getTimeInMillis();
hours = (int)Period.ConvertMillisToHours(duration);
so hours should return = 20
Now, if currentDate changes to 3:00pm, following the same logic previously described, shouldn't hours = 19???... Problem is, my program gets hours = 21 instead.
I've been really confused as to what I might be doing wrong. Is the problem with my Logic???... Or is it somewhere in my Code???... I feel terribly bad admitting that I've spent a few hours on and off this thing that I know is rather simple, But time is not my friend as usual, and I have to move on to things less trivial. Any form of help would be highly appreciated. Thanks Y'all!
Okay... I did find a solution to this issue earlier on... Turned out it was due to;
1. some bad logic on my side, and also
2. some loss of precision when using java.util.concurrent.TimeUnit to convet Milliseconds to Days
TimeUnit.DAYS.convert(args, TimeUnit.MILLISECONDS);
It still beats me why they had to make the convert method recieve its milliseconds argument as long and return days as long too, without creating an option to set the preferred RoundingMode.... Anyways, its been added to my short list of ( STAY-AWAY-FROM-IT ) API's. Lolz!