19

I'm getting two dates as String values and I wanted to check start time is earlier than the end time. I compare them as it is without converting them to date using SimpleDateFormat, like this:

String startTime = "2013-01-02 14:25:56";
String endTime   = "2013-01-02 14:30:56";

if(endTime.compareTo(startTime) > 0){
    System.out.println("End time is greater than start time");
}

Is it really necessary to convert them to date and compare? Will I miss anything? Am I doing the right thing?

Pshemo
  • 122,468
  • 25
  • 185
  • 269
someone
  • 6,577
  • 7
  • 37
  • 60
  • 8
    yyyy-mm-dd format is good because if you sort these kind of values, you get correct values, if you had mm.dd.yyyy or dd.mm.yyyy, you'd get wrong results ... at a first glance, it's all ok – cristi _b Jan 02 '13 at 15:57
  • 2
    If you are sure to always get this same format, then you're safe... – Alexis Pigeon Jan 02 '13 at 15:58
  • 4
    Worth noting as to why this works the way you have those strings: [lexicographical sorting](http://en.wikipedia.org/wiki/Lexicographical_order) – Brian Roach Jan 02 '13 at 16:00
  • 2
    On the other hand why not ? You are ignoring years of work dealing with dates, timezones, calendars and not utilizing the effort that other people have put in to make these things work right. There are so many 'ifs' attached to this working that I would just turn these things into dates and deal with the dates – Harald Scheirich Jan 02 '13 at 17:55

10 Answers10

18

What you will be missing is the verification if the dates are in fact well-formatted.

If the dates are formatted exactly as you showed every time, then this will work. If there's any chance that it might be different, then parsing and comparing the resulting Date objects will add at least somewhat of a check.

For example if one of the two dates happens to be formatted as 2013.01.02 14:30:56 or it even included an unformatted date such as yesterday then your code would silently assume some order (that most likely has little to do with the actual order) and proceed. What it should do is notify the user (or the log file, ...) that some expectation was not met.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • 3
    Good point. Another more subtle difference with the string comparison might be if you compare `2013-01-01 08:42:42` and `2013-01-01 8:42:42` and expect them to be equal. – Alderath Jan 02 '13 at 16:05
  • 1
    @Alderath: yes, that's what I was writing about when I wrote "are formatted *exactly* as you showed". If there's *any* variation in the formatting at all, then parsing is the much safer alternative (and as I hinted: I'd parse+compare in any case, unless there's a *very* good reason not to). – Joachim Sauer Jan 02 '13 at 16:06
  • Yeah. Sorry. I didn't mean to imply that I have discovered anything that you did not. I was merely giving another example of how dates can differ. What is notable with this difference is that if a user was prompted for input and "2013-01-02 14:25:56" was used as an example for which format the date should have, it is ambigous whether or not leading zeroes are required for hours with only one digit. (But I am guessing that the input which the OP gives to the comparison method is not user input, because if it was, it definitely would need to be validated) – Alderath Jan 02 '13 at 16:16
12

Is it really necessary to convert them to date and compare?

If you don't have to include timezones and can ensure that you always have this format the lexical order will work.

Will I miss anything?

You lose the flexibility

Am I doing the right thing?

That depends on the point of view. I use something similar in a specialized search-enginge (only for performance reasons). Usually I convert to Date and compare these objects.

Adrian Pronk
  • 13,486
  • 7
  • 36
  • 60
stacker
  • 68,052
  • 28
  • 140
  • 210
8

It is not good practice and a code smell.

You lose semantic correct and readable code. (and extensibility, timezones, and the other right things, that already had been said)

You don't want to compare two Strings, you want to compare 2 Dates - so just do this, compare two Date objects.

If you create unit-tests and test your comparing method, you will never write a method that compares 2 "string"-dates correctly in every case, without converting them to dates.

xpda
  • 15,585
  • 8
  • 51
  • 82
burna
  • 2,932
  • 18
  • 27
  • 1
    I have to agree with this answer most of all. To compare as Strings is a fragile approach to software. Yes, you can carefully define the conditions in which it works, but it's likely to fail at some point in the future, in a VERY difficult-to-find way. You simply cannot guarantee what will or will not change in the future. – dashrb Jan 02 '13 at 16:54
  • 1
    +1 for bringing up code semantics. too often we heard that "it works, so it's ok", but if the code follows semantics, you won't get yourself in a trap so easily. – Javier Jan 02 '13 at 20:36
7

You can compare the date time without properly parsing it if and only if these 3 conditions are met:

  1. The date time are always in the same format:

    • Same number of fields
    • The fields must be purely numeric. (String comparison: Jan > April, Wed > Thu).
    • The sizes of the fields are fixed (0 padded if necessary). For example, no proper padding will result in 10:01 < 1:01 (: has larger ASCII code than digits).
    • The non-numeric parts (including separators) must be the same down to the spacing.
  2. The fields are ordered in descending order by the size of the unit (larger unit to the right, and smaller unit to the left). For example: YEAR-MONTH-DAY HOUR:MINUTE:SECOND.MILISECOND

  3. They must be in the same time zone. The time zone information, if present, should have the same presentation (SGT and UTC+8 are currently equivalent, but the String comparison won't know about this). Note that the above ambiguous condition "same time zone" is enough for comparing equal, but to compare larger/smaller, there must be no change in time zone happening between the 2 dates being compare.

nhahtdh
  • 55,989
  • 15
  • 126
  • 162
2

what about

  "999-01-01 00:00:00"

"10000-01-01 00:00:00"
irreputable
  • 44,725
  • 9
  • 65
  • 93
  • good example but this breaks the whole point of keeping same date format, in order to compare properly, we should compare 10000 with 00999 and get a good result , otherwise, it will fail – cristi _b Jan 02 '13 at 16:16
2

Java or not, you must first ask these questions:

  • Do you need to compare time or just days ?
  • Do you need to check TimeZone, or all users are in the same timezone (or you don't care)

If you need to compare days, then string in 'YYYY-MM-dd' format are just perfect and efficient :

'2018-01-23' < '2018-03-21'. Always, in any language.

With time and no timezone, then storing time in database as 'YYYY-MM-dd HH:mm:ss' is also good.

With Timezone, then you have to learn your platforms (code and database), and understand what utc is (good luck !).

(Used under CC BY-NC 2.5 license from http://xkcd.com/1179/.)

Nicolas Zozol
  • 6,910
  • 3
  • 50
  • 74
1

I would recommend converting them to date first to be a little safer, but as long as you are SURE the format (or timezone, etc...) will never change on you, then a date compare and comparing that format of string should always be equivalent.

Scott Stafford
  • 43,764
  • 28
  • 129
  • 177
1

your approach is good because yyyy-mm-dd hh:ii:ss can be compared as a string and get correct results, other date formats will fail

another option is to read this stackoverflow question

How to compare dates in Java?

and you should simply parse your strings and create Date or Calendar objects, depends on what you want to do , below is something I find useful

http://www.mkyong.com/java/java-how-to-get-current-date-time-date-and-calender/

Community
  • 1
  • 1
cristi _b
  • 1,783
  • 2
  • 28
  • 43
1

Yes, it is better to convert the String to Date and compare.

  1. It ensures they are actually valid dates so no 20-20-2012.
  2. Once the conversion is complete only a single number comparison remains.
  3. It allows for great flexibility when comparing dates of different formats.
  4. The alternative is writing code that parses each number and compares it to the other, which is just as much work.
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
MrFox
  • 4,852
  • 7
  • 45
  • 81
0

My dates are coming from a string-based source and are always formatted YYYY-MM-DD, without time zone info or other complications. So when comparing a long list of dates, it's simpler and more efficient to compare them as strings rather than to convert them to date objects first.

This was never a problem until I made this mistake in my code:

boolean past = (dateStart.compareTo(now) == -1);

This was giving some incorrect results because compareTo doesn't only return values as -1, 0 or 1. This was the simple fix:

boolean past = (dateStart.compareTo(now) < 0);

I'm including this gotcha here because this is one of the SO questions I found when trying to figure out what I was doing wrong.

arlomedia
  • 8,534
  • 5
  • 60
  • 108