How to check if Current Hour falls between certain range - java

I am trying to check if Current Hour falls in between 7AM and 10AM
I am doing it this way
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
int hour = cal.get(Calendar.HOUR_OF_DAY);
if(hour >= 7 && hour <= 10)
{
}
Please tell me if this is a valid approach to follow

Yes that is a valid approach. You could also use the new Time API (needs Java 8)
import java.time.LocalTime;
...
int hour = LocalTime.now().getHour();
It's a bit shorter to get the hour. There is also an overloaded now(ZoneId zoneId) method.
Or make it a one liner with a temporal query (also needs Java 8):
Boolean isBetween7and10AM = LocalTime.now().query(date -> date.get(ChronoField.CLOCK_HOUR_OF_DAY) >=7 &&
date.get(ChronoField.CLOCK_HOUR_OF_DAY) < 10);

Yup. This looks fine. Remember that this Calendar field is dependent on the timezone.
BTW: Put the starting curly brace at the end of the previous line, since this is the common code formatting style.
:-)

Related

Time manipulation by -1 month +1 day is still 1 month difference from start

I would like to reach date that is -1month +1day, which should be 0month difference from start date.
Using joda-time 2.10:
int day = 29;
LocalDate date1 = new LocalDate(new GregorianCalendar(2019, Calendar.JUNE, day).getTime());
LocalDate date2 = date1.plusMonths(-1).plusDays(1);
Months.monthsBetween(date1,date2).getMonths(); // returns 0 <- it's OK
but the same code with input int day = 30; returns -1 which is bad.
That looks like an inconsequence in Joda library.
That's a case: shift by -1month change date by shift month number and keep day number no greater than in input, but month-difference between dates are depend on day of month.
Do you know any alternative and working solution?
I have found JSR-310 with ChronoUnit - that solves the problem, BUT it needs Java8. I would like to stay on Java7.

Formatting time in Android Application

I've created an Android grading app to use within my classes. All the database connections and grading logic has been laid out and functions precisely as it should.
However, I am having a problem incorporating the Java Calendar class. I need to be able to limit each class to submit their answers "only" during their class time. As you can see, I will need to incorporate a series of "if statements" in order to do this.
The problem is that I don't know how to get this time that I need to verify that my student's answer submissions are only handled during their class time.
This is what I've tried:
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR);
int minute = cal.get(Calendar.MINUTE);
As you can see, I am only able to get hours and minutes separate from each other. How do I get the real time? Just Hours and minutes not seconds.
In my code my set up should look like this:
int period = will be selected from a spinner object
if(period == 1 && (time>= 7:20 AM && time<= 9:00AM)) Then, go ahead and
submit your answers to online database.
if(period == 8 && (time>= 12:50PM && time<= 2:20PM)) Then, go ahead and
submit your answers to online database.
I don't know how to format this "time" object with the Calendar class.
Any help would be appreciated.
You can set hours and minutes to the calendar:
Calendar start = Calendar.getInstance();
start.set(Calendar.HOUR, 7);
start.set(Calendar.MINUTE, 20);
The same for the endDate:
Calendar end = Calendar.getInstance();
end.set(Calendar.HOUR, 9);
end.set(Calendar.MINUTE, 0);
To check that the current datetime is in the interval:
Calendar cal = Calendar.getInstance();//now
boolean isInInterval = cal.getTime().after(start.getTime()) && cal.getTime().before(end.getTime());

Getting range of months - Java

I want to implement a tab layout with a range of months. This range should contain the last and next 12 Months.
I know how to get the next 12 months but i stuck at how to get the last AND next 12 months. I could use the joda time library but i think this lib is too big for my small android application.
Can anybody help my by providing a small code snipped? Thanks!
You can simply use a Calendar class instance to do it, with Calendar#add(int field,
int amount) like:
//getting month names
DateFormatSymbols dfs = new DateFormatSymbols();
String[] months = dfs.getMonths();
//here is what you need
Calendar c = Calendar.getInstance();
System.out.println(c.getTime().toString());
c.add(Calendar.MONTH, -12);
for (int i = -12; i <=12; i++){
c.add(Calendar.MONTH, +1);
System.out.println(months[c.get(Calendar.MONTH)]);
}
DateFormatSymbols is here used, to get the names of the months only.
You can use the calendar class to get the current month. Then u can subtract 1 to get the value of last month or add 1 to get next month.
Here is an example snippet.
Calendar calendar = Calendar.getInstance();
int month = calendar.get(Calendar.MONTH);
calendar.set(Calendar.MONTH, month - 1);
int lastMonth = calendar.get(Calendar.MONTH);
U could write a loop to calculate last and next 12 months this way.
Cheers :)

Method executing differently when same arguments are passed

