4D-JUG
Would you like to react to this message? Create an account in a few clicks or log in to continue.

【プラグイン】日付のフォーマット変換と加減算

Go down

【プラグイン】日付のフォーマット変換と加減算 Empty 【プラグイン】日付のフォーマット変換と加減算

投稿 by miyako 2018-06-25, 9:32 am

日付のフォーマット変換と加減算を補助するプラグインを公開しました。

Howard HinnantさんのTime Zone Database Parserライブラリを利用しています。

https://howardhinnant.github.io/date/tz.html

日付文字列

4Dでは,日付(年月日)と時間(秒)を個別のデータ型として扱います,また,時刻(真夜中から経過した秒数=Time)と時間(Duration)の区別も曖昧です。時間は時刻に似ていますが,値がマイナスになったり,24時間を超えたりするところが時刻と違います。

日付と時間をひとつの値(文字列)にまとめるには,Stringを使用します。日付文字列のフォーマットには,いろいろなものがありますが,代表的なのは『RFC 1123』と『ISO』です。

SET TEXT TO PASTEBOARD(String(Current date;Date RFC 1123;Current time))
Sun, 24 Jun 2018 23:41:07 GMT

SET TEXT TO PASTEBOARD(String(Current date;ISO date GMT;Current time))
2018-06-24T23:41:57Z

4Dの日付・時間をRFCまたはISOに変換するのは容易ですが,逆に4Dの日付・時間を文字列から取り出すのはなかなか面倒です。

ISO

DateやTimeISO文字列に対応していますが,RFCには対応していません。日付や時間はローカルタイムゾーン(日本標準時はUTC+0900)で返されます。

$date:=Date("2018-06-24T23:41:57Z")  //18/06/25
$time:=Time("2018-06-24T23:41:57Z")  //08:41:57

ISO形式は,XMLやJSONでも使用されていますが,コマンドの振る舞いをよく理解して使用する必要がります。

XML

C_DATE($date)
XML DECODE("2018-06-24T23:41:57Z";$date)  //18/06/24
C_TIME($time)
XML DECODE("2018-06-24T23:41:57Z";$time)  //08:41:57

XML DECODEの場合,時間はローカルタイムゾーンに調整されますが,日付は単純に文字列から取り出される(時間に左右されない)ところがポイントです。つまり,コマンドは4Dの日付や時間をXMLに書き込むため,日付と時間を結合した文字列を使用してはいますが,目的は日付と時間のどちらかを扱うことであり,両方をまとめた値として扱うことはではない,ということがわかります。

JSON

C_DATE($date)
$date:=JSON Parse("\"2018-06-24T23:41:57Z\"";Is date)//18/06/25

JSON Parseの場合,日付はローカルタイムゾーンで返されます(振る舞いはデータベースパラメーターで変更できます)。JSON文字列を文字列として表現する必要があるので,値は二重引用符を付けて渡します。

XMLとは違い,ISO日付から時刻だけを取り出すことはできません。JSONの時間(時刻ではない)は文字列ではなく,ミリ秒(あるいは秒,単位はデータベースパラメーターで指定できます)つまり数値で表現されます。

まとめ

日付・時間をRFCまたはISO文字列に変換する:String
ISO日付文字列を日付に変換する:Date, JSON Parse
ISO日付文字列を時間に変換する:Time, XML DECODE
ISO日付文字列から日付だけを取り出す:XML DECODE

標準コマンドひとつではできないこと

RFC日付文字列を日付・時間に変換する
日付・タイムゾーン・サマータイム等を超えた時刻の計算

今回のプラグインは,こうした必要に応えるものです。

RFC日付からISO日付に変換する

$time:="Sun Sep 16 01:03:52 -0500 1973"
$fmt_in:="%a %b %d %T %z %Y"
$zone_out:=""
$fmt_out:="%FT%TZ"

$utc:=TZ Convert ($time;$fmt_in;$zone_out;$fmt_out)
 //1973-09-16T06:03:52.000Z

%a, %bなどのフォーマット文字列は,さまざまなプログラミング言語の『strftime』に準拠します。

https://linuxjm.osdn.jp/html/LDP_man-pages/man3/strftime.3.html

日付と時刻を別のタイムゾーンに変換する

$time:="Sun Sep 16 01:03:52 -0500 1973"
$fmt_in:="%a %b %d %T %z %Y"
$zone_out:="Australia/Sydney"
$fmt_out:="%FT%T %Z"

$aest:=TZ Convert ($time;$fmt_in;$zone_out;$fmt_out)
 //1973-09-16 16:03:52.000 AEST

日付によって,サマータイムが適用されたり,されなかったりすることが考慮されています。

タイムゾーンを超えた日付の計算

出発:ニューヨーク時間1978年12月30日の12:01
飛行時間:14時間44分
到着:テヘラン

$departure:="1978-12-30 12:01:00 -0500"
$fmt_in:="%F %T %z"
$fmt_out:="%F %T %z"
$zone_out:="Asia/Tehran"
$flight:=?14:44:00?

$arrival:=TZ Convert ($departure;\
$fmt_in;\
$zone_out;\
$fmt_out;\
$flight+0)
 //1978-12-31 11:45:00.000 +0400

現地時刻で1978年12月31日の11:45

この翌年からテヘランのタイムゾーンがUTF+0330に変更されたことも考慮されています。

出発:ニューヨーク時間1978年12月31日の12:01
飛行時間:14時間44分
到着:テヘラン

$arrival:=TZ Convert ($departure;\
$fmt_in;\
$zone_out;\
$fmt_out;\
$flight+0)
 //1979-01-01 11:15:00.000 +0330

現地時刻で1979年1月1日の11:15

ライブラリは,過去のうるう秒・政治的決定によるタイムゾーンの変更など,IANAの詳細なデータベースを使用しているので,正確です。インターネットを介して最新のデータベースをダウンロードするオプションや,Mac/Linuxのシステムデータを使用するオプションありますが,プラグインは簡便性を優先し,ローカルにファイルを持っています。

https://github.com/miyako/4d-plugin-tz

miyako

投稿数 : 480
登録日 : 2016/07/05

トップに戻る Go down

トップに戻る

- Similar topics

 
Permissions in this forum:
返信投稿: 不可