比较两个时间戳

时间:2012-01-07 11:50:46

标签: java timestamp compare

我想比较以下两个时间戳。它应返回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));
}

6 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

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

可悲的是,这是SimpleDateFormat的一个缺点。没有办法用它来解析或格式化decisecond或centisecond字段。

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

替代方法是使用尾随零填充字符串,以便小数秒始终为三位数,然后将正确解析。丑陋,但至少很简单。

答案 2 :(得分:1)

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

我只会使用这样一个SimpleDateFormat

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

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

所以我的建议是这些:

  • 如果您确实希望将这些不同的值相同,请将它们与具有正则表达式的字符串进行比较(我不建议使用此解决方案)。
  • 如果您将它们转换为Date,那么它们会有所不同,因为不是相同。
  • 或者(像其他人建议的那样)你可以从模式中移除.SS部分但是你会失去精确度..

答案 3 :(得分: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));

答案 4 :(得分:0)

似乎SimpleDateFormat将最后一部分解释为整数,而不是十进制部分。显而易见的解决方案是确保最后总共有三个数字,如果没有,则右边的填充为0。

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

答案 5 :(得分:0)

请参阅SimpleDateFormat

的javadoc
  

数字:对于格式化,模式字母的数量是最小的   数字和较短的数字被零填充到此数量。   对于解析,除非是,否则忽略模式字母的数量   需要将两个相邻的区域分开。

因此,.S构造中的.SSSimpleDateFormat仅用于格式化,而不用于解析。 equals检查返回false,因为getTime值对于Date类的equals方法中的文档都不同。对于d1,它看到5毫秒,d2 50毫秒。

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