Same arguments passed on the same method for the same object. It usually will display true, which is what I expect. But... sometimes it displays false. About 2-3 out of 100 times. What is wrong with this method that would be causing this behavior?
year, month, and day are instance variables containing "2012", "4", "1" respectively.
public boolean isInDateRange(String startDate, String endDate)
{
if(startDate == null || endDate == null){
return false;
}
Calendar today = Calendar.getInstance();
today.set(Integer.valueOf(year), Integer.valueOf(month), Integer.valueOf(day));
Calendar start = Calendar.getInstance();
//subtract 1 from the month parameter because java.util.Calendar's months
//go from 0 to 11 instead of 1 to 12.
start.set(Integer.valueOf(startDate.substring(0, 4)), Integer.valueOf(startDate.substring(5, 7)) - 1, Integer.valueOf(startDate.substring(8, 10)));
Calendar end = Calendar.getInstance();
end.set(Integer.valueOf(endDate.substring(0, 4)), (Integer.valueOf(endDate.substring(5, 7))) -1 , Integer.valueOf(endDate.substring(8, 10)));
return today.compareTo(start) >= 0 && today.compareTo(end) <= 0;
}
And here is what I am passing to it
calendarDetails.getTuesday().isInDateRange("2012-05-01 00:00:00", "2012-05-01 00:00:00")
You're ignoring the time in your calculations. On the few occasions that the millisecond ticks over between Calendar today = ... and Calendar start = ..., you end up with today, start, and end having the same value for the date, but the time of both start and end is ahead of today. Specifically, they're 1 ms ahead since you're using Calendar.getInstance(), which returns the current time, to build all three of them. So when that tick happens, today isn't between start and end. You should zero out the time if you don't care about it.
Post more information to help you better like for which inputs it is giving wrong result.
your program is working fine.
I think One Date can not be both greater than and less than other date.
You are passing same date in both the arguments. (2012-05-01 00:00:00).
Moreover you can debug yourself ,print dates whenever you are not getting expected results.

CodeReview: java Dates diff (in day resolution)

