Làm thế nào để tính toán thời gian trước khi vào Java trong Java?


127

Trong Ruby on Rails, có một tính năng cho phép bạn lấy bất kỳ Ngày nào và in ra cách đây "cách đây rất lâu".

Ví dụ:

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

Có một cách dễ dàng để làm điều này trong Java?


1
Xem: stackoverflow.com/questions/11/how-do-i-calculate-relative-time Đó là C #, nhưng tôi chắc chắn rằng bạn có thể chuyển đổi nó với ít rắc rối.
Brandon

Câu trả lời:


177

Hãy xem thư viện PrettyTime .

Cách sử dụng khá đơn giản:

import org.ocpsoft.prettytime.PrettyTime;

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

Bạn cũng có thể chuyển qua một ngôn ngữ cho các tin nhắn quốc tế:

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

Như đã lưu ý trong các bình luận, Android có chức năng này được tích hợp trong android.text.format.DateUtilslớp.


229
Trong trường hợp bạn đang làm việc trên Android, bạn có thể sử dụng: android.text.format.DateUtils # getRelativeTimeSpanString ()
Somatik

Bạn có thể vui lòng thêm một số mô tả cho câu trả lời của bạn, liên kết chỉ trả lời là không tốt cho bây giờ.
Ajay S

@Somatik nếu bạn cần lấy cái này trên nền tảng không phải Android, bạn có thể xem lớp đó trên AOSP.
greg7gkb

@ataylor cách sử dụng này trong Android ??
Hardik Parmar

getRelativeTimeSpanString không lý tưởng cho mọi tình huống và đó là lý do tại sao tôi đã tạo lớp riêng của mình dựa trên nhiều ví dụ ở đây. Xem giải pháp của tôi dưới đây: stackoverflow.com/a/37042254/468360
Được mã hóa vào

67

Bạn đã xem enum TimeUnit chưa? Nó có thể khá hữu ích cho loại điều này

    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
Tôi không nghĩ rằng đây là một câu trả lời hoàn chỉnh vì các đơn vị thời gian là độc lập. Ví dụ: thời gian tính bằng mili giây chỉ là thời gian phút * 60 * 1000. Bạn cần giảm từ mỗi đơn vị thời gian mà đơn vị thời gian lớn hơn tiếp theo (sau khi chuyển đổi sang đơn vị thời gian thấp hơn) để có thể sử dụng nó trong "thời gian trước " chuỗi.
Nativ

@Benj - Có đúng không? giải pháp trên? bởi vì một lần ở định dạng 12 giờ và một lần khác ở định dạng 24 giờ. Hãy cho tôi biết phản hồi của bạn cho truy vấn của tôi. Cảm ơn bạn trong nâng cao.
Swift

Điều này không chính xác mặc dù ... mỗi đơn vị độc lập với nhau như đã đề cập.
Jonathan Laliberte

1
Android thực hiện điều đó cho bạn Trong trường hợp bạn đang làm việc trên Android, bạn có thể sử dụng: android.text.format.DateUtils.getRelativeTimeSpanString (mili giây)
Wajid Ali

50

Tôi lấy câu trả lời của RealHowTo và Ben J và tạo phiên bản của riêng mình:

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

cái nào sẽ in như sau

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

Thật tuyệt Và thực sự dễ dàng để thêm các đơn vị thời gian khác, chẳng hạn như tuần
Piotr

1
cái này xứng đáng được nâng cấp hơn. Trước hết, không cần thư viện. Nó vẫn sạch sẽ, thanh lịch và dễ thay đổi.
fangzhzh

lỗi đánh máy nhỏ: bên trong mã của bạn, bạn đang tham chiếu các thuộc tính tĩnh "Danh sách" thay vì "TimeAgo". Lists.times.get (i) nên là TimeAgo.get (i) ... và cứ thế
Diogo Gomes

2
Ít gợi ý: sử dụng .append(temp != 1 ? "s" : "")thay .append(temp > 1 ? "s" : "")vì vì 0 cũng nên có shậu tố
berkus

