none
GetDateFormatEx - フォーマットに 0 埋めする方法 RRS feed

  • 質問

  • 現在ローカライズされたファイルの時刻表示を実装しようとしています。
    なので日本語・英語圏もろもろいろいろなフォーマット形式があるわけで
    lpFormatはNULLじゃないといけないと考えており、
    lpLocaleNameにLOCALE_NAME_USER_DEFAULTを付けることでローカライズの実装は完了しました。


    ですが、その時刻表示の後にファイル名を表示するので、1桁の場合などで、ずれてしまいます。
    やはりその場合は、lpFormatにL"Yyyy'/'MM'/'Dd"などと設定しなければいけないのでしょうか。

    GetLocaleInfoExでは、LOCALE_NAME_USER_DEFAULTでフォーマットを取得できることがわかりました。(H:mm:ssこんな風に)ということは、これからこの文字列を解析していくということでいいんでしょうか。

    wcsstrでHを探し、-1と+1個目の配列にHまたはhがないかどうか、そしてなければ別の配列にコピーする段階で付け加えるというような。


    • 編集済み onein528 2021年3月4日 12:21
    2021年3月3日 15:19

回答

  • もはやDIRを目指いしてコーディングしていること自体問題の範疇にありません。

    > MS-DOS時代には国際化機能もなく、表示書式はほぼハードコードされていました。
    それが今でも、変わらないといいたいということでしょうか。

    今14才で昔のことはよくわかりませんが、COMMAND.COMからCMD.EXEにかけて互換機能を保ちましたが、そのあとに大幅な機能アップデートがありました。MUIという概念が出たのは2004年ごろからで、もともとは国際化にはDLLを使ったり、言語固有の.pakなどを使っていました。NT系のOSになってCOMMAND.COMとはコードが違いますよね。ほかにもNT4.0のソースコードリークを見ましたが、ハードコードなんてしたら1795行なんかで済みませんよねDIR.C(CMD.Cでは1833行)自体で。エラーメッセージはソフトコードされているというわけでPutStdErrorなどの関数により、muiファイルから取り込んでいます。

    要は、コマンドプロンプトのソースコードは全面的に改良されていると仮定され、ハードコードのような運用の難しいソースコードなんかでビルドしているはずもない(現在のWin10でMUIがほとんどのアプリにあるということからも)という、仮定から、コマンドプロンプトのソースコードはソフトコーディングされており、時間表示、エラーメッセージなどの形式は国際化の手順に従って、フォーマットされているものだと考えております。

    質問の趣旨からそれているように思います。このスレッドはいったん下げて、また期末テスト後に再度スレッドを立ち上げたいと思います。質問がわかりにくくて済みませんでした。


    • 回答としてマーク onein528 2021年3月4日 14:50
    • 編集済み onein528 2021年3月4日 15:13
    2021年3月4日 14:50

