![](/img/trans.png)
[英]What is the difference between Calendar.WEEK_OF_MONTH and Calendar.DAY_OF_WEEK_IN_MONTH in Java's Calendar class?
[英]What's the difference between adding DAY_OF_MONTH or DAY_OF_YEAR to a Calendar object?
我想將某個日期增加 1 天。 我創建了一個日歷對象,如:
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, 2012);
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DAY_OF_MONTH, 31);
然后,為了增加 1 天,我可以做兩件事:
cal.add(Calendar.DAY_OF_MONTH, 1);
要么
cal.add(Calendar.DAY_OF_YEAR, 1);
還有其他“DAY”常量,但使用上述 2 種將天數增加 1 的方法,我得到了相同的結果。在這種情況下,這兩者會得到不同的結果嗎?
添加它確實沒有區別,但這
Calendar c = Calendar.getInstance();
System.out.println(c.get(Calendar.DAY_OF_MONTH));
System.out.println(c.get(Calendar.DAY_OF_YEAR));
印刷
28
363
Calendar.add
根據日歷的規則在給定的日歷字段中添加或減去指定的時間量。
MILLISECOND
是 0 到 999 之間的毫秒數
SECOND
是 0 到 59 之間的秒數
MINUTE
是 0 到 59 之間的分鍾數
HOUR
是 0 到 11 之間的小時數
HOUR_OF_DAY
是 0 到 23 之間的小時數
DAY_OF_WEEK
是與 1 和 7 之間的周相關的天
DAY_OF_MONTH
是與 1 到 31 之間的月份相關的日期
DAY_OF_YEAR
是與 1 到 365 之間的年份相關的日期
WEEK_OF_MONTH
是從 1 開始的與月份相關的周
WEEK_OF_YEAR
是從 1 開始的與年份相關的周
MONTH
是與 0 到 11 之間的年份相關的月份
YEAR
是從 1 開始的年數
小時、天和周有多個字段,但您選擇哪一個並不重要1 。 例如,對DAY_OF_WEEK
使用 -8 將起作用。
calendar.add(Calendar.DAY_OF_MONTH, -2); // subtract 2 days
calendar.add(Calendar.DAY_OF_WEEK, -2); // subtract 2 days
calendar.add(Calendar.DAY_OF_YEAR, -2); // subtract 2 days
calendar.add(Calendar.YEAR, -2); // subtract 2 years
1只使用Calendar.add
沒有關系,其他操作結果可能不同。
將Calendar.DATE
用於您的目的。 在您的情況下,這三個常量是同義詞。
調用 add 時沒有任何區別。 然而,吸氣劑返回不同的結果:D
來自GregorianCalendar#add
代碼片段
case DAY_OF_MONTH: // synonym of DATE
case DAY_OF_YEAR:
case DAY_OF_WEEK:
break;
DAY_OF_YEAR
get 和 set 的字段編號表示當前年份中的天數
DAY_OF_MONTH
get 和 set 的字段編號,指示月份中的某一天。 這是 DATE 的同義詞
如果一天大於 31,您將看到差異。
在這兩種情況下,您基本上都將日期提前了一個。 所以這兩種方法沒有區別。
但是堅持使用單一方法將使您的代碼庫保持一致,維護人員會感到賓至如歸,並且運行時可能也會通過編譯來優化方法調用。
實際上,根據您選擇的字段類型,可能會有差異:
* http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Calendar.html
使用模型。
為了激發 add() 和 roll() 的行為,考慮一個帶有月、日和年遞增和遞減按鈕的用戶界面組件,以及一個底層的 GregorianCalendar。 如果界面顯示 1999 年 1 月 31 日,用戶按下月份遞增按鈕,它應該顯示什么? 如果底層實現使用 set(),它可能會顯示 1999 年 3 月 3 日。更好的結果是 1999 年 2 月 28 日。此外,如果用戶再次按下月份增量按鈕,它應該顯示 1999 年 3 月 31 日,而不是 3 月 28 日, 1999。通過保存原始日期並使用 add() 或 roll(),根據是否應該影響較大的字段,用戶界面可以像大多數用戶直觀地期望的那樣運行。
LocalDate.of( 2012 , Month.JANUARY , 31 )
.plusDays( 1 )
2012-02-01
…要么…
LocalDate.of( 2012 , 1 , 31 ) // Sane numbering: 1-12 for January-December, and `2012` means year 2012.
.plusDays( 1 )
2012-02-01
Calendar
類令人困惑、笨拙且設計不佳。 其眾多問題之一是這些傳遞單位標志方法。 幸運的是,您現在可以忘記這個類的所有內容。
Java 8 及更高版本中內置的java.time類現在取代了遺留的日期時間類。
LocalDate
LocalDate
類表示沒有時間和時區的僅日期值。
時區對於確定日期至關重要。 對於任何給定時刻,日期因地區而異。 例如,在法國巴黎午夜過后幾分鍾是新的一天,而在魁北克蒙特利爾仍然是“昨天”。
如果未指定時區,JVM 會隱式應用其當前默認時區。 該默認值可能隨時更改,因此您的結果可能會有所不同。 最好將您想要/預期的時區明確指定為參數。
以continent/region
的格式指定正確的時區名稱,例如America/Montreal
、 Africa/Casablanca
或Pacific/Auckland
。 永遠不要使用EST
或IST
等 3-4 個字母的縮寫,因為它們不是真正的時區,不是標准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
如果您想使用 JVM 的當前默認時區,請詢問它並作為參數傳遞。 如果省略,則隱式應用 JVM 的當前默認值。 最好是明確的,因為 JVM 中任何應用程序的任何線程中的任何代碼都可能在運行時隨時更改默認值。
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
或指定日期。 您可以通過數字設置月份,1-12 月的數字為 1-12。
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
或者,更好的是使用預定義的Month
枚舉對象,一個用於一年中的每個月。 提示:在整個代碼庫中使用這些Month
對象而不僅僅是整數,以使您的代碼更具自文檔性、確保有效值並提供類型安全。
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
有了LocalDate
,您就可以查詢其部分。
要獲取月份中的日期,即從 2018 年 1 月 23 23
開始的“日期”,例如23
:
int dayOfMonth = ld.getDayOfMonth() ; // 1-31, depending on length of month.
要從 1-365 或閏年 1-366 獲取一年中的第 n 天:
int dayOfYear = ld.getDayOfYear() ;
在 java.time 中添加或減去天數非常簡單和直觀。 便捷方法和時間跨度對象使代碼更加清晰。
LocalDate dayLater = ld.plusDays( 1 ) ;
所以明天將是:
LocalDate tomorrow = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ).plusDays( 1 ) ;
或者,您可以表示不附加到時間線的時間跨度。 對於年-月-日,請使用Period
。 對於小時-分鍾-秒,請使用Duration
。
Period p = Period.ofDays( 1 ) ;
LocalDate dayLater = ld.plus( p ) ;
請注意,與遺留類不同, java.time 使用合理的編號。 數字2018
是2018
年。 1-12 月的月份編號為 1-12。 根據ISO 8601標准,星期一至星期日的星期幾編號為 1-7。
java.time框架內置於 Java 8 及更高版本中。 這些類取代麻煩的老傳統日期時間類,如java.util.Date
, Calendar
,和SimpleDateFormat
。
現在處於維護模式的Joda-Time項目建議遷移到java.time類。
要了解更多信息,請參閱Oracle 教程。 並在 Stack Overflow 上搜索許多示例和解釋。 規范是JSR 310 。
從哪里獲得 java.time 類?
ThreeTen-Extra項目用額外的類擴展了 java.time。 該項目是未來可能添加到 java.time 的試驗場。 您可以在這里找到一些有用的類,比如Interval
, YearWeek
, YearQuarter
,和更多。
除了日期之外,無論您使用 DAY_OF_MONTH 還是 DAY_OF_YEAR 都沒有任何區別。 但是,當您獲得 call getter 並傳遞其中一個時,這是有道理的。
使用 DATE 或 DAY_OF_MONTH 兩者都相同
這是區別:
DATE or DAY_OF_MONTH : Get and Set indicating the day of the month
DAY_OF_WEEK : get and set indicating the week number within the current month
DAY_OF_YEAR : get and set indicating the day number within the current ye
來源: https : //docs.oracle.com/javase/7/docs/api/java/util/Calendar.html
public static String findDay(int month, int day, int year) {
// Creating a calendar
Calendar calndr = Calendar.getInstance();
calndr.set(Calendar.MONTH, month-1);
calndr.set(Calendar.YEAR, year);
calndr.set(Calendar.DAY_OF_MONTH, day);
String[] strDays = new String[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday" };
return strDays[calndr.get(Calendar.DAY_OF_WEEK)-1].toUpperCase();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.