1
@ShajeelAfzal có, tham số thời lượng tính bằng mili giây nhưng đó là sự khác biệt giữa các lần không phải là một giá trị tuyệt đối. Những gì bạn đang nhận được là thời gian đã trôi qua từ ngày 1 tháng 1 năm 1970 ngày bắt đầu dấu thời gian unix
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 @ Định dạng thời lượng tính bằng mili giây thành định dạng có thể đọc được


Tôi đã kết thúc bằng cách sử dụng một phiên bản sửa đổi của điều này. Đăng bản sửa đổi của tôi cho bạn.
David Blevins

5
David Blevins, ví dụ khác về PrettyTime: stackoverflow.com/questions/3859288/ Khăn Big -1 để phát minh lại bánh xe một lần nữa và không đề xuất thư viện bên thứ 3 :-p
zakmck

9

Điều này dựa trên câu trả lời của RealHowTo vì vậy nếu bạn thích nó, hãy dành cho anh ấy / cô ấy một chút tình yêu.

Phiên bản đã dọn sạch này cho phép bạn chỉ định khoảng thời gian bạn có thể quan tâm.

Nó cũng xử lý phần "và" một chút khác nhau. Tôi thường thấy khi nối các chuỗi với một dấu phân cách, việc bỏ qua logic phức tạp sẽ dễ dàng hơn và chỉ cần xóa dấu phân cách cuối cùng khi bạn hoàn thành.

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

Mã nhỏ để tạo cho nó một vòng xoáy:

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

}

Mà sẽ xuất ra như sau:

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 

Và trong trường hợp bất cứ ai cũng cần nó, đây là một lớp sẽ chuyển đổi bất kỳ chuỗi nào như trên trở lại thành mili giây . Nó khá hữu ích để cho phép mọi người chỉ định thời gian chờ của nhiều thứ khác nhau trong văn bản có thể đọc được.


9

Có một cách đơn giản để làm điều này:

giả sử bạn muốn có thời gian 20 phút trước:

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

đó là nó..


1
Trong hầu hết các trường hợp, bạn muốn có một màn hình "thông minh", tức là. thay vì 5125 phút trước, bạn nói với x ngày trước.
PhiLho

7

Về các giải pháp tích hợp:

Java không có bất kỳ hỗ trợ tích hợp nào để định dạng thời gian tương đối, cũng không phải Java-8 và gói mới của nó java.time . Nếu bạn chỉ cần tiếng Anh và không có gì khác sau đó và chỉ sau đó một giải pháp làm bằng tay có thể được chấp nhận - hãy xem câu trả lời của @RealHowTo (mặc dù nó có nhược điểm mạnh là không tính đến múi giờ cho việc dịch các bản dịch tức thời sang giờ địa phương các đơn vị!). Dù sao, nếu bạn muốn tránh các giải pháp phức tạp được trồng tại nhà đặc biệt là cho các địa phương khác thì bạn cần một thư viện bên ngoài.

Trong trường hợp sau, tôi khuyên bạn nên sử dụng thư viện Time4J (hoặc Time4A trên Android). Nó cung cấp sự linh hoạt lớn nhất và sức mạnh i18n nhất . Lớp net.time4j.PrettyTime có bảy phương thức printRelativeTime...(...)cho mục đích này. Ví dụ sử dụng đồng hồ thử nghiệm làm nguồn thời gian:

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)

Một ví dụ khác sử dụng java.time.Instantlàm đầu vào:

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

Thư viện này hỗ trợ thông qua phiên bản mới nhất (v4.17) 80 ngôn ngữ và cả một số địa phương cụ thể theo quốc gia (đặc biệt là tiếng Tây Ban Nha, tiếng Anh, tiếng Ả Rập, tiếng Pháp). Dữ liệu i18n chủ yếu dựa trên phiên bản CLDR mới nhất v29 . Các lý do quan trọng khác tại sao sử dụng thư viện này là hỗ trợ tốt cho các quy tắc số nhiều (thường khác với tiếng Anh ở các địa phương khác), kiểu định dạng viết tắt (ví dụ: "1 giây trước") và các cách diễn đạt để tính đến các múi giờ . Time4J thậm chí còn nhận thức được các chi tiết kỳ lạ như bước nhảy vọt trong tính toán thời gian tương đối (không thực sự quan trọng nhưng nó tạo thành một thông điệp liên quan đến chân trời kỳ vọng). Khả năng tương thích với Java-8tồn tại do các phương thức chuyển đổi dễ dàng có sẵn cho các loại như java.time.Instanthoặc java.time.Period.

