Jeśli pracujesz na Androidzie, możesz użyć tego: android.text.format.DateUtils # getRelativeTimeSpanString ()
Somatik
Czy możesz dodać więcej opisu do swojej odpowiedzi, odpowiedź z samym łączem nie jest na razie dobra.
Ajay S
@Somatik, jeśli chcesz to uzyskać na platformie innej niż Android, możesz wyświetlić tę klasę na AOSP.
greg7gkb
@ataylor, jak to używać w systemie Android?
Hardik Parmar
Funkcja getRelativeTimeSpanString nie jest idealna dla wszystkich sytuacji i dlatego stworzyłem własną klasę na podstawie wielu przykładów tutaj. Zobacz moje rozwiązanie poniżej: stackoverflow.com/a/37042254/468360
Codeversed
67
Czy rozważałeś wyliczenie TimeUnit ? Może to być całkiem przydatne do tego rodzaju rzeczy
try{SimpleDateFormat format =newSimpleDateFormat("dd/MM/yyyy");Date past = format.parse("01/10/2010");Date now =newDate();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();}
Nie sądzę, że jest to pełna odpowiedź, ponieważ jednostki czasu są niezależne. Np. - czas milisekund to tylko minuty czas * 60 * 1000. Musisz zmniejszyć z każdej jednostki czasu kolejną większą jednostkę czasu (po przeliczeniu na niższą jednostkę czasu), aby móc z niej korzystać w "czasie temu " strunowy.
Nativ
@Benj - Czy to dobrze? powyższe rozwiązanie? ponieważ jeden czas jest w formacie 12-godzinnym, a inny w formacie 24-godzinnym. Daj mi znać swoją opinię dotyczącą mojego zapytania. Z góry dziękuję.
Swift
jest to jednak niepoprawne ... każda jednostka jest od siebie niezależna, jak już wspomniano.
Jonathan Laliberte
1
android robi to za ciebie Jeśli pracujesz na Androidzie, możesz użyć tego: android.text.format.DateUtils.getRelativeTimeSpanString (milisekundy)
Wajid Ali
50
Biorę odpowiedzi RealHowTo i Ben J i tworzę własną wersję:
publicclassTimeAgo{publicstaticfinalList<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));publicstaticfinalList<String> timesString =Arrays.asList("year","month","day","hour","minute","second");publicstaticString toDuration(long duration){StringBuffer res =newStringBuffer();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";elsereturn res.toString();}publicstaticvoid 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));}}
co spowoduje wydrukowanie następującego
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
Bardzo fajny. I bardzo łatwo jest dodać inne jednostki czasu, takie jak tydzień (tygodnie)
Piotr
1
ten zasługuje na więcej głosów. Przede wszystkim nie potrzeba żadnej biblioteki. Nadal jest czysty, elegancki i łatwy do zmiany.
fangzhzh
mała literówka: w kodzie odwołujesz się do statycznych właściwości „List” zamiast „TimeAgo”. Lists.times.get (i) powinno być TimeAgo.get (i) ... i tak dalej
Diogo Gomes
2
Mała sugestia: użyj .append(temp != 1 ? "s" : "")zamiast .append(temp > 1 ? "s" : "")ponieważ 0 powinno również mieć ssufiks
berkus
1
@ShajeelAfzal tak, parametr czasu trwania jest w milisekundach, ale jest to różnica między czasami, a nie wartość bezwzględna. To, co otrzymujesz, to czas, który minął od 1 stycznia 1970 roku, kiedy zaczął się znacznik czasu uniksowego
Skończyło się na poprawionej wersji tego. Wysłałem dla Ciebie moje poprawki.
David Blevins,
5
David Blevins, więcej przykładów na temat PrettyTime: stackoverflow.com/questions/3859288/ ... Duże -1 za ponowne wymyślenie koła i niezalecanie biblioteki innej firmy :-p
zakmck
9
Jest to oparte na odpowiedzi RealHowTo, więc jeśli Ci się spodoba, okaż mu też trochę miłości.
Ta oczyszczona wersja umożliwia określenie zakresu czasu, który może Cię zainteresować.
Trochę inaczej też traktuje część „i”. Często stwierdzam, że łącząc ciągi z separatorem, często łatwiej jest pominąć skomplikowaną logikę i po prostu usunąć ostatni separator, gdy skończysz.
import java.util.concurrent.TimeUnit;importstatic java.util.concurrent.TimeUnit.MILLISECONDS;publicclassTimeUtils{/**
* 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
*/publicstaticString formatMillis(long duration,TimeUnit max,TimeUnit min){StringBuilder res =newStringBuilder();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 aboutif(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();}}
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
A na wypadek, gdyby ktoś kiedykolwiek tego potrzebował, oto klasa, która przekształci dowolny ciąg, taki jak powyższy, z powrotem na milisekundy . Jest to bardzo przydatne, ponieważ pozwala ludziom określać limity czasu różnych rzeczy w czytelnym tekście.
W większości przypadków potrzebujesz „inteligentnego” wyświetlacza, tj. zamiast 5125 minut temu, mówisz x dni temu.
PhiLho,
7
O rozwiązaniach wbudowanych :
Java nie ma żadnej wbudowanej obsługi formatowania czasów względnych, także Java-8 i jej nowy pakiet java.time. Jeśli potrzebujesz tylko angielskiego i niczego więcej, wtedy i tylko wtedy ręcznie wykonane rozwiązanie może być akceptowalne - zobacz odpowiedź @RealHowTo (chociaż ma tę silną wadę, że nie bierze pod uwagę strefy czasowej przy tłumaczeniu natychmiastowych delt na czas lokalny jednostki!). W każdym razie, jeśli chcesz uniknąć skomplikowanych obejść opracowanych w domu, zwłaszcza w przypadku innych języków, potrzebujesz biblioteki zewnętrznej.
W drugim przypadku polecam skorzystać z mojej biblioteki Time4J (lub Time4A na Androidzie). Oferuje największą elastyczność i najwięcej mocy i18n . Klasa net.time4j.PrettyTime ma printRelativeTime...(...)do tego siedem metod . Przykład użycia zegara testowego jako źródła czasu:
TimeSource<?> clock =()->PlainTimestamp.of(2015,8,1,10,24,5).atUTC();Moment moment =PlainTimestamp.of(2015,8,1,17,0).atUTC();// our inputString durationInDays =PrettyTime.of(Locale.GERMAN).withReferenceClock(clock).printRelative(
moment,Timezone.of(EUROPE.BERLIN),TimeUnit.DAYS);// controlling the precisionSystem.out.println(durationInDays);// heute (german word for today)
Inny przykład użycia java.time.Instantjako dane wejściowe:
String relativeTime =PrettyTime.of(Locale.ENGLISH).printRelativeInStdTimezone(Moment.from(Instant.EPOCH));System.out.println(relativeTime);// 45 years ago
Ta biblioteka obsługuje w swojej najnowszej wersji (v4.17) 80 języków, a także niektóre ustawienia regionalne (szczególnie dla hiszpańskiego, angielskiego, arabskiego, francuskiego). Dane i18n są głównie oparte na najnowszej wersji CLDR v29 . Inne ważne powody, dla których warto korzystać z tej biblioteki, to dobra obsługa reguł liczby mnogiej (które często różnią się od angielskich w innych lokalizacjach), skrócony styl formatu (na przykład: „1 sekunda temu”) oraz wyraźne sposoby uwzględniania stref czasowych . Time4J zdaje sobie nawet sprawę z tak egzotycznych szczegółów, jak sekundy przestępne w obliczeniach czasów względnych (nie jest to naprawdę ważne, ale tworzy komunikat dotyczący horyzontu oczekiwań). Zgodność z Java-8istnieje dzięki łatwo dostępnym metodom konwersji dla typów takich jak java.time.Instantlub java.time.Period.
Czy są jakieś wady? Tylko dwa.
Biblioteka nie jest mała (także ze względu na duże repozytorium danych i18n).
Interfejs API nie jest dobrze znany, więc wiedza społeczności i wsparcie nie są jeszcze dostępne, w przeciwnym razie dostarczona dokumentacja jest dość szczegółowa i wyczerpująca.
(Kompaktowe) alternatywy:
Jeśli szukasz mniejszego rozwiązania i nie potrzebujesz tak wielu funkcji i jesteś gotów tolerować możliwe problemy z jakością związane z i18n-data, to:
Polecam ocpsoft / PrettyTime (wsparcie dla 32 języków (w rzeczywistości wkrótce 34) nadaje się do pracy z? java.util.DateTylko - patrz odpowiedź @ataylor). Standard branżowy CLDR (z konsorcjum Unicode) z jego dużym doświadczeniem społecznym nie jest niestety bazą danych i18n, więc dalsze ulepszenia lub ulepszenia danych mogą zająć trochę czasu ...
Jeśli używasz Androida, to pomocnicza klasa android.text.format.DateUtils jest wąską wbudowaną alternatywą (zobacz inne komentarze i odpowiedzi tutaj, z tą wadą, że nie ma wsparcia przez lata i miesiące. I jestem pewien, że tylko bardzo niewielu ludzi lubi styl API tej klasy pomocniczej.
Jeśli jesteś fanem Joda-Time , możesz spojrzeć na jego klasę PeriodFormat (obsługa 14 języków w wersji 2.9.4, z drugiej strony: Joda-Time z pewnością też nie jest kompaktowy, więc wspominam o tym tutaj tylko dla kompletność). Ta biblioteka nie jest prawdziwą odpowiedzią, ponieważ względne czasy w ogóle nie są obsługiwane. Będziesz musiał przynajmniej dodać dosłowne „temu” (i ręcznie usunąć wszystkie dolne jednostki z wygenerowanych formatów list - niezręczne). W przeciwieństwie do Time4J lub Android-DateUtils, nie ma specjalnej obsługi skrótów ani automatycznego przełączania z czasów względnych na reprezentacje czasu bezwzględnego. Podobnie jak PrettyTime, jest całkowicie zależny od niepotwierdzonego wkładu prywatnych członków społeczności Java do swoich danych i18n.
Jeśli szukasz prostego „Dzisiaj”, „Wczoraj” lub „X dni temu”.
privateString getDaysAgo(Date date){long days =(newDate().getTime()- date.getTime())/86400000;if(days ==0)return"Today";elseif(days ==1)return"Yesterday";elsereturn days +" days ago";}
Korzystanie ze środowiska java.time wbudowanego w język Java 8 i nowsze.
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");
Te Durationmetody raportują cały czas trwania jako całkowitą liczbę godzin i jako całkowitą liczbę minut. W Javie 8 klasa dziwnie nie miała żadnych metod, aby uzyskać każdą część godziny, minut i sekund. Java 9 przynosi tych metod to…Part.
CharSequence getRelativeTimeSpanString (długi czas, długi czas, długi minResolution)
Zwraca ciąg znaków opisujący „czas” jako czas względem „teraz”. Przedziały czasowe w przeszłości mają format „42 minuty temu”. Przedziały czasowe w przyszłości mają format „Za 42 minuty”.
Będziesz przechodzi swój timestampjak czas i System.currentTimeMillis()jak teraz . minResolutionPozwala określić minimalny Okres zgłosić.
Na przykład czas sprzed 3 sekund zostanie zgłoszony jako „0 minut temu”, jeśli jest ustawiony na MINUTE_IN_MILLIS. Podaj jeden z 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS itd.
Jest to lepszy kod, jeśli weźmiemy pod uwagę wydajność, ponieważ zmniejsza liczbę obliczeń.
Powód
Minuty są obliczane tylko wtedy, gdy liczba sekund jest większa niż 60, a godziny są obliczane tylko wtedy, gdy liczba minut jest większa niż 60 i tak dalej ...
Dla przedziału czasu niezwiązanego z osią czasu w skali lata-miesiące-dni użyj Period. W przypadku dni oznaczających 24-godzinne fragmenty czasu niezwiązane z kalendarzem i godziny-minuty-sekundy użyj Duration. Mieszanie obu skal rzadko ma sens.
Duration
Zacznij od pobrania aktualnego momentu, jak widać w UTC , przy użyciu Instantklasy.
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 );
Generuj tekst na godziny, minuty i sekundy.
// Generate text by calling `to…Part` methods.String output = d.toHoursPart()+" hours ago\n"+ d.toMinutesPart()+" minutes ago\n"+ d.toSecondsPart()+" seconds ago";
Zrzuć na konsolę.
System.out.println("From: "+ then +" to: "+ now );System.out.println( output );
Strefa czasowa ma kluczowe znaczenie przy ustalaniu daty. W dowolnym momencie data różni się na całym świecie według strefy. Na przykład, kilka minut po północy w Paryżu Francja jest nowym dniem, podczas gdy w Montrealu Quebec wciąż trwa „wczoraj” .
Jeśli nie określono strefy czasowej, maszyna JVM niejawnie stosuje swoją bieżącą domyślną strefę czasową. To ustawienie domyślne może się zmienić w dowolnym momencie w trakcie działania (!), Więc wyniki mogą się różnić. Lepiej jest jawnie określić żądaną / oczekiwaną strefę czasową jako argument. Jeśli jest to krytyczne, potwierdź strefę ze swoim użytkownikiem.
Określ prawidłową nazwę strefy czasowej w formacie Continent/Region, takie jak America/Montreal, Africa/Casablancalub Pacific/Auckland. Nigdy nie używaj skrótów składających się z 2-4 liter, takich jak ESTlub, ISTponieważ nie są to prawdziwe strefy czasowe, nie są standaryzowane, a nawet nie są unikalne (!).
ZoneId z =ZoneId.of("America/Montreal");LocalDate today =LocalDate.now( z );
Odtwórz datę sprzed ośmiu dni, miesięcy i lat.
LocalDate then = today.minusYears(8).minusMonths(8).minusDays(7);// Notice the 7 days, not 8, because of granularity of months.
Oblicz czas, który upłynął.
Period p =Period.between( then , today );
Zbuduj ciąg kawałków „dawniej”.
String output = p.getDays()+" days ago\n"+ p.getMonths()+" months ago\n"+ p.getYears()+" years ago";
Zrzuć na konsolę.
System.out.println("From: "+ then +" to: "+ today );System.out.println( output );
Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie ma potrzeby stosowania ciągów ani java.sql.*klas.
Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak Interval, YearWeek, YearQuarter, i więcej .
publicclassGetTimeLapse{publicstaticString getlongtoago(long createdAt){DateFormat userDateFormat =newSimpleDateFormat("E MMM dd HH:mm:ss Z yyyy");DateFormat dateFormatNeeded =newSimpleDateFormat("MM/dd/yyyy HH:MM:SS");Date date =null;
date =newDate(createdAt);String crdate1 = dateFormatNeeded.format(date);// Date CalculationDateFormat dateFormat =newSimpleDateFormat("MM/dd/yyyy HH:mm:ss");
crdate1 =newSimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(date);// get current date time with Calendar()Calendar cal =Calendar.getInstance();String currenttime = dateFormat.format(cal.getTime());DateCreatedAt=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;}}
Po przeanalizowaniu otrzymuję datę. datę, którą umieściłem w getRelativeTimeSpanString (bez żadnych dodatkowych parametrów jest w porządku, domyślnie minuty)
Otrzymasz wyjątek, jeśli nie wymyśliłeś prawidłowego ciągu parsowania , Coś w rodzaju: wyjątek przy znaku 5 . Spójrz na znak 5 i popraw początkowy ciąg analizy. . Możesz uzyskać inny wyjątek, powtarzaj te kroki, aż uzyskasz prawidłową formułę.
To jest bardzo podstawowy skrypt. łatwo jest improwizować.
Wynik: (XXX godzin temu) lub (XX dni temu / wczoraj / dziś)
<span id='hourpost'></span>,or
<span id='daypost'></span><script>
var postTime =newDate('2017/6/9 00:01');
var now =newDate();
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";}elseif(days <2){
result ="Yesterday";}else{
result = days +" Days ago";}
document.getElementById("hourpost").innerHTML = hours +"Hours Ago";
document.getElementById("daypost").innerHTML = result ;</script>
w tym celu zrobiłem Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years agow tym przykładzie, możesz przeanalizować datę taką 2018-09-05T06:40:46.183Zlub inną, jak poniżej
To jest biblioteka Androida, a nie biblioteka Java.
Madbreaks
0
Używam Instant, Date i DateTimeUtils. Dane (data), które są przechowywane w bazie danych w typie String, a następnie konwertowane na Instant.
/*
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.
*/publicString convertTimeToAgo(String dataDate){//InitializeString conversionTime =null;String suffix ="Yang Lalu";Date pastTime;//Parse from String (which is stored as Instant.now().toString()//And then convert to become DateInstant instant =Instant.parse(dataDate);
pastTime =DateTimeUtils.toDate(instant);//Today dateDate nowTime =newDate();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;}elseif(minute <60){
conversionTime = minute +" Minit "+ suffix;}elseif(hour <24){
conversionTime = hour +" Jam "+ suffix;}elseif(day >=7){if(day >30){
conversionTime =(day /30)+" Bulan "+ suffix;}elseif(day >360){
conversionTime =(day /360)+" Tahun "+ suffix;}else{
conversionTime =(day /7)+" Minggu "+ suffix;}}elseif(day <7){
conversionTime = day +" Hari "+ suffix;}return conversionTime;}
Opcja 1: bez zaokrąglania i tylko największy kontener czasu
Następująca funkcja wyświetli tylko największy kontener czasu, na przykład, jeśli prawdziwy czas, który upłynął "1 month 14 days ago", to ta funkcja będzie wyświetlana tylko "1 month ago". Ta funkcja również zawsze zaokrągla w dół, więc czas odpowiadający funkcji "50 days ago"będzie wyświetlany jako"1 month"
publicString formatTimeAgo(long millis){String[] ids =newString[]{"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 =newArrayList<>(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";}
Opcja 2: z zaokrągleniem
Po prostu zawiń kontener czasu, który chcesz zaokrąglić, instrukcją Math.round (...), więc jeśli chcesz zaokrąglić 50 daysdo 2 months, zmodyfikuj long months = days / 30dolong months = Math.round(days / 30.0)
Korzystanie Durationz jego to…Partmetod byłoby znacznie łatwiejsze, jak pokazano w mojej odpowiedzi .
Basil Bourque,
0
Oto mój przypadek testowy, mam nadzieję, że pomoże:
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"}
Straszliwa Calendarklasa została wyparta lat temu przez nowoczesne java.time klas wraz z przyjęciem JSR 310 . Słaba rada w 2019 r.
Basil Bourque
Musiałeś mieć na myśli var, nie val.
Basil Bourque
0
Funkcja getrelativeDateTime poda datę i godzinę, jak widać w powiadomieniu Whatsapp.
Aby uzyskać przyszłą względną datę i godzinę, dodaj dla niej warunki. Jest to tworzone specjalnie w celu uzyskania daty i godziny, takiej jak powiadomienie Whatsapp.
Dzięki za chęć udziału. Nie jest to dokładnie to, o co pytano, ale może ktoś może to wykorzystać. Ani ten ktoś, ani nikt inny nie powinien chcieć używać SimpleDateFormati Calendarchociaż. Te klasy są źle zaprojektowane i dawno przestarzałe. Zamiast tego przeczytaj odpowiedzi wykorzystujące java.time, nowoczesny interfejs API daty i czasu języka Java.
Ole VV
0
Ze względu na brak prostoty i zaktualizowanej odpowiedzi, następuje nowsza wersja Java 8 i nowszych
Odpowiedzi:
Spójrz na bibliotekę PrettyTime .
Jest dość prosty w użyciu:
Możesz również podać ustawienia regionalne dla wiadomości międzynarodowych:
Jak zauważono w komentarzach, Android ma tę funkcję wbudowaną w
android.text.format.DateUtils
klasę.źródło
Czy rozważałeś wyliczenie TimeUnit ? Może to być całkiem przydatne do tego rodzaju rzeczy
źródło
Biorę odpowiedzi RealHowTo i Ben J i tworzę własną wersję:
co spowoduje wydrukowanie następującego
źródło
.append(temp != 1 ? "s" : "")
zamiast.append(temp > 1 ? "s" : "")
ponieważ 0 powinno również miećs
sufikswięcej @ Sformatuj czas trwania w milisekundach do formatu czytelnego dla człowieka
źródło
Jest to oparte na odpowiedzi RealHowTo, więc jeśli Ci się spodoba, okaż mu też trochę miłości.
Ta oczyszczona wersja umożliwia określenie zakresu czasu, który może Cię zainteresować.
Trochę inaczej też traktuje część „i”. Często stwierdzam, że łącząc ciągi z separatorem, często łatwiej jest pominąć skomplikowaną logikę i po prostu usunąć ostatni separator, gdy skończysz.
Mały kod, aby nadać mu wir:
Który wyświetli następujące informacje:
A na wypadek, gdyby ktoś kiedykolwiek tego potrzebował, oto klasa, która przekształci dowolny ciąg, taki jak powyższy, z powrotem na milisekundy . Jest to bardzo przydatne, ponieważ pozwala ludziom określać limity czasu różnych rzeczy w czytelnym tekście.
źródło
można to zrobić w prosty sposób:
powiedzmy, że chcesz ustawić godzinę 20 minut temu:
Otóż to..
źródło
O rozwiązaniach wbudowanych :
Java nie ma żadnej wbudowanej obsługi formatowania czasów względnych, także Java-8 i jej nowy pakiet
java.time
. Jeśli potrzebujesz tylko angielskiego i niczego więcej, wtedy i tylko wtedy ręcznie wykonane rozwiązanie może być akceptowalne - zobacz odpowiedź @RealHowTo (chociaż ma tę silną wadę, że nie bierze pod uwagę strefy czasowej przy tłumaczeniu natychmiastowych delt na czas lokalny jednostki!). W każdym razie, jeśli chcesz uniknąć skomplikowanych obejść opracowanych w domu, zwłaszcza w przypadku innych języków, potrzebujesz biblioteki zewnętrznej.W drugim przypadku polecam skorzystać z mojej biblioteki Time4J (lub Time4A na Androidzie). Oferuje największą elastyczność i najwięcej mocy i18n . Klasa net.time4j.PrettyTime ma
printRelativeTime...(...)
do tego siedem metod . Przykład użycia zegara testowego jako źródła czasu:Inny przykład użycia
java.time.Instant
jako dane wejściowe:Ta biblioteka obsługuje w swojej najnowszej wersji (v4.17) 80 języków, a także niektóre ustawienia regionalne (szczególnie dla hiszpańskiego, angielskiego, arabskiego, francuskiego). Dane i18n są głównie oparte na najnowszej wersji CLDR v29 . Inne ważne powody, dla których warto korzystać z tej biblioteki, to dobra obsługa reguł liczby mnogiej (które często różnią się od angielskich w innych lokalizacjach), skrócony styl formatu (na przykład: „1 sekunda temu”) oraz wyraźne sposoby uwzględniania stref czasowych . Time4J zdaje sobie nawet sprawę z tak egzotycznych szczegółów, jak sekundy przestępne w obliczeniach czasów względnych (nie jest to naprawdę ważne, ale tworzy komunikat dotyczący horyzontu oczekiwań). Zgodność z Java-8istnieje dzięki łatwo dostępnym metodom konwersji dla typów takich jak
java.time.Instant
lubjava.time.Period
.Czy są jakieś wady? Tylko dwa.
(Kompaktowe) alternatywy:
Jeśli szukasz mniejszego rozwiązania i nie potrzebujesz tak wielu funkcji i jesteś gotów tolerować możliwe problemy z jakością związane z i18n-data, to:
Polecam ocpsoft / PrettyTime (wsparcie dla 32 języków (w rzeczywistości wkrótce 34) nadaje się do pracy z?
java.util.Date
Tylko - patrz odpowiedź @ataylor). Standard branżowy CLDR (z konsorcjum Unicode) z jego dużym doświadczeniem społecznym nie jest niestety bazą danych i18n, więc dalsze ulepszenia lub ulepszenia danych mogą zająć trochę czasu ...Jeśli używasz Androida, to pomocnicza klasa android.text.format.DateUtils jest wąską wbudowaną alternatywą (zobacz inne komentarze i odpowiedzi tutaj, z tą wadą, że nie ma wsparcia przez lata i miesiące. I jestem pewien, że tylko bardzo niewielu ludzi lubi styl API tej klasy pomocniczej.
Jeśli jesteś fanem Joda-Time , możesz spojrzeć na jego klasę PeriodFormat (obsługa 14 języków w wersji 2.9.4, z drugiej strony: Joda-Time z pewnością też nie jest kompaktowy, więc wspominam o tym tutaj tylko dla kompletność). Ta biblioteka nie jest prawdziwą odpowiedzią, ponieważ względne czasy w ogóle nie są obsługiwane. Będziesz musiał przynajmniej dodać dosłowne „temu” (i ręcznie usunąć wszystkie dolne jednostki z wygenerowanych formatów list - niezręczne). W przeciwieństwie do Time4J lub Android-DateUtils, nie ma specjalnej obsługi skrótów ani automatycznego przełączania z czasów względnych na reprezentacje czasu bezwzględnego. Podobnie jak PrettyTime, jest całkowicie zależny od niepotwierdzonego wkładu prywatnych członków społeczności Java do swoich danych i18n.
źródło
Jeśli szukasz prostego „Dzisiaj”, „Wczoraj” lub „X dni temu”.
źródło
java.time
Korzystanie ze środowiska java.time wbudowanego w język Java 8 i nowsze.
źródło
Duration
metody raportują cały czas trwania jako całkowitą liczbę godzin i jako całkowitą liczbę minut. W Javie 8 klasa dziwnie nie miała żadnych metod, aby uzyskać każdą część godziny, minut i sekund. Java 9 przynosi tych metodto…Part
.Stworzyłem prosty port Java timeago wtyczki jquery-timeago, która robi to, o co prosisz.
źródło
Jeśli tworzysz aplikację na Androida, zapewnia ona klasę narzędziową DateUtils dla wszystkich takich wymagań. Przyjrzyj się metodzie narzędziowej DateUtils # getRelativeTimeSpanString () .
Z dokumentów dla
CharSequence getRelativeTimeSpanString (długi czas, długi czas, długi minResolution)
Będziesz przechodzi swój
timestamp
jak czas iSystem.currentTimeMillis()
jak teraz .minResolution
Pozwala określić minimalny Okres zgłosić.źródło
Możesz użyć tej funkcji do obliczenia czasu temu
1) Tutaj time_ago jest w mikrosekundach
źródło
W oparciu o kilka odpowiedzi tutaj utworzyłem następujące informacje dla mojego przypadku użycia.
Przykładowe użycie:
źródło
Joda czasu pakiet ma pojęcie okresów . Możesz wykonywać działania arytmetyczne z okresami i datami.
Z dokumentów :
źródło
To nie jest ładne ... ale najbliższe mi przychodzi do głowy użycie Joda-Time (jak opisano w tym poście: Jak obliczyć czas, który upłynął od teraz za pomocą Joda Time?
źródło
Jest to lepszy kod, jeśli weźmiemy pod uwagę wydajność, ponieważ zmniejsza liczbę obliczeń. Powód Minuty są obliczane tylko wtedy, gdy liczba sekund jest większa niż 60, a godziny są obliczane tylko wtedy, gdy liczba minut jest większa niż 60 i tak dalej ...
źródło
java.time
The Answer autorstwa Habsq ma dobry pomysł, ale złe metody.
Dla przedziału czasu niezwiązanego z osią czasu w skali lata-miesiące-dni użyj
Period
. W przypadku dni oznaczających 24-godzinne fragmenty czasu niezwiązane z kalendarzem i godziny-minuty-sekundy użyjDuration
. Mieszanie obu skal rzadko ma sens.Duration
Zacznij od pobrania aktualnego momentu, jak widać w UTC , przy użyciu
Instant
klasy.Generuj tekst na godziny, minuty i sekundy.
Zrzuć na konsolę.
Period
Zacznij od uzyskania aktualnej daty.
Strefa czasowa ma kluczowe znaczenie przy ustalaniu daty. W dowolnym momencie data różni się na całym świecie według strefy. Na przykład, kilka minut po północy w Paryżu Francja jest nowym dniem, podczas gdy w Montrealu Quebec wciąż trwa „wczoraj” .
Jeśli nie określono strefy czasowej, maszyna JVM niejawnie stosuje swoją bieżącą domyślną strefę czasową. To ustawienie domyślne może się zmienić w dowolnym momencie w trakcie działania (!), Więc wyniki mogą się różnić. Lepiej jest jawnie określić żądaną / oczekiwaną strefę czasową jako argument. Jeśli jest to krytyczne, potwierdź strefę ze swoim użytkownikiem.
Określ prawidłową nazwę strefy czasowej w formacie
Continent/Region
, takie jakAmerica/Montreal
,Africa/Casablanca
lubPacific/Auckland
. Nigdy nie używaj skrótów składających się z 2-4 liter, takich jakEST
lub,IST
ponieważ nie są to prawdziwe strefy czasowe, nie są standaryzowane, a nawet nie są unikalne (!).Odtwórz datę sprzed ośmiu dni, miesięcy i lat.
Oblicz czas, który upłynął.
Zbuduj ciąg kawałków „dawniej”.
Zrzuć na konsolę.
Informacje o java.time
Struktura java.time jest wbudowana w Javę 8 i nowsze. Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak
java.util.Date
,Calendar
, iSimpleDateFormat
.Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj Stack Overflow, aby znaleźć wiele przykładów i wyjaśnień. Specyfikacja to JSR 310 .
Projekt Joda-Time , obecnie w trybie konserwacji , zaleca migrację do klas java.time .
Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie ma potrzeby stosowania ciągów ani
java.sql.*
klas.Skąd wziąć klasy java.time?
Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak
Interval
,YearWeek
,YearQuarter
, i więcej .źródło
Po długich poszukiwaniach znalazłem to.
źródło
Dla Androida Dokładnie tak, jak powiedział Ravi, ale ponieważ wiele osób chce po prostu skopiować i wkleić to, co jest tutaj.
Wyjaśnienie dla osób, które mają więcej czasu
Dawny. Otrzymuję dane z serwera w formacie Wed, 27 Jan 2016 09:32:35 GMT [to prawdopodobnie NIE Twój przypadek]
to jest tłumaczone na
SimpleDateFormat formatter = nowy SimpleDateFormat ("EEE, dd MMM rrrr HH: mm: ss Z");
skąd to wiem Przeczytaj dokumentację tutaj.
Po przeanalizowaniu otrzymuję datę. datę, którą umieściłem w getRelativeTimeSpanString (bez żadnych dodatkowych parametrów jest w porządku, domyślnie minuty)
Otrzymasz wyjątek, jeśli nie wymyśliłeś prawidłowego ciągu parsowania , Coś w rodzaju: wyjątek przy znaku 5 . Spójrz na znak 5 i popraw początkowy ciąg analizy. . Możesz uzyskać inny wyjątek, powtarzaj te kroki, aż uzyskasz prawidłową formułę.
źródło
}
Połączenie
val String = timeAgo (unixTimeStamp)
aby uzyskać czas temu w Kotlinie
źródło
Oto moja implementacja w Javie
źródło
mi to pasuje
źródło
To jest bardzo podstawowy skrypt. łatwo jest improwizować.
Wynik: (XXX godzin temu) lub (XX dni temu / wczoraj / dziś)
źródło
w tym celu zrobiłem
Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years ago
w tym przykładzie, możesz przeanalizować datę taką2018-09-05T06:40:46.183Z
lub inną, jak poniżejdodaj poniższą wartość w string.xml
kod java spróbuj poniżej
źródło
Możesz użyć biblioteki Java RelativeDateTimeFormatter , robi to dokładnie:
źródło
Używam Instant, Date i DateTimeUtils. Dane (data), które są przechowywane w bazie danych w typie String, a następnie konwertowane na Instant.
źródło
Poniższe rozwiązania są w czystej Javie:
Opcja 1: bez zaokrąglania i tylko największy kontener czasu
Następująca funkcja wyświetli tylko największy kontener czasu, na przykład, jeśli prawdziwy czas, który upłynął
"1 month 14 days ago"
, to ta funkcja będzie wyświetlana tylko"1 month ago"
. Ta funkcja również zawsze zaokrągla w dół, więc czas odpowiadający funkcji"50 days ago"
będzie wyświetlany jako"1 month"
Opcja 2: z zaokrągleniem
Po prostu zawiń kontener czasu, który chcesz zaokrąglić, instrukcją Math.round (...), więc jeśli chcesz zaokrąglić
50 days
do2 months
, zmodyfikujlong months = days / 30
dolong months = Math.round(days / 30.0)
źródło
Duration
z jegoto…Part
metod byłoby znacznie łatwiejsze, jak pokazano w mojej odpowiedzi .Oto mój przypadek testowy, mam nadzieję, że pomoże:
źródło
Calendar
klasa została wyparta lat temu przez nowoczesne java.time klas wraz z przyjęciem JSR 310 . Słaba rada w 2019 r.var
, nieval
.Funkcja getrelativeDateTime poda datę i godzinę, jak widać w powiadomieniu Whatsapp.
Aby uzyskać przyszłą względną datę i godzinę, dodaj dla niej warunki. Jest to tworzone specjalnie w celu uzyskania daty i godziny, takiej jak powiadomienie Whatsapp.
źródło
SimpleDateFormat
iCalendar
chociaż. Te klasy są źle zaprojektowane i dawno przestarzałe. Zamiast tego przeczytaj odpowiedzi wykorzystujące java.time, nowoczesny interfejs API daty i czasu języka Java.Ze względu na brak prostoty i zaktualizowanej odpowiedzi, następuje nowsza wersja Java 8 i nowszych
Jest to wersja korzystająca z Java Time API, która próbuje rozwiązać problemy z przeszłości w zakresie obsługi daty i godziny.
Javadoc
wersja 8 https://docs.oracle.com/javase/8/docs/api/index.html?java/time/package-summary.html
wersja 11 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html
Samouczek W3Schools - https://www.w3schools.com/java/java_date.asp
Artykuł DZone - https://dzone.com/articles/java-8-date-and-time
źródło