获取时间直到 Android 中的日期
Getting Time Until a Date in Android
我正在使用日期和时间对话框获取用户指定事件的日期和时间。该数据是通过执行以下操作转换的:
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 左右,其余数据也不正确。我究竟做错了什么?或者有哪些替代方案?
你可以使用 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 中描述了更多格式设置选项。
考虑使用 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
你的代码对我来说看起来很好,因为你正在做的事情。像其他人建议的那样使用 org.joda.time 是最佳做法,但它不能解决问题。相反,您需要做两件事:
- 验证用户输入的月份是否在范围内(他们可能输入了MM/DD/YYYY格式的日期)。大于 12 的月份值不会引发异常,并且您的 diff 将偏离。
构造日期的行,从月份中减去 1,因为月份应该从 0 到 11,例如:
newCalendar.set(yearE, monthE-1, dayE,hour, min, 0);
您是否期待看到类似的内容:
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 => 以秒为单位 diff/1000 = 2812500 => 以分钟为单位 => 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 是一款久经考验的产品。但是,如果您只需要一种计算,很少使用(如果有的话),我会说花一些时间来想出您自己的实现,而不是充分利用 Joda Time。
我正在使用日期和时间对话框获取用户指定事件的日期和时间。该数据是通过执行以下操作转换的:
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 左右,其余数据也不正确。我究竟做错了什么?或者有哪些替代方案?
你可以使用 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 中描述了更多格式设置选项。
考虑使用 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
你的代码对我来说看起来很好,因为你正在做的事情。像其他人建议的那样使用 org.joda.time 是最佳做法,但它不能解决问题。相反,您需要做两件事:
- 验证用户输入的月份是否在范围内(他们可能输入了MM/DD/YYYY格式的日期)。大于 12 的月份值不会引发异常,并且您的 diff 将偏离。
构造日期的行,从月份中减去 1,因为月份应该从 0 到 11,例如:
newCalendar.set(yearE, monthE-1, dayE,hour, min, 0);
您是否期待看到类似的内容:
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 => 以秒为单位 diff/1000 = 2812500 => 以分钟为单位 => 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 是一款久经考验的产品。但是,如果您只需要一种计算,很少使用(如果有的话),我会说花一些时间来想出您自己的实现,而不是充分利用 Joda Time。