Có bất kỳ nhược điểm? Chỉ có hai.

  • Thư viện không nhỏ (cũng vì kho dữ liệu i18n lớn của nó).
  • API chưa được biết đến nhiều nên kiến ​​thức và hỗ trợ cộng đồng chưa có sẵn nếu không tài liệu được cung cấp khá chi tiết và toàn diện.

(Nhỏ gọn) thay thế:

Nếu bạn tìm kiếm một giải pháp nhỏ hơn và không cần quá nhiều tính năng và sẵn sàng chịu đựng các vấn đề chất lượng có thể có liên quan đến dữ liệu i18n thì:

  • Tôi muốn giới thiệu ocpsoft / PrettyTime (hỗ trợ cho 32 ngôn ngữ thực sự (sắp 34?) Chỉ phù hợp với công việc java.util.Date- xem câu trả lời của @ataylor). CLDR tiêu chuẩn công nghiệp (từ tập đoàn Unicode) với nền tảng cộng đồng lớn của nó thật đáng tiếc không phải là cơ sở của dữ liệu i18n nên việc cải tiến hoặc cải thiện dữ liệu có thể mất một thời gian ...

  • Nếu bạn đang sử dụng Android thì lớp trợ giúp android.text.format.DateUtils là một giải pháp thay thế tích hợp mỏng (xem các bình luận và câu trả lời khác ở đây, với nhược điểm là nó không hỗ trợ trong nhiều năm và nhiều tháng. Và tôi chắc chắn rằng chỉ rất ít người thích phong cách API của lớp người trợ giúp này.

  • Nếu bạn là người hâm mộ của Joda-Time thì bạn có thể xem lớp periodFormat của nó (hỗ trợ cho 14 ngôn ngữ trong phiên bản v2.9.4, mặt khác: Joda-Time chắc chắn không nhỏ gọn, vì vậy tôi chỉ đề cập đến nó ở đây tính đầy đủ). Thư viện này không phải là một câu trả lời thực sự vì thời gian tương đối không được hỗ trợ. Bạn sẽ cần phải thêm ít nhất "trước đây" theo nghĩa đen (và tước thủ công tất cả các đơn vị thấp hơn từ các định dạng danh sách được tạo - lúng túng). Không giống như Time4J hay Android-DateUtils, nó không hỗ trợ đặc biệt cho chữ viết tắt hoặc tự động chuyển từ thời gian tương đối sang biểu diễn thời gian tuyệt đối. Giống như PrettyTime, nó hoàn toàn phụ thuộc vào sự đóng góp chưa được xác nhận của các thành viên tư nhân của cộng đồng Java vào dữ liệu i18n của nó.


5

Nếu bạn đang tìm kiếm một "Hôm nay" đơn giản, "Hôm qua" hoặc "x ngày trước".

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

Sử dụng khung java.time được tích hợp trong Java 8 trở lên.

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
Các Durationphương pháp đó báo cáo toàn bộ thời lượng là tổng số giờ và tổng số phút. Trong Java 8, lớp thiếu một cách kỳ lạ bất kỳ phương thức nào để có được từng phần của giờ và phút và giây. Java 9 mang lại các phương thức đó to…Part.
Basil Bourque

4

Tôi đã tạo một cổng thời gian Java đơn giản của trình cắm thêm jquery-timeago thực hiện những gì bạn đang yêu cầu.

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

4

Trong trường hợp bạn đang phát triển một ứng dụng cho Android, nó cung cấp lớp tiện ích DateUtils cho tất cả các yêu cầu như vậy. Hãy xem phương thức tiện ích DateUtils # getRelativeTimeSpanString () .

Từ các tài liệu cho

CharSequence getRelativeTimeSpanString (thời gian dài, lâu nay, minResolution dài)

Trả về một chuỗi mô tả 'thời gian' là thời gian liên quan đến 'bây giờ'. Khoảng thời gian trong quá khứ được định dạng như "42 phút trước". Khoảng thời gian trong tương lai được định dạng như "Trong 42 phút".

Bạn sẽ được đi qua của mình timestampnhư thời gianSystem.currentTimeMillis()như hiện nay . Việc minResolutioncho phép bạn chỉ định khoảng thời gian tối thiểu để báo cáo.

Ví dụ: thời gian 3 giây trong quá khứ sẽ được báo cáo là "0 phút trước" nếu điều này được đặt thành MINUTE_IN_MILLIS. Vượt qua một trong 0, MINUTE_IN_MILLIS, HOUR_IN_MILLIS, DAY_IN_MILLIS, WEEK_IN_MILLIS, v.v.


4

Bạn có thể sử dụng chức năng này để tính thời gian trước

 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) Ở đây time_ago tính bằng micro giây


