Java'da "zaman önce" nasıl hesaplanır?


127

Ruby on Rails'de, herhangi bir Tarihi almanıza ve bunun ne kadar "uzun zaman önce" olduğunu yazdırmanıza izin veren bir özellik vardır.

Örneğin:

8 minutes ago
8 hours ago
8 days ago
8 months ago
8 years ago

Java'da bunu yapmanın kolay bir yolu var mı?


1
Bakınız: stackoverflow.com/questions/11/how-do-i-calculate-relative-time Bu C #, ama eminim onu ​​çok az sorunla dönüştürebilirsiniz.
Brandon

Yanıtlar:


177

PrettyTime kitaplığına bir göz atın .

Kullanımı oldukça basit:

import org.ocpsoft.prettytime.PrettyTime;

PrettyTime p = new PrettyTime();
System.out.println(p.format(new Date()));
// prints "moments ago"

Ayrıca uluslararasılaştırılmış mesajlar için bir yerel ayar da geçebilirsiniz:

PrettyTime p = new PrettyTime(new Locale("fr"));
System.out.println(p.format(new Date()));
// prints "à l'instant"

Yorumlarda belirtildiği gibi, Android bu işlevselliğe android.text.format.DateUtilssınıfta yerleşiktir .


230
Android üzerinde çalışıyorsanız, şunu kullanabilirsiniz: android.text.format.DateUtils # getRelativeTimeSpanString ()
Somatik

Cevabınıza biraz daha açıklama ekleyebilir misiniz, sadece bağlantı cevabı şimdilik iyi değil.
Ajay S

@Somatik, bunu android olmayan bir platformda almanız gerekiyorsa, o sınıfı AOSP'de görüntüleyebilirsiniz.
greg7gkb

@ataylor bu Android'de nasıl kullanılır?
Hardik Parmar

getRelativeTimeSpanString tüm durumlar için ideal değildir ve bu yüzden buradaki birçok örneğe dayanarak kendi sınıfımı oluşturdum. Aşağıdaki
çözümüme

67

TimeUnit numaralandırmayı düşündünüz mü ? Bu tür şeyler için oldukça faydalı olabilir

    try {
        SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
        Date past = format.parse("01/10/2010");
        Date now = new Date();

        System.out.println(TimeUnit.MILLISECONDS.toMillis(now.getTime() - past.getTime()) + " milliseconds ago");
        System.out.println(TimeUnit.MILLISECONDS.toMinutes(now.getTime() - past.getTime()) + " minutes ago");
        System.out.println(TimeUnit.MILLISECONDS.toHours(now.getTime() - past.getTime()) + " hours ago");
        System.out.println(TimeUnit.MILLISECONDS.toDays(now.getTime() - past.getTime()) + " days ago");
    }
    catch (Exception j){
        j.printStackTrace();
    }

4
Zaman birimleri bağımsız olduğu için bunun tam bir cevap olduğunu düşünmüyorum. Örneğin, milisaniye süresi yalnızca dakikadır * 60 * 1000. Bir "süre önce kullanabilmek için, her bir zaman biriminden sonraki daha büyük zaman birimini (daha düşük zaman birimine dönüştürdükten sonra) azaltmanız gerekir. "string.
Nativ

@Benj - Doğru mu? Yukarıdaki çözüm? çünkü bir saat 12 saat biçiminde ve başka bir saat 24 saat biçiminde. Sorgum için geri bildiriminizi bildirin. Şimdiden teşekkürler.
Swift

bu yanlış olsa da ... her birim daha önce bahsedildiği gibi birbirinden bağımsızdır.
Jonathan Laliberte

1
android bunu sizin için yapar Android üzerinde çalışıyorsanız şunu kullanabilirsiniz: android.text.format.DateUtils.getRelativeTimeSpanString (milisaniye)
Wajid Ali

50

RealHowTo ve Ben J cevaplarını alıp kendi versiyonumu oluşturuyorum:

public class TimeAgo {
public static final List<Long> times = Arrays.asList(
        TimeUnit.DAYS.toMillis(365),
        TimeUnit.DAYS.toMillis(30),
        TimeUnit.DAYS.toMillis(1),
        TimeUnit.HOURS.toMillis(1),
        TimeUnit.MINUTES.toMillis(1),
        TimeUnit.SECONDS.toMillis(1) );
public static final List<String> timesString = Arrays.asList("year","month","day","hour","minute","second");

public static String toDuration(long duration) {

    StringBuffer res = new StringBuffer();
    for(int i=0;i< TimeAgo.times.size(); i++) {
        Long current = TimeAgo.times.get(i);
        long temp = duration/current;
        if(temp>0) {
            res.append(temp).append(" ").append( TimeAgo.timesString.get(i) ).append(temp != 1 ? "s" : "").append(" ago");
            break;
        }
    }
    if("".equals(res.toString()))
        return "0 seconds ago";
    else
        return res.toString();
}
public static void main(String args[]) {
    System.out.println(toDuration(123));
    System.out.println(toDuration(1230));
    System.out.println(toDuration(12300));
    System.out.println(toDuration(123000));
    System.out.println(toDuration(1230000));
    System.out.println(toDuration(12300000));
    System.out.println(toDuration(123000000));
    System.out.println(toDuration(1230000000));
    System.out.println(toDuration(12300000000L));
    System.out.println(toDuration(123000000000L));
}}

aşağıdakileri yazdıracak

0 second ago
1 second ago
12 seconds ago
2 minutes ago
20 minutes ago
3 hours ago
1 day ago
14 days ago
4 months ago
3 years ago

Gerçekten havalı. Ve hafta (lar) gibi başka zaman birimlerini eklemek gerçekten çok kolay
Piotr

1
bu daha fazla oyu hak ediyor. Her şeyden önce kitaplığa gerek yok. Hala temiz, zarif ve değiştirilmesi kolay.
fangzhzh

küçük yazım hatası: kodunuzun içinde "TimeAgo" yerine "Listeler" statik özelliklerine başvuruyorsunuz. Lists.times.get (i) TimeAgo.get (i) olmalı ... ve benzeri
Diogo Gomes

2
Küçük öneri: çünkü 0 .append(temp != 1 ? "s" : "")yerine kullanın son eki .append(temp > 1 ? "s" : "")de olmalıdırs
berkus

1
@ShajeelAfzal evet, süre parametresi milisaniye cinsindendir ancak mutlak bir değer olmayan zamanlar arasındaki bir farktır. Aldığınız şey, unix zaman damgasının başladığı tarih olan 1 Ocak 1970 tarihinden itibaren geçen zamandır
Riccardo Casatta

