質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

3550閲覧

DBに格納された日付がおかしい

thirdbox

総合スコア9

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

1クリップ

投稿2018/06/29 05:27

編集2018/06/29 06:09

前提・実現したいこと

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のフレームワークを使っています。

lang

1package jp.co.system.thirdbox.action; 2 3import javax.annotation.Resource; 4 5import org.seasar.framework.beans.util.Beans; 6import org.seasar.struts.annotation.ActionForm; 7import org.seasar.struts.annotation.Execute; 8 9import jp.co.system.thirdbox.dto.LoginDto; 10import jp.co.system.thirdbox.entity.Diary; 11import jp.co.system.thirdbox.form.DiaryForm; 12import jp.co.system.thirdbox.service.DiaryService; 13 14public class DiaryAction { 15 16 @Resource 17 @ActionForm 18 public DiaryForm diaryForm; 19 20 @Resource 21 public LoginDto loginDto; 22 23 @Resource 24 protected DiaryService diaryService; 25 26 @Execute(validator = false) 27 public String index(){ 28 return "diary.jsp"; 29 } 30 31 @Execute(validator = false) 32 public String keep(){ 33 diaryForm.accountId = loginDto.id; 34 Diary diary = new Diary(); 35 Beans.copy(diaryForm,diary).execute(); 36 diaryService.diaryInsert(diary); 37 return "finish.jsp"; 38 } 39 40} 41

lang

1package jp.co.system.thirdbox.form; 2 3import java.io.Serializable; 4import java.sql.Timestamp; 5import java.util.Date; 6 7import org.seasar.framework.container.annotation.tiger.Component; 8import org.seasar.framework.container.annotation.tiger.InstanceType; 9 10@Component(instance = InstanceType.SESSION) 11public class DiaryForm implements Serializable { 12 private static final long serialVersionUID = 1L; 13 14 /** idプロパティ */ 15 public Integer id; 16 17 /** accountIdプロパティ */ 18 public Integer accountId; 19 20 /** diaryDayプロパティ */ 21 public Date diaryDay; 22 23 /** activity1プロパティ */ 24 public String activity1; 25 26 /** activity2プロパティ */ 27 public String activity2; 28 29 /** activity3プロパティ */ 30 public String activity3; 31 32 /** createTimeプロパティ */ 33 public Timestamp createTime; 34 35 /** updateTimeプロパティ */ 36 public Timestamp updateTime; 37 38 /** deleteFlagプロパティ */ 39 public Integer deleteFlag; 40} 41

lang

1package jp.co.system.thirdbox.dto; 2 3import java.io.Serializable; 4import java.sql.Timestamp; 5import java.util.Date; 6 7import org.seasar.framework.container.annotation.tiger.Component; 8import org.seasar.framework.container.annotation.tiger.InstanceType; 9 10@Component(instance = InstanceType.SESSION) 11public class DiaryDto implements Serializable { 12 private static final long serialVersionUID = 1L; 13 14 /** idプロパティ */ 15 public Integer id; 16 17 /** accountIdプロパティ */ 18 public Integer accountId; 19 20 /** diaryDayプロパティ */ 21 public Date diaryDay; 22 23 /** activity1プロパティ */ 24 public String activity1; 25 26 /** activity2プロパティ */ 27 public String activity2; 28 29 /** activity3プロパティ */ 30 public String activity3; 31 32 /** createTimeプロパティ */ 33 public Timestamp createTime; 34 35 /** updateTimeプロパティ */ 36 public Timestamp updateTime; 37 38 /** deleteFlagプロパティ */ 39 public Integer deleteFlag; 40 41} 42

lang

