Check date range in java without time AND using jodatime - java

I have a date supplied by the user and of course today's date.
I'm attempting to verify that the difference between the 2 days is at least 2 weeks. I've done this using standard libraries - but I'm attempting to do this using jodaTime and I'm having some difficulty.
// BAD CODE - doesn't work
// NOTE: getUserSuppliedDate() returns an instance of java.sql.Date
// Also assume that validation prior to this call has been run that
// validates that the userSuppliedDate comes AFTER today's date - not sure if
// that is relevant in the context I'm attempting to use these particular jodaTime APIs.
DateTime jodaStartDate = new DateTime(getUserSuppliedDate());
if (Days.daysBetween(jodaStartDate, DateTime.now()).isLessThan(Days.days(14))) {
System.out.println("Bad user. You have chosen...poorly.");
}
else {
System.out.println("Well done user. You have supplied wisely.");
}
// GOOD CODE ---- ? Help =)

Your code gives you the wrong result because the dates supplied to Days.daysBetween() are in the wrong order. Since you specified that the user supplied date comes after the current date, your approach will result in a negative number of days.
It will work correctly if you switch the order, putting the earliest date first.
Compare the following two:
DateTime jodaStartDate = new DateTime().withYear(2018)
.withMonthOfYear(7)
.withDayOfMonth(5); // 15 days from now
System.out.println(Days.daysBetween(jodaStartDate, DateTime.now())); // "P-15D"
System.out.println(Days.daysBetween(DateTime.now(), jodaStartDate)); // "P15D"
In the first case, -15 days will evaluate to less than 14 days.
Using weeks instead of days, you'd run into the same problem:
System.out.println(Weeks.weeksBetween(jodaStartDate, DateTime.now())); // "P-2W"
System.out.println(Weeks.weeksBetween(DateTime.now(), jodaStartDate)); // "P2W"

Related

Java MOOC 92.3 ( I want to understand how to solve this question, not just be provided an answer)