42
  public class TimeUtils {

      public final static long ONE_SECOND = 1000;
      public final static long SECONDS = 60;

      public final static long ONE_MINUTE = ONE_SECOND * 60;
      public final static long MINUTES = 60;

      public final static long ONE_HOUR = ONE_MINUTE * 60;
      public final static long HOURS = 24;

      public final static long ONE_DAY = ONE_HOUR * 24;

      private TimeUtils() {
      }

      /**
       * converts time (in milliseconds) to human-readable format
       *  "<w> days, <x> hours, <y> minutes and (z) seconds"
       */
      public static String millisToLongDHMS(long duration) {
        StringBuffer res = new StringBuffer();
        long temp = 0;
        if (duration >= ONE_SECOND) {
          temp = duration / ONE_DAY;
          if (temp > 0) {
            duration -= temp * ONE_DAY;
            res.append(temp).append(" day").append(temp > 1 ? "s" : "")
               .append(duration >= ONE_MINUTE ? ", " : "");
          }

          temp = duration / ONE_HOUR;
          if (temp > 0) {
            duration -= temp * ONE_HOUR;
            res.append(temp).append(" hour").append(temp > 1 ? "s" : "")
               .append(duration >= ONE_MINUTE ? ", " : "");
          }

          temp = duration / ONE_MINUTE;
          if (temp > 0) {
            duration -= temp * ONE_MINUTE;
            res.append(temp).append(" minute").append(temp > 1 ? "s" : "");
          }

          if (!res.toString().equals("") && duration >= ONE_SECOND) {
            res.append(" and ");
          }

          temp = duration / ONE_SECOND;
          if (temp > 0) {
            res.append(temp).append(" second").append(temp > 1 ? "s" : "");
          }
          return res.toString();
        } else {
          return "0 second";
        }
      }


      public static void main(String args[]) {
        System.out.println(millisToLongDHMS(123));
        System.out.println(millisToLongDHMS((5 * ONE_SECOND) + 123));
        System.out.println(millisToLongDHMS(ONE_DAY + ONE_HOUR));
        System.out.println(millisToLongDHMS(ONE_DAY + 2 * ONE_SECOND));
        System.out.println(millisToLongDHMS(ONE_DAY + ONE_HOUR + (2 * ONE_MINUTE)));
        System.out.println(millisToLongDHMS((4 * ONE_DAY) + (3 * ONE_HOUR)
            + (2 * ONE_MINUTE) + ONE_SECOND));
        System.out.println(millisToLongDHMS((5 * ONE_DAY) + (4 * ONE_HOUR)
            + ONE_MINUTE + (23 * ONE_SECOND) + 123));
        System.out.println(millisToLongDHMS(42 * ONE_DAY));
        /*
          output :
                0 second
                5 seconds
                1 day, 1 hour
                1 day and 2 seconds
                1 day, 1 hour, 2 minutes
                4 days, 3 hours, 2 minutes and 1 second
                5 days, 4 hours, 1 minute and 23 seconds
                42 days
         */
    }
}

more @ Bir süreyi milisaniye cinsinden insan tarafından okunabilir bir biçime biçimlendirin


Bunun revize edilmiş bir versiyonunu kullanmayı bıraktım. Düzeltmelerimi sizin için yayınladım.
David Blevins

5
David Blevins, PrettyTime hakkında daha fazla örnek: stackoverflow.com/questions/3859288/… Tekerleği bir kez daha yeniden icat etmek ve 3. taraf kitaplığı
önermemek

9

Bu, RealHowTo'nun cevabına dayanmaktadır, bu yüzden eğer beğenirseniz, ona da biraz sevgi gösterin.

Bu temizlenmiş sürüm, ilgilenebileceğiniz zaman aralığını belirlemenize olanak tanır.

Aynı zamanda "ve" bölümünü biraz farklı şekilde ele alır. Sıklıkla dizeleri bir sınırlayıcıyla birleştirirken karmaşık mantığı atlamanın ve işiniz bittiğinde son sınırlayıcıyı silmenin daha kolay olduğunu düşünüyorum.

import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

public class TimeUtils {

    /**
     * Converts time to a human readable format within the specified range
     *
     * @param duration the time in milliseconds to be converted
     * @param max      the highest time unit of interest
     * @param min      the lowest time unit of interest
     */
    public static String formatMillis(long duration, TimeUnit max, TimeUnit min) {
        StringBuilder res = new StringBuilder();

        TimeUnit current = max;

        while (duration > 0) {
            long temp = current.convert(duration, MILLISECONDS);

            if (temp > 0) {
                duration -= current.toMillis(temp);
                res.append(temp).append(" ").append(current.name().toLowerCase());
                if (temp < 2) res.deleteCharAt(res.length() - 1);
                res.append(", ");
            }

            if (current == min) break;

            current = TimeUnit.values()[current.ordinal() - 1];
        }

        // clean up our formatting....

        // we never got a hit, the time is lower than we care about
        if (res.lastIndexOf(", ") < 0) return "0 " + min.name().toLowerCase();

        // yank trailing  ", "
        res.deleteCharAt(res.length() - 2);

        //  convert last ", " to " and"
        int i = res.lastIndexOf(", ");
        if (i > 0) {
            res.deleteCharAt(i);
            res.insert(i, " and");
        }

        return res.toString();
    }
}

Bir koşuşturma vermek için küçük bir kod:

import static java.util.concurrent.TimeUnit.*;

public class Main {

    public static void main(String args[]) {
        long[] durations = new long[]{
            123,
            SECONDS.toMillis(5) + 123,
            DAYS.toMillis(1) + HOURS.toMillis(1),
            DAYS.toMillis(1) + SECONDS.toMillis(2),
            DAYS.toMillis(1) + HOURS.toMillis(1) + MINUTES.toMillis(2),
            DAYS.toMillis(4) + HOURS.toMillis(3) + MINUTES.toMillis(2) + SECONDS.toMillis(1),
            DAYS.toMillis(5) + HOURS.toMillis(4) + MINUTES.toMillis(1) + SECONDS.toMillis(23) + 123,
            DAYS.toMillis(42)
        };

        for (long duration : durations) {
            System.out.println(TimeUtils.formatMillis(duration, DAYS, SECONDS));
        }

        System.out.println("\nAgain in only hours and minutes\n");

        for (long duration : durations) {
            System.out.println(TimeUtils.formatMillis(duration, HOURS, MINUTES));
        }
    }

}

Aşağıdakileri çıktı:

0 seconds
5 seconds 
1 day and 1 hour 
1 day and 2 seconds 
1 day, 1 hour and 2 minutes 
4 days, 3 hours, 2 minutes and 1 second 
5 days, 4 hours, 1 minute and 23 seconds 
42 days 

Again in only hours and minutes

0 minutes
0 minutes
25 hours 
24 hours 
25 hours and 2 minutes 
99 hours and 2 minutes 
124 hours and 1 minute 
1008 hours 

Ve herhangi birinin buna ihtiyacı olması durumunda, işte yukarıdaki gibi herhangi bir dizeyi tekrar milisaniyeye dönüştürecek bir sınıf . İnsanların okunabilir metinde çeşitli şeylerin zaman aşımlarını belirlemelerine izin vermek için oldukça kullanışlıdır.


9

bunu yapmanın basit bir yolu var:

Diyelim ki zamanı 20 dakika önce istiyorsun:

Long minutesAgo = new Long(20);
Date date = new Date();
Date dateIn_X_MinAgo = new Date (date.getTime() - minutesAgo*60*1000);

bu kadar..


1
Çoğu durumda "akıllı" bir ekran istiyorsunuz, yani. 5125 dakika yerine x gün önce söylediniz.
PhiLho

7

Hakkında yerleşik çözümleri:

