Java - Store amount of time (not interval) - java

I work with an spring4 webapp that needs the logic of storing and calculating an amount of time(hours and minutes), but it isn't an interval since the amount is inserted by user or retrieved by third part app with the HH:MM format.
By now it's done with Float values which I want to change because in float the minutes are in 100 base, and not in 60 base as it's correct.
I've tried the java.time.LocalTime but it doesn't work since it's not acceptable more than 24 hrs.
I think there may be a cleaner way to deal with it.
Thanks in advance
-----EDIT
This webapp calculate overtime work. The user inputs the amount of hours the employee have worked off contractual time.
At the moment it is mapped as a float field, which is converted an calculated as below:
float hours = //Conversion of the HH:MM string input to HH.MM float within the framework
valueToPay = hours * employee.getHourSalary();
This way isn't right because the minutes are not being calculated correctly. I could convert the entire time to amount of minutes, but I'm searching for a cleaner way, since the java.time API offers a lot.

LocalTime is for time of the day.
If you need a ducation, you have java.time.Duration. For example, a duration of 30 hours (which would not fit in a LocalTime):
Duration thirtyHours = Duration.ofHours(30);

use org.joda.time.Duration
from javadoc:
An immutable duration specifying a length of time in milliseconds.
A duration is defined by a fixed number of milliseconds. There is no concept of fields, such as days or seconds, as these fields can vary in length. A duration may be converted to a Period to obtain field values. This conversion will typically cause a loss of precision however.
Duration is thread-safe and immutable.

Related

java.time: the simplest way to get a difference in hours between two LocalTime objects

I want to get a difference in hours between a current time in a specific timezone and UTC time. I tried this:
LocalTime time = LocalTime.now();
System.out.println(time); //21:05:42:764
LocalTime utcTime = LocalTime.now(ZoneId.of("UTC"));
System.out.println(utcTime); //18:05:42:769
System.out.println(Duration.between(utcTime, time).getSeconds()/3600); //2
System.out.println(Duration.between(time, utcTime).getSeconds()/3600); //-3
Why is the difference between the last two results and are there better ways to do it? I need to get the number 3.
Why is the difference between the last two results
The reason that you're getting different results for the two computed durations is a combination of the fact that there is some tiny amount of time elapsed between the two recordings and the fact that the duration start time is included in the range but the duration end time is not.
Consider these times instead: 6:00:00:001 vs 8:00:00:000. Here it is very obvious that we're only exactly one millisecond off of two hours, but when we think about seconds we're either going to get 7199 or -7200. When we then do integer math (i.e. divide by 3600), we're going to get 1 or -2.
If it weren't for the one extra millisecond on the first timestamp, the absolute value of the two would be identical.
Duration is the wrong class. There is zero duration between "now" in one time zone and "now" in another. For a fun but memorable way to think about this, see here.
You appear to be seeking to know the current offset from UTC for a given time zone. You can use the ZonedDateTime class for that:
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Asia/Kolkata"));
ZoneOffset offset = zdt.getOffset();
int offsetMinutes = offset.getTotalSeconds() / 60;
double offsetHours = ((double) offsetMinutes) / 60;
System.out.println(offsetHours); // 5.5
You could also just use ZonedDateTime.now() on the first line, if you want to use the computer's current time zone.
With regard to LocalTime - that is just the time portion (hours, minutes, seconds, and smaller). Since there is no date associated, you can't necessarily determine which time zone offset it belongs to. There is more than one date that "today" going on at any given moment. Time zone offsets range from UTC-12 to UTC+14, so there are indeed values where the same time of day is happening on two different dates somewhere on the planet.
As an example, 08:00:00 in Hawaii (Pacific/Honolulu) on 2019-01-01 is also 08:00:00 in Kiribati (Pacific/Kiritimati), but on 2019-01-02 - the following date! (Reference here.) Thus, if you had a LocalTime object with 08:00:00 and it was 08:00:00 in one of those two zones, you'd not be able to tell which one it was, or what the corresponding UTC offset should be.
Also, keep in mind that time zone offsets are not limited to whole hours. There are present-day time zones with half-hour and 45-minute offset. Historically, there have been others.
Lastly, keep in mind that an offset is not necessarily enough to identify a time zone. Many time zones share offsets at some points in time, but differ in others. See "Time Zone != Offset" in the timezone tag wiki.
Oh, and about your results getting 2 in one direction and -3 in the other - this is a rounding error due to your integer division. If you print out the seconds value, you'll notice they are one second apart (10799, vs -10800). Dig closer and you'll find that "now" included fractional seconds that were truncated with the getSeconds call. (You called .now() twice, so they were at slightly different times.)

subtracting time in Java

