I try to calculate a List with times. But using LocalTime from Joda Time I can only get a 24 hours.
What is the right class to use to get e.g. 34hours 20minutes 14 seconds?
Thanks in advance
You may be look for Period:
A period in Joda-Time represents a period of time defined in terms of fields, for example, 3 years 5 months 2 days and 7 hours. This differs from a duration in that it is inexact in terms of milliseconds. A period can only be resolved to an exact number of milliseconds by specifying the instant (including chronology and time zone) it is relative to.
If you are looking to add times, so you can tell how many hours/seconds... are in between, you would maybe be better off if you use plain miliseconds calculations, add all the miliseconds and then subsrtact the miliseconds from your first time, and there you are, you have the span in miliseconds...
Related
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 set my Period object using the "millis" constructor and have all the relevant fields be updated accordingly (years, months, weeks, days, hours, minutes, seconds)
That is, using the following code:
mPeriod = new Period(millis, PeriodType.standard());
doesn't fill all the relevant fields accordingly.
only weeks and minutes (for input millis of 1325965615539)
can someone please help me figure this thing out ?
You can normalize it using Period#normalizedStandard();
However, there's no way Period can "fill in all the relevant fields", because it can't make assumptions about the number of days in months or years. The best it can do is to turn it into weeks, days, and time fields.
The Javadoc touches on this, but not in great detail:
If the period contains years or months, then the months will be
normalized to be between 0 and 11. The days field and below will be
normalized as necessary, however this will not overflow into the
months field. Thus a period of 1 year 15 months will normalize to 2
years 3 months. But a period of 1 month 40 days will remain as 1 month
40 days.
(Emphasis mine)
If you need it to normalize into years and months, you need to construct the Period with values in those fields.
Alternatively, you could use a Duration:
Construct a Duration with milliseconds
Use Duration#toPeriodFrom(ReadableInstant) to create a Period starting at a given instant in time (e.g. new DateTime()). According to the docs, this should work:
This conversion will determine the fields of a period accurately. The
results are based on the instant millis, the chronology of the
instant, the standard period type and the length of this duration.
Here's what normalize() should do to your millisecond input:
import org.joda.time.Period;
class Normalize {
public static void main(String[] args) {
Period period = new Period(1325965615539L);
System.out.println(period);
System.out.println(period.normalizedStandard());
}
}
// outputs
PT368323H46M55.539S
P2192W2DT19H46M55.539S
Notice the second line has been normalized, but only up to weeks.
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 :)
Why does Joda Time allow a Period constructor to take two LocalTimes but there is no Duration constructor like that?
I want to know because it may aid in my understanding of the best use of Joda Time.
Here's my thinking: Duration is good for social convention unaware applications and the lack of awareness is what makes it different from Period. LocalTime is good for convention unaware use because it has no timezone. This suggests Duration should be used with LocalTime and vice-versa.
A Duration is the amount of time between two precise Instants in time (which are completely independent of human concepts like years, days, and seconds). LocalTimes, however, represent ambiguous points in time (they require a date and time zone to define an Instant).
It makes sense to say there's a "standard duration" (the duration of the period assuming no DST, no leap years, no leap seconds (which Joda chronologies don't support, admittedly)) between two LocalTimes, but there's not enough information to compute a "true duration". I suspect this is why Duration doesn't have that constructor.
For example, let's suppose we have two LocalTimes: one representing 1:00 AM and 4:00 AM. 99% of the time, it'd make sense to say that's a duration of 3 hours. But, if they represent times on the day of a Daylight Saving Time switch, the duration would be 2 hours or 4 hours.
Period is defined more broadly, where it make senses to have a period between two partially-defined times like LocalTimes (just "3 hours" in the example). Periods correspond easily to standard durations, so one can just call period.toStandardDuration().
In Joda-Time 2, what is the difference between the three kinds of time spans:
Period
Interval
Duration
Why do we need three classes?
Which one performs better?
Why is dividing a Period or Duration or Interval instance not implemented? E.g. p = p.divideBy(2);
3 classes are needed because they represent different concepts so it is a matter of picking the appropriate one for the job rather than of relative performance. From the documentation with comments added by me in italics:
An interval in Joda-Time represents an interval of time from one millisecond instant to another instant. Both instants are fully specified instants in the datetime continuum, complete with time zone. Specific times are defined e.g. this might be the interval between 20:00:00GMT yesterday and 09:00:00GMT this morning.
A duration in Joda-Time represents a duration of time measured in milliseconds. The duration is often obtained from an interval. i.e. we can subtract start from end of an interval to derive a duration
A period in Joda-Time represents a period of time defined in terms of fields, for example, 3 years 5 months 2 days and 7 hours. This differs from a duration in that it is inexact in terms of milliseconds. A period can only be resolved to an exact number of milliseconds by specifying the instant (including chronology and time zone) it is relative to. e.g. consider the period of 1 year, if we add this to January 1st we will always arrive at the next January 1st but the duration will depend on whether the intervening year is a leap year or not. Similarly if we add 1 month to the 1st of a month then we will arrive at the 1st of the next month but the duration (in milliseconds) will vary based on the month in question
For question 3, A specific method to divide a duration is not really needed because we can always get the number of milliseconds from the duration as a long (using getMillis()), divide it and construct a new duration (using new Duration(long duration)).
Dividing a period doesn't really have a real meaning based on the definition of a period above. e.g. what is half a month? (its length would depend on which month).
To add to mikej's answer:
A Joda-Time duration is a "physical" time interval; eg:
12000 milliseconds <-- this is a duration
A Joda-Time interval is actually a pair of instants (start instant - end instant). An instant is, again, a "physical" concept, a point in the timeline. Eg (just a possible notation):
(2010/3/3 19:00:00.000 UTC ; 2010/3/3 20:00:00.000 UTC) <-- this is an interval
An interval, then, can be converted to a duration, but not the reverse.
Consider these two intervals:
I1=(2010/3/3 19:00:00.000 UTC ; 2010/3/3 20:00:00.000 UTC)
I2=(2010/3/3 21:00:00.000 UTC ; 2010/3/3 22:00:00.000 UTC)
As intervals, I1 and I2 are different, because the end-points are different; but if I convert them to durations, I get the same thing: 3600000 milliseconds.
(Math analogy: the intervals [10,12] and [95,97] are different intervals, but they have the same length: "interval length" maps to duration).
Finally, a period is a lapse of "civil time", expressed as a number of months, days, hours, etc. It does not -by itself- represent a "physical" interval, hence it can't be directly converted to a duration (months have variable lengths...).
This answers question 3: you can only divide by two a physical time (a duration).