For new and old readers to this question I strongly recommend that since Java 8 you use java.time, the modern Java date and time API, for your date work. The classes Date
, SimpleDateFormat
, GregorianCalendar
and Calendar
hat you were trying to use were troublesome and are fortunately long outdated. So nowadays avoid them.
So it’s about time this question gets answers that demonstrate the use of java.time. There is a good one by Basil Bourque. And here’s my shot.
I know that the moderators and some users don’t like reservations and disclaimers like this section and say I should instead ask questions in comments. I’m not sure it works with a 15 years old question that nevertheless still has readers. So I understand from your question that you want a method that does two things:
Date
.I assume:
2/29
since we don’t know whether it is in a leap year or not. You want to forbid February 30 and April 31.Using the comment by @Anonymous under the answer by Basil Bourque:
private static final DateTimeFormatter parser
= DateTimeFormatter.ofPattern("M/d", Locale.ROOT);
/** @throws DateTimeParseException If the string is not valid */
public static MonthDay parseMonthDay(String inString) {
return MonthDay.parse(inString, parser);
}
Trying it out:
System.out.println(parseMonthDay("2/29"));
Output:
--02-29
The method rejects for example 2/30
, 0/30
, 1/32
and 1/31 and some nonsense
. Funnily it accepts 001/031
.
Date
objectAs I said, you should not use Date
. Unless you indispensably need a Date
for a legacy API that you cannot upgrade to java.time just now, that is. But! You basically cannot convert your string to a Date
. A Date
is a point in time and despite the name cannot represent a date, not to mention a day of month without a year. What the troublesome old SimpleDateFormat
would do would be take the first moment of the date in its default year of 1970 in the default time zone of the JVM. Since 1970 was not a leap year this implies that 2/29
and 3/1
were both parsed into Sun Mar 01 00:00:00 (your time zone) 1970
, that is, you cannot distinguish.
So unless you have specific requirements that I cannot guess, I recommend that you stay with the MonthDay
object returned from my method above.
Forgive the repetition, you were using the troublesome old and error-prone classes. That typically leads to buggy code.
Your method needs both a return type and a method name, for example:
public Date paresMonthDay(String inString) throws ParseException {
When using SimpleDateFormat.parse()
you also need to declare throws ParseException
as shown unless you catch that exception in the method.
Since your method doesn’t use anything from the surrounding object, I recommend you declare it static
.
When the method parameter is declared as inString
, you need to use that name in the method body (you cannot refer to is as just inStr
).
As others have said you should use the built in library to parse the string, not parse it by hand. In particular converting it from M/d
to MM/dd
format seems just a waste.
As I said, you are parsing 2/29
and 3/1
into the same Date
.
There is no connection between your parsed date and your GregorianCalendar cal
. The latter has today’s date in the default time zone, so your are effectively checking whether the parsed month is after the current month and issuing your error message if it is.
You are not checking for negative numbers or 0 in the input. In my time zone your method just parsed 0/-1
into Sun Nov 29 00:00:00 CET 1970
and did not issue any error message.
The right bracket )
of your if
statement is inside a comment, so the compiler doesn’t see it.
In System.out.println
, println
must be with a lower case p
. In the same statement there is a double quote "
too many after month
.
If your method is to return a Date
, you must include a return
statement.
Oracle tutorial: Trail: Date Time explaining how to use java.time.