すべての返信

  • 桁数を揃えたいという発想そのものが日本的で国際化に反するということだと思います。

    LOCALE_NAME_USER_DEFAULTを選択した場合、コントロールパネルの設定に従います。そこで M/d/yyyy (English (United States)のデフォルト値)と設定されていたのなら桁数は揃いません。Explorer上でも桁数は揃っておらず、利用者はそれを受け入れているわけですから問題ないと思います。

    あとは作成するアプリケーションを国際化するか日本的レイアウトにするかの判断となりますので、その点は質問者さんにお任せします。

    2021年3月3日 23:01
  • 「アプリケーションにとっての表記」と「ユーザーインターフェイスにとっての表記」は別ですね。

    たとえばデータの入出力(CSV とか)では固定幅となる yyyy/MM/dd フォーマットを求めつつ、画面の表示にはコントロールパネルの設定に依存した書式を使うといったケースがあります。

    この場合、桁数を揃えて表示するかどうかはユーザー側の判断です。

    結果として日付表記が「February」「March」になるか「Feb」「Mar」になるか「02」「03」になるか「2」「3」になるか「شباط」「آذار」になるかは、ユーザーの選択。

    2021年3月4日 1:13
  • お世話になります。

    いや、なぜ国際化に反するかが疑問です。どこかの国で0が使えないなどだったらわかりますが、その桁ぞろえされていないフォーマットで提供されるのは単に桁ぞろえを必要としないGUIでの表示を目的としているかだと思います。コンソールAPP(cmd.exe)のDIRコマンドは日本でも英語でも0ぞろえしています。

    これは、どのように実装できるかお聞きしています。

    2021年3月4日 6:37
  • 何をおっしゃっているのかわかりません。

    僕の作っているコンソールアプリの仕様では0ぞろえするようにしようと考えています。またコマンドプロンプトのDIRコマンドではどのロケールに対しても数字を使用し、英語圏のなかでもU.S.ロケールではPMやAMを使用するといったしようとなっています(いろんな言語パックを適用した結果)。

    ですが、メモ帳での時刻表示の隠しコマンドといわれるF5キーを押した場合、0の桁ぞろえは行われません。またDIRコマンドの書式設定とも異なります。要は、GUIだから桁ぞろえは必要ないのではないかと考え、CUIでは必要なのではないか。ではその桁ぞろえはswprintfではロケール固有の表示にはならない。その場合win32apiでロケール固有の表示データベースから引っ張るのが普通で、そのAPIはGetDateFormatというわけで、これでは桁ぞろえが実現できないと悩んでいます。そしてそれを実現する方法はないかと聞いているわけで、言語ロケール固有の設定をなぜエンドユーザーが設定するのか意味が解りません。知恵袋より、質がいいと聞いたのですが....

    >結果として日付表記が「February」「March」になるか「Feb」「Mar」になるか「02」「03」になるか「2」「3」になるか「شباط」「آذار」になるかは、ユーザーの選択。

    このような表示は言語パックをen-USに設定したところにGetFormatでLOCALE_USER_DEFAULTでも表示されません。もう少し、質問の意図を理解してもらいたいです。

    2021年3月4日 6:48
  • レガシーかつ特殊ケースな dir をモデルにするのであれば、dir してデバッガで動きを見ればよいと思うのですが。要するに、ユーザーのロケールの format picture string を取ってから、好み以内の固定幅になりそうなものにせっせと変形してから、Get*Format() してます。


    2021年3月4日 10:02
  • レガシーかつ特殊ケースな dir をモデルにするのであれば、dir してデバッガで動きを見ればよいと思うのですが。

    レガシかどうかということはいわなくてもいいんじゃないですか?レガシ・特殊であるかどうかはコンソール開発に関係はないはずです。どの面がレガシだが特殊だが言っているのか全く分かりません。UWPがモダンで先進的・安易に開発できてコンソールなんかいらないーっての考えの持ち主ですか?僕的にはすごくwindowsにとって大切で何十年も続いてるレガシかもしれないけど、windowsを支えている気がします。ただwin32apiを勉強するwindowsの奥深く勉強することにおいてすごくいい教材だと思ってやってるんですよ。

    要するに、ユーザーのロケールの format picture string を取ってから、好み以内の固定幅になりそうなものにせっせと変形してから、Get*Format() してます。

    これはcmd.exeをデバッグトレースした結果の話ですか?それってカンニングですよね?なんでそんな話するんですか?そんな話をせていないです。

    一つ一つ考えてつまずいたら質問して質問したことは一生忘れないようにして、作ってるんですけどそういう回答はやめてほしいです。

    2021年3月4日 11:12
  • なにもかもネガティブに受けとめることに長けていらっしゃいますね。

    コマンド プロンプトはじゅうぶんにレガシーで特殊です。「過去にそうなっていたから」が仕様です。そのようなものの挙動は現物の動きを見るしかありません。

    2021年3月4日 11:27
  • DIRコマンドと同様の動きをするアプリを作るからDIRコマンドのアプリ元であるコマンドプロセッサのデバッグトレースを実施するんですか?ちょっと不明ですね。ネガティブかもしれないですけど、僕としての返答は答えを渡すのではなく、そこにたどりつくためのヒントを欲しいと思ったということです。

    > コマンド プロンプトはじゅうぶんにレガシーで特殊です。「過去にそうなっていたから」が仕様です。

    まあ、考えかた次第でしょう。「「過去にそうなっていたから」が仕様です。ここは不明ですが笑

    > そのようなものの挙動は現物の動きを見るしかありません。

    答えに逃げているようにしか思えないのは僕だけでしょうか。

    コマンドプロセッサはこうしてるよじゃなく、質問をよく見てください

    デバッグでも回答としてはいいんですけど、僕としてはヒントが欲しかったかなーっていう話でした。

    • 編集済み onein528 2021年3月4日 12:01
    2021年3月4日 11:57
  • CMD.EXEのDIRコマンドは、MS-DOSのCOMMAND.COMの互換機能です。そしてMS-DOS時代には国際化機能もなく、表示書式はほぼハードコードされていました。

    DIRコマンドに倣いたいのであれば、COMMAND.COMと同様に、国際化機能に頼らずご自身で各言語毎に独自の書式データを持てばいいと思います。


    • 編集済み 佐祐理 2021年3月4日 13:37
    • 回答としてマーク onein528 2021年3月4日 14:50
    • 回答としてマークされていない onein528 2021年3月4日 14:50
    2021年3月4日 13:36
  • もはやDIRを目指いしてコーディングしていること自体問題の範疇にありません。

    > MS-DOS時代には国際化機能もなく、表示書式はほぼハードコードされていました。
    それが今でも、変わらないといいたいということでしょうか。

    今14才で昔のことはよくわかりませんが、COMMAND.COMからCMD.EXEにかけて互換機能を保ちましたが、そのあとに大幅な機能アップデートがありました。MUIという概念が出たのは2004年ごろからで、もともとは国際化にはDLLを使ったり、言語固有の.pakなどを使っていました。NT系のOSになってCOMMAND.COMとはコードが違いますよね。ほかにもNT4.0のソースコードリークを見ましたが、ハードコードなんてしたら1795行なんかで済みませんよねDIR.C(CMD.Cでは1833行)自体で。エラーメッセージはソフトコードされているというわけでPutStdErrorなどの関数により、muiファイルから取り込んでいます。

    要は、コマンドプロンプトのソースコードは全面的に改良されていると仮定され、ハードコードのような運用の難しいソースコードなんかでビルドしているはずもない(現在のWin10でMUIがほとんどのアプリにあるということからも)という、仮定から、コマンドプロンプトのソースコードはソフトコーディングされており、時間表示、エラーメッセージなどの形式は国際化の手順に従って、フォーマットされているものだと考えております。

    質問の趣旨からそれているように思います。このスレッドはいったん下げて、また期末テスト後に再度スレッドを立ち上げたいと思います。質問がわかりにくくて済みませんでした。


    • 回答としてマーク onein528 2021年3月4日 14:50
    • 編集済み onein528 2021年3月4日 15:13
    2021年3月4日 14:50