4

Dựa trên một loạt các câu trả lời ở đây, tôi đã tạo ra những điều sau đây cho trường hợp sử dụng của mình.

Ví dụ sử dụng:

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

Nó rất hữu ích, Cảm ơn bạn rất nhiều.
Haya Akkad

3

Các Joda thời gian gói, có khái niệm về Thời hạn . Bạn có thể thực hiện số học với Chu kỳ và DateTimes.

Từ các tài liệu :

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


2

Đây là một mã tốt hơn nếu chúng ta xem xét hiệu suất. Nó làm giảm số lượng tính toán. Lý do Phút chỉ được tính nếu số giây lớn hơn 60 và Giờ chỉ được tính nếu số phút lớn hơn 60 và cứ thế ...

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
Trong trường hợp bạn đang làm việc trên Android, bạn có thể sử dụng: android.text.format.DateUtils.getRelativeTimeSpanString (mili giây)
Wajid Ali

2

java.time

Câu trả lời của Habsq có ý tưởng đúng nhưng phương pháp sai.

Đối với một khoảng thời gian không bị ràng buộc với dòng thời gian trên quy mô của năm-tháng-ngày, sử dụng Period. Đối với ngày có nghĩa là khối thời gian 24 giờ không liên quan đến lịch và giờ-phút-giây, sử dụng Duration. Trộn hai vảy hiếm khi có ý nghĩa.

Duration

Bắt đầu bằng cách tìm nạp thời điểm hiện tại như đã thấy trong UTC , sử dụng Instantlớp.

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

Tạo văn bản cho giờ, phút và giây.

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

Đổ vào bàn điều khiển.

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

Từ: 2019-06-04T11: 53: 55.714965Z đến: 2019-06-04T20: 02: 03.714965Z

8 giờ trước

8 phút trước

8 giây trước

Period

Bắt đầu bằng cách lấy ngày hiện tại.

Một múi giờ là rất quan trọng trong việc xác định một ngày. Đối với bất kỳ thời điểm nào, ngày thay đổi trên toàn cầu theo khu vực. Chẳng hạn, vài phút sau nửa đêm ở Paris Pháp là một ngày mới trong khi ngày hôm qua vẫn còn ở Montréal Québec .

Nếu không có múi giờ được chỉ định, JVM sẽ áp dụng ngầm định múi giờ mặc định hiện tại của nó. Mặc định đó có thể thay đổi bất cứ lúc nào trong thời gian chạy (!), Vì vậy kết quả của bạn có thể thay đổi. Tốt hơn là xác định rõ ràng múi giờ mong muốn / mong muốn của bạn làm đối số. Nếu quan trọng, xác nhận vùng với người dùng của bạn.

Chỉ định một tên múi giờ thích hợp trong các định dạng của Continent/Region, chẳng hạn như America/Montreal, Africa/Casablancahoặc Pacific/Auckland. Không bao giờ sử dụng chữ viết tắt 2-4 chữ cái như ESThoặc ISTchúng không phải là múi giờ thực, không được chuẩn hóa và thậm chí không phải là duy nhất (!).

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

