计算daysAgo返回错误的日子

时间:2017-11-19 08:30:45

标签: android

我正在尝试从两个日期,电话日期时间和我过去的日期计算daysAgo。

这是我的代码:

int daysAgo = DateUtilities.getTimeAgo(DateUtilities.stringToDateTime(updatedAt, true).getTime());

public static int getTimeAgo(long time) {
            if (time < 1000000000000L) {
                time *= 1000;
            }

            long now = System.currentTimeMillis();
            if (time > now || time <= 0) {
                return 0;
            }

            final long diff = now - time;
            return (int) (diff / DAY_MILLIS);
        }

public static Date stringToDateTime(String dateTime, boolean useUtc) throws ParseException {
            if (useUtc) {
                return new SimpleDateFormat("yyyy-mm-dd'T'HH:mm:ss").parse(dateTime);
            } else {
                return new SimpleDateFormat("yyyy-mm-dd").parse(dateTime);
            }
        }

此代码int daysAgo为我返回错误的日期,我通过此日期计算:2017-11-18T20:31:04.000Z,我的电话日期时间System.currentTimeMillis()1511080129979,然后结果为返回daysAgo305

3 个答案:

答案 0 :(得分:1)

您必须使用“MM”来表示月份,而不是“mm”。这是几分钟。你的代码

return new SimpleDateFormat("yyyy-mm-dd'T'HH:mm:ss").parse(dateTime);
return new SimpleDateFormat("yyyy-mm-dd").parse(dateTime);

应改为

return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(dateTime);
return new SimpleDateFormat("yyyy-MM-dd").parse(dateTime);

答案 1 :(得分:1)

这里的问题是预优化。

int daysAgo = DateUtilities.getTimeAgo(DateUtilities.stringToDateTime(updatedAt, true).getTime());

return new SimpleDateFormat("yyyy-mm-dd'T'HH:mm:ss").parse(dateTime);

只有当你知道他们在做什么时,上述陈述才是完美的,否则,他们甚至无法调试。

在这些情况下,我们了解TDD的真正重要性。

TDD方法

<强> DateUtilitiesUnitTest

public class DateUtilitiesUnitTest
{
    @Test
    public void testStringToDateTimeConversion()
    {
        Calendar expectedCal = Calendar.getInstance();
        // Here we set the month as Calendar.NOVEMBER
        // As per the Calendar API, month 11 == DECEMBER
        expectedCal.set(2017, Calendar.NOVEMBER, 18, 20, 31, 4);

        Date actualDate = DateUtilities.stringToDateTime("2017-11-18T20:31:04.000Z");
        Calendar actualCal = Calendar.getInstance();
        actualCal.setTime(actualDate);

        // Date.equals(Date), compares two Dates with the milliseconds precision, and cannot be used reliably
        // hence, we have to compare all the individual elements separately
        assertEquals("Year should be 2017", expectedCal.get(Calendar.YEAR), actualCal.get(Calendar.YEAR));
        assertEquals("Month should be " + expectedCal.get(Calendar.MONTH), expectedCal.get(Calendar.MONTH), actualCal.get(Calendar.MONTH));
        assertEquals("Day should be 18", expectedCal.get(Calendar.DAY_OF_MONTH), actualCal.get(Calendar.DAY_OF_MONTH));
        // If required, you may go ahead and compare Hours, Minutes and Seconds
    }

}

===第1步(测试失败)===

<强> DateUtilities.java

public static Date stringToDateTime(String dateTime)
{
    return null;
}

测试结果

java.lang.NullPointerException

===第2步(刚好通过测试)===

<强> DateUtilities.java

public static Date stringToDateTime(String dateTime)
{
    Calendar cal = Calendar.getInstance();
    // Here we set the month as Calendar.NOVEMBER
    // As per the Calendar API, month 11 == DECEMBER
    cal.set(2017, Calendar.NOVEMBER, 18, 20, 31, 4);

    return cal.getTime();
}

测试结果

1 Test passed

失败然后传递“伪测试”证明您的测试实际上正在运行,并且您实际上正在测试正确的方法。

===第3步(开始实施)===

<强> DateUtilities.java

public static Date stringToDateTime(String dateTime)
{
    SimpleDateFormat format = new SimpleDateFormat("yyyy-mm-dd'T'HH:mm:ss");
    Date date = null;
    try {
        date = format.parse(dateTime);
    }
    catch (ParseException e) {
        e.printStackTrace();
    }

    return date;
}

测试结果

java.lang.AssertionError: Month should be 10 
Expected :10
Actual   :0

我们抓住了这个问题! 预计月份为10(Calendar.NOVEMBER)
但是,我们得到0(Calendar.JANUARY)

===第4步(修复它!)===

<强> DateUtilities.java

public static Date stringToDateTime(String dateTime)
{
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    Date date = null;
    try {
        date = format.parse(dateTime);
    }
    catch (ParseException e) {
        e.printStackTrace();
    }

    return date;
}

测试结果

1 Test passed

答案 2 :(得分:0)

只需将日期格式更改为

即可
public static Date stringToDateTime(String dateTime, boolean useUtc) throws ParseException {
            if (useUtc) {
                return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(dateTime);
            } else {
                return new SimpleDateFormat("yyyy-MM-dd").parse(dateTime);
            }
        }

日期mm表示minutes MM表示months