2015-03-03 4 views
1

Я использую Диалог даты и времени, чтобы получить дату и время для события, заданного пользователем. Эти данные Преобразованный, выполнив следующие действия:Получение времени до даты в 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, а остальная часть данных неверен, а также. Что я делаю не так? Или какие альтернативы?

+2

Вы можете показать данные своего журнала? неправильные данные отображаются в последней строке? "int days = ~"? – sique

+0

Дни обычно около 30-32. – TastyLemons

+0

Проблема с кодом может заключаться в том, что событие прошло и diff отрицательный. Попробуйте 'diff = Math.abs (diff)'. – kichik

ответ

5

Рассмотрите возможность использования библиотеки Joda time вместо Календаря, с ней гораздо проще работать.

Как вы на андроид, я буду считать, что вы используете 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 
+0

По какой-то причине дни округляются до 23, когда я устанавливаю время на это точное время завтра. – TastyLemons

2

Для этого вы можете использовать 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.

+0

Период не существует на Android. – TastyLemons

+0

Joda не встроен, но вы можете добавить его JAR в APK. – kichik

+0

Но я имею в виду, что мне не нужно использовать внешнюю библиотеку, чтобы сделать что-то вроде этого. Или мне нужно? – TastyLemons

0

Ваш код выглядит хорошо для меня за то, что вы делаете. Использование org.joda.time, как предложили другие, является лучшей практикой, но это не решит проблему. Вместо этого вам нужно сделать две вещи:

  1. Проверьте месяц, что введенный пользователем в диапазоне (они могут быть введены даты в формате дд/ММ/ГГГГ). Значения месяца, превышающие 12, не будут генерировать исключение, а ваш diff будет уходить.
  2. Линия, на которой вы строите свою дату, вычесть 1 из месяца с месяца должно быть от 0 до 11, как:

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

Вы ожидали увидеть что-то подобное:

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 времени. Вышеприведенное вычисление находится совсем близко от моей головы. Я не могу гарантировать его правильность. Если вам также нужна относительная разница в месяце (например, 3 months, 2 days ....), потребуется много работы. Существует не DateUtils.MONTH_IN_MILLIS константа - меняющееся количество дней - 28, 29, 30, 31.

С другой стороны, Joda Time является проверенным продуктом &. Но если все, что вам нужно, это один из видов вычислений, которые используются редко (если вообще когда-либо), я бы сказал, потратьте немного времени и придумайте собственную реализацию, а не используете Joda Time.

Смежные вопросы