I need to write a function that takes two timestamps and segment the time range in Days, Hours and Seconds in that order. To walk through an example, lets say the input to our function is
val start = 08-01-14 12:30:00
val end = 08-04-14 12:30:00
our function will return
min -> (08-01-14 12:30:00, 08-01-14 13:00:00)
hour -> (08-01-14 13:00:00, 08-01-14 24:00:00)
day -> (08-02-14 00:00:00, 08-03-14 24:00:00)
hour -> (08-04-14 00:00:00, 08-04-14 12:00:00)
min -> (08-04-14 12:00:00, 08-04-14 12:30:00)
I have hand rolled an implementation that works but its a little kludgy, I am looking for a) is there a library that already does that? b) if not, what would be the best way to implement this?
I believe Jodatime does support calculating time periods/ranges; http://joda-time.sourceforge.net/apidocs/org/joda/time/Period.html
I have done this before with Jodatime , it's a little bit technical, but as Jodatime is an AWESOME API for everything time-ish in Java all devs should use it - There was rumours of Jodatime replacing Javas old time-apis...
Introduction: http://www.joda.org/joda-time/
EDIT:
Here's what you're looking for: http://joda-time.sourceforge.net/apidocs/org/joda/time/Interval.html
IF you are using Jodatime interval can calculate the range/interval/period between two time-objects
Related
I was working with a school question to figure out the algorithm to find the days between two given dates which would then be implemented in Java.
The algorithm of interest was found here:
http://www.sunshine2k.de/articles/coding/datediffindays/calcdiffofdatesindates.html
(Point 4)
It was one of the more efficient algorithms because it would have the least conditions to consider during the implementation. I understand how it works in this context, but I couldn't quite wrap my mind around the use of an origin/reference point anywhere else because it seems that a simple subtraction would get most jobs done.
Eg. To find the difference between 9 and 5,
I could just do 9-5 instead of
ref = 1
difference = (9-ref) - (5-ref)
Question: Why does using this reference/origin point work in this situation? What other situations can I consider using this reference/origin point to solve problems?
First rule of Software Engineering is "Don't reinvent the wheel".
Getting the days between two dates in Java 8 and later is trivial, there's no need to code your own algorithm:
LocalDate d2 = LocalDate.now();
LocalDate d1 = LocalDate.of(1950, Month.JANUARY, 1);
long days = d1.until(d2,ChronoUnit.DAYS);
Or even better
long days = ChronoUnit.DAYS.between(d1, d2);
To get difference between 9-th and 5-th day of the same month, you can just subtract 9-5 (if there was no calendar revolution in that period :)). But for different months and different years you must account for varying number of days in the month and varying number of days in the year.
The simplest way to account for these factors is to get absolute number of days from some origin day - so-named Julian day with our era beginning as origin
Actually, 9-5 uses a reference of 0 in the same way as (9-0) - (5-0).
Unlike numbers, where 0 is the reference point, for dates, the reference point is not obvious. Should it be 0 AD, 1900 AD, or something else? With the different number of days in months, leap years etc, the day scale is not uniform. So, it is useful to find the "distance" of a date from a common date, for e.g. 1970-01-01.
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).
So I'm using JodaTime in an app I've got and I need a way to tell if the current time is within 6 hours of midnight. Well actually I need to know if the time is within 8 hours of 2am, but JodaTime seems to provide a constant for midnight so I was looking at that. Anyway, I've tried a number of different things but nothing quite works. Any help or pointers would be appreciated.
This can be accomplished simply by using JodaTime without any math involved.
DateTime time = new DateTime(DateTimeZone.UTC);
Period period = new Period(time, time.plusDays(1).toDateMidnight());
System.out.println(period.getHours());
The time.plusDays(1).toDateMidnight() (yes, I was lazy), is so that I'm comparing with the next midnight, and not with today's midnight (which already passed).
If you want to check both before and after, just check both periods.
I would suggest using a DateTime object.
DateTime date = new DateTime();
int i = getSecondOfDay();
Then using a little math we can find the number of seconds 6pm would be.
18hours*60min*60seconds= 64800 seconds.
if ( i > 64800 ){
// Do what you need here
}
I assumed you needed to tell if it was 8 hours of am of this current day and not a specific day.
This is a bit hardcoded and pcalcao's answer is probably more flexible:
private static boolean isLessThan8HoursFrom2AM(DateTime date) {
return (date.getHourOfDay() >= 18 || date.getHourOfDay() < 10);
}
You can also check if the time of day is 6 hours from midday.
if(Math.abs(timeOfDay - 43200) >= 21600) // first or last 6 hours of day.
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 :)
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.