前提・実現したいこと
DBに格納される際に日付(date型)の値がおかしくなってしまいます。
送ったデータ「2018/06/29」⇒DBに格納されたデータ「0197-02-06」
発生している問題・エラーメッセージ
【Java側】
作成した入力フォームから『2018/06/29』という文字列をPOSTで飛ばしています。
受け取ったサーバサイド側のJavaプログラムでDate型の値で受け取るようにしています。
↓
【DB側】
格納された値が『0197-02-06』となっている。
試したこと
・サーバー、postgresql、tomcatなどのシステム時間(タイムゾーン)などは日本時間に設定済み
・クライアント側(入力フォーム)からPOSTで飛ばしている値は、『2018/06/29』であることは確認済み
・postgresqlのログから、発行されたSQLを見ると、この時点でINSERT~'0197-02-06'~となってしまっているのは確認済み
・該当するカラムの型はdate
・同じテーブル内に「作成日」というカラムもあり、そちらの型はtimestamp with time zone NOT NULL DEFAULT now() としていて、正しい日付が格納されているので、postgresqlの環境時間には問題はなさそう
補足情報(FW/ツールのバージョンなど)
【環境】
サーバー:AWS(Linux version 4.14.33-51.37.amzn1.x86_64)
Java-1.7
tomcat-7
postgresql-9.2.24
※DB用サーバーはなく、上記全て同じサーバー上で動いています
ソースコード
古いですが、seasar2のフレームワークを使っています。
package jp.co.system.thirdbox.action;
import javax.annotation.Resource;
import org.seasar.framework.beans.util.Beans;
import org.seasar.struts.annotation.ActionForm;
import org.seasar.struts.annotation.Execute;
import jp.co.system.thirdbox.dto.LoginDto;
import jp.co.system.thirdbox.entity.Diary;
import jp.co.system.thirdbox.form.DiaryForm;
import jp.co.system.thirdbox.service.DiaryService;
public class DiaryAction {
@Resource
@ActionForm
public DiaryForm diaryForm;
@Resource
public LoginDto loginDto;
@Resource
protected DiaryService diaryService;
@Execute(validator = false)
public String index(){
return "diary.jsp";
}
@Execute(validator = false)
public String keep(){
diaryForm.accountId = loginDto.id;
Diary diary = new Diary();
Beans.copy(diaryForm,diary).execute();
diaryService.diaryInsert(diary);
return "finish.jsp";
}
}
package jp.co.system.thirdbox.form;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
import org.seasar.framework.container.annotation.tiger.Component;
import org.seasar.framework.container.annotation.tiger.InstanceType;
@Component(instance = InstanceType.SESSION)
public class DiaryForm implements Serializable {
private static final long serialVersionUID = 1L;
/** idプロパティ */
public Integer id;
/** accountIdプロパティ */
public Integer accountId;
/** diaryDayプロパティ */
public Date diaryDay;
/** activity1プロパティ */
public String activity1;
/** activity2プロパティ */
public String activity2;
/** activity3プロパティ */
public String activity3;
/** createTimeプロパティ */
public Timestamp createTime;
/** updateTimeプロパティ */
public Timestamp updateTime;
/** deleteFlagプロパティ */
public Integer deleteFlag;
}
package jp.co.system.thirdbox.dto;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
import org.seasar.framework.container.annotation.tiger.Component;
import org.seasar.framework.container.annotation.tiger.InstanceType;
@Component(instance = InstanceType.SESSION)
public class DiaryDto implements Serializable {
private static final long serialVersionUID = 1L;
/** idプロパティ */
public Integer id;
/** accountIdプロパティ */
public Integer accountId;
/** diaryDayプロパティ */
public Date diaryDay;
/** activity1プロパティ */
public String activity1;
/** activity2プロパティ */
public String activity2;
/** activity3プロパティ */
public String activity3;
/** createTimeプロパティ */
public Timestamp createTime;
/** updateTimeプロパティ */
public Timestamp updateTime;
/** deleteFlagプロパティ */
public Integer deleteFlag;
}
package jp.co.system.thirdbox.service;
import static jp.co.system.thirdbox.entity.DiaryNames.*;
import static org.seasar.extension.jdbc.operation.Operations.*;
import java.util.List;
import javax.annotation.Generated;
import jp.co.system.thirdbox.entity.Diary;
/**
* {@link Diary}のサービスクラスです。
*
*/
@Generated(value = {"S2JDBC-Gen 2.4.46", "org.seasar.extension.jdbc.gen.internal.model.ServiceModelFactoryImpl"}, date = "2018/06/06 11:51:06")
public class DiaryService extends AbstractService<Diary> {
/**
* 識別子でエンティティを検索します。
*
* @param id
* 識別子
* @return エンティティ
*/
public Diary findById(Integer id) {
return select().id(id).getSingleResult();
}
/**
* 識別子の昇順ですべてのエンティティを検索します。
*
* @return エンティティのリスト
*/
public List<Diary> findAllOrderById() {
return select().orderBy(asc(id())).getResultList();
}
/*日記を1件挿入する*/
public int diaryInsert(Diary diary){
return jdbcManager.insert(diary).excludesNull().execute();
}
/* 全日記を取得(新しい順)
public List<Diary> findAllByaccountId(int accountId){
return jdbcManager.from(Diary.class).where("account_id = ?",accountId).orderBy(desc("diaryDay")).getResultList();
}*/
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+3
多分、こういうことが起きてる。
2018/06/29
↓
29年2018月06日
↓
2018ヶ月=168年と2ヶ月
↓
29+168=197年
↓
197年2月6日
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.36%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
mather
2018/06/29 14:30
日付文字列を受けとってDBに格納するまでの処理がソースコードにあるはずです。そちらを提示してください。
thirdbox
2018/06/29 14:39
ご連絡ありがとうございます。ソースコード追記しました。
mather
2018/06/29 14:43
入力された文字列をDate型に変換する処理はどこですか?diaryFormはどうやって定義されていますか?抜粋しすぎて Diary クラスの定義などが抜け落ちていますので、できる限りクラス定義など全体をコピペしたほうがいいです。あと、Markdownのコードブロックを使ってください。
Orlofsky
2018/06/29 15:10
質問の際は現象を再現できる必要最小限のコードを載せましょう。CREATE TABLE文も必要です。コードは https://teratail.com/help#about-markdown の[コードを入力]を使ってください。
szk.
2018/06/29 15:11
サーバ上でログ出力して、どこで変換されたか確認するのが一番早いと思いますが、、、なぜクライアントとDBしか確認しないのでしょうか。
thirdbox
2018/06/29 15:13
承知しました。ソースコード貼りなおしました。また、文字列のDate型変換はフレームワーク側で型の自動変換をおこなっています。
thirdbox
2018/06/29 15:18
Orlofskyさん、ありがとうございます。szkさん、おっしゃる通りです。ローカル環境ではこの現象が出ていないので、ソースコードに問題はないと勝手に判断していました。
thirdbox
2018/06/29 15:19
サーバー上でログ出力して確認してみます。
thirdbox
2018/06/29 15:53
javaのソースコードをいじり、DB格納前のDiaryServiceクラスのINSERT前にsysoutで日付を出力してみました。結果は、「0197-02-06」となっており、この時点で日付の変換がおかしいところまではわかりました。引き続き調べてみます。
thirdbox
2018/06/29 16:49
原因、わかりません、、、
szk.
2018/06/29 17:03
あと怪しいところは、サーバがリクエストを受け取った時とpropertyのコピーの前後。
thirdbox
2018/06/29 17:10
szkさん、了解です。ちなみに、再度色々と確認してみたら、JVMのタイムゾーンがUTCのままでした。これあやしいですよね?
thirdbox
2018/06/29 17:28
JVMのタイムゾーン直したけど関係なかったです。。。
szk.
2018/06/29 17:52
ローカル環境では再現なしということなので、サーバ(aws)が受け取った時には日付がおかしい可能性もあります。クライアントからサーバへのPOST/GETは文字列で行われるので、seasar2/tomcatが受け取ってコンバートした時かawsの設定が怪しかと。
thirdbox
2018/06/30 07:46
おはようございます。szkさん、返信ありがとうございます。awsの環境上でDate date = new Date();と実行したら「Sun Feb 06 00:00:00 JST 197」と表示されました。なのでここが問題です。ただ、JavaのDateクラスってどこの時間を見にいっているのでしょうか?