35

我正在 Android 应用程序中创建一个功能来获取任意日期(过去、现在或未来)并找到与现在相关的差异。

mynowduevariables 都是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 days19/12/2012in 0 days

希望时间出现在这些日期字符串上。

我做错了什么,是在 Android 上格式化日期的最佳方法吗?

4

10 回答 10

32

我的想法正在改变:

DateUtils.getRelativeTimeSpanString(due, now, 0L, DateUtils.FORMAT_ABBREV_ALL);

由于文档说它返回相对于现在的时间。

如果失败,请使用一些出色的库:

乔达时间

漂亮时光

过去

于 2013-08-09T12:33:33.040 回答
9

最后我已经实现了你想要的..!

首先你需要从这里下载 Joda Time

将其解压缩到任何文件夹并将joda-time-2.2.jar放入 androidProject/libs 文件夹。

主要活动

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);
  }
}

你只需要改变 day 的值,你就会得到期望的输出。目前我已将日期 10 作为输入,因此输出将是今天。

我设置了date/day = 10 , month = 8 , year = 2013 , hour = 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
于 2013-08-10T11:32:20.523 回答
4

在 Android 上格式化相对于现在的日期的最佳方法

我建议你使用JodaTime

它是轻量级的方便库,我认为实际上是处理 Date 实例的最佳工具。

你可以从这里开始。

于 2013-08-09T12:30:24.627 回答
4

为什么不检查yesterdaytomorrow避免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一个简单的检查。

于 2013-08-09T12:38:32.023 回答
1

构建.gradle

compile 'joda-time:joda-time:2.9.9'

实用程序.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
于 2017-09-07T02:06:46.473 回答
0

实际原因是数字 864000 以毫秒为单位,对应 14 分钟。与 DAY_IN_MILLIS(一天)相比,14 分钟太小了。在那里你得到“0天”。如果您希望它“在 14 分钟内”产生,只需将 DAY_IN_MILLIS 更改为 MIN_IN_MILLIS。

于 2015-12-05T07:27:07.353 回答
0

我来这里是为了另一种选择,但我找不到完美而不是我的代码。所以我在这里分享了任何改进都是受欢迎的。

public String getCreatedAtRelative() {
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
    df.setTimeZone(TimeZone.getTimeZone("IST"));
    CharSequence relative = null;
    try {
        relative = DateUtils.getRelativeTimeSpanString(df.parse(createdAt).getTime(), new Date().getTime(),
                0L, DateUtils.FORMAT_ABBREV_ALL);
    } catch (ParseException e) {
        Log.e("Parse Exception adapter", "created at", e);
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
    if (null == relative) {
        return createdAt;
    } else {
        return relative.toString().replace(".", " ");
    }
}
于 2020-04-06T19:05:21.617 回答
-1

对于 Android,您可以使用Joda-Time-Android库最简单的方法:

Date yourTime = new Date();
DateTime dateTime = new DateTime(yourTime); //or simple DateTime.now()
final String result = DateUtils.getRelativeTimeSpanString(getContext(), dateTime);
于 2015-02-11T13:09:53.247 回答
-1

所以你的计算是以毫秒为单位的,然后你用 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”)允许您获取日期格式,例如 2013 年 2 月 4 日星期一。

您可以随意更改模式:“EEEE dd/MM/yy”,...

于 2013-02-04T15:29:53.113 回答
-2

长现在 = System.currentTimeMillis();

DateUtils.getRelativeDateTimeString(mContext, now), DateUtils.SECOND_IN_MILLIS, DateUtils.DAY_IN_MILLIS, 0)

一个链接

于 2017-08-01T09:26:26.727 回答