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

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

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

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

1回答

5920閲覧

Cakephp3 Datetime型のミリ秒取得方法について

san11

総合スコア14

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

2グッド

2クリップ

投稿2017/03/02 06:00

編集2017/03/02 10:36

###前提・実現したいこと
CakePHP3.4.2にてDatetime(3)に設定されているカラムのデータをfindにて取得するとミリ秒以下が削られてしまいます。
こちらをミリ秒まで取得する方法をご存じの方いらっしゃいませんでしょうか?

###Datetime型のDebugの内容は以下の通りです

object(Cake\I18n\FrozenTime) { 'time' => '2017-03-02T01:40:10+09:00', 'timezone' => 'Asia/Tokyo', 'fixedNowTime' => false } DB上に実際に格納されている値:「2017-03-02 01:40:10.917」 i18nFormat('yyyy-MM-dd HH:mm:ss.S')も試してみましたが、ミリ秒が0になってしまいます。

###補足情報(言語/FW/ツール等のバージョンなど)
CakePHP 3.4.2
PHP 7.1.2
MariaDB 10.1.10

よろしくお願い致します。

###下記の回答を参考にさせて頂き動作が確認出来ましたのでコードを記載致します。

PHP

1//bootstrap.php 2Type::map('dtm', 'App\Database\Type\DateTimeMilliType'); 3Type::build('dtm') 4 ->useImmutable();

PHP

1//DateTimeMilliType.php 2namespace App\Database\Type; 3 4use Cake\Database\Type\DateTimeType; 5use Cake\Database\Driver; 6 7class DateTimeMilliType extends DateTimeType { 8 9 protected $_format = 'Y-m-d H:i:s.u'; 10 11 public function toPHP($value, Driver $driver) { 12 if ($value === null || strpos($value, '0000-00-00') === 0) { 13 return null; 14 } 15 16 if (strpos($value, '.') !== false) { 17 //list($value) = explode('.', $value); 18 } 19 20 $instance = clone $this->_datetimeInstance; 21 $tmp_obj = $instance->createFromFormat('Y-m-d H:i:s.u', $value); 22 return $tmp_obj; 23 } 24 25}

PHP

1//table 2 protected function _initializeSchema(Schema $schema) { 3 4 $schema->columnType("modified", 'dtm'); 5 $schema->columnType("created", 'dtm'); 6 return $schema; 7 }

PHP

1//ミリ秒まで取得 2//debug()だとミリ秒まで表示されないがformat()で表示されました 3//i18nFormatでも何故かミリ秒が表示されませんでした 4$item->created->format('Y-m-d H:i:s.u')
KiyoshiMotoki, maisumakun👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

独自のTypeを定義してあげればできると思います。

src/Database/Type/DateTimeMilliType.php
※独自のTypeクラスを作成(DateTimeTypeを拡張してformatを変更しているだけ)

php

1<?php 2namespace App\Database\Type; 3 4use Cake\Database\Type\DateTimeType; 5 6class DateTimeMilliType extends DateTimeType { 7 protected $_format = 'Y-m-d H:i:s.v'; 8}

config/bootstrap.phpの最後とかに以下の設定を追記

php

1Type::map('datetimemilli', 'App\Database\Type\DateTimeMilliType');

src/Model/Table/TimesTable.php (Table名やカラム名は実際のものに合わせてください)
※独自に作成したクラスをカラムのtypeを指定する

php

1<?php 2namespace App\Model\Table; 3 4use Cake\ORM\Table; 5use Cake\Database\Schema\Table as Schema; 6 7class TimesTable extends Table { 8 protected function _initializeSchema(Schema $schema) { 9 $schema->columnType("time", 'datetimemilli'); 10 return $schema; 11 } 12}

同じような質問があったので参考になるかと:CakePHP3.2のマイクロ秒でハマってます。
また、TypeについてはQiitaの記事が参考になるかと:【CakePHP3】 Type の話

投稿2017/03/02 07:35

編集2017/03/02 13:34
popobot

総合スコア6586

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

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

san11

2017/03/02 09:25

ご回答頂きまして誠にありがとうございました。 素晴らしいご回答に感謝致します。 頂いたコードにてミリ秒単位までの取得はできるようになったのですが、 'created' => '2017-03-02 01:40:10.917' という文字列にて値が返ってきております。 コードを見る限りobject(Cake\I18n\FrozenTime) での返却になるのではないかと思っておりましたが、こちらは問題無い動作でしょうか? 何度も申し訳ございませんが、よろしくお願い申し上げます。
popobot

2017/03/02 10:27 編集

ほんとですね...これだったら単にstringタイプにマッピングしても同じかもしれません...。 $schema->columnType("time", 'string'); CakeのTime系のクラスはミリ秒に対応していないので、これだけだとダメみたいですね。すみません。 Time系のクラスもミリ秒に対応して、Typeクラス側もうまくクラス化するところを直せばクラス化できるかもしれません。(あとはPHPのDateTimeクラスを使う方法もかるかもしれません) まぁ文字列でも良ければ、単にstringにするのもありかもです。加工はEntityでもできますので
san11

2017/03/02 10:33

ご回答頂きましてありがとうございます。 頂いたコードを元に自己解決出来ましたので、コードを記載させて頂きました。 初心者なのでこれで問題ないか自信はありませんがとりあえず動作は確認できました・・・
popobot

2017/03/02 14:02

素晴らしいですね! どうやら自分の最初の回答はTableクラスのcolumnTypeにTYPOがあって、stringになっていたみたいですね... すみません。 DateTimeMilliTypeにtoPHPを追加したらformatはミリ秒表示できますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問