1package jp.co.system.thirdbox.service; 2 3import static jp.co.system.thirdbox.entity.DiaryNames.*; 4import static org.seasar.extension.jdbc.operation.Operations.*; 5 6import java.util.List; 7 8import javax.annotation.Generated; 9 10import jp.co.system.thirdbox.entity.Diary; 11 12/** 13 * {@link Diary}のサービスクラスです。 14 * 15 */ 16@Generated(value = {"S2JDBC-Gen 2.4.46", "org.seasar.extension.jdbc.gen.internal.model.ServiceModelFactoryImpl"}, date = "2018/06/06 11:51:06") 17public class DiaryService extends AbstractService<Diary> { 18 19 /** 20 * 識別子でエンティティを検索します。 21 * 22 * @param id 23 * 識別子 24 * @return エンティティ 25 */ 26 public Diary findById(Integer id) { 27 return select().id(id).getSingleResult(); 28 } 29 30 /** 31 * 識別子の昇順ですべてのエンティティを検索します。 32 * 33 * @return エンティティのリスト 34 */ 35 public List<Diary> findAllOrderById() { 36 return select().orderBy(asc(id())).getResultList(); 37 } 38 39 40 /*日記を1件挿入する*/ 41 public int diaryInsert(Diary diary){ 42 return jdbcManager.insert(diary).excludesNull().execute(); 43 } 44 45/* 全日記を取得(新しい順) 46 public List<Diary> findAllByaccountId(int accountId){ 47 return jdbcManager.from(Diary.class).where("account_id = ?",accountId).orderBy(desc("diaryDay")).getResultList(); 48 }*/ 49 50

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mather

2018/06/29 05:30

日付文字列を受けとってDBに格納するまでの処理がソースコードにあるはずです。そちらを提示してください。
thirdbox

2018/06/29 05:39

ご連絡ありがとうございます。ソースコード追記しました。
mather

2018/06/29 05:43

入力された文字列をDate型に変換する処理はどこですか?diaryFormはどうやって定義されていますか?抜粋しすぎて Diary クラスの定義などが抜け落ちていますので、できる限りクラス定義など全体をコピペしたほうがいいです。あと、Markdownのコードブロックを使ってください。
Orlofsky

2018/06/29 06:10

質問の際は現象を再現できる必要最小限のコードを載せましょう。CREATE TABLE文も必要です。コードは https://teratail.com/help#about-markdown の[コードを入力]を使ってください。
szk.

2018/06/29 06:11

サーバ上でログ出力して、どこで変換されたか確認するのが一番早いと思いますが、、、なぜクライアントとDBしか確認しないのでしょうか。
thirdbox

2018/06/29 06:13

承知しました。ソースコード貼りなおしました。また、文字列のDate型変換はフレームワーク側で型の自動変換をおこなっています。
thirdbox

2018/06/29 06:18

Orlofskyさん、ありがとうございます。szkさん、おっしゃる通りです。ローカル環境ではこの現象が出ていないので、ソースコードに問題はないと勝手に判断していました。
thirdbox

2018/06/29 06:19

サーバー上でログ出力して確認してみます。
thirdbox

2018/06/29 06:53

javaのソースコードをいじり、DB格納前のDiaryServiceクラスのINSERT前にsysoutで日付を出力してみました。結果は、「0197-02-06」となっており、この時点で日付の変換がおかしいところまではわかりました。引き続き調べてみます。
thirdbox

2018/06/29 07:49

原因、わかりません、、、
szk.

2018/06/29 08:03

あと怪しいところは、サーバがリクエストを受け取った時とpropertyのコピーの前後。
thirdbox

2018/06/29 08:10

szkさん、了解です。ちなみに、再度色々と確認してみたら、JVMのタイムゾーンがUTCのままでした。これあやしいですよね?
thirdbox

2018/06/29 08:28

JVMのタイムゾーン直したけど関係なかったです。。。
szk.

2018/06/29 08:52

ローカル環境では再現なしということなので、サーバ(aws)が受け取った時には日付がおかしい可能性もあります。クライアントからサーバへのPOST/GETは文字列で行われるので、seasar2/tomcatが受け取ってコンバートした時かawsの設定が怪しかと。
thirdbox

2018/06/29 22:46

おはようございます。szkさん、返信ありがとうございます。awsの環境上でDate date = new Date();と実行したら「Sun Feb 06 00:00:00 JST 197」と表示されました。なのでここが問題です。ただ、JavaのDateクラスってどこの時間を見にいっているのでしょうか?
guest

回答1

0

ベストアンサー

多分、こういうことが起きてる。

2018/06/29

29年2018月06日

2018ヶ月=168年と2ヶ月

29+168=197年

197年2月6日

投稿2018/07/02 05:36

kopio

総合スコア487

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kopio

2018/07/02 05:51

日付を扱うときのロケールがアメリカになってると思うので、 どこかで指定できないかな?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問