如何在 android 中获得两个日期之间的差异?,尝试所有事情并发布

Posted

技术标签:

【中文标题】如何在 android 中获得两个日期之间的差异?,尝试所有事情并发布【英文标题】:How do I get difference between two dates in android?, tried every thing and post 【发布时间】:2012-05-28 06:08:15 【问题描述】:

我看到了这里的所有帖子,但我仍然不知道如何获得两个 android 日期之间的差异。

这就是我的工作:

long diff = date1.getTime() - date2.getTime();
Date diffDate = new Date(diff);

我明白了:日期是 1970 年 1 月 1 日,时间总是在两个小时内较大...我来自以色列,所以两个小时是 timeOffset。

我怎样才能得到正常的差异???

【问题讨论】:

这段代码使用了麻烦的旧日期时间类,现在已被 java.time 类取代。对于较旧的 Java 和 Android,请参阅 ThreeTen-BackportThreeTenABP 项目。 类似问题:date difference in days, in Android 试试这个***.com/a/68997515/15005298 【参考方案1】:

您已接近正确答案,您得到了这两个日期之间的毫秒差异,但是当您尝试根据该差异构建日期时,假设您要创建一个新的 Date 对象用那个差值作为它的纪元时间。如果您正在寻找以小时为单位的时间,那么您只需对该 diff 进行一些基本的算术运算即可获得不同的时间部分。

Java:

long diff = date1.getTime() - date2.getTime();
long seconds = diff / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;

科特林:

val diff: Long = date1.getTime() - date2.getTime()
val seconds = diff / 1000
val minutes = seconds / 60
val hours = minutes / 60
val days = hours / 24

所有这些数学运算都会简单地进行整数运算,因此它会截断任何小数点

【讨论】:

我可以根据这些信息创建日期对象吗? 这是一个时间,而不是一个日期,你想创建什么样的日期?【参考方案2】:
    long diffInMillisec = date1.getTime() - date2.getTime();

    long diffInDays = TimeUnit.MILLISECONDS.toDays(diffInMillisec);
    long diffInHours = TimeUnit.MILLISECONDS.toHours(diffInMillisec);
    long diffInMin = TimeUnit.MILLISECONDS.toMinutes(diffInMillisec);
    long diffInSec = TimeUnit.MILLISECONDS.toSeconds(diffInMillisec);

【讨论】:

需要 API 级别 31。【参考方案3】:

一些补充: 在这里,我将字符串转换为日期,然后比较当前时间。

String toyBornTime = "2014-06-18 12:56:50";
    SimpleDateFormat dateFormat = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    try 

        Date oldDate = dateFormat.parse(toyBornTime);
        System.out.println(oldDate);

        Date currentDate = new Date();

        long diff = currentDate.getTime() - oldDate.getTime();
        long seconds = diff / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;
        long days = hours / 24;

        if (oldDate.before(currentDate)) 

            Log.e("oldDate", "is previous date");
            Log.e("Difference: ", " seconds: " + seconds + " minutes: " + minutes
                    + " hours: " + hours + " days: " + days);

        

        // Log.e("toyBornTime", "" + toyBornTime);

     catch (ParseException e) 

        e.printStackTrace();
    

【讨论】:

从您的方法中,我减去两个日期当前日期和 10 天前的日期,它返回负毫秒。如果使用两个当前日期的小时差返回正毫秒。为什么? 将 diff 更改为:long diff = currentDate.getTime() - oldDate.getTime();会有帮助的。【参考方案4】:

java.time.Duration

使用java.time.Duration

    Duration diff = Duration.between(instant2, instant1);
    System.out.println(diff);

这将打印类似的东西

PT109H27M21S

这意味着 109 小时 27 分 21 秒的时间段。如果你想要一些更易读的东西——我会先给出 Java 9 版本,这是最简单的:

    String formattedDiff = String.format(Locale.ENGLISH,
            "%d days %d hours %d minutes %d seconds",
            diff.toDays(), diff.toHoursPart(), diff.toMinutesPart(), diff.toSecondsPart());
    System.out.println(formattedDiff);

现在我们得到

