オブジェクトと日付と時間

<code 4D>
C_OBJECT($test_o)
C_DATE($date1_d;$date2_d)
C_TIME($time1_h;$time2_h)
$test_o:=New object(“birthday”;“1990/4/25”;“create_time”;“12:30:45”)

$time1_h:=OB Get($test_o;“create_time”)
$date1_d:=OB Get($test_o;“birthday”)
$time2_h:=OB Get($test_o;“create_time”;Is time)
$date2_d:=OB Get($test_o;“birthday”;Is date)
</code 4D>

オプションでタイプを渡さない場合には仕方ないかもしれませんが、タイプを渡した場合には変換してほしいです。

ちなみに

<code 4D>
$time3_h:=$test_o.start_time
$date3_d:=$test_o.birthday
</code 4D>
オブジェクト表記でもエラーになるのですが、タイプを渡す方法はないのでしょうか?

引き続き、
<code 4D>
C_OBJECT($test_o)
C_DATE($date1_d;$date2_d)
C_TIME($time1_h;$time2_h)
$test_o:=New object(“birthday”;Current date;“create_time”;Current time)
$time1_h:=$test_o.create_time
$date1_d:=$test_o.birthday
$time2_h:=OB Get($test_o;“create_time”)
$date2_d:=OB Get($test_o;“birthday”)
</code 4D>

4Dが推奨しているデータを取得してみました。
時間は両方共正しい時間情報として取得できませんでした。
日付はエラーになります。可逆性がありません。 :frowning:

オブジェクトの内部フォーマットはJSONなので,日付と時間の区別はありません。
どちらも時間(ISO文字列)となります。
ですから,時間であっても,日付に変換して代入することが必要です。
一方,TimeとDateはISOに対応していますので,下記のようなコードで取り出すことができます。

$test_o:=New object(“birthday”;Current date;“create_time”;String(Current time;ISO date))
$time1_h:=Time($test_o.create_time)
$date1_d:=Date($test_o.birthday)

オブジェクト記法とFormの例題を作成しました。

https://github.com/miyako/4d-utility-backup-dialog

気づいたことですが,時間や日付に関しては,文字列入力ではなく,ポップアップなどのフォームオブジェクトを主体にすると最小限のコードで良い具合にUIが作成できそうです。

ご説明ありがとうございます。

$test_o:=New object(“birthday”;Current date;“create_time”;String(Current time;ISO date))

この様にしなければならないのであれば、

$test_o:=New object(“birthday”;Current date;“create_time”;Current time)

でiSOフォーマットに変換されるのが正しいのではないでしょうか?

オブジェクト記法はプレビュー段階であり,仕様が変更できるかもしれませんので,
バグ・要望として登録しました。

ACI0097752: Object notation: Time is not automatically converted to ISO date; it must be explicitly converted (which makes little sense)

In code, when a time value is assigned to an object, the value is stored milliseconds.

I supposed the idea is that:

Time is not a native JSON data type.
Number is a native JSON data type.
Time is counted in seconds in 4D, milliseconds in JS.
The conversion is bidirectional in 4D code:
4D Time to Object Numeric…multiply by 1000
Object Numeric to 4D Time…divide by 1000

However, with the introduction of object notation, it makes more sense to use the time portion of an ISO date instead of a number. The advantage of an ISO date is that it can be implicitly converted to Time. With object notation, there is no option to specify the data type as in OB Get; the only hint is the type of the left operand.

Example code in current implementation:

$o:=New object(“birthday”;Current date;“create_time”;String(Current time;ISO date))
$h:=Time($o.create_time)
$d:=Date($o.birthday)

So it becomes mandatory to use explicit casts, i.e. String(), Time(), Date() in each instance, even though the data type of the left operand is declared in code.

It would be better if 4D did the conversion to and from Time implicitly.

Example code in proposed implementation:

$o:=New object(“birthday”;Current date;“create_time”;Current time)
$h:=$o.create_time
$d:=$o.birthday[/code]

ご登録ありがとうございます。

現状は辻褄があわないので、実現されるとたすかります。 :pray:

本件,開発部(担当者レベルではなく,総責任者)より回答がありました。

オブジェクト型の導入当初より,時間は実数型で格納されるので,現在の動作が「正常」である,とのことでした。

ご期待に沿うことができずに申し訳ございません。

私の推測ですが,4Dの時間型は,時刻(TIMESTAMP)としての側面と,時間(DURATION)としての側面の両方があり,
負の値になったり,24時間を超過することもあるので,このような仕様になっているのではないでしょうか。

コーディングにおいては,時間型の特殊性に注意を払いながら,必要に応じてTime()/String()をかけたり,
*1000. *.001をかけたりする必要がありそうです。

よろしくお願い申し上げます。

4D内部の事情はよくわかるのですが、
実際にJSONを使ったやり取りをしていると困るので、余裕というか汎用性を考慮してほしいです。

時間に関してだと

hh:mm:ss
hhmmss
午前hh時mm分(ss分)
YYYY-MM-DDThh:mm:ss+09:00
DD.MM.YYYY hh:mm:ss
YYYY-MM-DD hh:mm:ss (MySQLのtimstampフォーマットらしい)
hh:mm:ss-08:00 (IS08601のフォーマットとしてあるらしい)

などで渡されてくることがあるので、
timeコマンド及び、OB GET(test_o;“time”;Is time)では正しく変換して欲しいです。

selection to JSONコマンドなどでの変換時のオプションとしても上記フォーマットが指定できる様にしてほしいです。

日付も同様です。
YYYY-MM-DDThh:mm:ssZだけでなく、

YYYYMMDD
YYYY/MM/DD
YYYY.MM.DD
平成29年12月28日

