Лучший способ отформатировать дату относительно Android на Android
Я создаю функцию в приложении для Android, чтобы получить произвольную дату (прошлое, настоящее или будущее) и найти разницу по отношению к настоящему времени.
Обе переменные now
и due
являются longs
, и это мой код:
long now = System.currentTimeMillis();
long due = now + 864000;
Log.d("Time in 1 day", DateUtils.getRelativeTimeSpanString(due,now, DateUtils.DAY_IN_MILLIS));
Я хочу, чтобы результат был чем-то вроде yesterday
, today
, in 4 days
или 19/12/2012
. Однако текущий вывод возвращает in 0 days
...
Я не хочу, чтобы время отображалось в этих строках даты.
Что я делаю неправильно и является лучшим методом для форматирования дат на Android?
Ответы
Ответ 1
Что я имею в виду, меняется:
DateUtils.getRelativeTimeSpanString(due, now, 0L, DateUtils.FORMAT_ABBREV_ALL);
Так как в документации указано, что оно возвращает время относительно.
Если это не удается использовать некоторые из блестящих библиотек:
Время в Джоде
PrettyTime
TimeAgo
Ответ 2
Наконец, я реализовал то, что вы хотели..!
Сначала вам нужно скачать Joda Time отсюда
Извлеките его в любую папку и поместите joda-time-2.2.jar в папку androidProject/libs.
MainActivity
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Months;
import org.joda.time.MutableDateTime;
import org.joda.time.Weeks;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
public class MainActivity extends Activity
{
private int day ;
private int month ;
private int year ;
private int hour ;
private int minute ;
private long selectedTimeInMillis;
private long currentTimeInMillis;
private String strDay ="";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
year = 2013;
month = 8;
day = 10;
hour = 15;
minute = 28;
DateTime selectedTime = new DateTime(year,month,day,hour,minute);
selectedTimeInMillis = selectedTime.getMillis();
MutableDateTime epoch = new MutableDateTime();
epoch.setDate(selectedTimeInMillis); //Set to Epoch time
DateTime now = new DateTime();
currentTimeInMillis = now.getMillis();
int days = Days.daysBetween(epoch, now).getDays();
int weeks = Weeks.weeksBetween(epoch, now).getWeeks();
int months = Months.monthsBetween(epoch, now).getMonths();
Log.v("days since epoch: ",""+days);
Log.v("weeks since epoch: ",""+weeks);
Log.v("months since epoch: ",""+months);
if(selectedTimeInMillis < currentTimeInMillis) //Past
{
long yesterdayTimeInMillis = currentTimeInMillis - 86400000;
DateTime today = new DateTime(currentTimeInMillis);
int year = today.getDayOfYear();
int intToday = today.getDayOfMonth();
DateTime yesterday = new DateTime(yesterdayTimeInMillis);
int intYesterday = yesterday.getDayOfMonth();
DateTime selectedDay = new DateTime(selectedTimeInMillis);
int intselectedDay = selectedDay.getDayOfMonth();
int intselectedYear = selectedDay.getDayOfYear();
if(intToday == intselectedDay & year == intselectedYear)
{
strDay = "today";
}
else if(intYesterday == intselectedDay)
{
strDay = "yesterday";
}
else
{
strDay = "before "+ days +" days from today";
}
}
else if(selectedTimeInMillis > currentTimeInMillis) //Future
{
long tomorrowTimeInMillis = currentTimeInMillis + 86400000;
DateTime tomorrow = new DateTime(tomorrowTimeInMillis);
int intTomorrow = tomorrow.getDayOfMonth();
DateTime today = new DateTime(selectedTimeInMillis);
int intToday = today.getDayOfMonth();
if(intToday == intTomorrow)
{
strDay = "tomorrow";
}
else
{
days = -days;
strDay = "after "+ days +" days from today";
}
}
Log.v("strDay: ",""+strDay);
}
}
Вам просто нужно изменить значение дня, и вы получите выход желания.
В настоящее время я дал дату 10 в качестве входных данных, поэтому выход будет сегодня.
Я установил дата/день = 10, месяц = 8, год = 2013, час = 15 > , min = 28
За прошлые даты:
input day 9 output yesterday
input day 3 output before 7 days from today
input year 2012 and day 10 output before 365 days from today
Для будущих дат:
input day 11 output tomorrow
input day 27 output after 17 days from today
input day 23 and year 2016 output after 1109 days from today
Ответ 3
Почему бы просто не проверить yesterday
и tomorrow
, чтобы избежать ошибки in 0 days
/0 days ago
и оставить DateUtils.getRelativeTimeSpanString
обрабатывать оставшиеся случаи?
String relative = null;
if(now < due && (due-now)<864000){
relative = "tomorrow";
}else if(now > due && (now-due)<864000){
relative = "yesterday";
}else{
relative = DateUtils.getRelativeTimeSpanString(due, now, DateUtils.DAY_IN_MILLIS); // e.g. "in 4 days"
}
Log.d("result", relative);
Изменить: вы также можете добавить today
с простой проверкой.
Ответ 4
Лучший способ отформатировать дату относительно Android на Android.
Я предлагаю вам использовать JodaTime
Это легкая удобная библиотека, и я думаю, что это лучший инструмент для работы с экземплярами Date.
И вы можете начать здесь.
Ответ 5
для Android вы можете использовать самый простой способ: Joda-Time-Android библиотека:
Date yourTime = new Date();
DateTime dateTime = new DateTime(yourTime); //or simple DateTime.now()
final String result = DateUtils.getRelativeTimeSpanString(getContext(), dateTime);
Ответ 6
Фактическая причина - номер 864000 в миллисекундах, что соответствует 14 минутам. 14 минут настолько малы по сравнению с DAY_IN_MILLIS (день). Там вы получите "через 0 дней".
Если вы хотите, чтобы он производил "через 14 минут", просто измените DAY_IN_MILLIS на MIN_IN_MILLIS.
Ответ 7
build.gradle
compile 'joda-time:joda-time:2.9.9'
Utils.java
private static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMM dd, yyyy");
private static SimpleDateFormat TIME_FORMAT = new SimpleDateFormat(" 'at' h:mm aa");
public static String getRelativeDateTimeString(Calendar startDateCalendar) {
if (startDateCalendar == null) return null;
DateTime startDate = new DateTime(startDateCalendar.getTimeInMillis());
DateTime today = new DateTime();
int days = Days.daysBetween(today.withTimeAtStartOfDay(), startDate.withTimeAtStartOfDay()).getDays();
String date;
switch (days) {
case -1: date = "Yesterday"; break;
case 0: date = "Today"; break;
case 1: date = "Tomorrow"; break;
default: date = DATE_FORMAT.format(startDateCalendar.getTime()); break;
}
String time = TIME_FORMAT.format(startDateCalendar.getTime());
return date + time;
}
Выход
Yesterday at 9:52 AM
Today at 9:52 AM
Tomorrow at 9:52 AM
Sep 05, 2017 at 9:52 AM
Ответ 8
Итак, ваши вычисления основаны на миллисекундах, затем вы форматируете результат с помощью SimpleDateFormat.
Для этого вы можете легко использовать форматирование SimpleDateFormat следующим образом:
Date date = new Date(milliseconds);
SimpleDateFormat formatter = new SimpleDateFormat("EEEE dd MMMM yyyy");
String strDate = formatter.format(date);
Итак, ваш расчет должен основываться на миллисекундах, затем вы форматируете результат с помощью SimpleDateFormat.
Шаблон ( "EEEE dd MMMM yyyy" ) позволяет вам получить формат даты, например, понедельник, 04 февраля 2013 года.
Вы можете изменить шаблон по своему усмотрению: "EEEE dd/MM/yy",...
Ответ 9
long now = System.currentTimeMillis();
DateUtils.getRelativeDateTimeString(mContext, now), DateUtils.SECOND_IN_MILLIS, DateUtils.DAY_IN_MILLIS, 0)
ссылка!