This exercise is from Java MOOC 92.3
Simply, I have two dates.
And a method which gives me the difference of the two.
(for instance: 3/10/2011 and 3/9/2012)
My method states that as long as the month and the day are greater than the later, then simply subtract the one for which the method is called.
Here's the problem:
If a date given as a parameter has a greater year, then when I subtract the two I come out with a negative number (ex: 2011 - 2012).
public int differenceInYears(MyDate comparedDate){
int result = 0;
if(this.month >= comparedDate.month && this.day >= comparedDate.day){
result = this.year - comparedDate.year;
}else{
result = this.year - comparedDate.year;
result--;
}
return result;
The code beyond the else is for the case in which the year is not what it may look to be (Example: If I was born in May 2000 and I technically should be 20 since it is 2020, but since it is not May yet, I am therefore 19).
My conditions are still met within the first if statement, even though the result is not correct. I have tried finding a case where I can appease both cases where it does not matter what date goes first, but I am struggling with the logic. Would appreciate input.
First, if I understand correctly that this is an exercise, it’s a fine exercise. For production work one would never invent their own date class but would and should use LocalDate from the standard library for a date. And ChronoUnit.YEARS.between() for finding your age.
If you have not yet had your birthday this year, you want to subtract one year from the result. This is correct. So how do we determine whether this year’s birthday is in the future? Take a look at the following possibilities. I have not run your code, so have filled out the last column from what I think will happen from reading the code.
Today Birthday Subtract 1? Does your code subtract 1?
--------------------------------------------------------
Apr 3 Feb 1 No No
Apr 3 Feb 6 No Yes
Apr 3 Apr 1 No No
Apr 3 Apr 6 Yes Yes
Apr 3 May 1 Yes Yes
Apr 3 May 6 Yes Yes
Another way to put the question: if the months are different, do we need to compare the day of month too?
I like your attitude. In accordance with your title I am not giving away the correctly working code. I too am convinced that you will not only learn more from writing it yourself, it will also give you greater pleasure. If you’re still stuck, please leave a comment and I’ll take one more look.
EDIT: For the problem of getting a negative result if the dates are in the opposite order: The simplest solution is to check the result after you’ve calculated. If it is negative, redo the entire calculation with the dates reversed. That is, with this. and comparedDate. in each other’s places. One elegent option is that in this case you tell the other MyDate object to do the calculation instead. Call the differenceInYears method of the other object passing this as argument.

String Matching is not happening between two time In JSP

Initial time=22:00:00,final time=23:59:59.
If the current time is, let's say 23:00:00 then I will get the success message otherwise error message will be shown. And I am comparing this time with the system time.
My code:
//retrieving the system time in string format
SimpleDateFormat sdfDate = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
String s=sdfDate.format(date);
//Initial and final predefined time
String ten ="22:00:00";
String twelve ="23:59:59";
//comparing with the system time
try{
if(s.compareTo("twelve")<0 && s.compareTo("ten")>0 ){
out.print("success");
}else{
out.print("failed");
}
}catch(Exception l){
System.out.println(l.toString());
}
I tried to check it when the system time was 23:45:00. I also confirmed the time by printing out.print(""+s);. But I got the failed message. I don't know my loop is working or not.
What can I do to fix this?
If you're comparing hours, don't use strings, use a proper type.
In Java you have:
Java >= 8: java.time.LocalTime
Java <= 7: org.threeten.bp.LocalTime (from external lib: http://www.threeten.org/threetenbp/)
In both you can do:
LocalTime ten = LocalTime.parse("22:00:00");
LocalTime twelve = LocalTime.parse("23:59:59");
// current time
LocalTime now = LocalTime.now();
// compare
if (now.isBefore(twelve) && now.isAfter(ten)) {
// succcess
}
To get the current time, you could also use the now method with a timezone (example: LocalTime.now(ZoneId.of("America/New_York"))), if you need the time at some specific place (now() without arguments will use the JVM default timezone).
Transforming the strings to a type that represents the data you're working with is much more reliable. Also note that this API makes the code much easier and more readable, with meaningful methods names such as isAfter and isBefore.
Comparing strings might work, but using the proper types works even better.
Try this:
if(s.compareTo(twelve) < 0 && s.compareTo(ten) > 0)
By putting quotes around twelve and ten, you're comparing to the strings "twelve" and "ten", and not referencing the variables twelve and ten that you defined ealier in the program.

Simple factory - checking data correctness

I have Month class which contains some data eg. number, number of days etc. I would like to create this class instance simply. I decided to create simple factory which contains months data and returns ready object. My question is where to check data correctness eg. January has 31 days and a couple others... Should Month class checks that data is correct or Factory should be responsible for it? (in this case we can create Month object with invalid data)...
Please don't reinvent calendar classes! Someone has already done it for you. Take a look at Joda-Time or the Java 8 package java.time. This are good starting points to learn how classes like Month should be designed.
The concepts of month and day of month shouldn't be mixed within a single class. Because how many days a month has depends on the year and the calendar system. The validation for invalid number of days should be done when you create a date from day of month, month and year. So it is part of the construction process of a date object.
This looks strange:
Month january = Month.newMonth(31);
The factory method which creates a Month object from an int should check if the parameter is in the range from 1 (January) to 12 (December) and return an enum representing the concrete month.
This is what I would expect:
Month january = Month.newMonth(1);
Your Month class should check this itself. It's always best practice to have the logic that is dependent only on the class in the class itself. Otherwise if someone else uses your application and instantiates a Month object without using the factory it will work, but it won't be what you as the designer intended.
You can handle an error however you like it, but I would do it in the constructor and then throw an error if someone tries instantiating it with invalid parameters.
You should validate the parameters before passing them in a constructor.
However a static factory method might not be the best place to validate input, if the input is dynamic and NOT done by you.
If you just want to make sure the compiler warns you if you use invalid parameters, you could throw a checked exception like this:
public static final Month newMonth(int numberOfDays) {
if(numberOfDays > 31 || numberOfDays < 28) {
throw new IllegalArgumentException("invalid numberOfDays");
}
return new Month(numberOfDays);
}
Either way, in my opinion, you should not go the try...catch way or make the constructor validate anything as it makes your code a lot less readable and also could break a lot of other code if you change your validation method.

Java: addToDay function

I'm trying to setup my addToDay function. I'm currently stuck on how to proceed with this or even write it correctly. The function itself will take a variable that ranges from -100 to 100. So you would basically add that variable to the current and if it was below the 0 then subtract a month or if it was above the months max day then add a month. Which i have that function setup so all i would have to do is call addToMonth with the correct amount. My problem lies within the amount of days each month has. For example, October has 31 days while November has 30. I have a function that will return the number of days in the current set month so i can call that to get how many max days should be in the current month. I'm thinking maybe a while loop would work but i just wanted to get anyone's thoughts on the best way to set it up.
I have 3 private ints: month, day, year. These are what need to be changed. I have both addTo functions for month and year setup already.
Here are some other functions i have created that can be used in this:
1. addToMonth(int delta) - changes the current month depending on the given parameter
2. getDaysInMonth() - will return the days in a month depending on the month itself
3. validateDay() - Will return true or false if the days fall outside the wanted requirements.
I don't want to use the calendar utility
I also don't want to use any other utilities. Just the base code with Junit for testing
Joda's plusDays() function and Java 8 LocalDate already has the logic that you are trying to achieve
Alright so i ended up just copying my original addToMonth function and modifying it abit to fit with days. So far it works but i do think it'll fail in the cases of different amounth of days not lining up.

Compare two times in Android

I know this is a quite discussed topic but I think I have a very specific problem.
I'm storing opening and closing time of stores on a database as well as GPS coordinates. I'd like to be able to show the stores on a map with a green marker if the store is open and red if close (wrt current time).
My problem is that I'm using the method string.compareTo(string) to know if the store is closed or open. Let's say we are on monday, the store close at 02:00 in the morning (tuesday morning), current time is 23:00. How can I tell the store is still open since 02:00 < 23:00 ?
Thank you for any answer,
Arnaud
edit: I'm editing my answer to give a better idea of what I meant. Also, try to back up a second and re-think the way you store your data structure. This is a very important part of programming and in most cases can be the difference between a bad design and a good design implementation.
Storing the time as a string is not a good idea, but in your case what you should do (I think) is this: (This code assumes that the hours for the store opening and closing time refer to the same day as now)
// Get the current time.
Calendar now = Calendar.getInstance();
// Create the opening time.
Calendar openingTime = Calendar.getInstance();
// Set the opening hours. (IMPORTANT: It will be very useful to know the day also).
openingTime.set(Calendar.HOUR_OF_DAY, storeOpeningTime); // (storeOpeningTime is in 24-hours format so for 10PM use 22).
// Check that the store "was opened" today.
if (now.before(openingTime)) {
return CLOSED;
}
// If the store "was opened" today check that it's not closed already ("tricky" part).
// Create the closing time and closing time for the store.
Calendar closingTime = Calendar.getInstance();
// Check if we are in the AM part.
if (storeClosingTime < 12 // Closing time is in the AM part.
&& storeClosingTime < openingTime // Closing time is before opening time, meaning next day.
// now and closingTime is the same day (edge case for if we passed midnight when getting closingTime)
&& closingTime.get(Calendar.DAY_OF_WEEK) == now.get(Calendar.DAY_OF_WEEK)) {
// Closing time is next day.
closingTime.add(Calendar.DAY_OF_WEEK, 1);
}
// Set the closing hours.
closingTime.set(Calendar.HOUR_OF_DAY, storeClosingTime); // (storeClosingTime is in 24-hours format so for 10PM use 22).
// Check if the store is not closed yet.
if (now.before(closingTime)) {
return OPEN;
}
// Store is closed.
return CLOSED;
I haven't tested this, but I think according to your questions and how to save the opening and closing times, this should work.
Important: There are more edge cases and tweaks you can make to the code to improve it, but I don't have enough time to do it now. I wanted to give a general guiding hand to solve your problem. Handling time and dates is never fun, you need to keep in mind a lot of elements like time zones and clock shifting in winter and summer in different countries. This is not a finished implementation in any way, and getting it to a finished state is not simple.

Categories

Resources