以String格式比较日期
我得到两个日期作为字符串值,我想检查开始时间早于结束时间。 我比较它们,因为它没有使用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"); }
是否真的有必要将它们转换为日期并进行比较? 我会想念什么吗? 我做对了吗?
是否真的有必要将它们转换为日期并进行比较?
如果您不必包含时区并且可以确保始终具有此格式,则词法顺序将起作用。
我会想念什么吗?
你失去了灵活性
我做对了吗?
这取决于观点。 我在专门的搜索引擎中使用类似的东西(仅出于性能原因)。 通常我转换为日期并比较这些对象。
您将缺少的是validation日期是否格式正确。
如果日期格式与您每次显示的格式完全相同 ,那么这将起作用。 如果它可能有所不同,那么解析和比较生成的Date
对象将至少添加一些检查。
例如,如果两个日期中的一个恰好被格式化为2013.01.02 14:30:56
或者它甚至包括未格式化的日期(例如yesterday
那么您的代码将默默地假设一些顺序(这很可能与实际无关)订单)并继续。 它应该做的是通知用户(或日志文件,……)某些期望未得到满足。
这不是一个好习惯和代码味道。
你失去了语义正确和可读的代码。 (以及已经说过的可扩展性,时区和其他正确的事情)
你不想比较两个String
,你想要比较2个Date
– 所以只需这样做,比较两个Date
对象。
如果您创建unit testing并测试比较方法,那么在任何情况下都不会编写一个正确比较2个“字符串”日期的方法,而不会将它们转换为日期。
当且仅当满足以下3个条件时,您可以比较日期时间而不正确解析它:
-
日期时间始终采用相同的格式:
- 相同数量的字段
- 字段必须是纯数字。 (字符串比较:
Jan
>April
,Wed
>Thu
)。 - 字段的大小是固定的(如果需要,填充0)。 例如,没有正确的填充将导致
10:01
<1:01
(:
ASCII码比数字大)。 - 非数字部分(包括分隔符)必须与间距相同。
-
字段按单位大小的降序排列(右侧较大,左侧较小)。 例如:
YEAR-MONTH-DAY HOUR:MINUTE:SECOND.MILISECOND
-
它们必须在同一时区。 时区信息(如果存在)应具有相同的表示(
SGT
和UTC+8
当前是等效的,但字符串比较不会知道这一点)。 注意,上述模糊条件“相同时区”足以比较相等,但是为了比较大/小,在比较的两个日期之间发生的时区必须没有变化。
关于什么
"999-01-01 00:00:00" "10000-01-01 00:00:00"
我建议首先将它们转换为更安全的日期,但只要您确定格式(或时区等)将永远不会改变您,那么日期比较并比较该格式的字符串应始终相当于。
你的方法很好,因为yyyy-mm-dd hh:ii:ss可以比较为字符串并得到正确的结果,其他日期格式将失败
另一种选择是阅读这个stackoverflow问题
如何比较Java中的日期?
你只需解析你的字符串并创建日期或日历对象,取决于你想做什么,下面是我认为有用的东西
http://www.mkyong.com/java/java-how-to-get-current-date-time-date-and-calender/
是的,最好将String转换为Date并进行比较。
- 它确保它们实际上是有效的日期,所以没有20-20-2012。
- 转换完成后,只剩下一个数字比较。
- 在比较不同格式的日期时,它具有很大的灵活性。
- 另一种方法是编写解析每个数字的代码并将其与另一个数字进行比较,这也是同样多的工作。
我的日期来自基于字符串的来源,并且始终格式为YYYY-MM-DD,没有时区信息或其他复杂情况。 因此,在比较一长串日期时,将它们作为字符串进行比较更简单,更有效,而不是先将它们转换为日期对象。
在我的代码中犯了这个错误之前,这从来都不是问题:
boolean past = (dateStart.compareTo(now) == -1);
这给出了一些不正确的结果,因为compareTo不仅返回值为-1,0或1.这是一个简单的修复:
boolean past = (dateStart.compareTo(now) < 0);
我把这个问题包括在这里,因为这是我在弄清楚我做错了什么时发现的SO问题之一。