4 days 13 hours 27 minutes 21 seconds

Duration 类是现代 Java 日期和时间 API java.time 的一部分。这捆绑在较新的 Android 设备上。在旧设备上,获取 ThreeTenABP 并将其添加到您的项目中,并确保从同一包中导入 org.threeten.bp.Duration 和您可能需要的其他日期时间类。

假设您还没有获得 Java 9 版本,您可以依次减去较大的单元以获得较小的单元:

    long days = diff.toDays();
    diff = diff.minusDays(days);
    long hours = diff.toHours();
    diff = diff.minusHours(hours);
    long minutes = diff.toMinutes();
    diff = diff.minusMinutes(minutes);
    long seconds = diff.toSeconds();

那么就可以像上面那样格式化四个变量了。

你做错了什么?

Date 代表一个时间点。它从来不是用来代表时间量、持续时间的,也不适合它。试图完成这项工作充其量会导致代码混乱且难以维护。你不想那样,所以请不要。

问题:java.time 不需要 Android API 26 级吗?

java.time 在较旧和较新的 Android 设备上都能很好地工作。它只需要至少 Java 6

在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 起)中,现代 API 是内置的。 在非 Android Java 6 和 7 中,获取 ThreeTen Backport,这是现代类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 导入日期和时间类以及子包。

链接

Oracle tutorial: Date Time,解释如何使用java.time。 ThreeTen Backport project,java.time 到 Java 6 和 7 的反向移植 ThreeTenABP,Android 版 ThreeTen Backport Question: How to use ThreeTenABP in Android Project,解释得很透彻。 Java Specification Request (JSR) 310。

【讨论】:

我认为这是最合适的答案。它应该被接受。【参考方案5】:

用Instant怎么样:

val instant1 = now()
val instant2 = now()
val diff: Duration = Duration.between(instant1, instant2)
val minutes = diff.toMinutes()

您甚至可以使用 instant1.toString() 保存 Instant 并使用 parse(string) 解析该字符串。

如果您需要支持 Android API 级别 Java 8+ API desugaring support 到你的项目。

【讨论】:

【参考方案6】:

如果您使用 Kotlin 语言进行 Android 开发,您可以在几天内获得不同的结果:

fun daysDiff(c1: Calendar, c2: Calendar): Long 
    val diffInMillis = c1.timeInMillis - c2.timeInMillis
    return diffInMillis.milliseconds.inWholeDays

或者,如果您想获得不同类型的结果,您可以将 inWholeDays 替换为 toInt(...)toDouble(...)toString(...)

如果您感兴趣的唯一日期差异是天数(假设为 Double 类型的结果),您可以像这样创建运算符扩展方法:

operator fun Calendar.minus(c: Calendar): Double 
    val diffInMillis = timeInMillis - c.timeInMillis
    return diffInMillis.milliseconds.toDouble(DurationUnit.DAYS)

然后像calendar2 - calendar1 这样的任何操作都会以Double 的形式返回天数差异。

【讨论】:

目前我们应该使用inWholeDays而不是inDays 谢谢@CoolMind,我也在回复中更新了它 干得好!可能我们不必使用@ExperimentalTime,我没有检查。 用工作代码检查和更新。 干得好!祝你好运!【参考方案7】:

这是我基于@Ole V. V. 的回答。

这也适用于单数。

private String getDuration(Date d1, Date d2) 
    Duration diff = Duration.between(d1.toInstant(), d2.toInstant());


    long days = diff.toDays();
    diff = diff.minusDays(days);
    long hours = diff.toHours();
    diff = diff.minusHours(hours);
    long minutes = diff.toMinutes();
    diff = diff.minusMinutes(minutes);
    long seconds = diff.toMillis();

    StringBuilder formattedDiff = new StringBuilder();
    if(days!=0)
        if(days==1)
            formattedDiff.append(days + " Day ");

        else 
            formattedDiff.append(days + " Days ");
        
    if(hours!=0)
        if(hours==1)
            formattedDiff.append(hours + " hour ");
        else
            formattedDiff.append(hours + " hours ");
        
    if(minutes!=0)
        if(minutes==1)
            formattedDiff.append(minutes + " minute ");
        else
            formattedDiff.append(minutes + " minutes ");
        
    if(seconds!=0)
        if(seconds==1)
            formattedDiff.append(seconds + " second ");
        else
            formattedDiff.append(seconds + " seconds ");
        
    


    return formattedDiff.toString();