Please your opinion on the following code.
I need to calculate the diff in days between 2 Date objects. It is assured that both Date objects are within the same TimeZone.
public class DateUtils {
public final static long DAY_TIME_IN_MILLIS = 24 * 60 * 60 * 1000;
/**
* Compare between 2 dates in day resolution.
*
* #return positive integer if date1 > date2, negative if date1 < date2. 0 if they are equal.
*/
public static int datesDiffInDays(final Date date1, final Date date2){
long date1DaysMS = date1.getTime() - (date1.getTime() % DAY_TIME_IN_MILLIS);
long date2DaysMS = date2.getTime() - (date2.getTime() % DAY_TIME_IN_MILLIS);
long timeInMillisDiff = (date1DaysMS - date2DaysMS);
int ret = (int) (timeInMillisDiff / DAY_TIME_IN_MILLIS);
return ret;
}
Can you point to a problem that I might have missed ?
EDIT: #mmyers asked if pass my unit test. Well - Yes. But I have no real experience with dates and I know that is a big subject. Posted below the unit test that I'm using.
public class TestMLDateUtils {
#Test
public final void testDatesDiffInDays() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
// 00:00:00.000 1.1.1970
Calendar cal1970 = Calendar.getInstance();
cal1970.setTimeInMillis(0);
Calendar tested = Calendar.getInstance();
tested.setTimeInMillis(0);
// Add 1 millisecond, date = 00:00:00.001 1.1.1970
tested.add(Calendar.MILLISECOND, 1);
assertTrue(DateUtils.datesDiffInDays(cal1970.getTime(), tested.getTime()) == 0);
// Add 1 second, date = 00:00:01.001 1.1.1970
tested.add(Calendar.SECOND, 1);
assertTrue(DateUtils.datesDiffInDays(cal1970.getTime(), tested.getTime()) == 0);
// Add 1 minute, date = 00:01:01.001 1.1.1970
tested.add(Calendar.MINUTE, 1);
assertTrue(DateUtils.datesDiffInDays(cal1970.getTime(), tested.getTime()) == 0);
// Add 1 hour, date = 01:01:01.001 1.1.1970
tested.add(Calendar.HOUR_OF_DAY, 1);
assertTrue(DateUtils.datesDiffInDays(cal1970.getTime(), tested.getTime()) == 0);
// date = 23:59:59.999 1.1.1970
tested.setTimeInMillis(0);
tested.add(Calendar.MILLISECOND, 999);
tested.add(Calendar.SECOND, 59);
tested.add(Calendar.MINUTE, 59);
tested.add(Calendar.HOUR_OF_DAY, 23);
//System.out.println("D: " + tested.getTime());
assertTrue(DateUtils.datesDiffInDays(cal1970.getTime(), tested.getTime()) == 0);
// date = 00:00:00.000 2.1.1970
tested.setTimeInMillis(0);
tested.add(Calendar.DAY_OF_MONTH, 1);
assertTrue(DateUtils.datesDiffInDays(cal1970.getTime(), tested.getTime()) == -1);
assertTrue(DateUtils.datesDiffInDays(tested.getTime(), cal1970.getTime()) == 1);
// date = 00:00:00.001 2.1.1970
tested.add(Calendar.MILLISECOND, 1);
assertTrue(DateUtils.datesDiffInDays(cal1970.getTime(), tested.getTime()) == -1);
assertTrue(DateUtils.datesDiffInDays(tested.getTime(), cal1970.getTime()) == 1);
// date = 00:00:01.001 2.1.1970
tested.add(Calendar.SECOND, 1);
assertTrue(DateUtils.datesDiffInDays(cal1970.getTime(), tested.getTime()) == -1);
assertTrue(DateUtils.datesDiffInDays(tested.getTime(), cal1970.getTime()) == 1);
// date = 00:01:01.001 2.1.1970
tested.add(Calendar.MINUTE, 1);
assertTrue(DateUtils.datesDiffInDays(cal1970.getTime(), tested.getTime()) == -1);
assertTrue(DateUtils.datesDiffInDays(tested.getTime(), cal1970.getTime()) == 1);
// date = 01:01:01.001 2.1.1970
tested.add(Calendar.HOUR_OF_DAY, 1);
assertTrue(DateUtils.datesDiffInDays(cal1970.getTime(), tested.getTime()) == -1);
assertTrue(DateUtils.datesDiffInDays(tested.getTime(), cal1970.getTime()) == 1);
// date = 13:01:01.001 2.1.1970
tested.add(Calendar.HOUR_OF_DAY, 12);
assertTrue(DateUtils.datesDiffInDays(cal1970.getTime(), tested.getTime()) == -1);
assertTrue(DateUtils.datesDiffInDays(tested.getTime(), cal1970.getTime()) == 1);
}
}
Immediate problem: days can have less than or more than 24 hours due to daylight saving time changes.
Secondary problem: normally when people think in days, they really mean "human days" rather than "periods of 24 hours". In other words, many people would say that 7pm-7am the next day is a difference of a day, whereas 7am-7pm the same day is a difference of zero days. Both are 12 hours. At that point, you really need to know the calendar that is being considered.
Of course, this may not matter for your situation, but we don't really know what that is.
Third problem: you're using the built-in calendar API instead of Joda Time. That's almost never a good idea - it's horrible and riddled with gotchas and problems. And yes, the regulars here will tell you that's always part of my answer when it comes to Java dates and times - and for good reason. It's really that important.
EDIT: Your test sets the default time zone to be UTC. That's not really a good idea (especially without resetting it in a finally statement). Time zones are tricky, but you should really think about what values you've got, what they mean, and what time zones are involved.
The time zone, if any, within the Date object is irrelevant, since you're using getTime(); that "[r]eturns the number of milliseconds since January 1, 1970, 00:00:00 GMT represented by this Date object."
However, you aren't accounting for leap seconds, which some implementations may return. Thus, if the day range you give has one or more leap seconds in it, and your times are near enough to the same time of day, your calculation may be wrong by a day. That said, there appears to be no way to see if any particular implementation accounts for leap seconds or not (I expect that most don't), and the difference is pretty darn trivial anyway.
There are many dimensions to a code review; rather than correctness, addressed by others, let me focus a little on style. This will of course be somewhat more subjective than a review concentrating on correctness.
I would inline the "ret" variable. It increases the size of the method without enhancing readability.
I would consider separating the conversion between milliseconds and days into a separate function. Your full class probably performs that division in multiple places. Even if not, it's helpful in that it's easier to name functions that do only one thing.
Speaking of naming, I would rename the function, perhaps to "dayDifference" - abbreviations cause many problems, not least of which is the difficulty of remember which abbreviation was used in which circumstance. If you use none, ever, that particular source of confusion is eliminated. Similarly, I would rename the constant to MILLISECONDS_PER_DAY.
Another problem which hasn't been mentioned yet is leap seconds. Days may have more or less than 24 * 60 * 60 seconds due to adjustments in UTC time to keep it more or less in synch with the mean solar year. Probably not a big deal for your usage, but you should at least be aware of the possibility.
A good API is what you need if you have non-trivial requirements for dealing with dates and times. The link to Joda Time in Jon Skeet's answer appears to be broken, so here is a link that does work.
Date already has this method, look up Date.compareTo(Date) in Javadoc.

Categories