2

期間文字列を表示する必要があるアプリを作成しています。いくつかの例:

  • 休憩まで残り1時間2分、
  • ブレイクまで残り2分8秒

今のところ、指定された秒数/ミリ秒/分で文字列を返す C++ 関数があります。

wxString getTimeStr(int value, 
                    ETimeUnit time_unit, // milliseconds or seconds or minutes or hours
                    wxString const & lang) // english or russian

言語、時間単位、および既存の値に応じて、多くの条件で構成されます。現在、アプリを他の言語に移植することを検討していますが、新しい言語ごとに C++ コードを記述するのは少し面倒です。標準関数を使用してその文字列を作成する方法はありますか?

アプリは wxWidgets を使用して C++ で記述されており、これまでのところ Windows でのみ動作します。プラットフォームに依存する関数は使用したくありませんが、知っておくと便利です。

4

4 に答える 4

1

関数を 2 つに分割することをお勧めします。

最初の部分は残り時間を wxTimeSpan として返します。

2 番目の部分は、wxTimeSpan を必要な言語に「翻訳」し、文字列を返します。これは、言語ごとに変更する必要がある唯一の部分です。

説明のために、次のように仮定します。

  • 私たちは時間と分しか気にしません
  • クリンゴンは時間/分を見るのが好き
  • Vulcans は分:時間を見るのが好きです
  • ロシア人は「分」を表す言葉にさまざまな形を持っている

次に、2番目の関数は次のように記述されます

// extract hours and residual minutes into CSV

wxString csv = theTimeSpan.Format("%H,%M);

// extract tokens for csv
wxString hours, mins
...

if( lang == "Klingon" ) {
  return hours + "/" + mins
} else if ( lang == "Vulcan" ) {
  return mins + ":" + hours 
} else if ( lang == "Russian" ) {
  wxString min_name;
  switch( mins.ToLong() ) {
    case 1: min_name = "---"; break;
    ...
  }
 return mins + " " + min_name;
}

残念ながら、たとえば期間内の時間数には本質的なあいまいさがあるため、Format を使用して任意の「時間構造」を取得することはできません。合計時間数 (たとえば、50 時間の期間の場合、これは 50 になります) または期間の 1 時間部分 (この場合、50 時間は 2 日に等しいため、2 になります) のいずれかです。そして2時間。

wxTimeSpan は、このあいまいさを次のように解決します: H の前に指定された D 形式が実際にあった場合、2 として解釈されます。そうでない場合は、50 です。より大きな単位の指定子の場合、残りの部分のみが取得され、それ以外の場合は完全な値が使用されます。

したがって、私のコード サンプルに示すように、csv トークンをいじる必要があります。

于 2012-11-04T13:45:11.430 に答える
1

言語ごとに異なるコードを書かなければ、完璧に行うことはできません。たとえば、あなたの既存のコードでは、「3 時半前の 5 分前」のような時刻を生成することは許可されていないに違いありません。そして、そのような拡張に行かなくても、英語の「half past three」は実際には「half to four」に翻訳されていると考えてください。

したがって、公式時刻を使用するだけでは不十分な場合 (もしそうなら を見てくださいwxLocale::GetInfo(wxLOCALE_TIME_FMT))、少なくともいくつかの言語を特別に処理するコードを書く必要があります。

于 2012-11-04T19:21:49.247 に答える
0

場合によっては、プログラムを自然言語に近づけるよりも、より技術的にする方がよい場合があります。私もそのような状況に陥っています(本当にかっこよく見せるために)。顧客が気にしないことがよくありました。情報は、正確な形式よりもはるかに重要な場合があります。

プログラマーは、トレードオフを選択する必要がある場合があります。これは、プログラミング言語/フレームワークに関係のない一種のメタソリューションです。つまり、解の正しさと期待値の正しさを重み付けする必要があります。

于 2012-12-12T08:52:23.817 に答える
0

ローカリゼーションの問題に対する従来のアプローチは、値のマップを作成label name -> label valueし、値のプレースホルダーを使用することです。

  1. コードでは、ラベル名のみを参照し、プレースホルダーの値を提供します
  2. 別の言語に移植するには、マップを翻訳するだけです

必要な洗練度に応じて、単純なプレースホルダー メカニズム ( snprintf-like) を使用したり、単純なパラメーター (単数形と複数形の区別など) に応じて実行時にミニ言語で値を構築できるようにしたりすることができます。

この例では、次のように単純になります。

using LabelsType = std::map<LabelName, std::string>;
using LangToLabelsType = std::map<Language, LabelsType>;

注: プレーンな文字列ではなく、言語の列挙型をお勧めします。

Linux を使用している場合は をお勧めしますがgettext、Windows で動作するかどうかはわかりません。それでも、それを調べて、それがどのように機能するかを確認することはできます。

于 2012-11-04T14:50:16.013 に答える