Tái tạo một ngày tám ngày, tháng và năm trước.

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

Tính thời gian trôi qua.

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

Xây dựng chuỗi các mảnh "thời gian trước".

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

Đổ vào bàn điều khiển.

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

Từ: 2010-09-27 đến: 2019-06-04

8 ngày trước

8 tháng trước

8 năm trước


Giới thiệu về java.time

Các java.time khung được xây dựng vào Java 8 và sau đó. Những lớp học thay thế cái cũ phiền hà di sản lớp học ngày thời gian như java.util.Date, Calendar, & SimpleDateFormat.

Để tìm hiểu thêm, xem Hướng dẫn Oracle . Và tìm kiếm Stack Overflow cho nhiều ví dụ và giải thích. Đặc điểm kỹ thuật là JSR 310 .

Các Joda thời gian dự án, bây giờ trong chế độ bảo trì , khuyên chuyển đổi sang các java.time lớp.

Bạn có thể trao đổi các đối tượng java.time trực tiếp với cơ sở dữ liệu của bạn. Sử dụng trình điều khiển JDBC tương thích với JDBC 4.2 trở lên. Không cần chuỗi, không cầnjava.sql.* lớp.

Nơi để có được các lớp java.time?

Các ThreeTen-Extra dự án mở rộng java.time với các lớp bổ sung. Dự án này là một nền tảng chứng minh cho các bổ sung có thể trong tương lai cho java.time. Bạn có thể tìm thấy một số các lớp học hữu ích ở đây chẳng hạn như Interval, YearWeek, YearQuarter, và nhiều hơn nữa .


Cảm ơn bạn rất nhiều!
Ticherhaz

1

Sau thời gian dài nghiên cứu tôi đã tìm thấy điều này.

    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

Đối với Android Chính xác như Ravi đã nói, nhưng vì nhiều người muốn chỉ sao chép dán thứ ở đây.

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

Giải thích cho những người có nhiều thời gian hơn

  1. Bạn nhận được dữ liệu từ một nơi nào đó. Trước tiên, bạn phải tìm ra định dạng của nó.

Ví dụ. Tôi nhận được dữ liệu từ một máy chủ ở định dạng Thứ tư, 27 tháng 1 năm 2016 09:32:35 GMT [đây có lẽ KHÔNG phải là trường hợp của bạn]

điều này được dịch sang

Trình định dạng SimpleDateFormat = new SimpleDateFormat ("EEE, dd MMM yyyy HH: mm: ss Z");

Làm sao tôi biết được? Đọc tài liệu ở đây.

Sau khi tôi phân tích nó, tôi nhận được một ngày. ngày đó tôi đã đặt trong getRelativeTimeSpanString (không có bất kỳ tham số bổ sung nào là ổn đối với tôi, để được mặc định là phút)

Bạn S get nhận được một ngoại lệ nếu bạn không tìm ra Chuỗi phân tích cú pháp chính xác , đại loại như: ngoại lệ ở ký tự 5 . Nhìn vào ký tự 5 và sửa chuỗi phân tích cú pháp ban đầu của bạn. . Bạn có thể nhận được một ngoại lệ khác, lặp lại các bước này cho đến khi bạn có công thức chính xác.


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"
    }
}

}

Gọi

chuỗi String = timeAgo (unixTimeStamp)

để có được thời gian trước đây trong Kotlin


0

Đây là triển khai Java của tôi về điều này

    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

nó làm việc cho tôi

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

Đây là kịch bản rất cơ bản. nó dễ dàng để ứng biến.
Kết quả: (XXX giờ trước) hoặc (XX ngày trước / Hôm qua / Hôm nay)

<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

Đối với điều này tôi đã thực hiện Just Now, seconds ago, min ago, hrs ago, days ago, weeks ago, months ago, years agotrong ví dụ này, bạn có thể phân tích ngày như thế 2018-09-05T06:40:46.183Znày hoặc bất kỳ ngày nào khác như dưới đây

