2012-01-07 172 views
1

我想比较以下两个时间戳。它应该返回true,但由于两个时间戳中的单位数和双位数毫秒,它返回false。我能做些什么,使之返回true比较两个时间戳

public static void main(String[] args) throws ParseException { 
    String d1 = "2011-12-31 07:11:01.5"; 
    String d2 = "2011-12-31 07:11:01.50"; 
    SimpleDateFormat s1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S"); 
    SimpleDateFormat s2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS"); 

    Date dateOne = s1.parse(d1); 
    Date dateTwo = s2.parse(d2); 

    System.out.println(dateOne.equals(dateTwo)); 
} 

回答

0

就试试这个(假设你不想考虑毫秒):

SimpleDateFormat s1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
     Date dateOne = s1.parse(d1);  
     Date dateTwo = s1.parse(d2);  
System.out.println(dateOne.equals(dateTwo)); 
1

的问题是,在S符号解析数为毫秒。总是。因此,在第一种情况下,“.5”被解析为5毫秒,“.50”被解析为50毫秒。他们都没有被解析为半秒,我怀疑是你想要的。

不幸的是,这是SimpleDateFormat的一个缺点。根本没有办法解析或格式化decisecond或厘秒字段。

当我最后不得不做这个(当然只是一段时间,而不是日期),我最终手动解析 - 用正则表达式分割字符串,然后手动将字段转换为毫秒。您也许可以切掉小数秒字段并手动解析,然后使用SimpleDateFormat解析剩余的字符串。

另一种方法是填充尾随零的字符串,以便小数秒总是三位数,然后才能正确解析。丑陋,但至少简单。

1

这是对的equals返回false。这两个字符串不同 - .5(解释为.05)不能与.50相同。如果您想比较Dates,则最好使用compareTo

而且我只用一个SimpleDateFormat这样的:

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS"); 

Date dateOne = format.parse(d1); 
Date dateTwo = format.parse(d2); 

所以我的建议是这些:

  • 如果你真的想有这些不同的值相同,比较它们与字符串一些正则表达式(我不会推荐这个解决方案)。
  • 如果你将它们转换为Date那么它们会不同,因为不是相同。
  • 或(和其他人一样在这里建议),您可以从模式中删除.SS一部分,但那么你将失去精度..
0

看来,SimpleDateFormat的解释最后一部分为整数,而不是作为小数部分。显而易见的解决方案是确保最后总是有三位数字,如果没有,则正确填充0。

然后使用模式yyyy-MM-dd HH:mm:ss.SSS来解析它。

+0

这是行不通的。它给出了与'.SS'相同的结果。 – user219882 2012-01-07 12:16:09

+0

无论你使用什么解析's'或'ss.SSS',它只会用于格式化。请参阅我在答案 – Robin 2012-01-07 12:28:21

+0

@Tomas中引用的javadoc部分。当我告诉你用零填充字符串以确保总是有三位数字时,你错过了这个部分。 – 2012-01-07 17:15:46

0

SimpleDateFormat的的Javadoc:

号码:格式化,模式字母的数目是最小 的位数,和更短的数字是零填充到这个量。 对于解析,模式字母的数量将被忽略,除非它需要分开两个相邻字段的 。

所以,你在你的SimpleDateFormat建设.S.SS仅用于格式化,而不是解析。 equals检查返回false,因为getTime值对于两者都不同,因为Date类的equals方法中的文档不同。对于d1它看到5毫秒和对于d2 50毫秒。

因此,与SimpleDateFormat这两个实例将永远不会相等。您可以选择忽略毫秒或者如果可能的话调整输入字符串。

2

其他人已经回答了原因。这里有一个出发点,以避开它:

import java.text.*; 
import java.util.Date; 

public class DatePercentage { 

    private final SimpleDateFormat dateFmt = new SimpleDateFormat(
           "yyyy-MM-dd HH:mm:ss"); 
    private final DecimalFormat decFmt = new DecimalFormat(); 

    public Date parse(String text) throws ParseException { 
     ParsePosition pos = new ParsePosition(0); 
     Date d = dateFmt.parse(text, pos); 

     if (d == null) { 
      throw new ParseException("Could not parse " + text + ": " + pos, 
            pos.getErrorIndex()); 
     } else if (pos.getIndex() < text.length()) { 
      Number dec = decFmt.parse(text, pos); // % milliseceonds 
      double pct = dec == null ? 0 : dec.doubleValue(); 

      if (0 < pct && pct < 1) { 
       long moreMillis = Math.round(pct * 1000); 
       d = new Date(d.getTime() + moreMillis); 
      } 
     } 
     return d; 
    } 

    public static void main(String[] args) throws ParseException { 
     String date = "2011-12-31 07:11:01"; 
     String [] millis = {"", ".5", ".50", ".500", ".5001", 
          ".051", ".5009", "garbage"}; 

     DatePercentage dp = new DatePercentage(); 

     for (int i = 0; i < millis.length; i++) { 
      String str = date + millis[i]; 
      System.out.format("%2s: %26s -> %tQ%n", i+1, str, dp.parse(str)); 
     } 
    } 
} 

输出:

1:  2011-12-31 07:11:01 -> 1325333461000 
2:  2011-12-31 07:11:01.5 -> 1325333461500 
3:  2011-12-31 07:11:01.50 -> 1325333461500 
4: 2011-12-31 07:11:01.500 -> 1325333461500 
5: 2011-12-31 07:11:01.5001 -> 1325333461500 
6: 2011-12-31 07:11:01.051 -> 1325333461051 
7: 2011-12-31 07:11:01.5009 -> 1325333461501 
8: 2011-12-31 07:11:01garbage -> 1325333461000