在Android中获取时间直到某个日期

时间:2015-03-03 03:08:05

标签: android android-datepicker

我正在使用日期和时间对话框来获取用户指定的事件的日期和时间。该数据是通过执行以下操作转换的:

int yearE = Integer.valueOf(evntDate.split("/")[2]);
int monthE = Integer.valueOf(evntDate.split("/")[1]);
int dayE = Integer.valueOf(evntDate.split("/")[0]); 
int hour = Integer.valueOf(evntTm.split(":")[0]);
int min = Integer.valueOf(evntTm.split(":")[1]);

使用值:

eventDate = "3/5/2015";
eventTime = "13:2";

然后我获取该数据并将其转换为毫秒并将其存储在数据库中:

newCalendar.set(yearE, monthE, dayE,hour, min, 0);
startTime = newCalendar.getTimeInMillis();
...

当我从数据库加载信息时,我会尝试计算到指定日期之前剩余的时间。所以我做了以下几点:

Long timeL = Long.valueOf(time);
Calendar eventDay = Calendar.getInstance();
eventDay.setTimeInMillis(timeL);
Calendar today = Calendar.getInstance();
long diff = eventDay.getTimeInMillis() - today.getTimeInMillis();

// CONVERT:
int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(diff);
int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(diff);
int hours = (int) TimeUnit.MILLISECONDS.toHours(diff);
int days = (int) TimeUnit.MILLISECONDS.toDays(diff);
...

当我记录上述数据时,天数通常在30-32左右,其余数据也不正确。我究竟做错了什么?或者有哪些替代方案?

4 个答案:

答案 0 :(得分:5)

考虑使用Joda time库而不是日历,使用它会更容易。

当你在Android上时,我会假设你正在使用gradle,所以继续把它放在你的依赖项中

compile 'joda-time:joda-time:2.3'

我已经创建了一个小psvm来演示如何使用它

import org.joda.time.DateTime;
import org.joda.time.Period;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.PeriodFormat;

import static java.lang.String.format;

public class DateTimeDemo {

    public static void main(String[] args) {

        // Your date/time values, I'll assume you missed a digit off the time ;)
        String eventDate = "3/5/2015";
        String eventTime = "13:20";

        // convert these to a DateTime object
        DateTime targetDateTime = DateTime.parse(format("%s %s", eventDate, eventTime), DateTimeFormat.forPattern("dd/MM/yyyy HH:mm"));

        // print out the millis, or in your case, save it to DB
        System.out.println("targetDateTime in millis is " + targetDateTime.getMillis());

        // grab a timestamp
        DateTime now = DateTime.now();

        // print it out, just for demo
        System.out.println("millis for now is " + now.getMillis());

        // create a period object between the two
        Period period = new Period(now, targetDateTime);

        // print out each part
        System.out.println("seconds " + period.getSeconds());
        System.out.println("hours " + period.getHours());
        System.out.println("months " + period.getMonths());

        // convert the period to a printable String
        String prettyPeriod = PeriodFormat.getDefault().print(period);

        // write it out!
        System.out.println(prettyPeriod);


    }
}

输出

targetDateTime in millis is 1430623200000
millis for now is 1425527593584
seconds 46
hours 22
months 1
1 month, 3 weeks, 6 days, 22 hours, 26 minutes, 46 seconds and 416 milliseconds

答案 1 :(得分:3)

您可以使用Joda

long dbTime = 1425525415837L;
Period period = new Period( dbTime, System.currentTimeMillis() );
String formatted = PeriodFormat.getDefault().print(period);
System.out.println( formatted );

如果您想要更多地控制格式,请使用PeriodFormatter

如果您想获得秒,分钟,小时等,而不仅仅是打印它们,您可以使用各种可用的方法。例如:

period.getSeconds();
period.getHours();
period.getMonths();

this question中描述了更多格式选项。

答案 2 :(得分:2)

你期待看到类似的东西:

seconds = 36 (always less than 60)
minutes = 12 (always less that 60)
hours   = 17 (always less than 24)
days    = 45 (always less that 31 if # of months is used, else < 366 if # of years is used)
...
...

从:

// CONVERT:
int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(diff);
int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(diff);
int hours = (int) TimeUnit.MILLISECONDS.toHours(diff);
int days = (int) TimeUnit.MILLISECONDS.toDays(diff);

那是一个逻辑错误。 TimeUnit.MILLISECONDS.toXXXX(long)整个时差转换为指定的单位。这对你没有价值。

例如,假设您将事件的日期设置为32 days from now - 并将时间设置为13:15

毫秒差异=

 2764800000 (32 days in millis) 
+  46800000 (13 hours in millis) 
+    900000 (15 minutes in millis)
= 2812500000

使用此时差,以下日志:

int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(diff);
int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(diff);
int hours = (int) TimeUnit.MILLISECONDS.toHours(diff);
int days = (int) TimeUnit.MILLISECONDS.toDays(diff);

产生

Seconds left: 2812500
Minutes left: 46875
Hours left: 781
Days left: 32

这些数字关闭。快速检查将是:毫秒时差为:2812500000 =&gt;以秒为单位将是diff / 1000 = 2812500 =&gt;在几分钟内将是=&gt; diff / 1000/60 = 46875等等。

相对时间:

要获得32 days, 13 hours and 15 minutes left之类的相对时间,你必须自己进行繁重的工作。举个例子:

// I will use the actual values instead of defined 
// variables to make this easier to follow
long timeDiff = 2812500000L;

// Simple division // we don't care about the remainder
// Result: 32
int days = 2812500000 / DateUtils.DAY_IN_MILLIS;

// This is what's left over after we take the days out.
// We'll use this to get the number of hours.
// Result: 47700000
long remainderFromDays = 2812500000 % DateUtils.DAY_IN_MILLIS;

// Simple division // we don't care about the remainder
// Result: 13
int hours = 47700000 / DateUtils.HOUR_IN_MILLIS;

// This is what's left over after we take the hours out.
// We'll use this to get the number of minutes.
// Result: 900000
long remainderFromHours = 47700000 % DateUtils.HOUR_IN_MILLIS;

// Result: 15
int minutes = 900000 / DateUtils.MINUTE_IN_MILLIS;

// Result: 0
long remainderFromMinutes = 900000 % DateUtils.MINUTE_IN_MILLIS;

// Result: 0
int seconds = 0 / 1000; // 1000 ms = 1 sec

Log.i("Time-Difference", "Event in: " + String.format("Event in %d days, %d hours, %d minutes and %d seconds", days, hours, minutes, seconds));

输出:

Event in: 32 days, 13 hours, 15 minutes and 0 seconds

这就是每个人都建议 Joda Time 的原因。上面的计算只是我的头脑。我无法保证其正确性。如果您还需要相对月份差异(例如3 months, 2 days ....),则需要进行大量工作。没有DateUtils.MONTH_IN_MILLIS常数 - 不同的天数--28,29,30,31。

另一方面,Joda Time是一个尝试过的&amp;测试产品。但是,如果您只需要一种计算,几乎不使用(如果有的话),我会花一些时间来提出您自己的实现,而不是使用Joda Time。

答案 3 :(得分:0)

您的代码看起来很适合您正在做的事情。像其他人所建议的那样使用org.joda.time是一种最佳实践,但它不会解决问题。相反,你需要做两件事:

  1. 验证用户输入的是否在范围内(他们可能已输入MM / DD / YYYY格式的日期)。月份值大于12不会抛出异常而 diff 将会消失。
  2. 您构建日期的行,从月份开始减去1应为0到11,如:

    newCalendar.set(yearE, monthE-1, dayE,hour, min, 0);