問題描述
我想將給定日歷實例的時間戳設置為一周的開始(星期一),而不是返回一個看似完全不相關的時間戳 - 除非我在此之前訪問任何日歷的字段.我在下面包含了一個示例,另請參閱 Ideone 中的這個可運行示例.
I want to set a given calendar instance's timestamp to the beginning of the week (Monday) and instead it returns a seemingly completely unrelated timestamp - unless I access any of the calendar's fields before doing so. I include a sample below, please also see this runnable example in Ideone.
這是預期的行為嗎?這背后的邏輯是什么?是的,我聽說過 Joda Time.
Is this expected behavior? What's the logic behind this? And yes, I've heard of Joda Time.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.TimeZone;
class MyTest {
private static Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("CET"), Locale.FRANCE);
private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
public static void main(String[] args) {
// Set to any date.
calendar.set(2013, 10, 3);
System.out.println(dateFormat.format(calendar.getTime()));
// Set to another day.
calendar.set(2014, 0, 15);
// --- THE WTF STARTS HERE ---
// Uncommenting the line below returns the correct date in the end.
// calendar.getTime();
// Set to monday of current week.
calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
// Expected outdate is 20140113
System.out.println(dateFormat.format(calendar.getTime()));
}
}
推薦答案
文檔中的字段操作章節解釋清楚.但它只是工作起來很奇怪.
Field Manipulation chapter in the docs explains it clearly. It just works weird though.
http://docs.oracle.com/javase/6/docs/api/java/util/Calendar.html
示例:考慮一個最初設置為 1999 年 8 月 31 日的 GregorianCalendar.調用set(Calendar.MONTH, Calendar.SEPTEMBER) 將日期設置為 1999 年 9 月 31 日.這是一個臨時的內部表示,解決到 1999 年 10 月 1 日,如果然后調用 getTime().但是,在之前調用 set(Calendar.DAY_OF_MONTH, 30)調用 getTime() 將日期設置為 1999 年 9 月 30 日,因為不會發生重新計算在 set() 本身之后.
Example: Consider a GregorianCalendar originally set to August 31, 1999. Calling set(Calendar.MONTH, Calendar.SEPTEMBER) sets the date to September 31, 1999. This is a temporary internal representation that resolves to October 1, 1999 if getTime()is then called. However, a call to set(Calendar.DAY_OF_MONTH, 30) before the call to getTime() sets the date to September 30, 1999, since no recomputation occurs after set() itself.
編輯
來自同一文檔的日歷字段解析部分
From the Calendar Fields Resolution part of the same doc
If there is any conflict in calendar field values, Calendar gives priorities to
calendar fields that have been set more recently. The following are the default
combinations of the calendar fields. The most recent combination, as determined
by the most recently set single field, will be used.
For the date fields:
YEAR + MONTH + DAY_OF_MONTH
YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
YEAR + DAY_OF_YEAR
YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
我認為 MONTH 和 DAY_OF_WEEK 之間的區別是這樣的.如果您在最后一條語句中設置 MONTH,它將與 YEAR+MONTH+DAY_OF_MONTH 匹配并覆蓋所有這些.如果您設置 DAY_OF_WEEK 它與 YEAR+DAY_OF_WEEK+WEEK_OF_YEAR 匹配,因此不會覆蓋月份值.或類似的東西.老實說,我越看越覺得破碎.這根本沒有意義.最好繼續使用 JodaTime
I think the difference between MONTH and DAY_OF_WEEK is this. If you set MONTH at the last statement it matches with YEAR+MONTH+DAY_OF_MONTH and overrides all of them. If you set DAY_OF_WEEK it matches with YEAR+DAY_OF_WEEK+WEEK_OF_YEAR so doesn't override the month value. Or something like that. To be honest, the more I look the more broken it seems. It doesn't make sense at all. Better keep using JodaTime
這篇關于設置 DAY_OF_WEEK 會返回意外結果的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!