0

I have a dates in format such as: - dd. - dd.MM.yyyy

Based on this information I want to receive from date and to date.

Naive implementation in pseudo code is:

  • Split the date into first part and second part
  • Create a SimpleDateFormat for second part
  • Take a look, whether the number in the first part is higher than the number in a second part.
  • If it is:
    • Decrement month for the first date
    • Create from date which will contain the dd from the first part, decremented month from the second part and year from the second part.
  • If it isn't:
    • Create from date which will contain the dd from the first part and month and year from second part.

This solution would probably work most of the time, but it feels rather awkward. Isn't there any better solution?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Jakub Balhar
  • 315
  • 1
  • 7
  • Possible duplicate of [Java string to date conversion](http://stackoverflow.com/questions/4216745/java-string-to-date-conversion) – The Roy May 10 '16 at 01:37
  • @DROY No, not a duplicate of that. This Question is about a date range, not a single date. Also this Question adds the challenge of deducing whether the starting date (given only as a mysterious day-of-month) is in the same month as the stop date or in the previous month. – Basil Bourque May 10 '16 at 04:08
  • It is a different question. I know how I can handle the String to date conversion, which I hope I proved by actually coming up with pseudocode, which can solve the issue. What I was looking for is whether there is any class like Interval, which would accept format such as dd. - dd.MM.yyyy and will provide the from date and to date. – Jakub Balhar May 10 '16 at 11:37

2 Answers2

0

I'd suggest you to check the package

org.joda.time

In particular the following classes

DateTime 
Period
felipe
  • 1,039
  • 1
  • 13
  • 27
0

java.time

The java.time framework is built into Java 8 and later. Much of that functionality is back-ported to Java 6 & 7 and to Android.

I provide some scraps of example code here, but untested – never run. Should get you going in the right direction.

Two tricky parts to this problem:

  • Year
    The Question says to assign the year. That is not the case for a stop date in January with a start date that turns out to be in previous month, December. You want the previous year in such a case. Solution is to let java.time subtract a month and handle the Jan-to-Dec math for you.
  • Month length
    Various months have different lengths, different number of days, obviously. Keep mind that you cannot try to put day-of-month 31 on to month of April. If your input data is always clean and valid, and our algorithm below is correct, this should be a non-issue. Nevertheless, I would certainly add some exception-catching code to my example code below to trap any attempt to form an invalid date.

I'll skip the string-splitting part, and assume you have a number (the day-of-month) from the first part, and a string of the date from the second part.

long dayOfMonth = Long.longValue( "31" );

That date is not in standard format, so we must specify a formatting pattern. A LocalDate represents a date-only value without time-of-day and without time zone.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd.MM.yyyy" );
LocalDate stop = LocalDate.parse( "21.05.2016" , formatter );

We can extract the day-of-month to compare.

LocalDate start = null;
int d = localDate.getDayOfMonth();

Do the comparison.

if( dayOfMonth >=d ) { // If start is in previous month…
    start = stop.minusMonths( 1 ).withDayOfMonth( dayOfMonth );
} else if (dayOfMonth < d ) { // If start is in same month…
    start = stop.withDayOfMonth( dayOfMonth );
} else {
    // FIXME: handle impossible condition as error. The 'if' statements are flawed.
}

By the way, the format of this input data is awkward and, frankly, silly. This kind of precious “cleverness” creates extra work, gives opportunity for confusion and errors, is completely needless without providing any benefits, and drives me nuts. If you have any control of this input data I strongly suggest either of two possible changes.

  • First, if exchanging data within your app, do not use strings. Use objects. Above you have seen the LocalDate object. You could pass those around. Or even define your own class LocalDateRange to house a pair of LocalDate objects. Or see this Question and especially this Answer that talks about using the Google Guava class Range to hold the pair of LocalDate objects.

  • Secondly, when you must serialize date-time values to strings, use the standard ISO 8601 formats. Such use is simple as the java.time classes by default use these formats when parsing/generating strings. A date-only value should be in YYYY-MM-DD order. A date range interval is a pair of those strings mated with a slash (SOLIDUS) or alternatively a pair of hyphens when a slash is inappropriate (such as file or folder naming within a Unix-related file system).

Community
  • 1
  • 1
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • Unfortunately, the input data are outside of my control and I need to use them. The issue I am facing is on the outer boundary of the application. Inside of the application, I am already using mostly Joda object for time handling. It is very good and concise answer, but it actually just says that there isn't really a better way because of the requirements, which are rather stupid. It kind of does and doesn't answer the original question therefore I am not sure If I should accept it as an answer. – Jakub Balhar May 10 '16 at 11:35