它与 StringBuilder 一起使用,将所有内容附加在一起。

【讨论】:

【参考方案8】:

我试过这个方法..但不知道为什么我没有得到正确的结果

long diff = date1.getTime() - date2.getTime();
long seconds = diff / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;

但是这行得通

long miliSeconds = date1.getTime() -date2.getTime();
long seconds = TimeUnit.MILLISECONDS.toSeconds(miliSeconds);
long minute = seconds/60;
long hour = minute/60;
long days = hour/24;

【讨论】:

【参考方案9】:

使用格鲁吉亚日历

 public void dateDifferenceExample() 

        // Set the date for both of the calendar instance
        GregorianCalendar calDate = new GregorianCalendar(2012, 10, 02,5,23,43);
        GregorianCalendar cal2 = new GregorianCalendar(2015, 04, 02);

        // Get the represented date in milliseconds
        long millis1 = calDate.getTimeInMillis();
        long millis2 = cal2.getTimeInMillis();

        // Calculate difference in milliseconds
        long diff = millis2 - millis1;

        // Calculate difference in seconds
        long diffSeconds = diff / 1000;

        // Calculate difference in minutes
        long diffMinutes = diff / (60 * 1000);

        // Calculate difference in hours
        long diffHours = diff / (60 * 60 * 1000);

        // Calculate difference in days
        long diffDays = diff / (24 * 60 * 60 * 1000);
    Toast.makeText(getContext(), ""+diffSeconds, Toast.LENGTH_SHORT).show();



【讨论】:

GregorianCalendar 是一个糟糕的类,多年前被 java.time 类取代,特别是 ZonedDateTime。建议 2019 年的老班是糟糕的建议。对于早期的 Android,请参阅 ThreeTen-BackportThreeTenABP 项目。【参考方案10】:

使用这些功能

    public static int getDateDifference(
        int previousYear, int previousMonthOfYear, int previousDayOfMonth,
        int nextYear, int nextMonthOfYear, int nextDayOfMonth,
        int differenceToCount)
    // int differenceToCount = can be any of the following
    //  Calendar.MILLISECOND;
    //  Calendar.SECOND;
    //  Calendar.MINUTE;
    //  Calendar.HOUR;
    //  Calendar.DAY_OF_MONTH;
    //  Calendar.MONTH;
    //  Calendar.YEAR;
    //  Calendar.----

    Calendar previousDate = Calendar.getInstance();
    previousDate.set(Calendar.DAY_OF_MONTH, previousDayOfMonth);
    // month is zero indexed so month should be minus 1
    previousDate.set(Calendar.MONTH, previousMonthOfYear);
    previousDate.set(Calendar.YEAR, previousYear);

    Calendar nextDate = Calendar.getInstance();
    nextDate.set(Calendar.DAY_OF_MONTH, previousDayOfMonth);
    // month is zero indexed so month should be minus 1
    nextDate.set(Calendar.MONTH, previousMonthOfYear);
    nextDate.set(Calendar.YEAR, previousYear);

    return getDateDifference(previousDate,nextDate,differenceToCount);

public static int getDateDifference(Calendar previousDate,Calendar nextDate,int differenceToCount)
    // int differenceToCount = can be any of the following
    //  Calendar.MILLISECOND;
    //  Calendar.SECOND;
    //  Calendar.MINUTE;
    //  Calendar.HOUR;
    //  Calendar.DAY_OF_MONTH;
    //  Calendar.MONTH;
    //  Calendar.YEAR;
    //  Calendar.----

    //raise an exception if previous is greater than nextdate.
    if(previousDate.compareTo(nextDate)>0)
        throw new RuntimeException("Previous Date is later than Nextdate");
    

    int difference=0;
    while(previousDate.compareTo(nextDate)<=0)
        difference++;
        previousDate.add(differenceToCount,1);
    
    return difference;