なども許容するオプションが必要だと感じます。
外部とのやり取りでこのフォーマットでと言うのがどうしてもあります。

4DってODBCでもそうですが外部システムとの連携できますって割には融通がきかないですよね。 :mrgreen:

詳細はまだ発表できませんが,16R6でオブジェクト型における日付の扱いが改良されることになりました。

Parse, Stringify, Type, Get, Set およびオブジェクト記法が対象で,既存のコードとの互換性にも配慮が払われています。

今後の公式ブログにご注目いただければ幸いです。

宮古さま。お世話になります。

時間の方はそのままでしょうか、こちらも改良されると助かります。 :pray:

どの様に改良されるのか、蓋をあけてみないとわからないでが期待してます。

: Keisuke MIYAKO

詳細はまだ発表できませんが,16R6でオブジェクト型における日付の扱いが改良されることになりました。

Parse, Stringify, Type, Get, Set
およびオブジェクト記法が対象で,既存のコードとの互換性にも配慮が払われています。

今後の公式ブログにご注目いただければ幸いです。

ブログを読んでみたところプロセス単位で動的に変更できるとのことだったので確認してみました。

[]22785554;“Your comment here…”[/]

オブジェクト変数のままだと、_Date type_のオプションでもISO表示"2018-02-09T00:00:00.000Z"なのですが
JSONに変換すると希望通り"2018-02-09"の表示になってました。
これはデバッガ側の問題でしょうか?

あとはこれの時間バージョンの追加をぜひお願いします。
標準の数値の他、ISO8601日付時間フォーマットと普通の時間フォーマットが希望です。 :pray:
JSON Validateのtimeフォーマットを考慮するのであれば、"00:00:00.000+09:00"も必要かもしれません。

開発部から(部分的に)回答がありました。

まず,JSON TO SELECTION, Selection to JSONについては,
外部アプリとのデータ受け渡しを想定したコマンドではなく,
(その用途を想定して)将来的に拡張する予定もない,とのことです。

外部アプリケーション向けにJSONを作成するのであれば,
PROCESS 4D TAGSを活用するか(こちらがイチ押しだそうです),
コレクション関数のhttp://doc.4d.com/4Dv16R6/4D/16-R6/collectionmap.301-3693387.ja.htmlmap()>で日付や時間を文字列に変換することが推奨されています。

: Keisuke MIYAKO

開発部から(部分的に)回答がありました。

まず,JSON TO SELECTION, Selection to JSONについては,
外部アプリとのデータ受け渡しを想定したコマンドではなく,
(その用途を想定して)将来的に拡張する予定もない,とのことです。

もしかして、これってImpot/Expot用ってことでしょうか。
今後、書き出し/読み込みダイアログのファイル形式として追加されるのでしょうか。それとも廃止の方向?

拡張する予定がない,というだけですので,廃止を検討しているというよりも,
汎用的なコマンドの第一歩ではなく,これで完成型だという意味かと思います。

機能的にはhttp://doc.4d.com/4Dv15/4D/15.5/MOBILE-Return-selection.301-3576803.ja.htmlMOBILE Return selection>を発展させたようなものですので,
4D Webサーバーとの組み合わせで使える簡易メソッド,
みたいな位置づけとお考えいただければ幸いです。

: Keisuke MIYAKO

拡張する予定がない,というだけですので,廃止を検討しているというよりも,
汎用的なコマンドの第一歩ではなく,これで完成型だという意味かと思います。

機能的には<http://doc.4d.com/4Dv15/4D/15.5/MOBILE-Return-selection.301-3576
03.ja.html>MOBILE Return selection>を発展させたようなものですので,
4D Webサーバーとの組み合わせで使える簡易メソッド,
みたいな位置づけとお考えいただければ幸いです。

ますます用途がわかりません。
ドキュメントに用途を明記していただけませんか?

資料をたどってみたのですが,用途(User Story)がきっちり文書として参照できるのは,v15以降となっているので,JSON TO SELECTIONの拡張(オブジェクト型フィールドのサポート)から間接的に知ることしかできませんでした。

そこから読み取れたのは,両コマンドがARRAY TO SELECTION,SELECTION TO ARRAY,SELECTION RANGE TO ARRAYの「仲間」だということでした。

たとえば,「Selection to JSON(table;objectField)」といった風に記述した場合,このフィールドを書き出せ,という意味にも,このフィールドのカレントレコード値をテンプレートとしてセレクションを書き出せ,という意味にも取れるが,「より一般的な用途である」という理由で,前者(テンプレートではなく,フィールド指定として解釈)の振る舞いを仕様とする,とありました。

ドキュメントに記述されているとおり,カレントセレクションからJSON文字列を作成する,あるいは,JSON文字列をカレントセレクションにコピーするというのが,コマンドの「用途」です。

外部システムとのデータ交換,HTML/JavaScript/Webエリアとの併用は,考えられる活用例(アイデア)ですが,そこまで具体的な用途を想定したコマンドが設計されているわけではない,ということになります。また,すでにお気づきかもしれませんが,RANGE版がないので,ある程度,レコード数が多くなると,操作を分割する必要がありますし,そうでなくても,「サーバー側で実行」メソッドプロパティを有効にしなければ,パフォーマンス面で難があるかと思います(インポート/エクスポート用に作られたものではないと思えるのはこれが理由です)。

いろいろ考えたのですがこのコマンドは制限がありすぎて本当に使いどころがないんです。 :mrgreen:

: Keiji HOSAKA

いろいろ考えたのですがこのコマンドは制限がありすぎて本当に使いどころがないんです。 :mrgreen:
v17からORDAの導入で、JSON TO SELECTION/Selection to JSONの2つこコマンドは事実上ディスコンですね。 :smiley:
ただし時間フィールドの扱いはなんとかしてほしいです。