thêm giá trị dưới đây vào chuỗi

  <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>

mã java thử bên dưới

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

Trong trường hợp bạn đang làm việc trên Android, bạn có thể sử dụng: android.text.format.DateUtils.getRelativeTimeSpanString (mili giây)
Wajid Ali

0

Bạn có thể sử dụng Thư viện RelativeDateTimeFormatter của Java , nó thực hiện chính xác điều đó:

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
Đó là thư viện Android, không phải thư viện Java.
Madbreaks

0

Tôi đang sử dụng Instant, Date và DateTimeUtils. Dữ liệu (ngày) được lưu trữ trong cơ sở dữ liệu theo kiểu Chuỗi và sau đó chuyển đổi thành 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.
     */
    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
Bạn đang sử dụng các lớp thời gian cũ khủng khiếp đã được các lớp java.time thay thế nhiều năm trước .
Basil Bourque

@BasilBourque Tôi vẫn không thể tìm ra cách mới nhất để làm điều này.
Ticherhaz

@BasilBourque Tôi đã thêm một số mã để tôi hiểu nó. github.com/ticherhaz/tarikhmasa
Ticherhaz

0

Các giải pháp sau đây đều là Java thuần túy:

Tùy chọn 1: Không làm tròn và chỉ chứa thời gian lớn nhất

Hàm sau sẽ chỉ hiển thị vùng chứa thời gian lớn nhất, ví dụ: nếu thời gian trôi qua thực sự là "1 month 14 days ago", hàm này sẽ chỉ hiển thị "1 month ago". Hàm này cũng sẽ luôn làm tròn xuống, vì vậy thời gian tương đương "50 days ago"sẽ hiển thị dưới dạng"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";
    }

Cách 2: Với làm tròn

Chỉ cần gói phần chứa thời gian mà bạn muốn làm tròn bằng câu lệnh Math.round (...), vì vậy nếu bạn muốn làm tròn 50 daysthành 2 months, hãy sửa đổi long months = days / 30thànhlong months = Math.round(days / 30.0)


1
Sử dụng Durationvới các to…Partphương pháp của nó sẽ dễ dàng hơn nhiều, như thể hiện trong Câu trả lời của tôi .
Basil Bourque

0

Đây là trường hợp thử nghiệm của tôi, hy vọng nó sẽ giúp:

    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
Lớp khủng khiếp Calendarđã được thay thế từ nhiều năm trước bởi các lớp java.time hiện đại với việc áp dụng JSR 310 . Lời khuyên tồi trong năm 2019.
Basil Bourque

Bạn phải có ý nghĩa var, không val.
Basil Bourque

0

Hàm getrelativeDateTime sẽ cho bạn thời gian như bạn thấy trong thông báo Whatsapp.
Để có được tương đối Ngày Thời gian thêm điều kiện cho nó. Điều này được tạo riêng để nhận Ngày giờ như thông báo Whatsapp.

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

Cảm ơn vì muốn đóng góp. Đó không phải là chính xác những gì đã được hỏi, nhưng có lẽ ai đó có thể sử dụng nó. Không ai mà không ai khác muốn sử dụng SimpleDateFormatCalendar, mặc dù. Những lớp học được thiết kế kém và lỗi thời. Thay vào đó hãy đọc các câu trả lời đang sử dụng java.time, API ngày và giờ Java hiện đại.
Ole VV

0

Để không đơn giản và phản hồi được cập nhật, hãy làm theo phiên bản Java 8 và phiên bản mới hơn

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

Đây là phiên bản sử dụng API thời gian Java cố gắng giải quyết các vấn đề từ quá khứ để xử lý Ngày và Giờ.

Javadoc

phiên bản 8 https://docs.oracle.com/javase/8/docs/api/index.html?java/time/package-summary.html

phiên bản 11 https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html

Hướng dẫn của W3Schools - https://www.w3schools.com/java/java_date.asp

Bài viết của DZone - https://dzone.com/articles/java-8-date-and-time

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.