Check if current date date is within current month - java

I'm aware there are several similiar questions. But mine is different in two points
Usage of java.util.* classes only (our server currently operates only with those)
I need to determine whether given date is after the specified date OR represents same day (typically today)
This is what I got:
if ((new Date().getMonth() == object.getDate().getMonth() && new Date().getYear() == object.getDate().getYear()
&& new Date().getDay() == object.getDate().getDay())
|| (new Date().after(object.getDate()) && new Date().getMonth() == object.getDate().getMonth()
&& new Date().getYear() == object.getDate().getYear()))
This thing works, but let's be honest - doesn't look really elegant. Is there way to do this in prettier way?

if you want to use your solution, it's anyway worth optimizing it. For example, create new Date() only once. Also to make it more readable and shorter, extract object.getDate() as a variable above all these comparisons. One more way to solve your problem can be:
public static void main(String[] args) {
Calendar min = getMinDateOfMonth();
Calendar max = getMinDateOfMonth();
max.set(Calendar.MONTH, min.get(Calendar.MONTH) + 1);
if (min.getTime().before(object.getDate()) && max.getTime().after(object.getDate())) {
// you're inside the month
}
}
private static Calendar getMinDateOfMonth() {
Calendar min = Calendar.getInstance();
min.set(Calendar.DAY_OF_MONTH, 1);
min.set(Calendar.HOUR, 0);
min.set(Calendar.MINUTE, 0);
min.set(Calendar.SECOND, 0);
min.set(Calendar.MILLISECOND, 0);
return min;
}

Related

Java 8 Time API / Is current time in time frame [duplicate]

Please suggest if there is an API support to determine if my time is between 2 LocalTime instances, or suggest a different approach.
I have this entity:
class Place {
LocalTime startDay;
LocalTime endDay;
}
which stores the working day start and end time, i.e. from '9:00' till '17:00', or a nightclub from '22:00' till "5:00".
I need to implement a Place.isOpen() method that determines if the place is open at a given time.
A simple isBefore/isAfter does not work here, because we also need to determine if the end time is on the next day.
Of course, we can compare the start and end times and make a decision, but I want something without additional logic, just a simple between() call. If LocalTime is not sufficient for this purpose, please suggest other.
If I understand correctly, you need to make two cases depending on whether the closing time is on the same day as the opening time (9-17) or on the next day (22-5).
It could simply be:
public static boolean isOpen(LocalTime start, LocalTime end, LocalTime time) {
if (start.isAfter(end)) {
return !time.isBefore(start) || !time.isAfter(end);
} else {
return !time.isBefore(start) && !time.isAfter(end);
}
}
This looks cleaner for me:
if (start.isBefore(end)) {
return start.isBefore(date.toLocalTime()) && end.isAfter(date.toLocalTime());
} else {
return date.toLocalTime().isAfter(start) || date.toLocalTime().isBefore(end);
}
I have refactored #assylias answer so i use int instead of local time as i get open and close hour from api int integer format
public static boolean isOpen(int start, int end, int time) {
if (start>end) {
return time>(start) || time<(end);
} else {
return time>(start) && time<(end);
}
}
public static boolean isOpen(int start, int end) {
SimpleDateFormat sdf = new SimpleDateFormat("HH");
Date resultdate = new Date();
String hour = sdf.format(resultdate);
int time = Integer.valueOf(hour);
if (start>end) {
return time>(start) || time<(end);
} else {
return time>(start) && time<(end);
}
}

How to check if Current Hour falls between certain range

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.
:-)

Get difference between two dates in years - without months - without days

I am using the following function in Joda-Time to get difference between two dates:
public static int getDiffYear(Date first) {
int yearsBetween = Years.yearsBetween(new DateTime(first), new DateTime()).getYears();
return yearsBetween;
}
The date supplied to function is: 0001-10-02 (YYYY-MM_DD)
I get the difference as 2013 as checked against today, however I find the correct result should be 2012. Because the day still is 01.
I have a separate function in pure Java, with the desired result:
public static int getDiffYear(Date first) {
Calendar a = Calendar.getInstance();
a.setTime(first);
Calendar b = Calendar.getInstance();
int diff = b.get(Calendar.YEAR) - a.get(Calendar.YEAR);
if (a.get(Calendar.MONTH) > b.get(Calendar.MONTH) ||
(a.get(Calendar.MONTH) == b.get(Calendar.MONTH) && a.get(Calendar.DATE) > b.get(Calendar.DATE))) {
diff--;
}
return diff;
}
Joda will take days into account with yearsBetween. Try this:
public static int getDiffYear() {
LocalDate firstDate = new LocalDate(1, 10, 2);
LocalDate today = new LocalDate();
int yearsBetween = Years.yearsBetween(firstDate, today).getYears();
return yearsBetween;
}
It will return 2012 as of today (2014/10/01). This indicates something is happening in the conversion from java.util.Date.
EDIT: This is due to what Marko Topolnik mentioned. When you do new DateTime(first) you are getting a DateTime of 0001-09-30.
The Years utility class is going to only check the difference in years. If you need to keep the days into account, you should use the Days class and recalculate the result to years.

get count back of DateTime that where within the correct range - Joda Time

I want to get the count back of DateTime that where within the correct range with Joda Time.
I have this version at the moment which is only good to check for a specific day:
public int getIntFatalitiesAtDay(DateTime AtDay) {
int resultCount = 0;
for( Fatality f : fatalities) {
if(Days.daysBetween(f.date, AtDay).getDays() == 0) {
resultCount++;
}
}
return resultCount;
}
This was usefull when i looped threw every day. However now i go by months with:
for (DateTime iDate = fa.firstDate; iDate.isBefore(fa.lastDate); iDate = iDate.plusMonths(1)) { ... }
And now i would like to get the count of fatalities that month.
Could someone help?
(Also from that year, althought i would like to see a option aswell where it doesn't look at the year but that's less important.)
Java's java.util.Date class has methods for determining if one date is before or after another. If you convert the DateTime objects to Date objects, you can do:
if (f.date.after(beginngingDate) && f.date.before(endingDate)).

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