2012-04-26 135 views
1

我在我的MySQL表中存儲了幾天和幾小時的時間戳。我現在要做的就是每天從上個星期天到星期日(工作一週)工作的特定用戶。另一個選項是從今天到上週日(本週)每天檢索。有些員工每天都不工作。計算上週日和從今天到上週日的前一週

我不知道如何在Java中編寫此代碼或是否存在特定的MySQL函數。

回答

3

在Java中,你可以把日曆類用好找上一個星期日:

Calendar c = Calendar;
c.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
Date lastSunday = c.getTime();

那麼你可以通過1個WEEK_OF_MONTH遞減之前找到星期天:

c.add(Calendar.WEEK_OF_MONTH, -1);
Date sundayBeforeThat = c.getTime();

+0

謝謝。所以代碼的前三行將檢索上個星期日的數據。例如今天是27-04-2012(星期五)。這個變量的日期是22-04-2012? 再次感謝 – Camus 2012-04-26 14:19:01

+0

這是正確的(從我測試過) – 2012-04-27 09:04:48

+0

其實我試過這段代碼,它的工作原理有點不同。第一行應該是Calendar c = Calendar.getInstance;第二行返回第二天,而不是以前。但我很感激幫助。現在我可以解決它並找到適合我的問題的解決方案。 – Camus 2012-04-29 02:27:10

0

TL;博士

LocalDate.now(ZoneId.of("Pacific/Auckland")) 
     .with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)) 

java.time

現代的方法使用java.time類。

請記住,TIMESTAMP data type in MySQL處於UTC時區。

相比之下,您希望某個特定時區非常重要的特定日期值的特定日期。時區對確定日期至關重要。對於任何特定的時刻,日期因地區而異。例如,Paris France午夜後幾分鐘是新的一天,而在Montréal Québec仍然是「昨天」。

continent/region的格式指定一個proper time zone name,如America/MontrealAfrica/Casablanca,或Pacific/Auckland。切勿使用3-4字母縮寫,如ESTIST,因爲它們是而不是真正的時區,不是標準化的,甚至不是唯一的(!)。

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

讓我們得到最後一個星期日,如果是星期天,則不包括今天。使用TemporalAdjusters(註釋複數)類中的TemporalAdjuster實現。指定一個DayOfWeek枚舉對象。

LocalDate previousSunday = today.with(TemporalAdjusters.previous(DayOfWeek.SUNDAY)) ; 

讓星期天再回來。

LocalDate startingSunday = previousSunday.minusWeeks(1) ; 

我們需要確切的時刻,而不是整個日期。獲取一天中的第一個時刻。不要以爲這意味着00:00:00的時間。夏令時(DST)等異常意味着該日可能會從01:00:00開始。讓java.time弄清楚。

ZonedDateTime zdtStart = startingSunday.atStartOfDay(z) ; 

接下來我們需要結束時間。其實,不是結束的時間。確定一週的第二個結尾是棘手的。日期時間工作中的常見做法是使用半開式方法來定義一段時間。在半開放時,開始是,包括,而結尾是,獨家。這意味着我們希望從一個星期日的第一時刻開始,跑到但不包括下個星期日的第一時刻。

請注意,您不能在SQL中使用BETWEEN進行Half-Open,因爲該命令已關閉,這意味着開始和結束都包含在內。

ZonedDateTime zdtStop = previousSunday.atStartOfDay(z) ; 

MySQL中的查詢將以UTC完成。因此,讓我們從ZonedDateTime對象中提取Instant對象,因爲它們始終以UTC定義。

Instant start = zdtStart.toInstant() ; 
Instant stop = zdtStop.toInstant() ; 

如果你的JDBC驅動程序支持JDBC 4.2和更高版本,可以直接通過PreparedStatement::setObjectResultSet::getObject在查詢中使用這些Instant對象。

此SQL代碼未經測試,但應指向正確的方向。

String sql = "SELECT * from tbl_ WHERE col_ >= ? AND col_ < ? ; " ; 
PreparedStatement pstmt = conn.prepareStatement(sql) ; 
pstmt.setObject(1 , start) ; 
pstmt.setObject(2 , stop) ; 
ResultSet rs = pstmt.executeQuery() ; 
… 
    Instant instant = rs.getObject(… , Instant.class) ; 

關於java.time

java.time框架是建立在Java 8和更高版本。這些類取代了日期時間類legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time項目現在位於maintenance mode,建議遷移到java.time類。請參閱Oracle Tutorial。並搜索堆棧溢出了很多例子和解釋。規格是JSR 310

從何處獲取java.time類?

ThreeTen-Extra項目與其他類擴展java.time。這個項目是未來可能增加java.time的一個試驗場。您可以在這裏找到一些有用的類,如Interval,YearWeek,YearQuartermore

相關問題