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
Related
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.
I wanted to implement this algorithm but I am struggling with writing the function that calculates the unix time for UTC time (not local time). For example,
Instant.now().getEpochSecond();
returns unix time according to my local time. But how can I make it work for UTC time? Thank you.
So to be able to get the epoch time in java you would have to use System.currentTimeMillis()
And then dividing this number by 1000 will result in the Unix epoch. A call like this would suffice.
long unixTime = System.currentTimeMillis() / 1000L;
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).
I'm trying to get the total amount of Milliseconds (not the millis field) from the Period object instance. I've tried multiple conversions, as I couldn't find any method easily giving it.
Has anyone ever needed that and managed to retrieve it ?
(I need this for my patch, to figure out a negative period; negative millis = negative period.)
You can't get the millis directly from a Period, since fields like months and years are variable in terms of milliseconds.
In order to make this work, you need to supply a "baseline" instant from which Period can calculate that actual millisecond duration.
For example, the Period.toDurationFrom and Period.toDurationTo methods take such a baseline instant, and calculate a Duration object, which you can then obtain the millis.
The Javadoc for toDurationFrom says:
Gets the total millisecond duration of this period relative to a start instant.
This method adds the period to the specified instant in order to calculate the duration.
An instant must be supplied as the duration of a period varies. For example, a period of 1 month could vary between the equivalent of 28 and 31 days in milliseconds due to different length months. Similarly, a day can vary at Daylight Savings cutover, typically between 23 and 25 hours.
So you need to pick an appropriate baseline instant for your application.
If you want to get the millis from a specific time it can be done by using the plus() or minus() methods of the DateTime class.
e.g. getting the millis from now
DateTime start = new DateTime(); //NOW
DateTime end = start.plus(<your period>);
long millis = end.getMillis() - start.getMillis();
Using Joda time 2.3, it is:
toStandardDuration().getMillis()
Given a any unix timestamp (i.e. 1306396801) which translates to 26.05.2011 08:00:01, how can I determine if this is within a given timeframe (i.e. 08:00:00 and 16:00:00)?
This needs to work for any day. I just want to know if this timestamp is within the given time-interval, on any future (or past) day, the date is unimportant. I don't care if it is on the 25th or 26th, as long as it is between 08:00 and 16:00.
I am on the lookout for a java solution, but any pseudo code that works will be ok, I'll just convert it.
My attempts so far has been converting it to a java Calendar, and reading out the hour/min/sec values and comparing those, but that just opened up a big can of worms. If the time interval I want it between is 16.30, I can't just check for tsHour > frameStartHour && tsMin > frameStartMin as this will discard any timestamps that got a minute part > 30.
Thank you for looking at this :)
To clarify.
I am only using and referring to UTC time, my timestamp is in UTC, and the range I want it within is in UTC.
I think I understand what you want. You want to test for any day, if it's between 8am and 4pm UTC. Take the timestamp mod 24*3600. This will give you the number of seconds elapsed in the day. Then you just compare that it's between 8*3600 and 16*3600. If you need to deal with timezones, things get more complicated.
Given your timestamp (in seconds) and the desired time zone, Jodatime gives you the hour which leads you to a simple integer range check.
new org.joda.time.DateTime(timestamp*1000L, zone).getHourOfDay()
With java.util.* its more difficult.
If I understood you correctly, you only need to normalize your dates to some common value. Create three instances of Calendar - one with your time, but day, month, and year set to zero, and two with start and end of your timeframe, other fields also zeroed. Then you can use Calendar.after() and Calendar.before() to see if the date is within the range.
Your unix timestamp is an absolute time. Your time frame is relative. You need some kind of time zone information in order to solve this problem. I just answered some of this for PostgreSQL a few minutes ago. Hopefully that article is of use.
Convert the beginning of your range to a unix timestamp, and the end of your range to a unix tmestamp, then it's a simple integer check.