こんにちは、あんこ先生です。
日付の表現って文化やシステ厶によって異なりますよね。
区切り文字ひとつとってもスラッシュやピリオドだったり、英語や日本語だったり、世代や嗜好で多種多様ですね。
ところが、集計やアプリ作成する側からしてみれば、統一されていないってすごいストレスなんです。
そこで、どんな文字列が舞い込んできてもアプリ内で日付型に変換してしまおうというのが、今回の記事です。
正直、取り込む前に成型すればこと足りることなので、そちらを強くオススメします。
とはいえ、どうしてもって理由がある場合、必ず役立ちますのでぜひ読み進めてください。
いつもどおり、コードは極力コピペで動くようにしています。
- 大抵のケースは、日付の選択コントロールで半強制的に日付型にできること
- Excelで使える技はほとんど通用しないこと
- 和暦⇔西暦は変換テーブルを用意すると便利なこと
Contents
いろんな文字列を日付型に変換できるか調べる
結論
すべてテキスト型のお話です。
- 区切り文字があるか固定長8桁数値は、日付の選択コントロールに入れることで変換できます。
- 日付の選択コントロールに入れる=DateValue関数と同義でした。
- Text関数(yyyy/mm/dd)は変換できないケースもあります。
- 意外なところでは、アメリカ表記は正しく処理できませんね。
日付の選択コントロールの使い方は、次の記事をご覧ください。
除外対象
上図の灰色網掛け部分を、なんとかして日付型に変換していきます。
ただし、月日部分が3桁以下の場合は月と日を明確に区別できないため対象外とします。
例えば、2022123では2022/1/23なのか、それとも2022/12/3なのかわかりませんよね。
この場合はあきらめて、手動で元データを直してください。
シリアル値を日付型に変換する
シリアル値とは
日付や日時を計算するため、あらかじめシステムで設定された基準日からの通算日数を表す値です。
Excelと同様にPowerAppsも1900年1月1日が1となります。
もし1日ずれているようであれば、タイムゾーンを確認してみてください。
UTCになっていると、時差分の-9時間が適用され1899年12月31日開始となります。
また、日付の選択コントロールは1970年より前は対応していません。
それ以前の日付を表示させる場合は、他のコントロールを使いましょう。
StartYearプロパティの値を変更すれば1970年以前も選択可能です。
DatePicker01.DefaultDateプロパティ
シリアル値は1から始まるため、1日前の日付に足す形をとりました。
DateAdd(DateValue("1899/12/31"),Value(TextInput01.Text),TimeUnit.Days)
年月日順不定を日付型に変換する
年月日の順番がバラバラ、かつ桁数不定の場合
月日が一桁の場合、桁数が変わるパターンです。
例では2022年3月1日を月/日/年の順で表記しています。
いわゆるアメリカ表記ですね。
区切り文字があるので、それを利用して一旦テーブルを構築し、並び替えます。
テーブル化はSplit関数を使います。
3レコードのテーブルになるため、First関数などを用いて必要な情報を抽出します。
Gallery01.Itemsプロパティ
Split(TextInput01.Text,"/")
DatePicker01.DefaultDateプロパティ
Last(Gallery01.AllItems).Value&"/"& //最終行(年)
First(Gallery01.AllItems).Value&"/"& //開始行(月)
Last(FirstN(Gallery01.AllItems,2)).Value //真ん中行(日)
年月日の順番がバラバラ、桁数固定の場合
次は桁数固定の場合です。
月日が一桁だと10の位に0が入ります。
たとえば、03/01/2022のような形です。
この場合、年月日の位置が分かっているのでその部分を抜き取ります。
抜き取りには、Mid関数を使います。
Left関数やRight関数もありますが、Mid関数のみでも対応できます。
DatePicker01.DefaultDateプロパティ
Mid(TextInput01.Text,7,4)&"/"& //年
Mid(TextInput01.Text,1,2)&"/"& //月
Mid(TextInput01.Text,4,2) //日
スペースを含む文字列を日付型に変換する
スペースがちりばめられている場合
月や日の前後に半角スペースが含まれていたり、なぜか全角のスペースを使用しているパターンです。
見栄えを良くしようとして失敗してるアレです。
不要なものは取り除いてしまいましょう。
特定文字の除外はSubstitute関数を使います。
DatePicker01.DefaultDateプロパティ
Substitute(TextInput01.Text," ","") //半角スペースを除外
Substitute(TextInput01.Text," ","") //全角スペースを除外
西暦省略表記を日付型に変換する
西暦を2桁に省略している場合
幅の問題や文字数制限でよく使われる表現です。
2桁西暦の頭にアポストロフィが付いています。
あと80年くらいは20xx年で通じるので、気にせず頭を20に変換してしまいましょう。
特定文字の置き換えもSubstitute関数を使います。
DatePicker01.DefaultDateプロパティ
Substitute(TextInput01.Text,"’","20") //’を20に変換
和暦を日付型に変換
変換用和暦テーブルの作成
日本人なので和暦大好きです。
でもシステムは西暦で計算されるため、そのままだと非常に使いにくいです。
しかも、和暦は年の途中から切り替わるので計算がとても煩雑になります。
そのため、変換用和暦テーブルを用意した方が早道になります。急がば回れですね。
構成は、基準日と元号、増加させる年数の3つです。
Button01.OnSelectプロパティ
ClearCollect(_T和暦,
{Date:DateValue("2019/5/1"),Calendar:"令和",Value:2018},
{Date:DateValue("1989/1/8"),Calendar:"平成",Value:1988},
{Date:DateValue("1926/12/25"),Calendar:"昭和",Value:1925}
)
年部分を和暦から西暦に変換してから再結合
次に変換用和暦テーブルを参照させて、元号と一致した増加させる年数を取得します。
その値を和暦に足して年を求めます。
月日は元のテキストをSplit関数で年を基準委分割し、後者を使います。
年の文字が抜けているので忘れずに追記してください。
これで西暦への変換を終えます。
逆の手順で、西暦から和暦へも変換できます。
Label.Textプロパティ
LookUp(_T和暦,Calendar=Mid(Label01.Text,1,2),Mid(Label01.Text,3,2)+Value&"年"&
Last(Split(Label01.Text,"年")).Value)
まとめ
今回は、さまざまな文字列をなんとかして日付型に変換してみました。
その過程で、文字列のテーブル化や文字変換なども紹介できましたね。
この辺をおさえておくと、型変換を行う際につまずきにくくなります。
使い方はアイデア次第!さっそくアプリに組み込んで動作させてみましょう!