18

我得到两个日期作为字符串值,我想检查开始时间是否早于结束时间。我将它们按原样进行比较,而不使用将它们转换为日期SimpleDateFormat,如下所示:

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");
}

真的有必要将它们转换为日期并进行比较吗?我会错过什么吗?我在做正确的事吗?

4

10 回答 10

17

如果日期实际上格式正确,您将缺少验证。

如果日期的格式与您每次显示的完全相同,那么这将起作用。如果有任何可能不同,那么解析和比较结果Date对象将至少增加一些检查。

例如,如果两个日期之一恰好被格式化为,2013.01.02 14:30:56或者它甚至包含一个未格式化的日期,例如,yesterday那么您的代码会默默地假设某个顺序(这很可能与实际顺序几乎没有关系)并继续。它应该做的是通知用户(或日志文件,...)某些期望没有得到满足。

于 2013-01-02T15:59:45.490 回答
11

真的有必要将它们转换为日期并进行比较吗?

如果您不必包含时区并且可以确保您始终使用这种格式,那么词汇顺序将起作用。

我会错过什么吗?

你失去了灵活性

我在做正确的事吗?

这取决于观点。我在专门的搜索引擎中使用了类似的东西(仅出于性能原因)。通常我转换为日期并比较这些对象。

于 2013-01-02T16:03:20.843 回答
8

这不是好的做法,而且代码味道不好。

你失去了语义正确和可读的代码。(以及已经说过的可扩展性、时区和其他正确的东西)

你不想比较两个Strings,你想比较 2 Dates - 所以就这样做,比较两个Date对象。

如果您创建单元测试并测试您的比较方法,您将永远不会编写一个在每种情况下都正确比较 2 个“字符串”日期的方法,而不会将它们转换为日期。

于 2013-01-02T16:06:47.023 回答
7

当且仅当满足以下 3 个条件时,您可以在不正确解析的情况下比较日期时间:

  1. 日期时间始终采用相同的格式:

    • 相同数量的字段
    • 字段必须是纯数字。(字符串比较:Jan> April, Wed> Thu)。
    • 字段的大小是固定的(必要时填充 0)。例如,没有适当的填充将导致10:01< 1:01( :ASCII 码大于数字)。
    • 非数字部分(包括分隔符)必须与间距相同。
  2. 这些字段按单位的大小降序排列(较大的单位在右侧,较小的单位在左侧)。例如:YEAR-MONTH-DAY HOUR:MINUTE:SECOND.MILISECOND

  3. 它们必须在同一时区。时区信息(如果存在)应该具有相同的表示形式(SGT并且UTC+8当前是等效的,但字符串比较不会知道这一点)。请注意,上述模棱两可的条件“相同时区”足以比较相等,但要比较更大/更小,被比较的两个日期之间的时区必须没有变化。

于 2013-01-02T16:06:10.550 回答
2

关于什么

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

"10000-01-01 00:00:00"
于 2013-01-02T16:03:38.050 回答
2

不管是不是 Java,你必须先问这些问题:

  • 您需要比较时间还是只比较天数?
  • 你需要检查TimeZone,还是所有用户都在同一个时区(或者你不在乎)

如果您需要比较日期,那么 'YYYY-MM-dd' 格式的字符串就是完美且高效的:

'2018-01-23' < '2018-03-21'. 总是,用任何语言。

有了时间并且没有时区,那么将时间存储在数据库中作为 'YYYY-MM-dd HH:mm:ss' 也很好。

使用时区,您必须了解您的平台(代码和数据库),并了解什么是 UTC(祝您好运!)。

(在来自http://xkcd.com/1179/的 CC BY-NC 2.5 许可下使用。)

于 2019-02-19T09:12:47.170 回答
1

我建议先将它们转换为日期更安全一些,但只要你确定格式(或时区等)永远不会改变你,那么日期比较和比较字符串的格式应该总是是等价的。

于 2013-01-02T16:00:53.757 回答
1

您的方法很好,因为 yyyy-mm-dd hh:ii:ss 可以作为字符串进行比较并获得正确的结果,其他日期格式将失败

另一种选择是阅读这个stackoverflow问题

如何比较Java中的日期?

你应该简单地解析你的字符串并创建 Date 或 Calendar 对象,这取决于你想要做什么,下面是我觉得有用的东西

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

于 2013-01-02T16:03:14.633 回答
1

是的,最好将字符串转换为日期并进行比较。

  1. 它确保它们实际上是有效的日期,所以没有 20-20-2012。
  2. 转换完成后,只剩下一个数字比较。
  3. 在比较不同格式的日期时,它具有很大的灵活性。
  4. 另一种方法是编写代码来解析每个数字并将其与另一个数字进行比较,这同样是工作量。
于 2013-01-02T16:03:28.183 回答
0

我的日期来自基于字符串的来源,并且始终采用 YYYY-MM-DD 格式,没有时区信息或其他复杂情况。因此,在比较一长串日期时,将它们作为字符串进行比较比先将它们转换为日期对象更简单、更有效。

在我在代码中犯了这个错误之前,这从来都不是问题:

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

这给出了一些不正确的结果,因为 compareTo 不仅将值返回为 -1、0 或 1。这是简单的修复:

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

我在这里包括了这个问题,因为这是我在试图找出我做错了什么时发现的 SO 问题之一。

于 2018-02-07T00:50:26.197 回答