Hello I am trying to create a teacher utility to port over to android OS. However I am running into a little trouble. I would like to create a class called Period. This class would contain the start and end time of that period. ie. Period one starts at 7:45 and ends at 8:45. I would also like to have a method for time left in period. for example it is now 8:10 and there are 35 minutes left. I am able to get the current time from System.currentTimeMillis(). However I am having trouble trying to figure out the best way to store the start and end time of the periods. i have taken a look at the Calendar class in Java and it seems like time is always tied to a date as well as a time. This does not seem to make seance for my application since the end time of the period happens on multiple days and not just on one particular date. Any help understanding this would be a great help. Thanks all
If your goal is to be able to compare the start and end time of the period with the current time, then you need a way to compute the date and time of the period's bounds for today.
So get a Calendar instance for today, set its time to 7:45, and compare the time of the calendar with the current time (same for the upper bound, of course).
To represent each bound, you could simply use an int for the hours and a second int for the minutes.
Check out the JodaTime library. The DateTime object has what you want.
Take a look at JodaTime.
Specifically, Period: http://joda-time.sourceforge.net/key_period.html
Calendar is a king of wrapper around the class Date which has mostly deprecated functions. I've heard that the JodoTime API is great for comparing two timestamps (http://joda-time.sourceforge.net/).
One way to store the start and end time for the periods would be to instantiate an ArrayList of dates so you can compare any given time to the lesson periods.
From what I can tell, you should store the time as a number of seconds (optionally milliseconds) from last midnight. Thus, your period one, 7.45, starts at 45*60 (45 minutes * 60 seconds per minute) + 7*60*60 (7 hours times minutes times seconds!) = 2 700 + 25 200 = 27 900.
Do the same calculation for your end date, and as long as they begin and end on the same day, you can easily subtract the difference and thus get the interval in between. If they do not happen on the same date, then Java's time and date classes are both excellent and a must. These classes essentially work the same algorithm, but do not count the seconds from "last midnight", instead they count the amount of milliseconds from the UNIX epoch time (1 January 1970).

How do I store time in a variable?

One of my classes Event will have an instance field which is called timeStamp. Now, I have another class which will set the timeStamp according to some other algorithm which is not really relevant here.
My question is what type should I store this timeStamp in? From what I've researched so far I have the impression that it should be calculated in milliseconds and thus store it in a double perhaps.
Basically the Clock class I have simulates time in the following format : hh:mm:ss. However, since it's a discrete event simulation that I'm developing it jumps from event to event, which it determines by timeStamp value i.e. each event object has a timeStamp value which is stored in a PrioityQueue. So I thought about storing the timeStamp in the same format as the Clock , which I guess would involve me creating a new class TimeStamp that then becomes the type of the timestamp. Or should I just make the clock simulate time in milliseconds?
What are your thoughts on this? I'm not sure on the most efficient/clean way to implement this.
When a date is stored as milliseconds since the epoch, you should use a long.
There's no need for a double, since you're not interested in fractions of a millisecond.
You can't use an int because the maximum int value is only large enough to represent approximately one month in millis.
You can get such a value like this:
long millisSinceEpoch = Calendar.getInstance().getTimeInMillis();
Store the milliseconds in a long.
You can use the DateTime class in Joda Time to perform all sorts of intricacies on the resulting number. This overload allows you to plug the milliseconds value directly into a DateTime object.

Difference between minutes

Say I have 2 strings in the following format:
"09/21 10:06AM"
"09/21 10:10AM"
How do I find the time difference between these strings, stored as an int? This has to be robust enough to handle situations like 10:59AM and 11:02AM (odd number of minutes in between), 11:59AM and 12:03PM (AM to PM switch) etc. No need to worry about seconds.
Thanks!
I would suggest:
Use Joda Time instead of the built-in API; it's much nicer.
Parse into LocalDateTime values
Find the difference between them with:
Minutes period = Minutes.minutesBetween(first, second);
int minutes = period.getMinutes();
DateFormat.Parse
Calculate difference between dates.
Parse the strings to Date objects and get the difference between them in milliseconds. Then convert those milliseconds to minutes (divide by 60000 and take the ceiling of the result).
If there is a switch to daylight savings the difference can be an hour more on one day than another.
It best to use a library which does this already. JodaTime is best, but SimpleDateFormat and Date will probably do what you need.
Convert the 2 Strings to Dates.
Subtract one from the other.
Multiply the result by 1440 (Number of minutes in a day).
Round the result to an Integer.
Let me know if it works :)

Compare hours and minutes

I am developing an app based on date and time in java. In this app, my user is allowed to record an video only once per hour. so for this I am storing the previous time has used my app.
So when the user starts my app for the next time, I am comparing the time and if the time interval is more than one hour I must allow my user to record, else I should not allow. How to compare hours and minutes efficiently in java?
Get the system time with
long time = System.currentTimeMillis();
and compare the new time with the old one. One hour means a difference of 1000 * 60 * 60 milliseconds
From #Dalino answer, you may use TimeUnit enum class for time conversions.
long now = System.currentTimeMillis();
long lastVisit = ...; // in milliseconds
if(TimeUnit.MILLISECONDS.toHours(now - lastVisit) > 0) {
// allow
}
Why not just store the time when they exit (or whatever) and then on start up, read the time, add an hour to it, and compare with the current time?
You don't need to compare the actual hours and minutes - just the duration of time between then and now.
Personally I'd suggest using Joda Time for all Java date/time work, but in this case you could just use Date, and add an hour's-worth of milliseconds. Note that you should definitely store a UTC date/time instead of a local one, as otherwise daylight saving changes etc will mess things up.
I would use Joda Period: have a look here

Categories