2012-04-26 35 views
1

私はMySQLテーブルにタイムスタンプとして何日か何時間を保存しています。私が今したいのは、特定のユーザーが先週の日曜日から日曜日(仕事の1週間前)まで働いた毎日を検索することです。もう1つのオプションは、今日から最後の日曜日(今週)まで毎日を取得します。一部の従業員は毎日働いていません。最後の日曜日の1週間前と今日から最後の日曜日の計算

私はこれをJavaでコード化する方法や、特定のMySQL機能があるかどうかはわかりません。 、あなたが以前の日曜日見つけるためにうまく利用してCalendarクラスを置くことができるJavaで

答えて

3

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

ありがとうございました。コードの最初の3行は最後の日曜日のデータを取得します。たとえば、今日は27-04-2012(金曜日)です。この変数の日付は22-04-2012になりますか? ありがとうもう一度 – Camus

+0

が正しい(私がテストしたものから) –

+0

実際に私はこのコードを試してきました。最初の行はCalendar c = Calendar.getInstance; 2行目は前の日ではなく次の日を返します。しかし、私は助けに感謝します。今私はそれを回避し、私の問題に適した解決策を見つけることができます。 – Camus

0

TL; DR

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です。

は、America/MontrealAfrica/Casablanca、又はPacific/Aucklandとして、continent/regionの形式でproper time zone nameを指定します。 ESTまたはISTのような3〜4文字の略語は、ではなく、のように、標準化されておらず、ユニークではない(!)と使用しないでください。

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

日曜日の場合は今日を除いて最後の日曜日を取得しましょう。 TemporalAdjusters(複数の注記)クラスにあるTemporalAdjusterの実装を使用します。 DayOfWeek列挙型オブジェクトを指定します。

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

さらに日曜日を取得します。

完全な日付ではなく、正確な時刻が必要です。今日の最初の瞬間を手に入れよう。時間帯が00:00:00であると仮定しないでください。夏時間(DST)などの異常は、その日が01:00:00のような時刻に開始される可能性があることを意味します。 java.timeがそれを把握させる。

ZonedDateTime zdtStart = startingSunday.atStartOfDay(z) ; 

次に、終了時刻が必要です。実際には、終了時刻ではありません。分割された第2週末の決定は難しい。日付/時刻の作業の一般的なプラクティスは、Half-Openアプローチを使用して時間の範囲を定義することです。ハーフオープンでは、開始はを含む)であり、終了は)です。これは、ある日曜日の最初の瞬間から始まり、次の日曜日の最初の瞬間まで実行したいと考えていることを意味します。

BETWEENはHalf-Open用のSQLでは使用できません。このコマンドはClosedであり、開始と終了の両方を含むことに注意してください。

ZonedDateTime zdtStop = previousSunday.atStartOfDay(z) ; 

MySQLのクエリはUTCで行われます。だから、InstantのオブジェクトをZonedDateTimeオブジェクトから抽出してみましょう。これらのオブジェクトは常に定義どおりに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に組み込まれており、後にされています。これらのクラスは、java.util.DateCalendar、& SimpleDateFormatなど、面倒な古いlegacy日時クラスに取って代わります。

maintenance modeにあるJoda-Timeプロジェクトは、java.timeクラスへの移行を推奨しています。

詳しくはOracle Tutorialをご覧ください。そして、多くの例と説明のためにStack Overflowを検索してください。仕様はJSR 310です。

ここで、java.timeクラスを取得するには?

  • Java SE 8Java SE 9、以降
    • 内蔵しています。
    • バンドルされた実装の標準Java APIの一部です。
    • のJava 9は、いくつかのマイナーな機能と修正が追加されます。
  • Java SE 6Java SE 7
    • java.time機能の多くはThreeTen-BackportのJava 6 & 7に戻って、移植されます。
  • Android
      ThreeTenABP
    • プロジェクトは、具体的にはAndroid用(上記)ThreeTen-バックポートを適応させます。
    • How to use ThreeTenABP…を参照してください。

ThreeTen-Extraプロジェクトでは、追加のクラスでjava.timeを拡張します。このプロジェクトは、将来のjava.timeへの追加の可能性を証明する土台です。ここでは、IntervalYearWeekYearQuartermoreなどの便利なクラスがあります。

関連する問題