【讨论】:

这段代码使用了麻烦的旧日期时间类,现在已被 java.time 类取代。对于较旧的 Java 和 Android,请参阅 ThreeTen-BackportThreeTenABP 项目。 日历类是旧的日期时间类吗? 是的,在 java.time 包之外找到的任何与日期时间相关的类现在都是遗留的,应该避免使用。这包括DateCalendar,以及java.sql 类。请参阅 Oracle 教程。【参考方案11】:

用 Kotlin 编写: 如果您需要两个日期之间的差异并且不关心日期本身(如果您需要在应用程序中执行某些操作,例如基于保存在共享首选项中的其他操作时间的时间)。 第一次保存:

val firstTime:Long= System.currentTimeMillis()

第二次保存:

val now:Long= System.currentTimeMillis()

计算2次之间的毫秒数:

val milisecondsSinceLastTime: Long =(now-lastScrollTime)

【讨论】:

【参考方案12】:

当您尝试从该差异中构造一个日期时,假设您要创建一个新的 Date 对象,并将该差异值作为其纪元时间。

//get time in milliseconds
long diff = date1.getTime() - date2.getTime();
//get time in seconds
long seconds = diff / 1000;
//and so on
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;

有关更多信息,您可以使用这些链接:

Oracle tutorial: Date Time,讲解如何使用java.time。

ThreeTen Backport project,java.time 到 Java 的反向移植 6 和 7。

ThreeTenABP,Android 版 ThreeTen Backport。

问题:How to use ThreeTenABP in Android Project,解释得很透彻。

【讨论】:

【参考方案13】:

获取上午和下午之间的时差

private int  getTimeDiff() 
    SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss aa");
    Date systemDate = Calendar.getInstance().getTime();
    String myDate = sdf.format(systemDate);
    Date current = null;
    Date Date2 = null;
    try 
        current = sdf.parse(myDate);
        // current = sdf.parse("05:00:00 pm");
        Date2 = sdf.parse("12:00:00 am");
     catch (ParseException e) 
        e.printStackTrace();
    
    long millse = Date2.getTime() - current.getTime();
    long mills = Math.abs(millse);
    int Hours = (int) (mills / (1000 * 60 * 60));
    int Mins = (int) (mills / (1000 * 60)) % 60;
    long Secs = (int) (mills / 1000) % 60;
    String diff = Hours + ":" + Mins + ":" + Secs;
    int min = 60-Mins;
    if (Hours >= 12) 
        String requiredTime = 24 - Hours + ":" + Mins + ":" + Secs;
        int minutes= ((24-Hours)*60)-Mins;
        return minutes;

     else 
        int time = 12 - Hours;
        int hours=time+12;
        int res = (hours*60);
        int minutes = res-Mins;
        return minutes;
    

【讨论】:

考虑扔掉早已过时且臭名昭著的麻烦SimpleDateFormat和朋友。看看您是否可以使用desugaring 或将ThreeTenABP 添加到您的Android 项目中,以便使用现代Java 日期和时间API 的java.time。使用起来感觉好多了。【参考方案14】:

对我有用的最短答案。以毫秒为单位发送开始和结束日期。

public int GetDifference(long start,long end)
    Calendar cal = Calendar.getInstance();
    cal.setTimeInMillis(start);
    int hour = cal.get(Calendar.HOUR_OF_DAY);
    int min = cal.get(Calendar.MINUTE);
    long t=(23-hour)*3600000+(59-min)*60000;

    t=start+t;

    int diff=0;
    if(end>t)
        diff=(int)((end-t)/ TimeUnit.DAYS.toMillis(1))+1;
    

    return  diff;

【讨论】:

以上是关于如何在 android 中获得两个日期之间的差异?,尝试所有事情并发布的主要内容,如果未能解决你的问题,请参考以下文章

如何获得 s-s-rS 中两个日期变量之间的差异

如何获得两个日期之间的小时差?

如何在postgreSQL中获得精确的日期差异?

没有闰日的两个日期之间的差异

Laravel中两个日期之间的差异

获取 JavaScript 中两个日期之间的差异? [复制]