簡體   English   中英

Momentjs calendar()等同於Java

[英]Momentjs calendar() equivalent for Java

Momentjs具有calendar()函數,可以實現如下所示的打印時間跨度。

例如:

“上周一的1:14 PM”

“ 09/21/2017”(如果日期是前一陣子)

Java中是否有等效的功能(如果可能,可以使用Joda-Time)?

moment().subtract(10, 'days').calendar(); // 09/21/2017
moment().subtract(6, 'days').calendar();  // Last Monday at 1:14 PM
moment().subtract(3, 'days').calendar();  // Last Thursday at 1:14 PM
moment().subtract(1, 'days').calendar();  // Yesterday at 1:14 PM
moment().calendar();                      // Today at 1:14 PM
moment().add(1, 'days').calendar();       // Tomorrow at 1:14 PM
moment().add(3, 'days').calendar();       // Wednesday at 1:14 PM
moment().add(10, 'days').calendar();      // 10/11/2017

java.time

現代方法使用行業領先的java.time類。

ZoneId z = ZoneId.now( “America/Montreal”  ) ;
LocalDate today = LocalDate.now( z ) ;

使用加號和減號方法進行數學運算。

LocalDate tomorrow = today.plusDays( 1 ) ;

搜索堆棧溢出。 幾乎每個基本的日期時間問題都已經被要求回答。

字符串

java.time類不會生成諸如“明天”和“上周一”之類的字符串。 因此,沒有直接等同於您引用的庫的信息。 您將不得不自己做農民工作。

搜索DateTimeFormatter類和DateTimeFormatterBuilder類。

同樣, DayOfWeek枚舉及其自動本地化的getDisplayName方法可能很有用。

prettytime

盡管我沒有使用過prettytime庫,但它可能會對您有所幫助。

喬達時間

Joda-Time項目處於維護模式。 該團隊建議遷移到java.time類。


關於java.time

java.time框架內置於Java 8及更高版本中。 這些類取代了麻煩的舊的舊式日期時間類,例如java.util.DateCalendarSimpleDateFormat

現在處於維護模式Joda-Time項目建議遷移到java.time類。

要了解更多信息,請參見Oracle教程 並在Stack Overflow中搜索許多示例和說明。 規格為JSR 310

在哪里獲取java.time類?

ThreeTen-Extra項目使用其他類擴展了java.time。 該項目為將來可能在java.time中添加內容提供了一個試驗場。 您可以在這里找到一些有用的類,比如IntervalYearWeekYearQuarter ,和更多

Java中沒有內置函數,但是使用現有的API並不是很難。 首先,您需要獲得與今天(以天為單位)的差額,然后根據moment.js規則選擇適當的字符串:

Last week         Last Monday at 2:30 AM
The day before    Yesterday at 2:30 AM
The same day      Today at 2:30 AM
The next day      Tomorrow at 2:30 AM
The next week     Sunday at 2:30 AM
Everything else   7/10/2011

在Joda-Time中,可以使用org.joda.time.Days類來獲取天數差異。 一個細節是,我只考慮日期(日/月/年),而忽略了時間(小時/分鍾/秒)來獲得差異(但您可以根據需要進行調整)。 該方法將是這樣的:

public String calendar(DateTime dt) {
    StringBuilder sb = new StringBuilder();

    // check difference in days from today, considering just the date (ignoring the hours)
    int days = Days.daysBetween(new LocalDate(), dt.toLocalDate()).getDays();
    if (days == 0) { // today
        sb.append("Today ");
    } else if (days == 1) { // tomorrow
        sb.append("Tomorrow ");
    } else if (days == -1) { // yesterday
        sb.append("Yesterday ");
    } else if (days > 0 && days < 7) { // next week
        sb.append(dt.dayOfWeek().getAsText(Locale.ENGLISH)).append(" ");
    } else if (days < 0 && days > -7) { // last week
        sb.append("Last ").append(dt.dayOfWeek().getAsText(Locale.ENGLISH)).append(" ");
    }

    if (Math.abs(days) < 7) { // difference is less than a week, append current time
        sb.append("at ").append(dt.toString("h:mm a", Locale.ENGLISH));
    } else { // more than a week of difference
        sb.append(dt.toString("M/d/yyyy"));
    }

    return sb.toString();
}

我正在使用org.joda.time.LocalDate來獲取時差,因此時間將被忽略(如果您使用DateTime ,則經過24小時以上的時差僅為1天,因此請更改代碼根據您的需要)。

我還使用Math.abs(days) < 7來考慮差異是否超過一周,但是我不知道moment.js認為<= 7

無論如何,一些用法示例:

DateTime now = new DateTime();
System.out.println(calendar(now.minusDays(10))); // 9/22/2017
System.out.println(calendar(now.minusDays(6))); // Last Tuesday at 9:34 AM
System.out.println(calendar(now.minusDays(3))); // Last Friday at 9:34 AM
System.out.println(calendar(now.minusDays(1))); // Yesterday at 9:34 AM
System.out.println(calendar(now)); // Today at 9:34 AM
System.out.println(calendar(now.plusDays(1))); // Tomorrow at 9:34 AM
System.out.println(calendar(now.plusDays(3))); // Thursday at 9:34 AM
System.out.println(calendar(now.plusDays(10))); // 10/12/2017