Java, zamanları biçimlendirmek için yerleşik desteğe sahip değildir, ayrıca Java-8 ve yeni paketi de yoktur java.time. Yalnızca İngilizceye ihtiyacınız varsa ve başka hiçbir şeye ihtiyacınız yoksa o zaman ve ancak o zaman el yapımı bir çözüm kabul edilebilir - @RealHowTo yanıtına bakın (ancak anlık deltaların yerel saate çevrilmesi için saat dilimini hesaba katmamak gibi güçlü bir dezavantajı vardır. birimler!). Her neyse, özellikle diğer yerel ayarlar için evde büyüyen karmaşık geçici çözümlerden kaçınmak istiyorsanız, o zaman harici bir kitaplığa ihtiyacınız var.

İkinci durumda, kütüphanemi Time4J (veya Android'de Time4A) kullanmanızı tavsiye ederim . En büyük esnekliği ve çoğu i18n gücünü sunar . Net.time4j.PrettyTime sınıfının printRelativeTime...(...)bu amaç için yedi yöntemi vardır . Zaman kaynağı olarak bir test saatinin kullanıldığı örnek:

TimeSource<?> clock = () -> PlainTimestamp.of(2015, 8, 1, 10, 24, 5).atUTC();
Moment moment = PlainTimestamp.of(2015, 8, 1, 17, 0).atUTC(); // our input
String durationInDays =
  PrettyTime.of(Locale.GERMAN).withReferenceClock(clock).printRelative(
    moment,
    Timezone.of(EUROPE.BERLIN),
    TimeUnit.DAYS); // controlling the precision
System.out.println(durationInDays); // heute (german word for today)

java.time.InstantGirdi olarak kullanılan başka bir örnek :

String relativeTime = 
  PrettyTime.of(Locale.ENGLISH)
    .printRelativeInStdTimezone(Moment.from(Instant.EPOCH));
System.out.println(relativeTime); // 45 years ago

Bu kütüphane, en son sürümü (v4.17) 80 dili ve ayrıca bazı ülkeye özgü yerel ayarları (özellikle İspanyolca, İngilizce, Arapça, Fransızca) desteklemektedir. İ18n verileri temel olarak en yeni CLDR sürümü v29'u temel alır . Bu kitaplığı kullanmanın diğer önemli nedenleri , çoğul kuralları (diğer yerel ayarlardaki İngilizceden genellikle farklıdır), kısaltılmış biçim stilini (örneğin: "1 saniye önce") ve saat dilimlerini hesaba katmanın anlamlı yolları için iyi destek sağlamaktır . Time4J, göreceli zaman hesaplamalarındaki artık saniyeler gibi egzotik ayrıntıların bile farkındadır (gerçekten önemli değil, ancak beklenti ufkuyla ilgili bir mesaj oluşturur). Java-8 ile uyumlujava.time.Instantveya gibi türler için kolayca kullanılabilen dönüştürme yöntemleri nedeniyle mevcuttur java.time.Period.

Herhangi bir sakınca var mı? Sadece iki.

  • Kitaplık küçük değildir (ayrıca büyük i18n-veri deposu nedeniyle).
  • API iyi bilinmediğinden topluluk bilgisi ve desteği henüz mevcut değil, aksi takdirde sağlanan belgeler oldukça ayrıntılı ve kapsamlıdır.

(Kompakt) alternatifler:

Daha küçük bir çözüm arıyorsanız ve çok fazla özelliğe ihtiyacınız yoksa ve i18n verileriyle ilgili olası kalite sorunlarını tolere etmeye istekliyseniz, o zaman:

  • Ocpsoft / PrettyTime'ı tavsiye ederim (aslında 32 dil desteği (yakında 34?) java.util.DateSadece çalışmak için uygun - @ ataylor cevabına bakın). Büyük topluluk geçmişine sahip endüstri standardı CLDR (Unicode konsorsiyumundan) maalesef i18n verilerinin temeli değildir, bu nedenle verilerin daha fazla geliştirilmesi veya iyileştirilmesi biraz zaman alabilir ...

  • Android kullanıyorsanız yardımcı sınıf android.text.format.DateUtils ince bir yerleşik alternatiftir (diğer yorumlara ve yanıtlara buradan bakın, dezavantajı yıllarca ve aylarca desteklenmemesidir. Ve eminim ki yalnızca çok az kişi bu yardımcı sınıfın API stilini beğenir.

  • Eğer bir hayranı iseniz Joda-Time sonra onun sınıf bakabilirsiniz PeriodFormat bırakma v2.9.4 14 dil için (destek, diğer tarafta: Joda-Time Sadece burada söz yüzden de mutlaka kompakt değildir tamlık). Bu kitaplık gerçek bir cevap değil çünkü göreli zamanlar hiç desteklenmiyor. En azından "önce" kelimesini eklemeniz gerekir (ve oluşturulan liste biçimlerinden tüm alt birimleri elle ayırmanız - garip). Time4J veya Android-DateUtils'ten farklı olarak, kısaltmalar veya göreli zamanlardan mutlak zaman gösterimlerine otomatik geçiş için özel bir desteği yoktur. PrettyTime gibi, Java topluluğunun özel üyelerinin i18n verilerine onaylanmamış katkılarına tamamen bağlıdır.


5

Basit bir "Bugün", "Dün" veya "x gün önce" arıyorsanız.

private String getDaysAgo(Date date){
    long days = (new Date().getTime() - date.getTime()) / 86400000;

    if(days == 0) return "Today";
    else if(days == 1) return "Yesterday";
    else return days + " days ago";
}

5

java.time

Java 8 ve sonraki sürümlerde yerleşik olan java.time çerçevesini kullanma .

LocalDateTime t1 = LocalDateTime.of(2015, 1, 1, 0, 0, 0);
LocalDateTime t2 = LocalDateTime.now();
Period period = Period.between(t1.toLocalDate(), t2.toLocalDate());
Duration duration = Duration.between(t1, t2);

System.out.println("First January 2015 is " + period.getYears() + " years ago");
System.out.println("First January 2015 is " + period.getMonths() + " months ago");
System.out.println("First January 2015 is " + period.getDays() + " days ago");
System.out.println("First January 2015 is " + duration.toHours() + " hours ago");
System.out.println("First January 2015 is " + duration.toMinutes() + " minutes ago");

1
Bu Durationyöntemler, tüm süreyi toplam saat sayısı ve toplam dakika sayısı olarak bildirir . Java 8'de sınıf tuhaf bir şekilde saat, dakika ve saniyenin her bir parçasını elde etmek için herhangi bir yöntemden yoksundu . Java 9 bu yöntemleri getiriyor to…Part.
Basil Bourque

5

Buradaki bir dizi cevaba dayanarak, kullanım durumum için aşağıdakileri oluşturdum.

Örnek kullanım:

String relativeDate = String.valueOf(
                TimeUtils.getRelativeTime( 1000L * myTimeInMillis() ));

import java.util.Arrays;
import java.util.List;

import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * Utilities for dealing with dates and times
 */
public class TimeUtils {

    public static final List<Long> times = Arrays.asList(
        DAYS.toMillis(365),
        DAYS.toMillis(30),
        DAYS.toMillis(7),
        DAYS.toMillis(1),
        HOURS.toMillis(1),
        MINUTES.toMillis(1),
        SECONDS.toMillis(1)
    );

    public static final List<String> timesString = Arrays.asList(
        "yr", "mo", "wk", "day", "hr", "min", "sec"
    );

    /**
     * Get relative time ago for date
     *
     * NOTE:
     *  if (duration > WEEK_IN_MILLIS) getRelativeTimeSpanString prints the date.
     *
     * ALT:
     *  return getRelativeTimeSpanString(date, now, SECOND_IN_MILLIS, FORMAT_ABBREV_RELATIVE);
     *
     * @param date String.valueOf(TimeUtils.getRelativeTime(1000L * Date/Time in Millis)
     * @return relative time
     */
    public static CharSequence getRelativeTime(final long date) {
        return toDuration( Math.abs(System.currentTimeMillis() - date) );
    }

    private static String toDuration(long duration) {
        StringBuilder sb = new StringBuilder();
        for(int i=0;i< times.size(); i++) {
            Long current = times.get(i);
            long temp = duration / current;
            if (temp > 0) {
                sb.append(temp)
                  .append(" ")
                  .append(timesString.get(i))
                  .append(temp > 1 ? "s" : "")
                  .append(" ago");
                break;
            }
        }
        return sb.toString().isEmpty() ? "now" : sb.toString();
    }
}

Çok faydalı, çok teşekkür ederim.
Haya Akkad

4

İstediğinizi yapan jquery-timeago eklentisinin basit bir Java timeago bağlantı noktası oluşturdum .

TimeAgo time = new TimeAgo();
String minutes = time.timeAgo(System.currentTimeMillis() - (15*60*1000)); // returns "15 minutes ago"

4

Android için bir uygulama geliştiriyorsanız, bu tür tüm gereksinimler için DateUtils yardımcı program sınıfını sağlar . DateUtils # getRelativeTimeSpanString () yardımcı program yöntemine bir göz atın .

Dokümanlardan

CharSequence getRelativeTimeSpanString (uzun zaman, uzun şimdi, uzun minResolution)

'Zaman'ı' şimdi'ye göre bir zaman olarak tanımlayan bir dize döndürür. Geçmişteki zaman aralıkları "42 dakika önce" olarak biçimlendirilmiştir. Gelecekteki zaman aralıkları "42 dakika içinde" şeklinde biçimlendirilir.

Eğer geçen olacağım timestampolarak zaman ve System.currentTimeMillis()şekilde şimdi . minResolutionEğer asgari zaman aralığı rapor etmek belirlemenizi sağlar.

Örneğin, MINUTE_IN_MILLIS olarak ayarlanmışsa, 3 saniyelik geçmiş bir zaman "0 dakika önce" olarak rapor edilecektir. 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS vb.


4

Zamanı hesaplamak için bu işlevi kullanabilirsiniz.

 private String timeAgo(long time_ago) {
        long cur_time = (Calendar.getInstance().getTimeInMillis()) / 1000;
        long time_elapsed = cur_time - time_ago;
        long seconds = time_elapsed;
        int minutes = Math.round(time_elapsed / 60);
        int hours = Math.round(time_elapsed / 3600);
        int days = Math.round(time_elapsed / 86400);
        int weeks = Math.round(time_elapsed / 604800);
        int months = Math.round(time_elapsed / 2600640);
        int years = Math.round(time_elapsed / 31207680);

        // Seconds
        if (seconds <= 60) {
            return "just now";
        }
        //Minutes
        else if (minutes <= 60) {
            if (minutes == 1) {
                return "one minute ago";
            } else {
                return minutes + " minutes ago";
            }
        }
        //Hours
        else if (hours <= 24) {
            if (hours == 1) {
                return "an hour ago";
            } else {
                return hours + " hrs ago";
            }
        }
        //Days
        else if (days <= 7) {
            if (days == 1) {
                return "yesterday";
            } else {
                return days + " days ago";
            }
        }
        //Weeks
        else if (weeks <= 4.3) {
            if (weeks == 1) {
                return "a week ago";
            } else {
                return weeks + " weeks ago";
            }
        }
        //Months
        else if (months <= 12) {
            if (months == 1) {
                return "a month ago";
            } else {
                return months + " months ago";
            }
        }
        //Years
        else {
            if (years == 1) {
                return "one year ago";
            } else {
                return years + " years ago";
            }
        }
    }

1) Burada time_ago mikrosaniye cinsindendir


3

Joda zamanlı paket, kavramı vardır Dönemleri . Periyotlar ve Tarih Saatleriyle aritmetik yapabilirsiniz.

Gönderen docs :

public boolean isRentalOverdue(DateTime datetimeRented) {
  Period rentalPeriod = new  Period().withDays(2).withHours(12);
  return datetimeRented.plus(rentalPeriod).isBeforeNow();
}


2

Performansı düşünürsek bu daha iyi bir koddur, hesaplama sayısını azaltır. Neden Dakikalar yalnızca saniye sayısı 60'tan büyükse hesaplanır ve Saatler yalnızca dakika sayısı 60'tan büyükse vb. Hesaplanır ...

class timeAgo {

static String getTimeAgo(long time_ago) {
    time_ago=time_ago/1000;
    long cur_time = (Calendar.getInstance().getTimeInMillis())/1000 ;
    long time_elapsed = cur_time - time_ago;
    long seconds = time_elapsed;
   // Seconds
    if (seconds <= 60) {
        return "Just now";
    }
    //Minutes
    else{
        int minutes = Math.round(time_elapsed / 60);

        if (minutes <= 60) {
            if (minutes == 1) {
                return "a minute ago";
            } else {
                return minutes + " minutes ago";
            }
        }
        //Hours
        else {
            int hours = Math.round(time_elapsed / 3600);
            if (hours <= 24) {
                if (hours == 1) {
                    return "An hour ago";
                } else {
                    return hours + " hrs ago";
                }
            }
            //Days
            else {
                int days = Math.round(time_elapsed / 86400);
                if (days <= 7) {
                    if (days == 1) {
                        return "Yesterday";
                    } else {
                        return days + " days ago";
                    }
                }
                //Weeks
                else {
                    int weeks = Math.round(time_elapsed / 604800);
                    if (weeks <= 4.3) {
                        if (weeks == 1) {
                            return "A week ago";
                        } else {
                            return weeks + " weeks ago";
                        }
                    }
                    //Months
                    else {
                        int months = Math.round(time_elapsed / 2600640);
                        if (months <= 12) {
                            if (months == 1) {
                                return "A month ago";
                            } else {
                                return months + " months ago";
                            }
                        }
                        //Years
                        else {
                            int years = Math.round(time_elapsed / 31207680);
                            if (years == 1) {
                                return "One year ago";
                            } else {
                                return years + " years ago";
                            }
                        }
                    }
                }
            }
        }
    }

}

}

1
Android üzerinde çalışıyorsanız, şunu kullanabilirsiniz: android.text.format.DateUtils.getRelativeTimeSpanString (milisaniye)
Wajid Ali

2

java.time

Habsq tarafından cevap doğru fikri ama yanlış yöntemleri vardır.

Yıllar-aylar-günler ölçeğinde zaman çizelgesine bağlı olmayan bir zaman aralığı için kullanın Period. Takvim ve saat-dakika-saniye ile ilgisi olmayan 24 saatlik zaman dilimleri anlamına gelen günler için kullanın Duration. İki ölçeği karıştırmak nadiren mantıklıdır.

Duration

Sınıfı kullanarak UTC'de görüldüğü gibi geçerli anı getirerek başlayın Instant.

Instant now = Instant.now();  // Capture the current moment as seen in UTC.
Instant then = now.minus( 8L , ChronoUnit.HOURS ).minus( 8L , ChronoUnit.MINUTES ).minus( 8L , ChronoUnit.SECONDS );
Duration d = Duration.between( then , now );

Saat, dakika ve saniye için metin oluşturun.

// Generate text by calling `to…Part` methods.
String output = d.toHoursPart() + " hours ago\n" + d.toMinutesPart() + " minutes ago\n" + d.toSecondsPart() + " seconds ago";

Konsola boşaltın.

System.out.println( "From: " + then + " to: " + now );
System.out.println( output );

Gönderen: 2019-06-04T11: 53: 55.714965Z to: 2019-06-04T20: 02: 03.714965Z

8 saat önce

8 dakika önce

8 saniye önce

Period

Geçerli tarihi alarak başlayın.

Tarih belirlemede saat dilimi çok önemlidir. Herhangi bir an için tarih, dünya genelinde bölgeye göre değişir. Örneğin, Paris'te gece yarısından birkaç dakika sonra Fransa , Montréal Québec'te hala "dün" iken yeni bir gündür .

Saat dilimi belirtilmezse, JVM, geçerli varsayılan saat dilimini örtük olarak uygular. Bu varsayılan çalışma süresi (!) Sırasında herhangi bir anda değişebilir, bu nedenle sonuçlarınız değişebilir. İstediğiniz / beklenen saat dilimini açıkça bir bağımsız değişken olarak belirtmek daha iyidir. Kritikse, bölgeyi kullanıcınızla onaylayın.

Bir belirtme uygun bir zaman dilimi adı biçiminde Continent/Regiongibi America/Montreal, Africa/Casablancaya da Pacific/Auckland. Hiçbir zaman gibi 2-4 harfli bir kısaltma kullanın ESTveya ISToldukları gibi değil , gerçek zaman dilimleri, değil standardize ve hatta benzersiz değil (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Sekiz gün, aylar ve yıllar önceki bir tarihi yeniden oluşturun.

LocalDate then = today.minusYears( 8 ).minusMonths( 8 ).minusDays( 7 ); // Notice the 7 days, not 8, because of granularity of months. 

Geçen zamanı hesaplayın.

Period p = Period.between( then , today );

"Zaman önce" parçalarının dizisini oluşturun.

String output = p.getDays() + " days ago\n" + p.getMonths() + " months ago\n" + p.getYears() + " years ago";

Konsola boşaltın.

System.out.println( "From: " + then + " to: " + today );
System.out.println( output );

Gönderen: 2010-09-27: 2019-06-04

8 gün önce

8 ay önce

8 yıl önce


Hakkında java.time

Java.time çerçevesi daha sonra Java 8 ve yerleşiktir. Bu sınıflar zahmetli eski yerini mirası gibi tarih-saat sınıfları java.util.Date, Calendar& SimpleDateFormat.

Daha fazla bilgi edinmek için Oracle Eğitimi'ne bakın . Ve birçok örnek ve açıklama için Stack Overflow'da arama yapın. Spesifikasyon JSR 310'dur .

Şu anda bakım modunda olan Joda-Time projesi, java.time sınıflarına geçişi tavsiye ediyor .

Sen değiştirebilir java.time sizin veritabanı ile doğrudan nesneleri. JDBC 4.2 veya üstü ile uyumlu bir JDBC sürücüsü kullanın . Dizelere gerek yok, derslere gerek yok .java.sql.*

Java.time sınıflarını nereden edinebilirim?

ThreeTen-Ekstra proje ek sınıfları ile java.time uzanır. Bu proje, java.time uygulamasına gelecekteki olası eklemeler için kanıtlayıcı bir zemindir. Burada bazı yararlı sınıfları gibi bulabilir Interval, YearWeek, YearQuarter, ve daha .


Çok teşekkür ederim!
Ticherhaz

1

Uzun araştırmalardan sonra bunu buldum.

    public class GetTimeLapse {
    public static String getlongtoago(long createdAt) {
        DateFormat userDateFormat = new SimpleDateFormat("E MMM dd HH:mm:ss Z yyyy");
        DateFormat dateFormatNeeded = new SimpleDateFormat("MM/dd/yyyy HH:MM:SS");
        Date date = null;
        date = new Date(createdAt);
        String crdate1 = dateFormatNeeded.format(date);

        // Date Calculation
        DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        crdate1 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(date);

        // get current date time with Calendar()
        Calendar cal = Calendar.getInstance();
        String currenttime = dateFormat.format(cal.getTime());

        Date CreatedAt = null;
        Date current = null;
        try {
            CreatedAt = dateFormat.parse(crdate1);
            current = dateFormat.parse(currenttime);
        } catch (java.text.ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // Get msec from each, and subtract.
        long diff = current.getTime() - CreatedAt.getTime();
        long diffSeconds = diff / 1000;
        long diffMinutes = diff / (60 * 1000) % 60;
        long diffHours = diff / (60 * 60 * 1000) % 24;
        long diffDays = diff / (24 * 60 * 60 * 1000);

        String time = null;
        if (diffDays > 0) {
            if (diffDays == 1) {
                time = diffDays + "day ago ";
            } else {
                time = diffDays + "days ago ";
            }
        } else {
            if (diffHours > 0) {
                if (diffHours == 1) {
                    time = diffHours + "hr ago";
                } else {
                    time = diffHours + "hrs ago";
                }
            } else {
                if (diffMinutes > 0) {
                    if (diffMinutes == 1) {
                        time = diffMinutes + "min ago";
                    } else {
                        time = diffMinutes + "mins ago";
                    }
                } else {
                    if (diffSeconds > 0) {
                        time = diffSeconds + "secs ago";
                    }
                }

            }

        }
        return time;
    }
}

1

Android için Tam olarak Ravi'nin dediği gibi, ancak birçok insan sadece kopyalayıp buraya yapıştırmak istediğinden .

  try {
      SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
      Date dt = formatter.parse(date_from_server);
      CharSequence output = DateUtils.getRelativeTimeSpanString (dt.getTime());
      your_textview.setText(output.toString());
    } catch (Exception ex) {
      ex.printStackTrace();
      your_textview.setText("");
    }

Daha fazla zamanı olan insanlar için açıklama

  1. Verileri bir yerden alırsınız. İlk önce formatını bulmalısın.

Ör. Verileri bir sunucudan 27 Ocak 2016 Çar, 09:32:35 GMT biçiminde alıyorum [bu muhtemelen sizin durumunuz DEĞİLDİR]

bu tercüme edildi

SimpleDateFormat biçimlendirici = yeni SimpleDateFormat ("EEE, gg MMM yyyy HH: mm: ss Z");

nasıl bilebilirim Belgeleri buradan okuyun .

Sonra ayrıştırdıktan sonra bir tarih alırım. getRelativeTimeSpanString'e koyduğum tarih (herhangi bir ek parametre olmadan benim için sorun değil, varsayılan olarak dakika olarak)

Bir istisna olsun OLACAK sen anlamaya olmasaydı doğru ayrıştırma Dize istisna: gibi bir şey karakteri 5 at . 5. karaktere bakın ve ilk ayrıştırma dizenizi düzeltin. . Başka bir istisna ile karşılaşabilirsiniz, doğru formülü elde edene kadar bu adımları tekrarlayın.


1
private const val SECOND_MILLIS = 1
private const val MINUTE_MILLIS = 60 * SECOND_MILLIS
private const val HOUR_MILLIS = 60 * MINUTE_MILLIS
private const val DAY_MILLIS = 24 * HOUR_MILLIS

object TimeAgo {

fun timeAgo(time: Int): String {

    val now = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())
    if (time > now || time <= 0) {
        return "in the future"
    }

    val diff = now - time
    return when {
        diff < MINUTE_MILLIS -> "Just now"
        diff < 2 * MINUTE_MILLIS -> "a minute ago"
        diff < 60 * MINUTE_MILLIS -> "${diff / MINUTE_MILLIS} minutes ago"
        diff < 2 * HOUR_MILLIS -> "an hour ago"
        diff < 24 * HOUR_MILLIS -> "${diff / HOUR_MILLIS} hours ago"
        diff < 48 * HOUR_MILLIS -> "yesterday"
        else -> "${diff / DAY_MILLIS} days ago"
    }
}

}

Aramak

val String = timeAgo (unixTimeStamp)

zaman önce Kotlin'de almak için


0

İşte bunun Java Uygulamam

    public static String relativeDate(Date date){
    Date now=new Date();
    if(date.before(now)){
    int days_passed=(int) TimeUnit.MILLISECONDS.toDays(now.getTime() - date.getTime());
    if(days_passed>1)return days_passed+" days ago";
    else{
        int hours_passed=(int) TimeUnit.MILLISECONDS.toHours(now.getTime() - date.getTime());
        if(hours_passed>1)return days_passed+" hours ago";
        else{
            int minutes_passed=(int) TimeUnit.MILLISECONDS.toMinutes(now.getTime() - date.getTime());
            if(minutes_passed>1)return minutes_passed+" minutes ago";
            else{
                int seconds_passed=(int) TimeUnit.MILLISECONDS.toSeconds(now.getTime() - date.getTime());
                return seconds_passed +" seconds ago";
            }
        }
    }

    }
    else
    {
        return new SimpleDateFormat("HH:mm:ss MM/dd/yyyy").format(date).toString();
    }
  }

0

benim için çalışıyor

public class TimeDifference {
    int years;
    int months;
    int days;
    int hours;
    int minutes;
    int seconds;
    String differenceString;

    public TimeDifference(@NonNull Date curdate, @NonNull Date olddate) {

        float diff = curdate.getTime() - olddate.getTime();
        if (diff >= 0) {
            int yearDiff = Math.round((diff / (AppConstant.aLong * AppConstant.aFloat)) >= 1 ? (diff / (AppConstant.aLong * AppConstant.aFloat)) : 0);
            if (yearDiff > 0) {
                years = yearDiff;
                setDifferenceString(years + (years == 1 ? " year" : " years") + " ago");
            } else {
                int monthDiff = Math.round((diff / AppConstant.aFloat) >= 1 ? (diff / AppConstant.aFloat) : 0);
                if (monthDiff > 0) {
                    if (monthDiff > AppConstant.ELEVEN) {
                        monthDiff = AppConstant.ELEVEN;
                    }
                    months = monthDiff;
                    setDifferenceString(months + (months == 1 ? " month" : " months") + " ago");
                } else {
                    int dayDiff = Math.round((diff / (AppConstant.bFloat)) >= 1 ? (diff / (AppConstant.bFloat)) : 0);
                    if (dayDiff > 0) {
                        days = dayDiff;
                        if (days == AppConstant.THIRTY) {
                            days = AppConstant.TWENTYNINE;
                        }
                        setDifferenceString(days + (days == 1 ? " day" : " days") + " ago");
                    } else {
                        int hourDiff = Math.round((diff / (AppConstant.cFloat)) >= 1 ? (diff / (AppConstant.cFloat)) : 0);
                        if (hourDiff > 0) {
                            hours = hourDiff;
                            setDifferenceString(hours + (hours == 1 ? " hour" : " hours") + " ago");
                        } else {
                            int minuteDiff = Math.round((diff / (AppConstant.dFloat)) >= 1 ? (diff / (AppConstant.dFloat)) : 0);
                            if (minuteDiff > 0) {
                                minutes = minuteDiff;
                                setDifferenceString(minutes + (minutes == 1 ? " minute" : " minutes") + " ago");
                            } else {
                                int secondDiff = Math.round((diff / (AppConstant.eFloat)) >= 1 ? (diff / (AppConstant.eFloat)) : 0);
                                if (secondDiff > 0) {
                                    seconds = secondDiff;
                                } else {
                                    seconds = 1;
                                }
                                setDifferenceString(seconds + (seconds == 1 ? " second" : " seconds") + " ago");
                            }
                        }
                    }

                }
            }

        } else {
            setDifferenceString("Just now");
        }

    }

    public String getDifferenceString() {
        return differenceString;
    }

    public void setDifferenceString(String differenceString) {
        this.differenceString = differenceString;
    }

    public int getYears() {
        return years;
    }

    public void setYears(int years) {
        this.years = years;
    }

    public int getMonths() {
        return months;
    }

    public void setMonths(int months) {
        this.months = months;
    }

    public int getDays() {
        return days;
    }

    public void setDays(int days) {
        this.days = days;
    }

    public int getHours() {
        return hours;
    }

    public void setHours(int hours) {
        this.hours = hours;
    }

    public int getMinutes() {
        return minutes;
    }

    public void setMinutes(int minutes) {
        this.minutes = minutes;
    }

    public int getSeconds() {
        return seconds;
    }

    public void setSeconds(int seconds) {
        this.seconds = seconds;
    } }

0

Bu çok basit bir senaryodur. doğaçlaması kolaydır.
Sonuç: (XXX Saat Önce) veya (XX Gün Önce / Dün / Bugün)

<span id='hourpost'></span>
,or
<span id='daypost'></span>

<script>
var postTime = new Date('2017/6/9 00:01'); 
var now = new Date();
var difference = now.getTime() - postTime.getTime();
var minutes = Math.round(difference/60000);
var hours = Math.round(minutes/60);
var days = Math.round(hours/24);

var result;
if (days < 1) {
result = "Today";
} else if (days < 2) {
result = "Yesterday";
} else {
result = days + " Days ago";
}

document.getElementById("hourpost").innerHTML = hours + "Hours Ago" ;
document.getElementById("daypost").innerHTML = result ;
</script>

0

Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years agoBu örnekte yaptığım bunun için tarihi 2018-09-05T06:40:46.183Zşu veya aşağıdaki gibi ayrıştırabilirsiniz

string.xml'de aşağıdaki değeri ekleyin

  <string name="lbl_justnow">Just Now</string>
    <string name="lbl_seconds_ago">seconds ago</string>
    <string name="lbl_min_ago">min ago</string>
    <string name="lbl_mins_ago">mins ago</string>
    <string name="lbl_hr_ago">hr ago</string>
    <string name="lbl_hrs_ago">hrs ago</string>
    <string name="lbl_day_ago">day ago</string>
    <string name="lbl_days_ago">days ago</string>
    <string name="lbl_lstweek_ago">last week</string>
    <string name="lbl_week_ago">weeks ago</string>
    <string name="lbl_onemonth_ago">1 month ago</string>
    <string name="lbl_month_ago">months ago</string>
    <string name="lbl_oneyear_ago" >last year</string>
    <string name="lbl_year_ago" >years ago</string>

java kodunu aşağıda deneyin

  public String getFormatDate(String postTime1) {
        Calendar cal=Calendar.getInstance();
        Date now=cal.getTime();
        String disTime="";
        try {
            Date postTime;
            //2018-09-05T06:40:46.183Z
            postTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(postTime1);

            long diff=(now.getTime()-postTime.getTime()+18000)/1000;

            //for months
            Calendar calObj = Calendar.getInstance();
            calObj.setTime(postTime);
            int m=calObj.get(Calendar.MONTH);
            calObj.setTime(now);

            SimpleDateFormat monthFormatter = new SimpleDateFormat("MM"); // output month

            int mNow = Integer.parseInt(monthFormatter.format(postTime));

            diff = diff-19800;

            if(diff<15) { //below 15 sec

                disTime = getResources().getString(R.string.lbl_justnow);
            } else if(diff<60) {

                //below 1 min
                disTime= diff+" "+getResources().getString(R.string.lbl_seconds_ago);
            } else if(diff<3600) {//below 1 hr

                // convert min
                long temp=diff/60;

                if(temp==1) {
                    disTime= temp + " " +getResources().getString(R.string.lbl_min_ago);
                } else {
                    disTime = temp  + " " +getResources().getString(R.string.lbl_mins_ago);
                }
            } else if(diff<(24*3600)) {// below 1 day

                // convert hr
                long temp= diff/3600;
                System.out.println("hey temp3:"+temp);
                if(temp==1) {
                    disTime = temp  + " " +getResources().getString(R.string.lbl_hr_ago);
                } else {
                    disTime = temp + " " +getResources().getString(R.string.lbl_hrs_ago);
                }
            } else if(diff<(24*3600*7)) {// below week

                // convert days
                long temp=diff/(3600*24);
                if (temp==1) {
                    //  disTime = "\nyesterday";
                    disTime = temp + " " +getResources().getString(R.string.lbl_day_ago);
                } else {
                    disTime = temp + " " +getResources().getString(R.string.lbl_days_ago);
                }
            } else if(diff<((24*3600*28))) {// below month

                // convert week
                long temp=diff/(3600*24*7);
                if (temp <= 4) {

                    if (temp < 1) {
                        disTime = getResources().getString(R.string.lbl_lstweek_ago);
                    }else{
                        disTime = temp + " " + getResources().getString(R.string.lbl_week_ago);
                    }

                } else {
                    int diffMonth = mNow - m;
                    Log.e("count : ", String.valueOf(diffMonth));
                    disTime = diffMonth + " " + getResources().getString(R.string.lbl_month_ago);
                }
            }else if(diff<((24*3600*365))) {// below year

                // convert month
                long temp=diff/(3600*24*30);

                System.out.println("hey temp2:"+temp);
                if (temp <= 12) {

                    if (temp == 1) {
                        disTime = getResources().getString(R.string.lbl_onemonth_ago);
                    }else{
                        disTime = temp + " " + getResources().getString(R.string.lbl_month_ago);
                    }
                }

            }else if(diff>((24*3600*365))) { // above year

                // convert year
                long temp=diff/(3600*24*30*12);

                System.out.println("hey temp8:"+temp);

                if (temp == 1) {
                    disTime = getResources().getString(R.string.lbl_oneyear_ago);
                }else{
                    disTime = temp + " " + getResources().getString(R.string.lbl_year_ago);
                }
            }

        } catch(Exception e) {
            e.printStackTrace();
        }

        return disTime;
    }

Android üzerinde çalışıyorsanız, şunu kullanabilirsiniz: android.text.format.DateUtils.getRelativeTimeSpanString (milisaniye)
Wajid Ali

0

Java'nın Library RelativeDateTimeFormatter'ı kullanabilirsiniz , tam olarak şunu yapar:

RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance();
 fmt.format(1, Direction.NEXT, RelativeUnit.DAYS); // "in 1 day"
 fmt.format(3, Direction.NEXT, RelativeUnit.DAYS); // "in 3 days"
 fmt.format(3.2, Direction.LAST, RelativeUnit.YEARS); // "3.2 years ago"

 fmt.format(Direction.LAST, AbsoluteUnit.SUNDAY); // "last Sunday"
 fmt.format(Direction.THIS, AbsoluteUnit.SUNDAY); // "this Sunday"
 fmt.format(Direction.NEXT, AbsoluteUnit.SUNDAY); // "next Sunday"
 fmt.format(Direction.PLAIN, AbsoluteUnit.SUNDAY); // "Sunday"

 fmt.format(Direction.LAST, AbsoluteUnit.DAY); // "yesterday"
 fmt.format(Direction.THIS, AbsoluteUnit.DAY); // "today"
 fmt.format(Direction.NEXT, AbsoluteUnit.DAY); // "tomorrow"

 fmt.format(Direction.PLAIN, AbsoluteUnit.NOW); // "now"

1
Bu bir Android kitaplığı, Java kitaplığı değil.
Madbreaks

0

Instant, Date ve DateTimeUtils kullanıyorum. Veritabanında String türünde depolanan ve daha sonra Instant'a dönüştürülen veriler (tarih).

    /*
    This method is to display ago.
    Example: 3 minutes ago.
    I already implement the latest which is including the Instant.
    Convert from String to Instant and then parse to Date.
     */
    public String convertTimeToAgo(String dataDate) {
    //Initialize
    String conversionTime = null;
    String suffix = "Yang Lalu";
    Date pastTime;
    //Parse from String (which is stored as Instant.now().toString()
    //And then convert to become Date
    Instant instant = Instant.parse(dataDate);
    pastTime = DateTimeUtils.toDate(instant);

    //Today date
    Date nowTime = new Date();

    long dateDiff = nowTime.getTime() - pastTime.getTime();
    long second = TimeUnit.MILLISECONDS.toSeconds(dateDiff);
    long minute = TimeUnit.MILLISECONDS.toMinutes(dateDiff);
    long hour = TimeUnit.MILLISECONDS.toHours(dateDiff);
    long day = TimeUnit.MILLISECONDS.toDays(dateDiff);

    if (second < 60) {
        conversionTime = second + " Saat " + suffix;
    } else if (minute < 60) {
        conversionTime = minute + " Minit " + suffix;
    } else if (hour < 24) {
        conversionTime = hour + " Jam " + suffix;
    } else if (day >= 7) {
        if (day > 30) {
            conversionTime = (day / 30) + " Bulan " + suffix;
        } else if (day > 360) {
            conversionTime = (day / 360) + " Tahun " + suffix;
        } else {
            conversionTime = (day / 7) + " Minggu " + suffix;
        }
    } else if (day < 7) {
        conversionTime = day + " Hari " + suffix;
    }
    return conversionTime;
    }

1
Yıllar önce java.time sınıfları tarafından değiştirilen korkunç eski tarih-saat sınıflarını kullanıyorsunuz .
Basil Bourque

@BasilBourque Bunu yapmanın en son yolunu hala bulamıyorum.
Ticherhaz

@BasilBourque Bunu anlamam için bazı kodlar ekledim. github.com/ticherhaz/tarikhmasa
Ticherhaz

0

Aşağıdaki çözümlerin tümü saf Java içindedir:

Seçenek 1: Yuvarlama yok ve yalnızca en büyük zaman kapsayıcısı

Aşağıdaki işlev yalnızca en büyük zaman kabını görüntüleyecektir, örneğin, gerçek geçen süre ise "1 month 14 days ago", bu işlev yalnızca görüntülenecektir "1 month ago". Bu işlev aynı zamanda her zaman aşağı yuvarlanacaktır, bu nedenle değerine eşdeğer bir zaman şöyle "50 days ago"görüntülenecektir"1 month"

public String formatTimeAgo(long millis) {
        String[] ids = new String[]{"second","minute","hour","day","month","year"};

        long seconds = millis / 1000;
        long minutes = seconds / 60;
        long hours = minutes / 60;
        long days = hours / 24;
        long months = days / 30;
        long years = months / 12;

        ArrayList<Long> times = new ArrayList<>(Arrays.asList(years, months, days, hours, minutes, seconds));

        for(int i = 0; i < times.size(); i++) {
            if(times.get(i) != 0) {
                long value = times.get(i).intValue();

                return value + " " + ids[ids.length - 1 - i] + (value == 1 ? "" : "s") + " ago";
            }
        }

        return "0 seconds ago";
    }

Seçenek 2: Yuvarlama ile

Basitçe yuvarlak için istediğini eğer öyleyse, bir Math.round (...) deyimi ile yuvarlak istediğiniz zaman kabı sarmak 50 daysiçin 2 months, değiştirmek long months = days / 30içinlong months = Math.round(days / 30.0)


1
Kullanılması Durationonun ile to…Partgösterildiği gibi yöntemlerle, çok daha kolay olurdu benim Yanıt .
Basil Bourque

0

İşte benim test durumum, umarım yardımcı olur:

    val currentCalendar = Calendar.getInstance()
    currentCalendar.set(2019, 6, 2, 5, 31, 0)

    val targetCalendar = Calendar.getInstance()
    targetCalendar.set(2019, 6, 2, 5, 30, 0)

    val diffTs = currentCalendar.timeInMillis - targetCalendar.timeInMillis
    val diffMins = TimeUnit.MILLISECONDS.toMinutes(diffTs)
    val diffHours = TimeUnit.MILLISECONDS.toHours(diffTs)
    val diffDays = TimeUnit.MILLISECONDS.toDays(diffTs)
    val diffWeeks = TimeUnit.MILLISECONDS.toDays(diffTs) / 7
    val diffMonths = TimeUnit.MILLISECONDS.toDays(diffTs) / 30
    val diffYears = TimeUnit.MILLISECONDS.toDays(diffTs) / 365

    val newTs = when {
        diffYears >= 1 -> "Years $diffYears"
        diffMonths >= 1 -> "Months $diffMonths"
        diffWeeks >= 1 -> "Weeks $diffWeeks"
        diffDays >= 1 -> "Days $diffDays"
        diffHours >= 1 -> "Hours $diffHours"
        diffMins >= 1 -> "Mins $diffMins"
        else -> "now"
    }

1
Korkunç Calendarsınıf, yıllar önce JSR 310'un benimsenmesiyle modern java.time sınıfları tarafından değiştirildi . 2019'da kötü tavsiye.
Basil Bourque

Kastetmiş olmalısın var, değil val.
Basil Bourque

0

GetrelativeDateTime Eğer Whatsapp bildiriminde gördüğümüz gibi işlev size tarih saat verecektir.
Gelecekteki göreceli Tarih Saatini almak için bunun için koşullar ekleyin. Bu, Whatsapp bildirimi gibi Tarih Saatini almak için özel olarak oluşturulmuştur.

private static String getRelativeDateTime(long date) {
    SimpleDateFormat DateFormat = new SimpleDateFormat("MMM dd, yyyy", Locale.getDefault());
    SimpleDateFormat TimeFormat = new SimpleDateFormat(" hh:mm a", Locale.getDefault());
    long now = Calendar.getInstance().getTimeInMillis();
    long startOfDay = StartOfDay(Calendar.getInstance().getTime());
    String Day = "";
    String Time = "";
    long millSecInADay = 86400000;
    long oneHour = millSecInADay / 24;
    long differenceFromNow = now - date;

    if (date > startOfDay) {
        if (differenceFromNow < (oneHour)) {
            int minute = (int) (differenceFromNow / (60000));
            if (minute == 0) {
                int sec = (int) differenceFromNow / 1000;
                if (sec == 0) {
                    Time = "Just Now";
                } else if (sec == 1) {
                    Time = sec + " second ago";
                } else {
                    Time = sec + " seconds ago";
                }
            } else if (minute == 1) {
                Time = minute + " minute ago";
            } else if (minute < 60) {
                Time = minute + " minutes ago";
            }
        } else {
            Day = "Today, ";
        }
    } else if (date > (startOfDay - millSecInADay)) {
        Day = "Yesterday, ";
    } else if (date > (startOfDay - millSecInADay * 7)) {
        int days = (int) (differenceFromNow / millSecInADay);
        Day = days + " Days ago, ";
    } else {
        Day = DateFormat.format(date);
    }
    if (Time.isEmpty()) {
        Time = TimeFormat.format(date);
    }
    return Day + Time;
}

public static long StartOfDay(Date date) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(date);
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    return calendar.getTimeInMillis();
}

Katkıda bulunmak istediğiniz için teşekkürler. Tam olarak sorulan bu değil, ama belki birisi kullanabilir. Ne o kimse ne de başkası kullanmak istememeli SimpleDateFormatve Calendaryine de. Bu sınıflar kötü tasarlanmış ve modası geçmiş. Bunun yerine, modern Java tarih ve saat API'si olan java.time'ı kullanan yanıtları okuyun.
Ole VV

0

Basitlik ve güncellenmiş yanıt eksikliği nedeniyle, daha yeni Java 8 ve sonraki sürümleri takip eder

import java.time.*;
import java.time.temporal.*;

public class Time {
    public static void main(String[] args) {

        System.out.println(LocalTime.now().minus(8, ChronoUnit.MINUTES));
        System.out.println(LocalTime.now().minus(8, ChronoUnit.HOURS));
        System.out.println(LocalDateTime.now().minus(8, ChronoUnit.DAYS));
        System.out.println(LocalDateTime.now().minus(8, ChronoUnit.MONTHS));
    }
}

Bu, Tarih ve Saat ile uğraşmak için geçmişteki sorunları çözmeye çalışan Java Zaman API'sini kullanan sürümdür.

Javadoc

sürüm 8 https://docs.oracle.com/javase/8/docs/api/index.html?java/time/package-summary.html

versiyon 11 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html

W3Schools Eğitimi - https://www.w3schools.com/java/java_date.asp

DZone Makalesi - https://dzone.com/articles/java-8-date-and-time

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.