輸出(考慮到今天是10月2日2017年第二 ,我跑的代碼在我的本地時間上午09點34分):

2017年9月22日
上星期二上午9:34
上周五上午9:34
昨天上午9:34
今天上午9:34
明天上午9:34
星期四上午9:34
2017年10月12日

您還可以修改該方法以獲取一個參考日期進行比較(而不是在方法內部使用硬編碼的new LocalDate() )。


Java新的日期/時間API

Joda-Time處於維護模式,並且已被新的API取代,因此,我不建議使用它來啟動新項目。 即使在joda的網站上,它也說: “請注意,Joda-Time被認為是一個很大的“完成”項目。沒有計划進行重大增強。如果使用Java SE 8,請遷移到java.time(JSR-310)。”

如果您使用的是Java 8 ,請考慮使用新的java.time API 與舊的API相比 ,它更容易, 更不會出錯且更不會出錯

如果您使用的是Java 6或7 ,則可以使用ThreeTen Backport ,它是Java 8的新日期/時間類的絕佳反向端口 對於Android ,您還需要ThreeTenABP (更多有關如何在此處使用它的信息 )。

下面的代碼對兩者都適用。 唯一的區別是包名稱(在Java 8中為java.time ,在ThreeTen Backport(或Android的ThreeTenABP)中為org.threeten.bp ),但是類和方法相同。

該API與Joda-Time非常相似,因此代碼之間存在細微差別:

static DateTimeFormatter HOUR_FORMAT = DateTimeFormatter.ofPattern("h:mm a", Locale.ENGLISH);

static DateTimeFormatter MDY_FORMAT = DateTimeFormatter.ofPattern("M/d/yyyy");

public String calendar(ZonedDateTime dt) {
    StringBuilder sb = new StringBuilder();

    // check difference in days from today, considering just the date (ignoring the hours) 
    long days = ChronoUnit.DAYS.between(LocalDate.now(), dt.toLocalDate());
    if (days == 0) { // today
        sb.append("Today ");
    } else if (days == 1) { // tomorrow
        sb.append("Tomorrow ");
    } else if (days == -1) { // yesterday
        sb.append("Yesterday ");
    } else if (days > 0 && days < 7) { // next week
        sb.append(dt.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.ENGLISH)).append(" ");
    } else if (days < 0 && days > -7) { // last week
        sb.append("Last ").append(dt.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.ENGLISH)).append(" ");
    }

    if (Math.abs(days) < 7) {  // difference is less than a week, append current time
        sb.append("at ").append(dt.format(HOUR_FORMAT));
    } else { // more than a week of difference
        sb.append(dt.format(MDY_FORMAT));
    }

    return sb.toString();
}

我使用了ZonedDateTime它等效於Joda的DateTime (它表示時區中的日期和時間)。

當調用DAYS.between ,我將其轉換為LocalDate ,因此比較僅考慮日期(日/月/年)。 如果我改用ZonedDateTime ,那么還將考慮時間,因此,只有經過24小時以上(因此您可以根據需要更改),結果才是1天。

請注意,我還必須創建2個DateTimeFormatter實例。 我在方法外部創建了它們,因此可以重用它們(無需始終在方法內部創建它們)。 Joda-Time不需要它,因為Joda對象中的toString方法可以采用某種模式並在內部創建格式化程序,而在java.time API中,您必須顯式創建格式化程序。

使用它也類似於Joda-Time:

ZonedDateTime now = ZonedDateTime.now();
System.out.println(calendar(now.minusDays(10))); // 9/22/2017
System.out.println(calendar(now.minusDays(6))); // Last Tuesday at 9:34 AM
System.out.println(calendar(now.minusDays(3))); // Last Friday at 9:34 AM
System.out.println(calendar(now.minusDays(1))); // Yesterday at 9:34 AM
System.out.println(calendar(now)); // Today at 9:34 AM
System.out.println(calendar(now.plusDays(1))); // Tomorrow at 9:34 AM
System.out.println(calendar(now.plusDays(3))); // Thursday at 9:34 AM
System.out.println(calendar(now.plusDays(10))); // 10/12/2017

只是有關時區的注釋。 java.time API中,所有日期類都有一個no-arg now()方法,該方法獲取JVM默認時區中的當前日期/時間。

盡管它非常方便,但也有一些缺點,因為即使在運行時也可以在不通知的情況下更改默認時區。 如果可能的話,最好指定所需的時區。

該API使用IANA時區名稱 (格式始終為Region/City ,例如America/New_YorkEurope/Paris )。 避免使用3個字母的縮寫(例如CETEST ),因為它們是模棱兩可的並且不是標准的

您可以通過調用ZoneId.getAvailableZoneIds()獲得可用時區的列表(並選擇最適合您的系統的時區ZoneId.getAvailableZoneIds()

要獲取特定時區中的當前日期/時間,請使用ZoneId類:

// get the current date/time in a specific timezone
ZonedDateTime.now(ZoneId.of("Europe/Paris"));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM