C 文字列操作 新しいページはコチラ

提供: yonewiki
移動: 案内, 検索
(文字列大文字小文字変換)
(文字列と日付・日時・時間の変換)
 
1行: 1行:
 +
[[C PlusPlus#Cにもあった技術|C++]]へ戻る
 +
 +
 
※このページではC言語にも存在していたという意味で記事タイトルがC 文字列操作になっていますが、<br />
 
※このページではC言語にも存在していたという意味で記事タイトルがC 文字列操作になっていますが、<br />
 
[[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br />
 
[[C PlusPlus|C++]]でも同様です。[[C PlusPlus|C++]]だけの機能がある場合は明記します。<br />
 
<br />
 
<br />
 
== '''文字列操作''' ==
 
== '''文字列操作''' ==
 +
 
文字列のコピー、連結、比較、一致、区切り文字分割、探索、文字列長取得といった操作を文字列操作と呼びます。上記のような操作はCRT関数として提供されているため、関数の使い方さえ覚えれば簡単に操作できます。
 
文字列のコピー、連結、比較、一致、区切り文字分割、探索、文字列長取得といった操作を文字列操作と呼びます。上記のような操作はCRT関数として提供されているため、関数の使い方さえ覚えれば簡単に操作できます。
更に、文字列の型変換、文字コード変換、大文字小文字変換、半角文字、全角文字変換、ファイルパス操作、ファイル名操作、拡張子取得といった文字列操作の応用もプログラミングでは必要になってきますし、文字列の検索と置換、ファイルへの入出力といった操作までを習得すると概ねの操作ができるようになります。<br />
+
更に、文字列の型変換、文字コード変換、大文字小文字変換、半角文字、全角文字変換、ファイルパス操作、ファイル名操作、拡張子取得といった文字列操作の応用もプログラミングでは必要になってきますし、文字列の検索と置換、ファイルへの入出力といった操作までを習得すると概ねの操作ができるようになります。ちなみに、XMLとか、HTMLとか特定の形式のテキストを取り扱う技術についてはここでは、取り上げません。記述するとしたら別の項目になるかと思います。<br />
  
  
56行: 60行:
  
  
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#include <tchar.h>
 
#include <tchar.h>
 
int main() {
 
int main() {
65行: 69行:
 
}
 
}
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight2>
 
出力結果
 
出力結果
<syntaxhighlight lang="cpp">
+
<syntaxhighlight2 lang="cpp">
 
  0/ 3:cStr0[ 0]=表示:よねウィキの機能<yonewiki>
 
  0/ 3:cStr0[ 0]=表示:よねウィキの機能<yonewiki>
 
StrCount=21
 
StrCount=21
76行: 80行:
 
  2/ 3:cStr0[ 2]=表示:よねウィキの機能2<yonewiki>
 
  2/ 3:cStr0[ 2]=表示:よねウィキの機能2<yonewiki>
 
StrCount=22
 
StrCount=22
</syntaxhighlight>
+
</syntaxhighlight2>
 
_mb系の関数を利用するには、<nowiki>#include <mbstring.h></nowiki>をインクルードする必要があります。<br />
 
_mb系の関数を利用するには、<nowiki>#include <mbstring.h></nowiki>をインクルードする必要があります。<br />
  
85行: 89行:
  
  
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#include <tchar.h>
 
#include <tchar.h>
 
#include <mbstring.h>
 
#include <mbstring.h>
108行: 112行:
 
delete[] ppcStr1;
 
delete[] ppcStr1;
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight2>
 
という具合にして、const char→char→_mabslenで文字列長探索が出来ます。出力結果は以下のとおりです。<br />
 
という具合にして、const char→char→_mabslenで文字列長探索が出来ます。出力結果は以下のとおりです。<br />
<syntaxhighlight lang="cpp">
+
<syntaxhighlight2 lang="cpp">
 
const マルチバイト文字→マルチバイト文字コピー→_mbslen関数2バイト文字認識文字列長探索
 
const マルチバイト文字→マルチバイト文字コピー→_mbslen関数2バイト文字認識文字列長探索
 
  0/ 4:cStr1[ 0]=
 
  0/ 4:cStr1[ 0]=
124行: 128行:
 
StrCount=22
 
StrCount=22
  
</syntaxhighlight>
+
</syntaxhighlight2>
 
_mbstrlen関数を使う場合はコピー操作が必要にならず、const宣言している文字列変数を使っての文字列長探索ができます。<br />
 
_mbstrlen関数を使う場合はコピー操作が必要にならず、const宣言している文字列変数を使っての文字列長探索ができます。<br />
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#include <tchar.h>
 
#include <tchar.h>
 
#include <mbstring.h>
 
#include <mbstring.h>
137行: 141行:
 
}
 
}
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight2>
 
出力結果は以下のとおりです。<br />
 
出力結果は以下のとおりです。<br />
<syntaxhighlight lang="cpp">
+
<syntaxhighlight2 lang="cpp">
 
const マルチバイト文字→_mbstrlen関数2バイト文字認識文字列長探索
 
const マルチバイト文字→_mbstrlen関数2バイト文字認識文字列長探索
 
  0/ 4:cStr1[ 0]=
 
  0/ 4:cStr1[ 0]=
153行: 157行:
 
StrCount=22
 
StrCount=22
  
</syntaxhighlight>
+
</syntaxhighlight2>
 
といった具合にいろいろな関数があるので、一つづつ掘り下げて理解しておくのも、必要です。こういう違いがあるということを把握していれば、臨機応変に対応しやすくなるかもです。自分は分かったつもりにならずに、常に謙虚に確かめてみる姿勢ってのは、必要なんじゃないかと思います。そして常に、自分が実施するであろうパターンを網羅して確かめる。だから、あえて文字列の配列の場合にどうやればいいのかを探ります。
 
といった具合にいろいろな関数があるので、一つづつ掘り下げて理解しておくのも、必要です。こういう違いがあるということを把握していれば、臨機応変に対応しやすくなるかもです。自分は分かったつもりにならずに、常に謙虚に確かめてみる姿勢ってのは、必要なんじゃないかと思います。そして常に、自分が実施するであろうパターンを網羅して確かめる。だから、あえて文字列の配列の場合にどうやればいいのかを探ります。
  
183行: 187行:
  
 
で、結局は_tcsncpy_sを使いなさいってことになります。Unicode設定ならワイド文字版で、文字列長に厳しい設定が必要なwcsncpy_sだね。第二引数は配列の大きさ+終端\0のための要素1つ分。バイト数ではないです。動的に生成した変数の場合は配列の大きさが取得できないので、wcslen(_tcslen)のような文字列長取得関数を使って、戻ってきた値に\0の要素のために1を加算した値が良いです。<br />
 
で、結局は_tcsncpy_sを使いなさいってことになります。Unicode設定ならワイド文字版で、文字列長に厳しい設定が必要なwcsncpy_sだね。第二引数は配列の大きさ+終端\0のための要素1つ分。バイト数ではないです。動的に生成した変数の場合は配列の大きさが取得できないので、wcslen(_tcslen)のような文字列長取得関数を使って、戻ってきた値に\0の要素のために1を加算した値が良いです。<br />
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#include <iostream>
 
#include <iostream>
 
//#include<locale.h> tchar.hがインクルードされていれば、いらない。
 
//#include<locale.h> tchar.hがインクルードされていれば、いらない。
245行: 249行:
 
return 0;
 
return 0;
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight2>
 
という感じでしたね。無理やり_mbscpy関数を使ってみるとこんな感じですね。unsigned char型は宣言と同時にnew演算子の定義は出来ないようです。const型のcharからはキャストできないから、結局は一度、strcpy_sを使って、char型の文字列に置き換えないといけないです。マルチバイト型の2バイト文字認識操作関数って結局は、char型と同じなので、文字数を数えるときはstrlenで数えないといけない。char型と_mbsxxx関数を行ったり来たりするだけです。<br />
 
という感じでしたね。無理やり_mbscpy関数を使ってみるとこんな感じですね。unsigned char型は宣言と同時にnew演算子の定義は出来ないようです。const型のcharからはキャストできないから、結局は一度、strcpy_sを使って、char型の文字列に置き換えないといけないです。マルチバイト型の2バイト文字認識操作関数って結局は、char型と同じなので、文字数を数えるときはstrlenで数えないといけない。char型と_mbsxxx関数を行ったり来たりするだけです。<br />
 
出力結果は以下のとおり<br />
 
出力結果は以下のとおり<br />
<syntaxhighlight lang="cpp">
+
<syntaxhighlight2 lang="cpp">
 
_tcslen(cStr0[i])=21
 
_tcslen(cStr0[i])=21
 
ppcStr0=表示:よねウィキの機能<yonewiki>,
 
ppcStr0=表示:よねウィキの機能<yonewiki>,
292行: 296行:
 
ppucStr2=表示:よねウィキの機能2<yonewiki>,
 
ppucStr2=表示:よねウィキの機能2<yonewiki>,
 
  cStr1=表示:よねウィキの機能2<yonewiki>,
 
  cStr1=表示:よねウィキの機能2<yonewiki>,
</syntaxhighlight>
+
</syntaxhighlight2>
 
上記に加えて、コピーする文字数を引数とするcpyの前にnが付く関数_tcsncpy_s/wcsncpy_s/strncpy_s/_mbsncpy_sにする場合は<br />
 
上記に加えて、コピーする文字数を引数とするcpyの前にnが付く関数_tcsncpy_s/wcsncpy_s/strncpy_s/_mbsncpy_sにする場合は<br />
<syntaxhighlight lang="cpp">
+
<syntaxhighlight2 lang="cpp">
 
 
 
 
310行: 314行:
 
 
 
 
</syntaxhighlight>
+
</syntaxhighlight2>
 
と、4つの引数をとるように記述します。第4引数が出力する最大文字の配列数です。出力する文字数と考えることもできます。マルチバイト文字の場合には出力する文字数を指定できるのは効果的で、先頭から何バイト目で区切れば日本語文字が分断されないかの判断もしてくれながらの出力となります。この出力する文字数をあえてバイト単位で指定する_mbsnbcpy_sもあります。ただし、コピー先の文字列の配列はstrlenのようなバイト数分で準備する必要があることに注意が必要です。出力文字数を指定する場合は文字列全体の長さではなく、指定した文字数で必要な文字列バイト数を算出しておいて、メモリを確保するように処理を記述するのが良いかもしれません。ここでは強制キャストを使いましたが、もともとの文字列がunsigned charとして定義されているものをコピーするときに_mbs系の文字列コピーを利用するというのが自然な使い方になります。<br />
 
と、4つの引数をとるように記述します。第4引数が出力する最大文字の配列数です。出力する文字数と考えることもできます。マルチバイト文字の場合には出力する文字数を指定できるのは効果的で、先頭から何バイト目で区切れば日本語文字が分断されないかの判断もしてくれながらの出力となります。この出力する文字数をあえてバイト単位で指定する_mbsnbcpy_sもあります。ただし、コピー先の文字列の配列はstrlenのようなバイト数分で準備する必要があることに注意が必要です。出力文字数を指定する場合は文字列全体の長さではなく、指定した文字数で必要な文字列バイト数を算出しておいて、メモリを確保するように処理を記述するのが良いかもしれません。ここでは強制キャストを使いましたが、もともとの文字列がunsigned charとして定義されているものをコピーするときに_mbs系の文字列コピーを利用するというのが自然な使い方になります。<br />
  
332行: 336行:
 
例によって_sのついた連結先文字列の配列サイズを明記する関数に_lのついた個別ロケール設定関数。そして連結させたい文字列の文字数を記述するncatに文字数をバイト数で指定するnbcat。あとはワイド文字のwcsで始まる関数。マルチバイトのstrで始まる関数。マルチバイト2バイト文字対応の_mbsで始まる関数。全部で22種類。引数は文字列コピーと同じですが、コピー先の変数が既に文字列が格納されてる\0で終わる文字列になっていて、処理をした結果、第一引数の文字列先頭アドレスの中身が文字列連結した結果になるという点が異なると覚えれば、連結とコピーは似ていると覚えればよいかと思います。先の文字列コピーのプログラムのコピーcpy系関数の後ろに連結cat系関数を追加して、文字列を2回繰り返されるようにしたサンプルです。所謂(いわゆる)、手抜きです。ただし、連結関数では連結後の文字列の配列大きさを要求されるため、あらかじめ動的に確保する領域が2倍になっていることに注意して下さい。<br />
 
例によって_sのついた連結先文字列の配列サイズを明記する関数に_lのついた個別ロケール設定関数。そして連結させたい文字列の文字数を記述するncatに文字数をバイト数で指定するnbcat。あとはワイド文字のwcsで始まる関数。マルチバイトのstrで始まる関数。マルチバイト2バイト文字対応の_mbsで始まる関数。全部で22種類。引数は文字列コピーと同じですが、コピー先の変数が既に文字列が格納されてる\0で終わる文字列になっていて、処理をした結果、第一引数の文字列先頭アドレスの中身が文字列連結した結果になるという点が異なると覚えれば、連結とコピーは似ていると覚えればよいかと思います。先の文字列コピーのプログラムのコピーcpy系関数の後ろに連結cat系関数を追加して、文字列を2回繰り返されるようにしたサンプルです。所謂(いわゆる)、手抜きです。ただし、連結関数では連結後の文字列の配列大きさを要求されるため、あらかじめ動的に確保する領域が2倍になっていることに注意して下さい。<br />
  
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#include <iostream>
 
#include <iostream>
 
//#include<locale.h> tchar.hがインクルードされていればいらない。
 
//#include<locale.h> tchar.hがインクルードされていればいらない。
397行: 401行:
 
return 0;
 
return 0;
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight2>
  
 
出力結果<br />
 
出力結果<br />
<syntaxhighlight lang="cpp">
+
<syntaxhighlight2 lang="cpp">
 
_tcslen(cStr0[i])=21
 
_tcslen(cStr0[i])=21
 
ppcStr0=表示:よねウィキの機能<yonewiki>表示:よねウィキの機能<yonewiki>,
 
ppcStr0=表示:よねウィキの機能<yonewiki>表示:よねウィキの機能<yonewiki>,
444行: 448行:
 
ppucStr2=表示:よねウィキの機能2<yonewiki>表示:よねウィキの機能2<yonewiki>表示:よねウィキの機能2<yonewiki>表示:よねウィキの機能2<yonewiki>,
 
ppucStr2=表示:よねウィキの機能2<yonewiki>表示:よねウィキの機能2<yonewiki>表示:よねウィキの機能2<yonewiki>表示:よねウィキの機能2<yonewiki>,
 
  cStr1=表示:よねウィキの機能2<yonewiki>,
 
  cStr1=表示:よねウィキの機能2<yonewiki>,
</syntaxhighlight>
+
</syntaxhighlight2>
  
 
=='''文字列比較'''==
 
=='''文字列比較'''==
477行: 481行:
  
  
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#include <iostream>
 
#include <iostream>
 
//#include<locale.h> wchar.hがインクルードされていれば、いらない。
 
//#include<locale.h> wchar.hがインクルードされていれば、いらない。
565行: 569行:
 
return 0;
 
return 0;
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight2>
  
 
出力結果
 
出力結果
<syntaxhighlight lang="cpp">
+
<syntaxhighlight2 lang="cpp">
 
_tcslen(cStr0[i])=22
 
_tcslen(cStr0[i])=22
 
ppcStr0=表示:よねウィキの機能0<yonewiki>表示:よねウィキの機能0<yonewiki>,
 
ppcStr0=表示:よねウィキの機能0<yonewiki>表示:よねウィキの機能0<yonewiki>,
663行: 667行:
 
i=3, k=3, iCmpResult=0,
 
i=3, k=3, iCmpResult=0,
  
</syntaxhighlight>
+
</syntaxhighlight2>
 
と、こんな感じです。結果を見るとわかるのですが、1,-1,0で結果が表現され、先頭から比較して、一番最初に異なる文字同志を比較したときの結果、文字コードの値が大きかったか小さかったかで、1と-1とに結果が分かれます。これを使って昇順に並べたりすることも出来ます。もちろん0が返ってきたときは、完全一致です。等しかったということになります。<br />
 
と、こんな感じです。結果を見るとわかるのですが、1,-1,0で結果が表現され、先頭から比較して、一番最初に異なる文字同志を比較したときの結果、文字コードの値が大きかったか小さかったかで、1と-1とに結果が分かれます。これを使って昇順に並べたりすることも出来ます。もちろん0が返ってきたときは、完全一致です。等しかったということになります。<br />
  
699行: 703行:
 
<br />
 
<br />
 
という具合の動作であります。collの特徴的なのは辞書順と呼んでいる比較の概念だと思います。ASCIIコードでは大文字と小文字とでは、小文字の方が大きい文字コード番号が付与されていますが、wcs**coll系の比較をする関数では、小文字の方が値が小さいものとして判定してくれます。漢字の範囲になるとロケールで指定したcp932の文字コード順で比較してくれます。阿という文字と哀という文字はUnicode(UTF16)では阿-0x963F 哀-0x54C0 表-0x8868であり、Shift_JISのcp932では阿-0x88A2 哀-0x88A3 表-0x955Cと定義されていますから、阿<nowiki><</nowiki>哀<nowiki><</nowiki>表 のように比較をしてくれます。coll系の関数を使わない場合は 哀<nowiki><</nowiki>表<nowiki><</nowiki>阿のように比較されます。この阿や哀や表という名前のファイル名のテキストをWindowsのエクスプローラで昇順表示すると、この順番になることも確認できます。Shift_JISコード順でソートされてるんだなぁと確認が出来ると思います。Cp932の半角記号あたりの辞書順ってのは、どうなってるんでしょうね。これもまた今度しらべてみたいと思います。ファイル名に使えない文字あたりはどんな順番なんだろうか?
 
という具合の動作であります。collの特徴的なのは辞書順と呼んでいる比較の概念だと思います。ASCIIコードでは大文字と小文字とでは、小文字の方が大きい文字コード番号が付与されていますが、wcs**coll系の比較をする関数では、小文字の方が値が小さいものとして判定してくれます。漢字の範囲になるとロケールで指定したcp932の文字コード順で比較してくれます。阿という文字と哀という文字はUnicode(UTF16)では阿-0x963F 哀-0x54C0 表-0x8868であり、Shift_JISのcp932では阿-0x88A2 哀-0x88A3 表-0x955Cと定義されていますから、阿<nowiki><</nowiki>哀<nowiki><</nowiki>表 のように比較をしてくれます。coll系の関数を使わない場合は 哀<nowiki><</nowiki>表<nowiki><</nowiki>阿のように比較されます。この阿や哀や表という名前のファイル名のテキストをWindowsのエクスプローラで昇順表示すると、この順番になることも確認できます。Shift_JISコード順でソートされてるんだなぁと確認が出来ると思います。Cp932の半角記号あたりの辞書順ってのは、どうなってるんでしょうね。これもまた今度しらべてみたいと思います。ファイル名に使えない文字あたりはどんな順番なんだろうか?
 +
 +
 +
coll系の比較の中身を見るための関数としては、strxfrm関数がある。これがロケール設定にしたがった照合順序文字列を生成してくれる。これは文字列ではあるが、書き出すことは出来ない照合のための文字コードだと考えればよい。中身をみたければstrxfrmで変換してバイトコードを確認することができるが、ロケール設定によってはなぜこんな変換になるんだ?というような不思議な変換がなされる。とくにen-US.utf8とかになると発音記号のアクセントや、特殊記号を別の辞書順と管理するため、1つの文字列が3つに分割され、1文字でもトークンとなるバイトコードが2つと文字列、アクセント、大文字小文字で3つのバイトコードで5バイトになる。更に特殊記号がひとつでも現れる文字列なら4つに分割され、特殊記号の使われる位置情報まで生成される。このような照合順序規則がロケールごとに存在する。coll系の比較関数はとんでもなく複雑な処理を行う比較関数なのだ。それゆえ通常のcmp系の関数と比べても、処理時間がかかる。localeごとの照合順序について理解しているならば、strxfrmで返還後のコードを使って、strcoll関数のような比較処理を高速化することも可能となる。ロケールによる処理も含めた関数の利用が必要になるケースもあるかもしれないが、ロケールの特徴を理解して、使うのも大事だし、使いどころが肝心となる。
  
 
  '''★豆知識'''
 
  '''★豆知識'''
 
  '''Unicodeの符号化方式UTF-16とは…'''
 
  '''Unicodeの符号化方式UTF-16とは…'''
 
  日本語の範囲ではUTF16は2バイト文字と考えて良いですが、Unicode全体では0x10FFFFまで利用することになっていますので、0x10000以上の値を持つ文字コードは4バイト文字になります。この0x10000以上の値になる場合は、ビット列で表現すると110110????xxxxxx 110111xxxxxxxxxxのような形式になり????の部分のには上位ビットと下位ビットを16ビットずつに分けた時に0xUUUUDDDDと表記するならば、0xUUUUは0x0001~0x0010の値となり得て、そのUUUU-1の値が????に入ります。xの部分には下位DDDDのビット列そのものが
 
  日本語の範囲ではUTF16は2バイト文字と考えて良いですが、Unicode全体では0x10FFFFまで利用することになっていますので、0x10000以上の値を持つ文字コードは4バイト文字になります。この0x10000以上の値になる場合は、ビット列で表現すると110110????xxxxxx 110111xxxxxxxxxxのような形式になり????の部分のには上位ビットと下位ビットを16ビットずつに分けた時に0xUUUUDDDDと表記するならば、0xUUUUは0x0001~0x0010の値となり得て、そのUUUU-1の値が????に入ります。xの部分には下位DDDDのビット列そのものが
  入ったような値になります。そういう意味ではUnicodeのUTF-16という符号化方式では16bit(2byte)だったり32bit(4byte)のコードになります。
+
  入ったような値になります。そういう意味ではUnicodeのUTF-16という符号化方式では16bit(2byte)だったり32bit(4byte)のコードになります。※更に異体字セレクタというコードが付与されるケースがあり、付与される場合はUnicode文字番号つづけて、E0100、E0101、E0102…といった値が付与されます。UTF-16の2バイトコードであれば、さらにDB40 DD00という4バイトが付与され一文字が6文字になります。似ている文字をこのセレクタ番号によって切り替えるという仕組みです。したがって2バイト文字は6バイトに、4バイト文字は8バイトになります。テキストエディタおよびフォントも対応していないと使えないような特殊な文字ですが、存在している以上、対応しなければならない可能性はあります。現状はあまり対応されていないようですが、メモ帳でさえも異体字セレクタに対応しているというのが現実です。
 
   
 
   
 
  '''Unicodeの符号化方式UTF-8とは…'''
 
  '''Unicodeの符号化方式UTF-8とは…'''
710行: 717行:
 
  x0,x1,x2,x3, x4,x5,x6,x7, x8,x9,xA,xB, xC,xD,xE,xFと表現すると、
 
  x0,x1,x2,x3, x4,x5,x6,x7, x8,x9,xA,xB, xC,xD,xE,xFと表現すると、
 
  (1110),(x0,x1,x2,x3),(10,x4,x5),(x6,x7, x8,x9),(10,xA,xB),(xC,xD,xE,xF)となります。
 
  (1110),(x0,x1,x2,x3),(10,x4,x5),(x6,x7, x8,x9),(10,xA,xB),(xC,xD,xE,xF)となります。
  文字の先頭に3バイトなら3つの1が付き、1バイト目を構成し、 次のバイト以降はバイト先頭に全て10をつける。おかげさまで、1バイト目の下位4bitと、3バイト目の下位4bitの16進数だけはそのままだけど、他のbitは16進表記が、変化します。読み起こすのは大変ですね。文字列の最初を見つけたら、そこから文字列に起こしていけば良いですが、新しい変換表を考えないと直感的にはUnicode文字のコード表には表現できないですね。
+
  文字の先頭に3バイトなら3つの1が付き、1バイト目を構成し、 次のバイト以降はバイト先頭に全て10をつける。おかげさまで、1バイト目の下位4bitと、3バイト目の下位4bitの16進数だけはそのままだけど、他のbitは16進表記が、変化します。読み起こすのは大変ですね。文字列の最初を見つけたら、そこから文字列に起こしていけば良いですが、新しい変換表を考えないと直感的にはUnicode文字のコード表には表現できないですね。UTF-8の場合、異体字セレクタはF3 A0 84 80という4バイトが不可されて、3バイト文字は7バイト 4バイト文字は8バイトになります。セレクタがひとつ変化する都度最後の2バイトが80→81→82と変化していきます。
  
 
=='''文字列区切り文字分割'''==
 
=='''文字列区切り文字分割'''==
733行: 740行:
 
比較関数よりは少ないけど、やっぱりマルチバイト版、マルチバイト2バイト文字対応版、ワイド文字版、それに_sをつけた文字列長を指定するセキュア版と個別ロケール指定をする_lのロケール版があります。_l版についてはココまで使い方を触れてこなかったのですが、
 
比較関数よりは少ないけど、やっぱりマルチバイト版、マルチバイト2バイト文字対応版、ワイド文字版、それに_sをつけた文字列長を指定するセキュア版と個別ロケール指定をする_lのロケール版があります。_l版についてはココまで使い方を触れてこなかったのですが、
  
<syntaxhighlight lang="cpp">
+
<syntaxhighlight2 lang="cpp">
 
_locale_t locale;
 
_locale_t locale;
 
locale = _tsetlocale(LC_ALL, _T("Japanese"));
 
locale = _tsetlocale(LC_ALL, _T("Japanese"));
</syntaxhighlight>
+
</syntaxhighlight2>
 
として、localeという変数に_locale_t型の値を_tsetlocaleの返り値として格納しておいたものを関数の最後の引数にします。<br />
 
として、localeという変数に_locale_t型の値を_tsetlocaleの返り値として格納しておいたものを関数の最後の引数にします。<br />
 
コマンドプロンプトで動作確認してるだけの段階でlocale変数を利用しても、文字化けしか起こせないと思うので、テキスト出力とかを覚えてから試してみるといいかもしれません。<br />
 
コマンドプロンプトで動作確認してるだけの段階でlocale変数を利用しても、文字化けしか起こせないと思うので、テキスト出力とかを覚えてから試してみるといいかもしれません。<br />
761行: 768行:
  
 
区切り文字として複数の文字を指定できますが、それぞれ1文字が独立した区切り文字ですので、// のような2文字以上で構成される区切り文字はこの関数だけでは対応できません。新しい手法が必要になります。
 
区切り文字として複数の文字を指定できますが、それぞれ1文字が独立した区切り文字ですので、// のような2文字以上で構成される区切り文字はこの関数だけでは対応できません。新しい手法が必要になります。
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#include <iostream>
 
#include <iostream>
 
#include <tchar.h>
 
#include <tchar.h>
921行: 928行:
 
   return 0;
 
   return 0;
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight2>
 
という具合にtcstok_s関数を使えば、並列してトークン処理が進められるようです。第3引数の参照というC++独自の型を使って、44行目 78行目での最初の呼び出し(エスタブリッシュとも表現します。エスタブリッシュショットというと撮影なんかでワンシーンの手前に一枚絵の風景絵を置くことで、時間帯を表現したりする手法を指します。夜景がシーンの前に入れば室内に映像が切り替わっても夜の出来事であるように示唆するものです。)をして、111、114、131行目のように連続して現れるであろう区切り文字を検索します。111,114行目では、もう区切り文字が現れることがないことがわかっているのですが、2個目のトークンを取得するために実行したり、ループ処理を終わらせるために再度、実行したりという手法で使っています。アイデア次第でなんでもありです。最初にカンマ区切りでトークンを取得するのですが、その間で、さらにカンマ区切りトークンの中に必ず一度現れる、スラッシュによるトークン処理を入れこんでいます。区切り文字が違うだけで全く同じ処理です。こういうプログラム記法は普通はしません。通常は、関数のようなサブプログラムにして、関数を呼び出すことで同じ処理になるように記述します。C++の場合は関数でなくても、クラスのメンバ関数にしても良い訳です。結局同じことですが…。<br />
 
という具合にtcstok_s関数を使えば、並列してトークン処理が進められるようです。第3引数の参照というC++独自の型を使って、44行目 78行目での最初の呼び出し(エスタブリッシュとも表現します。エスタブリッシュショットというと撮影なんかでワンシーンの手前に一枚絵の風景絵を置くことで、時間帯を表現したりする手法を指します。夜景がシーンの前に入れば室内に映像が切り替わっても夜の出来事であるように示唆するものです。)をして、111、114、131行目のように連続して現れるであろう区切り文字を検索します。111,114行目では、もう区切り文字が現れることがないことがわかっているのですが、2個目のトークンを取得するために実行したり、ループ処理を終わらせるために再度、実行したりという手法で使っています。アイデア次第でなんでもありです。最初にカンマ区切りでトークンを取得するのですが、その間で、さらにカンマ区切りトークンの中に必ず一度現れる、スラッシュによるトークン処理を入れこんでいます。区切り文字が違うだけで全く同じ処理です。こういうプログラム記法は普通はしません。通常は、関数のようなサブプログラムにして、関数を呼び出すことで同じ処理になるように記述します。C++の場合は関数でなくても、クラスのメンバ関数にしても良い訳です。結局同じことですが…。<br />
  
1,123行: 1,130行:
  
 
というわけで、これくらいできて当然という変換をやってみます。
 
というわけで、これくらいできて当然という変換をやってみます。
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#include <string>
 
#include <string>
 
#include <stdlib.h>
 
#include <stdlib.h>
1,284行: 1,291行:
 
   }
 
   }
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight2>
 
上から<br />
 
上から<br />
 
char(LPSTR)→TCHAR(LPTSTR)<br />
 
char(LPSTR)→TCHAR(LPTSTR)<br />
1,321行: 1,328行:
 
更に変換を続けたのものが以下になります。
 
更に変換を続けたのものが以下になります。
  
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
_tsetlocale(LC_ALL, _T("Japanese"));
 
_tsetlocale(LC_ALL, _T("Japanese"));
 
_locale_t locale;
 
_locale_t locale;
1,593行: 1,600行:
 
delete[] sizeReturnValue;
 
delete[] sizeReturnValue;
 
delete[] pnStrArrayElement;
 
delete[] pnStrArrayElement;
</syntaxhighlight>
+
</syntaxhighlight2>
  
 
_bstr_t型からの変換に関するサンプルを追加しました。
 
_bstr_t型からの変換に関するサンプルを追加しました。
1,614行: 1,621行:
 
では引き続き、変換のサンプルを…
 
では引き続き、変換のサンプルを…
  
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 
//・CComBSTR→char
 
//・CComBSTR→char
1,809行: 1,816行:
 
//動的確保変数の解放
 
//動的確保変数の解放
 
delete[] psysstring_StrCnv;
 
delete[] psysstring_StrCnv;
</syntaxhighlight>
+
</syntaxhighlight2>
  
 
引き続き、変換のサンプルを記述していきます。残るはCComBSTR、CStringA、CStringW、string、System::String基準の変換ですね。
 
引き続き、変換のサンプルを記述していきます。残るはCComBSTR、CStringA、CStringW、string、System::String基準の変換ですね。
  
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 
//・CStringA→char
 
//・CStringA→char
2,004行: 2,011行:
 
//動的確保変数の解放
 
//動的確保変数の解放
 
delete[] psysstring_StrCnv;
 
delete[] psysstring_StrCnv;
</syntaxhighlight>
+
</syntaxhighlight2>
  
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 
//・CStringW→char
 
//・CStringW→char
2,199行: 2,206行:
 
//動的確保変数の解放
 
//動的確保変数の解放
 
delete[] psysstring_StrCnv;
 
delete[] psysstring_StrCnv;
</syntaxhighlight>
+
</syntaxhighlight2>
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 
//・string→char
 
//・string→char
2,389行: 2,396行:
 
//動的確保変数の解放
 
//動的確保変数の解放
 
delete[] psysstring_StrCnv;
 
delete[] psysstring_StrCnv;
</syntaxhighlight>
+
</syntaxhighlight2>
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 
//★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 
//・SystemString→char
 
//・SystemString→char
2,593行: 2,600行:
 
//動的確保変数の解放
 
//動的確保変数の解放
 
delete[] pstring_StrCnv;
 
delete[] pstring_StrCnv;
</syntaxhighlight>
+
</syntaxhighlight2>
  
 
と、こんな感じです。もっと効率の良い変換があったらごめんなさい。動的に必要最小限のメモリを確保させながらの処理だとこんな感じになるよっていう例になっていると思います。プログラムによっては、配列の大きさを固定したっていいわけです。その方がコーディングや変数管理が楽になる場合もあります。この章に関しては以上です。既に準備されている型の変換なんてのは、変換するための関数が準備されているので、比較的簡単な技術になります。全角半角変換や文字コード変換処理を実際に組む方が難しいかもしれません。それもおいおい記述したいと思います。
 
と、こんな感じです。もっと効率の良い変換があったらごめんなさい。動的に必要最小限のメモリを確保させながらの処理だとこんな感じになるよっていう例になっていると思います。プログラムによっては、配列の大きさを固定したっていいわけです。その方がコーディングや変数管理が楽になる場合もあります。この章に関しては以上です。既に準備されている型の変換なんてのは、変換するための関数が準備されているので、比較的簡単な技術になります。全角半角変換や文字コード変換処理を実際に組む方が難しいかもしれません。それもおいおい記述したいと思います。
2,641行: 2,648行:
  
 
以下、テスト時のエラーログです。ひょっとしたら自分だけなのかもしれませんが、既知のバグみたいな?いやテストだけで出るエラーみたいな感じなので気にしないことにします。え?ホントにそれでいいのか?調べるのも面倒だし、放置。
 
以下、テスト時のエラーログです。ひょっとしたら自分だけなのかもしれませんが、既知のバグみたいな?いやテストだけで出るエラーみたいな感じなので気にしないことにします。え?ホントにそれでいいのか?調べるのも面倒だし、放置。
<syntaxhighlight lang="text">
+
<syntaxhighlight2 lang="text">
 
KNOWN ISSUES
 
KNOWN ISSUES
 
#11217 <http://bugs.icu-project.org/trac/ticket/11217>
 
#11217 <http://bugs.icu-project.org/trac/ticket/11217>
2,663行: 2,670行:
 
[/tsconv/nccbtst/TestSubWithValueCallBack]
 
[/tsconv/nccbtst/TestSubWithValueCallBack]
 
[/tsconv/ncnvtst/TestResetBehaviour]
 
[/tsconv/ncnvtst/TestResetBehaviour]
</syntaxhighlight>
+
</syntaxhighlight2>
 
表:icucheck.bat Win32 Release のテスト結果でのエラー
 
表:icucheck.bat Win32 Release のテスト結果でのエラー
  
2,684行: 2,691行:
  
 
プロジェクトの設定は以上です。以下が実際の変換サンプルになります。これまでのサンプルもそうですが、実際にはサポートクラスを作って、毎回新しく変数定義しているものは、クラスを呼ぶたびにまとめて生成されるようなセットを作るべきです。変換サポートクラスの作り方については、クラスに関する記述を掘り下げるセクションで触れたいと思いますが、ここでは例のごとく直線的なプログラムになっています。
 
プロジェクトの設定は以上です。以下が実際の変換サンプルになります。これまでのサンプルもそうですが、実際にはサポートクラスを作って、毎回新しく変数定義しているものは、クラスを呼ぶたびにまとめて生成されるようなセットを作るべきです。変換サポートクラスの作り方については、クラスに関する記述を掘り下げるセクションで触れたいと思いますが、ここでは例のごとく直線的なプログラムになっています。
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#include "stdafx.h"
 
#include "stdafx.h"
 
#include <unicode/ucnv.h>
 
#include <unicode/ucnv.h>
2,804行: 2,811行:
 
   return 0;
 
   return 0;
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight2>
 
という具合に変換すると結果として
 
という具合に変換すると結果として
<syntaxhighlight lang="text">
+
<syntaxhighlight2 lang="text">
 
JIS文字列
 
JIS文字列
 
004a:0049:0053:6587:5b57:5217:
 
004a:0049:0053:6587:5b57:5217:
2,814行: 2,821行:
 
4a:49:53:95:b6:8e:9a:97:f1:
 
4a:49:53:95:b6:8e:9a:97:f1:
  
</syntaxhighlight>
+
</syntaxhighlight2>
 
のようなものが得られます。
 
のようなものが得られます。
  
2,833行: 2,840行:
  
 
ibm-943_P130-1999 7 ★ibm-943_P130-1999 ibm-943 '''Shift_JIS''' cp943 943 ibm-943_VASCII_VSUB_VPUA x-IBM943
 
ibm-943_P130-1999 7 ★ibm-943_P130-1999 ibm-943 '''Shift_JIS''' cp943 943 ibm-943_VASCII_VSUB_VPUA x-IBM943
<syntaxhighlight lang="text" line start="1">
+
<syntaxhighlight2 lang="text" line start="1">
 
UTF-8 14 ★UTF-8 ibm-1208 ibm-1209 ibm-5304 ibm-5305 ibm-13496 ibm-13497 ibm-17592 ibm-17593 windows-65001 cp1208 x-UTF_8J unicode-1-1-utf unicode-2-0-utf-8
 
UTF-8 14 ★UTF-8 ibm-1208 ibm-1209 ibm-5304 ibm-5305 ibm-13496 ibm-13497 ibm-17592 ibm-17593 windows-65001 cp1208 x-UTF_8J unicode-1-1-utf unicode-2-0-utf-8
 
UTF-16 7 ★UTF-16 ISO-10646-UCS-2 ibm-1204 ibm-1205 unicode csUnicode ucs-2
 
UTF-16 7 ★UTF-16 ISO-10646-UCS-2 ibm-1204 ibm-1205 unicode csUnicode ucs-2
3,066行: 3,073行:
 
ibm-16804_X110-1999,swaplfnl 2 ★ibm-16804_X110-1999,swaplfnl ibm-16804-s390
 
ibm-16804_X110-1999,swaplfnl 2 ★ibm-16804_X110-1999,swaplfnl ibm-16804-s390
 
ebcdic-xml-us 1 ★ebcdic-xml-us
 
ebcdic-xml-us 1 ★ebcdic-xml-us
</syntaxhighlight>
+
</syntaxhighlight2>
  
  
3,077行: 3,084行:
  
 
とりあえずは、ICUの方の変換を記載しておきます。大文字、小文字変換の他に日本語ひらがなとカタカナとローマ字の相互変換についてもサンプルを示しました。ICUを使えば、簡単に変換してくれます。完璧ではなさそうなので、一括変換する場合は注意して使う必要はありそうです。
 
とりあえずは、ICUの方の変換を記載しておきます。大文字、小文字変換の他に日本語ひらがなとカタカナとローマ字の相互変換についてもサンプルを示しました。ICUを使えば、簡単に変換してくれます。完璧ではなさそうなので、一括変換する場合は注意して使う必要はありそうです。
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#pragma once
 
#pragma once
  
3,268行: 3,275行:
 
}
 
}
  
</syntaxhighlight>
+
</syntaxhighlight2>
  
 
出力結果
 
出力結果
<syntaxhighlight lang="text">
+
<syntaxhighlight2 lang="text">
 
★小文字 → 大文字変換
 
★小文字 → 大文字変換
 
ABCDEFGHIJKLMLOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ:
 
ABCDEFGHIJKLMLOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ:
3,310行: 3,317行:
 
アイウエオギャギュギョチャチュチェピャピュピョヴザゼィシケメアイウエオギャギュギョアイウエオアブクデ@;:*+/:
 
アイウエオギャギュギョチャチュチェピャピュピョヴザゼィシケメアイウエオギャギュギョアイウエオアブクデ@;:*+/:
  
</syntaxhighlight>
+
</syntaxhighlight2>
 
ひらがな→ローマ字変換が残念な結果になっているようでして、ひらがなと一緒に記述していたカタカナのギャギュギョをg~ャg~ュg~ョと変換してしまったようです。こんな変換をプログラムで提供することは稀れだと思いますが、ICUのバグのようですので、注意して使いましょう。ひらがなローマ字変換とか変換遊びの範囲まで来てるような気がします。やってみようとするところは凄いと思います。ほかにもたくさんの変換マップがあるようです。テキストエディタで特殊な変換を提供してみるのもおもしろいのかもしれません。使いこなせるユーザの方が少なさそうです。半角全角変換も同じような要領で実施できます。これらの変換は基本的にはUnicodeの中で実施され、その後、Unicodeから違う文字コードへの変換をするといった作業にで文字コードへの対応を実現します。次の項目では、これらの変換と同時に文字コードの変換を行う手法についても触れています。
 
ひらがな→ローマ字変換が残念な結果になっているようでして、ひらがなと一緒に記述していたカタカナのギャギュギョをg~ャg~ュg~ョと変換してしまったようです。こんな変換をプログラムで提供することは稀れだと思いますが、ICUのバグのようですので、注意して使いましょう。ひらがなローマ字変換とか変換遊びの範囲まで来てるような気がします。やってみようとするところは凄いと思います。ほかにもたくさんの変換マップがあるようです。テキストエディタで特殊な変換を提供してみるのもおもしろいのかもしれません。使いこなせるユーザの方が少なさそうです。半角全角変換も同じような要領で実施できます。これらの変換は基本的にはUnicodeの中で実施され、その後、Unicodeから違う文字コードへの変換をするといった作業にで文字コードへの対応を実現します。次の項目では、これらの変換と同時に文字コードの変換を行う手法についても触れています。
  
3,341行: 3,348行:
  
 
<nowiki>***</nowiki>upr***系の関数になります。こちらも_str***に_wcs***、_mbs***と接尾句に****_sや****_lそして****_s_lがつくものの組み合わせが存在しています。
 
<nowiki>***</nowiki>upr***系の関数になります。こちらも_str***に_wcs***、_mbs***と接尾句に****_sや****_lそして****_s_lがつくものの組み合わせが存在しています。
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#pragma once
 
#pragma once
 
#include "stdafx.h"
 
#include "stdafx.h"
3,429行: 3,436行:
 
   return 0;
 
   return 0;
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight2>
 
+
出力結果
 +
<syntaxhighlight2 lang="text">
 +
★大文字→小文字変換
 +
abcdefg
 +
hijklmn
 +
opqrstu
 +
vwxyz
 +
★小文字→大文字変換
 +
ABCDEFG
 +
HIJKLMN
 +
OPQRSTU
 +
VWXYZ
 +
</syntaxhighlight2>
 
上記のように変換できます。余談になりますが、配列はppcStr[i]のように記述できますが、結局のところ *(ppcStr + i)のように書き直すことができます。配列を宣言したときに、その変数は既にポインタ変数になっているので、宣言したときから、配列変数であることを示すプレフィックス(接頭句)としてpをつけておくのもよいですね。ポインタの配列はppと接頭句が付けられますし、char型ならppcという具合の接頭句の規則を自分は使っています。intはiじゃなくてnを接頭句に使うんですけど。面倒になって接頭句を付け忘れたりもします。そうするとしばらくして、これ何の変数だっけ?という具合になるおじいちゃんぶりを発揮します。たぶん、こうなってくると、「さっき食べたでしょ?おじいちゃん(^_^)。」って言われると、もう断食状態になります。やばいです。人が書いたプログラムと合わせると、また接頭句の規則が乱れて、自分自身では理解ができなくなってくるのです。たぶん自分は大きなプログラムを作るのには向いていませんね。せめて個人的に作っているプログラムの範囲では、規則どおりにやって間違いを減らしたいと思います。チームでやるときは、今までにつちかってきた規則と基盤を胸にきざみつつも応用力が試されます。int nSize[] = {10,20,30};みたいに宣言したときも実はnSizeってのは、この配列の先頭アドレスを保有する変数になってるわけだから、int pnSize[] = {10,20,30};として宣言して、*(pnSize + i) みたいにして、使うのもいいし、pnSize[i]として配列のように使うのもいい。ポインタ変数をあつかってるんだなぁって意識できてるだけマシ。プロになると、まぁそんな細かい事いわなくても自然と意識できるんでしょう。ただ、構造体やらクラスの配列だとpSize[i].mValueとかpSize[i].mFunc()みたいにできるものでも *(pSize + i).xxxとはできず、(*(pSize + i)).mValue のように全体をカッコでくくらないと駄目です。そして、アロー演算子は(*(ポインタ変数)).mValueのようなメンバ変数や関数の参照をおきかえるものでしたから、配列を[]を使わないで表現できることをしっていれば、(pSize + i)->mValueと記述を切り替えるのもたやすいですね。
 
上記のように変換できます。余談になりますが、配列はppcStr[i]のように記述できますが、結局のところ *(ppcStr + i)のように書き直すことができます。配列を宣言したときに、その変数は既にポインタ変数になっているので、宣言したときから、配列変数であることを示すプレフィックス(接頭句)としてpをつけておくのもよいですね。ポインタの配列はppと接頭句が付けられますし、char型ならppcという具合の接頭句の規則を自分は使っています。intはiじゃなくてnを接頭句に使うんですけど。面倒になって接頭句を付け忘れたりもします。そうするとしばらくして、これ何の変数だっけ?という具合になるおじいちゃんぶりを発揮します。たぶん、こうなってくると、「さっき食べたでしょ?おじいちゃん(^_^)。」って言われると、もう断食状態になります。やばいです。人が書いたプログラムと合わせると、また接頭句の規則が乱れて、自分自身では理解ができなくなってくるのです。たぶん自分は大きなプログラムを作るのには向いていませんね。せめて個人的に作っているプログラムの範囲では、規則どおりにやって間違いを減らしたいと思います。チームでやるときは、今までにつちかってきた規則と基盤を胸にきざみつつも応用力が試されます。int nSize[] = {10,20,30};みたいに宣言したときも実はnSizeってのは、この配列の先頭アドレスを保有する変数になってるわけだから、int pnSize[] = {10,20,30};として宣言して、*(pnSize + i) みたいにして、使うのもいいし、pnSize[i]として配列のように使うのもいい。ポインタ変数をあつかってるんだなぁって意識できてるだけマシ。プロになると、まぁそんな細かい事いわなくても自然と意識できるんでしょう。ただ、構造体やらクラスの配列だとpSize[i].mValueとかpSize[i].mFunc()みたいにできるものでも *(pSize + i).xxxとはできず、(*(pSize + i)).mValue のように全体をカッコでくくらないと駄目です。そして、アロー演算子は(*(ポインタ変数)).mValueのようなメンバ変数や関数の参照をおきかえるものでしたから、配列を[]を使わないで表現できることをしっていれば、(pSize + i)->mValueと記述を切り替えるのもたやすいですね。
  
3,441行: 3,460行:
 
以下はICUを利用した全角→半角変換です。
 
以下はICUを利用した全角→半角変換です。
  
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#pragma once
 
#pragma once
  
3,569行: 3,588行:
 
   retuen 0;
 
   retuen 0;
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight2>
 
出力結果
 
出力結果
<syntaxhighlight lang="text">
+
<syntaxhighlight2 lang="text">
 
★UnicodeString変数の出力サンプル
 
★UnicodeString変数の出力サンプル
 
あいうえおアイウエオABCDE@;:*+/:
 
あいうえおアイウエオABCDE@;:*+/:
3,590行: 3,609行:
 
あいうえおアイウエオABCDE@;:*+/ 22:
 
あいうえおアイウエオABCDE@;:*+/ 22:
 
3042:3044:3046:3048:304a:ff71:ff72:ff73:ff74:ff75:0041:0042:0043:0044:0045:0040:003b:003a:002a:002b:002f:0000:
 
3042:3044:3046:3048:304a:ff71:ff72:ff73:ff74:ff75:0041:0042:0043:0044:0045:0040:003b:003a:002a:002b:002f:0000:
</syntaxhighlight>
+
</syntaxhighlight2>
 
という感じに変換ができます。ICUの使い方さえわかれば、いろいろできますね。記事を書きながら、自分もようやくわかってきた感じ。ぉぃ。
 
という感じに変換ができます。ICUの使い方さえわかれば、いろいろできますね。記事を書きながら、自分もようやくわかってきた感じ。ぉぃ。
  
3,598行: 3,617行:
  
 
createInstanceで指定できる変換タイプ名は以下のとおりです。
 
createInstanceで指定できる変換タイプ名は以下のとおりです。
<syntaxhighlight lang="text">
+
<syntaxhighlight2 lang="text">
 
Arabic-Latin
 
Arabic-Latin
 
Arabic-Latin/BGN
 
Arabic-Latin/BGN
3,879行: 3,898行:
 
Any-Hebrew
 
Any-Hebrew
 
Any-uz_Cyrl
 
Any-uz_Cyrl
</syntaxhighlight>
+
</syntaxhighlight2>
  
=='''文字列の検索と置換'''==
+
=='''文字列の検索と置換・正規表現'''==
 
文字列の検索と置換は、メモ帳でCtrl+Fとかで検索するようなものや置換する処理と同じように目的の文字列を探す方法とファイルの検索のようにワイルドカードを使う方法があり、検索して一致した文字列を置き換えるという処理も同じみですが、もうひとつの検索と置換のやり方として、正規表現(Regular Expresion)という手法があります。これはワイルドカードによる指定にさらに文字列の先頭にある特定の文字列があって、さらに特定の文字列にはさまれた部分があって、文字列の最後尾にも特定の文字があったら、その挟まれた文字の先頭グループ1、グループ2、…グループnとして、順次、変換法則にしたがって変換といった複雑な指定が可能になる手法です。正規表現は複雑なこともできるし、単純なこともできる。できるだけ複雑なモノを単純にしてから操作をする手法など、検索と置換には多岐にわたる手法が存在します。また、検索効率をあげる手法もありかなり文字列操作の中でも奥深い技術を必要とする操作です。まずは単純な検索と置換。それと簡単な正規表現にチャレンジしてみましょう。正規表現の使い方をここでは取り上げて、正規表現による問題解決手法は、ここ以外での説明にしたいと思います。
 
文字列の検索と置換は、メモ帳でCtrl+Fとかで検索するようなものや置換する処理と同じように目的の文字列を探す方法とファイルの検索のようにワイルドカードを使う方法があり、検索して一致した文字列を置き換えるという処理も同じみですが、もうひとつの検索と置換のやり方として、正規表現(Regular Expresion)という手法があります。これはワイルドカードによる指定にさらに文字列の先頭にある特定の文字列があって、さらに特定の文字列にはさまれた部分があって、文字列の最後尾にも特定の文字があったら、その挟まれた文字の先頭グループ1、グループ2、…グループnとして、順次、変換法則にしたがって変換といった複雑な指定が可能になる手法です。正規表現は複雑なこともできるし、単純なこともできる。できるだけ複雑なモノを単純にしてから操作をする手法など、検索と置換には多岐にわたる手法が存在します。また、検索効率をあげる手法もありかなり文字列操作の中でも奥深い技術を必要とする操作です。まずは単純な検索と置換。それと簡単な正規表現にチャレンジしてみましょう。正規表現の使い方をここでは取り上げて、正規表現による問題解決手法は、ここ以外での説明にしたいと思います。
  
 
以下、ICUのRegexを使った検索と置換の正規表現による処理のサンプルです。
 
以下、ICUのRegexを使った検索と置換の正規表現による処理のサンプルです。
<syntaxhighlight lang="cpp" line start="1">
+
<syntaxhighlight2 lang="cpp" line start="1">
 
#pragma once
 
#pragma once
  
4,088行: 4,107行:
 
   return 0;
 
   return 0;
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight2>
 
出力結果
 
出力結果
<syntaxhighlight lang="text">
+
<syntaxhighlight2 lang="text">
 
★正規表現検索
 
★正規表現検索
 
★パターンマッチ結果出力
 
★パターンマッチ結果出力
4,185行: 4,204行:
 
★部分一致パターンの置換結果出力
 
★部分一致パターンの置換結果出力
 
リン★とミカ★/ナ★とモ★,ごは★やおか★/おさ★もつま★,progra★と技★
 
リン★とミカ★/ナ★とモ★,ごは★やおか★/おさ★もつま★,progra★と技★
</syntaxhighlight>
+
</syntaxhighlight2>
 
149行目以降に記述した部分一致からのプログラムはやや複雑な表記になっていますが、これはICUに準備された関数だけでは部分一致の処理ができないために自分で工夫をしなければならないことに起因しています。
 
149行目以降に記述した部分一致からのプログラムはやや複雑な表記になっていますが、これはICUに準備された関数だけでは部分一致の処理ができないために自分で工夫をしなければならないことに起因しています。
  
4,227行: 4,246行:
 
http://msdn.microsoft.com/ja-jp/library/vstudio/z9da80kz.aspx
 
http://msdn.microsoft.com/ja-jp/library/vstudio/z9da80kz.aspx
  
<syntaxhighlight lang="cpp" line start="1">
+
 
 +
マルチバイト文字の1文字を数値として取得する関数として
 +
 
 +
_strnextc、_wcsnextc、_mbsnextc、_mbsnextc_lがあり、ここでは_mbsnetcを使いました。その下に関数を使わない場合の数値の取得方法についても処理を記述しました。1文字バイト構成を羅列したときの整数値に変換した数値を抜き出したいという特殊な用途に応える関数になっています。自分で計算するのは面倒な手続きが必要になりそうなことがサンプルからわかると思います。
 +
 
 +
http://msdn.microsoft.com/ja-jp/library/vstudio/5zsfy4ab.aspx
 +
 
 +
<syntaxhighlight2 lang="cpp" line start="1">
 
#pragma once
 
#pragma once
 
#include "stdafx.h"
 
#include "stdafx.h"
4,278行: 4,304行:
 
   int SingleChr = 'r';
 
   int SingleChr = 'r';
 
   unsigned int mbSingleString;   
 
   unsigned int mbSingleString;   
 +
  unsigned int mbSingleStringNextC;
 
   unsigned int nKeta;
 
   unsigned int nKeta;
  
4,303行: 4,330行:
  
 
   pucPos = (unsigned char*)pcSingleStr;
 
   pucPos = (unsigned char*)pcSingleStr;
 +
 +
  mbSingleStringNextC = _mbsnextc(pucPos);
 +
  printf_s( "MultiByteString検索文字 SigngleWord:%04x(%s)\n", mbSingleStringNextC, pcSingleStr);
 +
 
 
   pucPos = _mbsinc(pucPos);//一文字分ポインタを進める関数
 
   pucPos = _mbsinc(pucPos);//一文字分ポインタを進める関数
 
   result = (int)(pucPos - (unsigned char*)pcSingleStr);
 
   result = (int)(pucPos - (unsigned char*)pcSingleStr);
4,366行: 4,397行:
  
  
</syntaxhighlight>
+
</syntaxhighlight2>
 
出力結果 等幅フォントに設定したテキストエディタに張り付けると、もう少し見やすくなります。
 
出力結果 等幅フォントに設定したテキストエディタに張り付けると、もう少し見やすくなります。
<syntaxhighlight lang="text">
 
文字列検索:
 
  
      日本語文字の検索用文字列です。The quick brown dog jumps over the lazy fox
+
文字列検索:
              1        2        3        4        5        6
+
 
      123456789012345678901234567890123456789012345678901234567890123456789
+
      日本語文字の検索用文字列です。The quick brown dog jumps over the lazy fox
 +
                1        2        3        4        5        6
 +
      123456789012345678901234567890123456789012345678901234567890123456789
 +
 +
★マルチバイト対応検索
 +
MultiByteString検索文字 SigngleWord:97f1(列)
 +
f1
 +
97
 +
MultiByteString検索文字 SigngleWord:97f1(列)
 +
incriment:2[Byte]
 +
 +
検索結果:  最初の 97f1(列) が見つかった位置は 23[Byte]目
 +
 +
 +
★シングルバイト文字の初期値による検索
 +
検索文字:  r
 +
検索結果:  最初の r が見つかった位置は 42[Byte]目
 +
検索結果:  最後に r が見つかった位置は 60[Byte]目
 +
 +
 +
★文字列への文字列検索
 +
検索文字:  文字列
 +
検索結果:  最初の (文字列) が見つかった位置は 19[Byte]目
  
★マルチバイト対応検索
+
文字列全体の一致による検索の関数はstrstr関数で、***str系の関数です。他にも文字セット検索なるものはあります。
f1
+
97
+
MultiByteString検索文字 SigngleWord:97f1(列)
+
incriment:2[Byte]
+
  
検索結果:  最初の 97f1(列) が見つかった位置は 23[Byte]目
+
=='''文字列ファイルへの入出力'''==
 +
ここまで、やってきた手法で文字列をファイルに保存することをやってみます。文字列はかならずしもテキストファイルとして保管されるものではありません。DBに格納されるもの、バイナリファイルに格納されるもの、圧縮されるもの、様々です。ここでは一般的なテキストファイルとして保管し、簡単なテキストDBとしての操作について作業します。
  
  
★シングルバイト文字の初期値による検索
+
まずは、テキストから文字列の読み込みのサンプルをぺたぺたとしたいのですが、一応、標準の関数でサポートされている範囲の文字コードはShiftJISとUTF-8とUTF-16でVisualStudio2005からfopenやwfopen関数が拡張されて、2番目の引数ファイルオープンモード文字列に ccs=UTF-8とかccs=UTF-16LEと記載することで、ファイルポインタをつかってのストリーム入力時fgetws関数でワイド文字(UNICODE)に変換してくれます。テキストは自分で作るといいのですが、自分は以下のような簡単なテキストを文字コード別に準備したので、参考にリンクを張っておきます。なんてことないテキストファイルなので、無価値なのものです。
検索文字:  r
+
検索結果:  最初の r が見つかった位置は 42[Byte]目
+
検索結果:  最後に r が見つかった位置は 60[Byte]目
+
  
 +
[[メディア:文字列操作サンプル用文字コード4種セット.lzh | 文字列操作サンプル用文字コード4種セット.lzh]]
  
★文字列への文字列検索
+
JISやEUCといったサポートされていない文字コードのテキストファイルの場合はバイナリモードでファイルを読み込む必要があり、1バイトづつ処理をして、文字列として変換したりすることで、文字列操作を行います。変換そのものは先に紹介した文字コード変換で対応することが可能ですので、とりこんだバイナリコードをどうやって変換関数のなかに収めるかというのが課題になると思います。その例はのちほど考えるとして、まずはオーソドックスなファイルの読み込みからやってみます。
検索文字:  文字列
+
検索結果:  最初の (文字列) が見つかった位置は 19[Byte]目
+
</syntaxhighlight>
+
文字列全体の一致による検索の関数はstrstr関数で、***str系の関数です。他にも文字セット検索なるものはあります。
+
  
=='''文字列ファイルパス操作'''==
+
<syntaxhighlight2 lang="cpp" line start="1">
ファイルパスにも日本語文字列が使われますし、検索やフォルダ作成、フォルダのコピーといった作業をしたあと、フルパスを保持する必要があったりもします。ファイルの全検索こそが文字列の検索でもあるわけで、パス名操作には文字列連結や拡張子の抽出。Tokenによる階層深さの探索。使用禁止文字チェックと文字列操作の応用が必要になります。
+
#pragma once
 +
#include "stdafx.h"
 +
#include <stdlib.h>
 +
#include <string> //std::string型定義
 +
#include <mbstring.h> //mbs***関数
 +
#include <iostream> //cpp cout etc 一般入出力関数
 +
#include <locale> //Locale関数
 +
#include <tchar.h> //TCHAR型+_tcs***関数
 +
#include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ
 +
#include "atlbase.h" //同上
 +
#include "cstringt.h" //CStringTの定義プリプロセッサ
 +
#include <vector>
  
=='''文字列ファイル名操作'''==
+
#include <sys/timeb.h>  //Timeb型構造体
文字列の操作でありながら、ファイルの名前を変更するという処理も少し特別な作業になります。拡張子の抽出も実施する必要があります。
+
  
=='''文字列ファイルへの入出力'''==
+
//_bstr_t型を利用するプリプロセッサ
ここまで、やってきた手法で文字列をファイルに保存することをやってみます。文字列はかならずしもテキストファイルとして保管されるものではありません。DBに格納されるもの、バイナリファイルに格納されるもの、圧縮されるもの、様々です。ここでは一般的なテキストファイルとして保管し、簡単なテキストDBとしての操作について作業します。
+
#include "comutil.h"
 +
#ifdef _DEBUG
 +
#pragma comment(lib, "comsuppwd.lib")
 +
#else
 +
#pragma comment(lib, "comsuppw.lib")
 +
#endif
 +
//_bstr_t
 +
 
 +
//ICU ucnvプリプロセッサ
 +
#include <unicode/ucnv.h>
 +
#include <unicode/translit.h>
 +
#include <unicode/regex.h>
 +
#ifdef _DEBUG
 +
//#pragma comment(lib, "icudt.lib")
 +
#pragma comment(lib, "icuind.lib")//ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も
 +
#pragma comment(lib, "icuucd.lib")//ICU ucnvを使うために必要なライブラリ
 +
//#pragma comment(lib, "icuiod.lib")
 +
#else
 +
#pragma comment(lib, "icudt.lib")
 +
#pragma comment(lib, "icuind.lib")
 +
#pragma comment(lib, "icuuc.lib")
 +
#pragma comment(lib, "icuio.lib")
 +
#endif
 +
 
 +
 
 +
#include "UnicodeConverter.h"
 +
 
 +
 
 +
using namespace std;
 +
int _tmain(int argc, _TCHAR* argv[])
 +
{
 +
  _tsetlocale(LC_ALL, _T("Japanese")); //ロケールセットすると_l関数でロケール指定しなくても日本語が使われます。
 +
 
 +
_locale_t localeJpanease;
 +
localeJpanease = _create_locale(LC_ALL, "Japanese");
 +
 
 +
  FILE* pfileText;
 +
  errno_t errNo;
 +
  size_t* psizeRuturnValue = new size_t;
 +
  int nCloseCnt;
 +
  wchar_t pwcStrFilePathNewTexttoBinary[] = L"C:\\...\\...\\...\\new_test_t2b.txt";//...\\...\\...には正確なパスを指定。
 +
  wchar_t pwcStrFilePathNewUTF16LE[]      = L"C:\\...\\...\\...\\new_test_utf16b.txt";
 +
  wchar_t pwcStrFilePathNewUTF8[]        = L"C:\\...\\...\\...\\new_test_utf8b.txt";
 +
  wchar_t pwcStrFilePathNewUTF8BOM[]      = L"C:\\...\\...\\...\\new_test_utf8bomb.txt";
 +
  wchar_t pwcStrFilePathShiftJIS[]        = L"C:\\...\\...\\...\\test.txt";
 +
  wchar_t pwcStrFilePathJIS[]            = L"C:\\...\\...\\...\\test_jis.txt";
 +
  wchar_t pwcStrFilePathEUC[]            = L"C:\\...\\...\\...\\test_euc.txt";
 +
  wchar_t pwcStrFilePathUtf8Bom[]        = L"C:\\...\\...\\...\\test_utf8.txt";
 +
  wchar_t pwcStrFilePathUtf8[]            = L"C:\\...\\...\\...\\test_utf8N.txt";
 +
  wchar_t pwcStrFilePathUtf16LE[]        = L"C:\\...\\...\\...\\test_utf16LE.txt";
 +
 
 +
  wchar_t pwcStrGohan[] = L"ごはんを食べたよ。\r\n";//\r\n = CR LF = 0x0D 0x0A
 +
  char* pcStrStream;
 +
  wchar_t* pwcStrStream;
 +
  char* pcStrErr;
 +
  wchar_t* pwcStrErr;
 +
 
 +
  pcStrStream = new char[1024];
 +
  pwcStrStream = new wchar_t[1024];
 +
  pcStrErr = new char[1024];
 +
  pwcStrErr = new wchar_t[1024];
 +
 
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
  //★UTF8のBOM無しテキストの読み込み
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
 
 +
  //※読み込みバッファを1024文字にしているので、1024文字以上の行を一続きにさせたい場合は、工夫が必要。それは後で考えます。
 +
  //※行ごとにバッファの文字数を動的に確保したい場合、
 +
  // 一文字づつスキャンして改行コードが現れるところまでのバイト長を確保するという手法もありそう。
 +
 
 +
  fpos_t* fposPos = new fpos_t;
 +
 
 +
  printf("★UTF8のBOM無しテキストの読み込み\n");
 +
  errNo = _wfopen_s( &pfileText, pwcStrFilePathUtf8, L"r,ccs=UTF-8");
 +
  printf("Error?->%d\n", errNo);
 +
 
 +
  fgetpos(pfileText, fposPos);
 +
  printf("fpos-> %04d\n", *fposPos); //ファイルを開いた時点でのポジションの確認。BOM無しだと0文字目。
 +
 
 +
  //Unicodeサンプル文字 1行目
 +
  printf("文字コードUTF-16->");
 +
  for(int i=0; i < (int)wcslen(pwcStrGohan) + 1; i++){
 +
    printf("%04x:",*(pwcStrGohan + i));
 +
  }
 +
  printf("\n");
 +
 
 +
  printf("utf8N.txtテキストファイルの中身とその他の情報出力\n");
 +
  while(!feof(pfileText)){
 +
 
 +
    pwcStrErr = fgetws(pwcStrStream,1024,pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。
 +
                                                    //先頭からUTF-8→UTF16形式で文字列を取得する。
 +
    wprintf(L"%s(%s)\n", pwcStrStream, pwcStrErr);//UTF-16のpwcStrStreamをSJIS(Locale設定)で書き出し。UTF-16のままだと文字化けする。
 +
   
 +
    printf("文字コードUTF-16->");
 +
    for(int i=0 ;i < 20 ;i++){ //Unicodeに変換された文字コードを先頭20文字だけ出力。
 +
      printf("%04x:",*(pwcStrStream + i));
 +
    }
 +
 
 +
    fgetpos(pfileText, fposPos);
 +
    printf("fpos-> %04d\n", *fposPos); 
 +
  }
 +
  printf("[EOF]");
 +
  printf("\n");
 +
 
 +
  nCloseCnt = fclose(pfileText);
 +
  printf("nCloseErr->%d\n", nCloseCnt);
 +
 
 +
  nCloseCnt = _fcloseall();
 +
  printf("nCloseCnt->%d\n", nCloseCnt);
 +
  printf("\n");
 +
 
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
  //★UTF8のBOM有りテキストの読み込み
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
 
 +
  printf("★UTF8のBOM有りテキストの読み込み\n");
 +
  errNo = _wfopen_s( &pfileText, pwcStrFilePathUtf8Bom, L"r,ccs=UTF-8");
 +
  printf("Error?->%d\n", errNo);
 +
 
 +
  fgetpos(pfileText, fposPos);
 +
  printf("fpos-> %04d\n", *fposPos); //ファイルを開いた時点でのポジションの確認。BOM無しだと3(0からカウントなので実際は4byte目)。
 +
 
 +
  printf("utf8.txtテキストファイルの中身\n");
 +
  while(!feof(pfileText)){
 +
 
 +
    pwcStrErr = fgetws(pwcStrStream,1024,pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。
 +
                                                    //UTF-8(BOMはEF BB BFなので4バイト目)からUTF16形式で文字列を取得する。
 +
                                                    //※FE FFをUTF-8でエンコードするとEF BB BF
 +
                                                    //※FE FF = 1111 1110 1111 1111 を
 +
                                                    //                1111    11  10  11    11  1111 を
 +
                                                    //          1110 (XXXX) 10(XX) (XX)(YY) 10(YY) (YYYY)と割り当て
 +
                                                    //1110 1111 1011 1011 1011 1111 = EF BB BF
 +
 
 +
    if(pwcStrErr != NULL ){                       
 +
      wprintf(L"%s", pwcStrStream);//UTF-16LEのpwcStrStreamをSJIS(Locale設定)で書き出し。UTF-16LEのままだと文字化けする。
 +
    }
 +
  }
 +
  printf("[EOF]");
 +
  printf("\n");
 +
 
 +
  nCloseCnt = fclose(pfileText);
 +
  printf("nCloseErr->%d\n", nCloseCnt);
 +
  printf("\n");
 +
 
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
  //★UTF16のBOM有りテキストの読み込み
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
 
 +
  printf("★UTF16LEのBOM有りテキストの読み込み\n");
 +
  errNo = _wfopen_s( &pfileText, pwcStrFilePathUtf16LE, L"r,ccs=UTF-16LE");
 +
  printf("Error?->%d\n", errNo);
 +
 
 +
  fgetpos(pfileText, fposPos);
 +
  printf("fpos-> %04d\n", *fposPos); //ファイルを開いた時点でのポジションの確認。BOM有りで2(0からカウントなので実際は3byte目)。
 +
 
 +
  printf("utf8.txtテキストファイルの中身\n");
 +
  while(!feof(pfileText)){
 +
 
 +
    pwcStrErr = fgetws(pwcStrStream,1024,pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。
 +
    if(pwcStrErr != NULL ){                        //UTF-16(BOMはFE FFなので3バイト目)からUTF16形式で文字列を取得する。
 +
      wprintf(L"%s", pwcStrStream);//UTF-16のpwcStrStreamをSJIS(Locale設定)で書き出し。UTF-16のままだと文字化けする。
 +
    }
 +
  }
 +
  printf("[EOF]");
 +
  printf("\n");
 +
 
 +
  nCloseCnt = fclose(pfileText);
 +
  printf("nCloseErr->%d\n", nCloseCnt);
 +
  printf("\n");
 +
 
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
  //★ShiftJISテキストの読み込み
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
 
 +
  printf("★ShiftJISテキストの読み込み\n");
 +
  errNo = _wfopen_s( &pfileText, pwcStrFilePathShiftJIS, L"r");
 +
  printf("Error?->%d\n", errNo);
 +
 
 +
  fgetpos(pfileText, fposPos);
 +
  printf("fpos-> %04d\n", *fposPos); //ファイルを開いた時点でのポジションの確認。
 +
 
 +
  printf("test.txtテキストファイルの中身\n");
 +
  while(!feof(pfileText)){
 +
   
 +
    pcStrErr = fgets(pcStrStream, 1024, pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。
 +
    if(pcStrErr != NULL ){                     
 +
      printf("%s", pcStrStream);
 +
    }
 +
  }
 +
  printf("[EOF]");
 +
  printf("\n");
 +
 
 +
  nCloseCnt = fclose(pfileText);
 +
  printf("nCloseErr->%d\n", nCloseCnt);
 +
  printf("\n");
 +
 
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
  //★JISテキストの読み込み
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
 
 +
  //int型でchar配列のサイズを動的に確保ができるので、int型の範囲のファイルなら
 +
  //一度に格納できるプログラムになっています。intの範囲を超えると動的メモリ確保で
 +
  //失敗します。その先の工夫はまた別途考える必要があります。少し筒変換したり…。
 +
 
 +
  int nSize = 0;
 +
  int nFeedCnt = 0;
 +
 
 +
  char* pcStrFile;
 +
  fpos_t* pfposStartPos = new fpos_t;
 +
  printf("★JISテキストの読み込み\n");
 +
  errNo = _wfopen_s( &pfileText, pwcStrFilePathJIS, L"rb");
 +
  printf("Error?->%d\n", errNo);
 +
 
 +
  fgetpos(pfileText, fposPos);
 +
  printf("fpos-> %04d\n", *fposPos); //ファイルを開いた時点でのポジションの確認。
 +
 
 +
  printf("test_jis.txtテキストファイルの中身\n");
 +
  fgetpos(pfileText, pfposStartPos);
 +
  while(!feof(pfileText)){
 +
    nSize = nSize + nFeedCnt * 1024;
 +
    nFeedCnt++;
 +
    *psizeRuturnValue = fread(pcStrStream, sizeof(char), 1024, pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。
 +
      fgetpos(pfileText, fposPos);                 
 +
      for(int i = 0; i < *fposPos; i++){
 +
        printf("%02x:",0x000000FF & *(pcStrStream + i));
 +
      }
 +
  }
 +
  printf("[EOF]");
 +
  printf("\n");
 +
 
 +
  nSize = nSize + (int)*fposPos - ((nFeedCnt - 1) * 1024);
 +
  fsetpos(pfileText, pfposStartPos);
 +
  pcStrFile = new char[nSize + 1];
 +
  while(!feof(pfileText)){
 +
    *psizeRuturnValue = fread(pcStrFile, sizeof(char), nSize + 1, pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。
 +
      for(int i = 0; i < nSize; i++){
 +
        printf("%02x:",0x000000FF & *(pcStrFile + i));
 +
      }
 +
  }
 +
 
 +
  printf("[EOF]");
 +
  printf("\n");
 +
  fgetpos(pfileText, fposPos);
 +
  printf("fpos-> %04d\npReturnValue-> %04d\n", *fposPos, *psizeRuturnValue); //ファイルを開いた時点でのポジションの確認。
 +
 
 +
 
 +
  nCloseCnt = fclose(pfileText);
 +
  printf("nCloseErr->%d\n", nCloseCnt);
 +
  printf("\n");
 +
 
 +
  UConverter* ucnvTest;
 +
  UErrorCode uerrorNum;
 +
  int nStrSize;
 +
  int nStrResultSize;
 +
  nStrSize = nSize;
 +
 
 +
  std::wstring stringCnvResult(nStrSize, L'\0');
 +
 
 +
  ucnvTest = ucnv_open("iso-2022-jp", &uerrorNum);
 +
  nStrResultSize = ucnv_toUChars(
 +
    ucnvTest,
 +
    &stringCnvResult[0], stringCnvResult.size(), // 変換先のポインタとサイズ
 +
    &pcStrFile[0], nStrSize,         // 変換元のポインタとサイズ
 +
    &uerrorNum
 +
  );
 +
  stringCnvResult.resize(nStrResultSize);
 +
  ucnv_close(ucnvTest);
 +
  _tprintf(_T("%s\n"), stringCnvResult.c_str());
 +
  printf("\n");
 +
  return 0;
 +
}
 +
</syntaxhighlight2>
 +
出力結果
 +
<syntaxhighlight2 lang="text">
 +
★UTF8のBOM無しテキストの読み込み
 +
Error?->0
 +
fpos-> 0000
 +
文字コードUTF-16LE->3054:306f:3093:3092:98df:3079:305f:3088:3002:000d:000a:0000:
 +
utf8N.txtテキストファイルの中身とその他の情報出力
 +
ごはんを食べたよ。
 +
(ごはんを食べたよ。
 +
)
 +
文字コードUTF-16LE->3054:306f:3093:3092:98df:3079:305f:3088:3002:000a:0000:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:fpos-> 0029
 +
 
 +
(
 +
)
 +
文字コードUTF-16LE->000a:0000:3093:3092:98df:3079:305f:3088:3002:000a:0000:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:fpos-> 0031
 +
 
 +
(
 +
)
 +
文字コードUTF-16LE->000a:0000:3093:3092:98df:3079:305f:3088:3002:000a:0000:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:fpos-> 0033
 +
それだけだよ。
 +
(それだけだよ。
 +
)
 +
文字コードUTF-16LE->305d:308c:3060:3051:3060:3088:3002:000a:0000:000a:0000:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:fpos-> 0056
 +
それだけだよ。
 +
((null))
 +
文字コードUTF-16LE->305d:308c:3060:3051:3060:3088:3002:000a:0000:000a:0000:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:cdcd:fpos-> 0056
 +
[EOF]
 +
nCloseErr->0
 +
nCloseCnt->0
 +
 
 +
★UTF8NのBOM有りテキストの読み込み
 +
Error?->0
 +
fpos-> 0003
 +
utf8.txtテキストファイルの中身
 +
ごはんを食べたよ。
 +
 
 +
 
 +
それだけだよ。
 +
[EOF]
 +
nCloseErr->0
 +
 
 +
★UTF16LEのBOM有りテキストの読み込み
 +
Error?->0
 +
fpos-> 0002
 +
utf8.txtテキストファイルの中身
 +
ごはんを食べたよ。
 +
 
 +
 
 +
それだけだよ。
 +
[EOF]
 +
nCloseErr->0
 +
 
 +
★ShiftJISテキストの読み込み
 +
Error?->0
 +
fpos-> 0000
 +
test.txtテキストファイルの中身
 +
ごはんを食べたよ。
 +
 
 +
 
 +
それだけだよ。
 +
[EOF]
 +
nCloseErr->0
 +
 
 +
★JISテキストの読み込み
 +
Error?->0
 +
fpos-> 0000
 +
test_jis.txtテキストファイルの中身
 +
1b:24:42:24:34:24:4f:24:73:24:72:3f:29:24:59:24:3f:24:68:21:23:1b:28:4a:0d:0a:0d:0a:0d:0a:1b:24:42:24:3d:24:6c:24:40:24:31:24:40:24:68:21:23
 +
:1b:28:4a:0d:0a:[EOF]
 +
1b:24:42:24:34:24:4f:24:73:24:72:3f:29:24:59:24:3f:24:68:21:23:1b:28:4a:0d:0a:0d:0a:0d:0a:1b:24:42:24:3d:24:6c:24:40:24:31:24:40:24:68:21:23
 +
:1b:28:4a:0d:0a:[EOF]
 +
fpos-> 0052
 +
pReturnValue-> 0000
 +
nCloseErr->0
 +
 
 +
ごはんを食べたよ。
 +
 
 +
 
 +
それだけだよ。
 +
 
 +
</syntaxhighlight2>
 +
という感じです。ごはんを食べたよ それだけだよ。というサンプルの文字列に特に深い意味はありませんが、Windowsは改行コードにCR LFを使うのが一般的です。しかしながら、ファイルから取り込んできた文字列にでは\r 0x0dは無くなって\nにあたる0x0aだけが残る仕様になっています。これらの改行復帰コードを厳密に扱う場合には書き込みするときや、文字列操作時に工夫が必要になります。文字コードがどんなふうに扱われているのか、厳密にどうなっているのか調べるためにも、時々は文字コードそのものを出力して確かめるのも大事なのではないかと思います。人間様にわかる文字だけを出力していたのでは、コンピュータを正確にあやつることは難しいです。JISの変換ではファイルオープン時にバイナリで開いています。これをchar型の変数に格納して、ICUのJIS→UNICODE変換を実施しています。
 +
 
 +
 
 +
テキストファイルをバイナリで読み込む場合には区切りが大事です。動的に生成できる文字列配列の大きさはint型の範囲が限界ですので、ひとつだけで扱おうとするのは無理がありますし、int型くらい大きいサイズのメモリ確保は無理があります。もう少し小さい単位で文字列を扱える工夫が必要になります。JISテキストファイルなら改行コードまでの大きさくらいが良いと思います。文字列の中に改行コードが見つかるまで文字数を計算して、それでメモリ確保をし、JIS文字列を変換して、作業用の文字列配列に格納するといった、そういう仕組みにするだけのことです。このプログラムはテキストエディタやファイルローダとしての役割を担うものではないので、そこまでの具体的な拡張には挑戦しませんでした。実際の組み込みでは、プログラムが扱うデータの大きさにちょうどよい区切りを準備することになると思います。
 +
まぁこのままでもかなり大きさまで扱えるので、コンソールで遊ぶ程度ならこれでもいいんではないでしょうか?それよか、メモリ確保がうまくいかない場合の例外処理とか追加しますかね。そのあたりの説明はまた別の項目になるかと思います。
 +
 
 +
 
 +
ファイル読み込み時に文字コードセットが判明しているサンプルプログラムのようなケースはプログラムが簡単でしたが、もともとのファイル形式を自動判別して読み込むプログラムに対応しようとすると、またひとつ大変さが増します。自動判別ができないのはutf-8で書かれた英字だけのファイルを開いた場合で、ShiftJISとするのが最適なのか?UTF-8として開くのが最適なのかは、ユーザにあらかじめ決めてもらった方が良いかもしれません。一度でも日本語が使われていれば、おのずと判定ができるわけですが、すべての文字をチェックして英字以外の範囲の文字コードを見つけて、それが、どの文字コードなのかを判別する仕組みが必要です。
 +
 
 +
 
 +
おもしろそうですが、文字コードに詳しくないので、自分はまだその手法をしりません。また今度、考えてみようと思います。文字化けしてるコードをみて、あーこれはもともとはこのコードだったんだろうなという感覚はあるんですが、それと似たような法則があるんでしょうね。結局、この判定もICUでできちゃうんですけどね。これも時間があればやってみたいと思います。
 +
 
 +
 
 +
次はファイル出力にあたる書き込みですね。
 +
<syntaxhighlight2 lang="cpp" line start="1">
 +
  //JISからUTF-16LEへの変換処理
 +
 
 +
  UConverter* ucnvTest;
 +
  UErrorCode uerrorNum;
 +
  int nStrSize;
 +
  int nStrResultSize;
 +
  char pcStrUTF16LEBOM[] = "\xFF\xFE";//\xエスケープシーケンスはx以降の16進数とした文字コードを示すもの。1バイトの文字コード指定で利用できます。
 +
  char pcStrUTF8BOM[] = "\xEF\xBB\xBF";
 +
  nStrSize = nSize;
 +
 
 +
  std::wstring stringCnvResult(nStrSize, L'\0');
 +
 
 +
  ucnvTest = ucnv_open("iso-2022-jp", &uerrorNum);
 +
  nStrResultSize = ucnv_toUChars(
 +
    ucnvTest,
 +
    &stringCnvResult[0], stringCnvResult.size(), // 変換先のポインタとサイズ
 +
    &pcStrFile[0], nStrSize,         // 変換元のポインタとサイズ
 +
    &uerrorNum
 +
  );
 +
  stringCnvResult.resize(nStrResultSize);
 +
  ucnv_close(ucnvTest);
 +
  _tprintf(_T("%s\n"), stringCnvResult.c_str());
 +
  printf("\n");
 +
 
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
  //★UTF16LEのTextモードでの書き込み
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
 
 +
  //\n 0x0Aが \r\nに変換されるため、Binaryモードで読み込んだ\r\nを保持した文字列から
 +
  //変換した文字列をテキストモードで書き込むと\r\r\nのように2重復帰が書き込まれる。
 +
  //テキストエディタでは\rひとつでも、改行されるため \r と \r\nで2つ改行になる。
 +
 
 +
  errNo = _wfopen_s( &pfileText, pwcStrFilePathNewTexttoBinary, L"w,ccs=UTF-16LE");
 +
  fputws(stringCnvResult.c_str(), pfileText);
 +
  fclose(pfileText);
 +
 
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
  //★UTF16LEのBinaryモードテキストの書き込み
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
 
 +
  errNo = _wfopen_s( &pfileText, pwcStrFilePathNewUTF16LE, L"wb");
 +
  fputs(pcStrUTF16LEBOM,pfileText);
 +
  fputws(stringCnvResult.c_str(), pfileText);
 +
  fclose(pfileText);
 +
 
 +
  //UnicodeUTF-16LEのutf-8への変換処理
 +
  ucnvTest = ucnv_open("UTF-8", &uerrorNum);
 +
 
 +
  nStrSize = stringCnvResult.size();
 +
  std::string stringCnvResult3(ucnv_getMaxCharSize(ucnvTest) * nStrSize , L'\0');
 +
 
 +
 
 +
  nStrResultSize = ucnv_fromUChars(
 +
    ucnvTest,
 +
    &stringCnvResult3[0], stringCnvResult3.size(), // 変換先のポインタとサイズ
 +
    &stringCnvResult[0], nStrSize, // 変換元のポインタとサイズ
 +
    &uerrorNum
 +
  );
 +
  stringCnvResult3.resize(nStrResultSize);
 +
  ucnv_close(ucnvTest);
 +
  printf("%s\n", stringCnvResult3.c_str());
 +
 
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
  //★UTF8のBOM無しテキストの書き込み
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
 
 +
  errNo = _wfopen_s( &pfileText, pwcStrFilePathNewUTF8, L"wb");
 +
  //fputs(pcStrUTF8BOM,pfileText);
 +
  fputs(stringCnvResult3.c_str(), pfileText);
 +
  fclose(pfileText);
 +
 
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
  //★UTF8のBOM有りテキストの書き込み
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
 
 +
  errNo = _wfopen_s( &pfileText, pwcStrFilePathNewUTF8BOM, L"wb");
 +
  fputs(pcStrUTF8BOM,pfileText);
 +
  fputs(stringCnvResult3.c_str(), pfileText);
 +
  fclose(pfileText);
 +
</syntaxhighlight2>
 +
先述の読み込み処理に続けてのプログラムになります。ファイルオープンモードでwを指定して、fputs関数でchar型の書き込み、fputwsでwchar_t型の書き込みをするような形式です。モードaで追記なのでファイル末尾から追記されます。ファイルの先頭に追加するときはBOMコードの後の所にファイルポジションをfsetpos関数で移動してからfputws/fputsで書き込むと良いでしょう。新規のファイル作成となるモードwのバイナリモードwbでは、BOMコードを付与しなければならないケースも出てきます。fputsでBOMコードを保持した文字列を引数にすると良いです。bを付けないテキストモードでの書き込みでは、ccs=UTF-8やccs=UTF-16LEを指定すると自動でBOMコードを追記してくれますので、そのままUTF-16ならwchar_t型の文字列を書き出せばよいです。但し、バイナリモードで読み込んだ文字列は\r\nがそのまま文字列になっているので、書き出し時に後ろの\nが\r\nに変換され、\r\r\nになってしまうので、バイナリモードで読み込んだ文字をテキストモードで書き出すのはやめた方がいいです。どうしても相互乗り換えするのであれば、改行コードの置換処理が必要です。UTF-8のテキストモード書き込みでもユニコードのUTF-16LE形式で書き込むことでUTF-8に変換されますので、プログラム内部ではUnicodeで文字列を扱った方が効率が良いと思います。テキストモードでサポートしない文字コードのような特殊な形式に変換する場合はバイナリモードで文字列を読み込んで、変換処理を実施し、char型に格納した文字コードをバイナリモードで書き出すと良いでしょう。サンプルプログラムではテキストモードで読み込んだJIS文字をUnicodeに変換しUTF-16テキストモードで書き込んだ失敗例をプログラムにしてあります。ファイルオープンモードをうまく使いこなすことと、Unicode以外の文字列はchar型でバイナリとして扱うところがポイントです。変換処理はICUに任せればかなり柔軟な入出力処理が作れると思います。
 +
 
 +
 
 +
ファイルオープンモードについてですが、r、w、a、rb、wb、ab の他にもr+ のように+記号を付けるパターンがあります。この場合、r+ 既存ファイルに読み込み上書き、w+ 新規ファイルで読み書き、a+ 既存ファイルに読み追記ができます。cをつけるとflush関数による反映ですべての操作が確定しファイルに反映するモードになります。通常はcではないモードのnが規定値になっています。bを指定しない場合も実際はtが規定値として扱われています。他にもディスクにファイルを残さずメモリ上だけでファイルの操作をするためにT(ファイル生成されない)やD(ファイルポインタを閉じると削除されるファイル)といった一時ファイル指定もありますし、シーケンシャルアクセス最適化のSにランダムアクセス最適化のR、子プロセスに継承しないNといった非常に難しいコアなオプションもあります。シーケンシャルやランダムアクセスについては記録するディスクの仕組みにもよりますが、通常はシーケンシャルの方が読み取り効率が良いはずですが、ランダムに配置された方が待ち時間が少なくなるというケースもあります。大容量・大量のファイルを扱う場合によく調べて選択するとよいかもしれません。Nは違うプログラム(子プロセス)からファイルポインタを2重に参照させないというようなオプションかと思います。やってみたことないので、具体的な例はここでは示せません。やはり経験が少ないと細かいところまでは説明できないですね。無念。
 +
 
 +
 
 +
ここの長ったらしい文字列処理の説明の総括的なプログラミングになっているかと思います。全部理解してこそ、やりきれる処理です。文字列処理のプログラムを普段作らない自分でもこの程度なら理解しておきたいものです。ここのサンプルは直線的なプログラムで無駄の多いサンプルです。みなさんはもっともっと効率のいい文字列処理をやって下さい。ここでは関数の引数や、クラスの考え方をあまり知らなくても、文字列処理ができるように、あまり多くの技術を使わないそういう無駄なサンプルになっていますが、上から順番に処理していくだけなので、処理の順番は理解しやすいようになっているのではないかと自負するところです。あとは文字コードの自動判定くらいを触れて、文字列処理に関するこの記事は終了にしたいなぁと思います。誰も読まないかもしれないのに、よくこんなにウダウダと長ったらしい文章を書いたなぁ。恐るべしだ。でも、こういううだうだした説明ともっと若いときに出会っていたら、もっと手早く理解できたのになぁと自分は思います。この長い文書が誰かの役に立っていたなら幸せなことです。
 +
 
 +
 
 +
ICUによる文字コード自動判定のプログラムは以下のとおりです。
 +
<syntaxhighlight2 lang="cpp" line start="1">
 +
#pragma once
 +
#include "stdafx.h"
 +
#include <stdlib.h>
 +
#include <string>      //std::string型定義
 +
#include <mbstring.h>  //mbs***関数
 +
#include <iostream>    //cpp cout etc 一般入出力関数
 +
#include <locale>      //Locale関数
 +
#include <tchar.h>    //TCHAR型+_tcs***関数
 +
#include "atlstr.h"    //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ
 +
#include "atlbase.h"  //同上
 +
#include "cstringt.h"  //CStringTの定義プリプロセッサ
 +
#include <vector>      //Vector型テンプレートクラス
 +
 
 +
#include <sys/timeb.h> //Timeb型構造体
 +
 
 +
//_bstr_t型を利用するプリプロセッサ(ライブラリはデバッグモードとリリースモード個別設定)
 +
#include "comutil.h"
 +
 
 +
#ifdef _DEBUG
 +
#pragma comment(lib, "comsuppwd.lib")
 +
#else
 +
#pragma comment(lib, "comsuppw.lib")
 +
#endif
 +
//_bstr_t _End
 +
 
 +
//ICU ucnvプリプロセッサ(ライブラリはデバッグモードとリリースモード個別設定)
 +
#include <unicode/ucnv.h>    //ucnv文字コード変換ライブラリヘッダ
 +
#include <unicode/translit.h> //文字変換ライブラリヘッダ
 +
#include <unicode/regex.h>    //正規表現
 +
#include <unicode/ucsdet.h>  //文字コード判定
 +
 
 +
#ifdef _DEBUG
 +
//#pragma comment(lib, "icudt.lib")
 +
#pragma comment(lib, "icuind.lib")  //ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も
 +
#pragma comment(lib, "icuucd.lib")  //ICU ucnvを使うために必要なライブラリ
 +
//#pragma comment(lib, "icuiod.lib")
 +
#else
 +
//#pragma comment(lib, "icudt.lib")
 +
#pragma comment(lib, "icuind.lib")  //ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も
 +
#pragma comment(lib, "icuuc.lib")  //ICU ucnvを使うために必要なライブラリ
 +
//#pragma comment(lib, "icuio.lib")
 +
#endif
 +
//ICU ucnv _End
 +
 
 +
#include "UnicodeConverter.h"
 +
 
 +
using namespace std;
 +
 
 +
int _tmain(int argc, _TCHAR* argv[])
 +
{
 +
  _tsetlocale(LC_ALL, _T("Japanese")); //ロケールセットすると_l関数でロケール指定しなくても日本語が使われます。
 +
 
 +
_locale_t localeJpanease;
 +
localeJpanease = _create_locale(LC_ALL, "Japanese");
 +
 
 +
  FILE* pfileText;
 +
  fpos_t* fposPos = new fpos_t;
 +
  errno_t errNo;
 +
  size_t* psizeRuturnValue = new size_t;
 +
 
 +
  wchar_t pwcStrFilePath[]            = L"C:\\Users\\Administrator\\Documents\\マイ インフォメーション\\ファイル入出力\\test_utf16LE.txt";
 +
  char* pcStrStream;
 +
  pcStrStream = new char[1024];
 +
  int nCloseResult = 0;
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
  //★テキストの読み込み
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★
 +
 
 +
  //int型でchar配列のサイズを動的に確保ができるので、int型の範囲のファイルなら
 +
  //一度に格納できるプログラムになっています。intの範囲を超えると動的メモリ確保で
 +
  //失敗します。その先の工夫はまた別途考える必要があります。少し筒変換したり…。
 +
 
 +
  int nSize = 0;
 +
  int nFeedCnt = 0;
 +
 
 +
  char* pcStrFile;
 +
  fpos_t* pfposStartPos = new fpos_t;
 +
  printf("★テキストの読み込み\n");
 +
  errNo = _wfopen_s( &pfileText, pwcStrFilePath, L"rb");
 +
  printf("Error?->%d\n", errNo);
 +
 
 +
  fgetpos(pfileText, fposPos);
 +
  printf("fpos-> %04d\n", *fposPos); //ファイルを開いた時点でのポジションの確認。
 +
 
 +
  printf("test.txtテキストファイルの中身\n");
 +
  fgetpos(pfileText, pfposStartPos);
 +
  while(!feof(pfileText)){
 +
    nSize = nSize + nFeedCnt * 1024;
 +
    nFeedCnt++;
 +
    *psizeRuturnValue = fread(pcStrStream, sizeof(char), 1024, pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。
 +
      fgetpos(pfileText, fposPos);                 
 +
      for(int i = 0; i < *fposPos; i++){
 +
        printf("%02x:",0x000000FF & *(pcStrStream + i));
 +
      }
 +
  }
 +
  printf("[EOF]");
 +
  printf("\n");
 +
 
 +
  nSize = nSize + (int)*fposPos - ((nFeedCnt - 1) * 1024);
 +
  fsetpos(pfileText, pfposStartPos);
 +
  pcStrFile = new char[nSize + 1];
 +
  while(!feof(pfileText)){
 +
    *psizeRuturnValue = fread(pcStrFile, sizeof(char), nSize + 1, pfileText);//最終行がEOFのみの場合に失敗して1行前の値が残ることに注意。
 +
      for(int i = 0; i < nSize; i++){
 +
        printf("%02x:",0x000000FF & *(pcStrFile + i));
 +
      }
 +
  }
 +
 
 +
  printf("[EOF]");
 +
  printf("\n");
 +
  fgetpos(pfileText, fposPos);
 +
  printf("fpos-> %04d\npReturnValue-> %04d\n", *fposPos, *psizeRuturnValue); //ファイルを開いた時点でのポジションの確認。
 +
 
 +
 
 +
  nCloseResult = fclose(pfileText);
 +
  printf("nCloseErr->%d\n", nCloseResult);
 +
  printf("\n");
 +
 
 +
  UConverter* ucnvTest;
 +
  UErrorCode uerrorNum = U_ZERO_ERROR;
 +
  int nStrSize;
 +
  int nStrResultSize;
 +
  char pcStrUTF16LEBOM[] = "\xFF\xFE";
 +
  char pcStrUTF8BOM[] = "\xEF\xBB\xBF";
 +
  nStrSize = nSize;
 +
 
 +
  UCharsetDetector* pucsetdetecDetector = ucsdet_open(&uerrorNum);
 +
  ucsdet_setText(pucsetdetecDetector, pcStrFile, nSize, &uerrorNum);
 +
 
 +
  int32_t int32FindCharSetCnt = 0;
 +
  const UCharsetMatch* pucsetmatchStrCode = ucsdet_detect(pucsetdetecDetector, &uerrorNum);
 +
 
 +
  const char* cpcDetectStrCodeName;
 +
  const char* cpcDetectStrCodeLanguage;
 +
  cpcDetectStrCodeName = ucsdet_getName(pucsetmatchStrCode, &uerrorNum);//文字コード名 ICUの文字コードセット名に適した形式。
 +
  cpcDetectStrCodeLanguage = ucsdet_getLanguage(pucsetmatchStrCode, &uerrorNum);
 +
 
 +
  printf("★ICU Code Detectorによるテキストの文字コード自動判定\n");
 +
  printf("CodeName->%s\n",cpcDetectStrCodeName);
 +
  printf("CodeLang->%s\n",cpcDetectStrCodeLanguage);//RFC3066コードを取得できる。
 +
 
 +
  //Shift_JISからUTF-16LEへの変換処理
 +
 
 +
  //先頭がBOMコードなら変換する文字の先頭アドレスをBOMコードの長さを割り出し、nShiftByteに記録。
 +
  int nShiftByte = 0;
 +
  if(strlen(pcStrFile) >= 3){
 +
    if(strncmp(pcStrFile,pcStrUTF8BOM,3) == 0){
 +
      nShiftByte = 3;
 +
    }
 +
  }
 +
  if(strlen(pcStrFile) >= 2){
 +
    if(strncmp(pcStrFile,pcStrUTF16LEBOM,2) == 0){
 +
      nShiftByte = 2;
 +
    }
 +
  }
 +
 
 +
  std::wstring stringCnvResult(nStrSize, L'\0');
 +
 
 +
  ucnvTest = ucnv_open(cpcDetectStrCodeName, &uerrorNum);//変換する文字コードは自動判定で取得した文字コード。
 +
  nStrResultSize = ucnv_toUChars(
 +
    ucnvTest,
 +
    &stringCnvResult[0], stringCnvResult.size(),           // 変換先のポインタとサイズ
 +
    &pcStrFile[0 + nShiftByte], nStrSize - nShiftByte, // 変換元のポインタとサイズ BOMサイズがnShiftByteに格納されている。
 +
    &uerrorNum
 +
  );
 +
  stringCnvResult.resize(nStrResultSize);
 +
  ucnv_close(ucnvTest);
 +
  ucsdet_close(pucsetdetecDetector);
 +
  _tprintf(_T("%s[EOF]"), stringCnvResult.c_str());
 +
  printf("\n");
 +
  return 0;
 +
}
 +
</syntaxhighlight2>
 +
出力結果 utf16LEのテキストを指定した場合。
 +
<syntaxhighlight2 lang="text">
 +
★テキストの読み込み
 +
Error?->0
 +
fpos-> 0000
 +
test.txtテキストファイルの中身
 +
ff:fe:54:30:6f:30:93:30:92:30:df:98:79:30:5f:30:88:30:02:30:0d:00:0a:00:0d:00:0a:00:0d:00:0a:00:5d:30:8c:30:60:30:51:30:60:30:88:30:02:30:0d:00:0a:00:[EOF]
 +
ff:fe:54:30:6f:30:93:30:92:30:df:98:79:30:5f:30:88:30:02:30:0d:00:0a:00:0d:00:0a:00:0d:00:0a:00:5d:30:8c:30:60:30:51:30:60:30:88:30:02:30:0d:00:0a:00:[EOF]
 +
fpos-> 0050
 +
pReturnValue-> 0000
 +
nCloseErr->0
 +
 
 +
★ICU Code Detectorによるテキストの文字コード自動判定
 +
CodeName->UTF-16LE
 +
CodeLang->
 +
ごはんを食べたよ。
 +
 
 +
 
 +
それだけだよ。
 +
[EOF]
 +
</syntaxhighlight2>
 +
出力結果 utf8のテキストを指定した場合。
 +
<syntaxhighlight2 lang="text">
 +
★テキストの読み込み
 +
Error?->0
 +
fpos-> 0000
 +
test.txtテキストファイルの中身
 +
ef:bb:bf:e3:81:94:e3:81:af:e3:82:93:e3:82:92:e9:a3:9f:e3:81:b9:e3:81:9f:e3:82:88:e3:80:82:0d:0a:0d:0a:0d:0a:e3:81:9d:e3:82:8c:e3:81:a0:e3:81:91:e3:81:a0:e3:82:88:e3:80:82:0d:0a:[EOF]
 +
ef:bb:bf:e3:81:94:e3:81:af:e3:82:93:e3:82:92:e9:a3:9f:e3:81:b9:e3:81:9f:e3:82:88:e3:80:82:0d:0a:0d:0a:0d:0a:e3:81:9d:e3:82:8c:e3:81:a0:e3:81:91:e3:81:a0:e3:82:88:e3:80:82:0d:0a:[EOF]
 +
fpos-> 0059
 +
pReturnValue-> 0000
 +
nCloseErr->0
 +
 
 +
★ICU Code Detectorによるテキストの文字コード自動判定
 +
CodeName->UTF-8
 +
CodeLang->
 +
ごはんを食べたよ。
 +
 
 +
 
 +
それだけだよ。
 +
[EOF]
 +
</syntaxhighlight2>
 +
出力結果 JISのテキストを指定した場合。
 +
<syntaxhighlight2 lang="text">
 +
★テキストの読み込み
 +
Error?->0
 +
fpos-> 0000
 +
test.txtテキストファイルの中身
 +
1b:24:42:24:34:24:4f:24:73:24:72:3f:29:24:59:24:3f:24:68:21:23:1b:28:4a:0d:0a:0d:0a:0d:0a:1b:24:42:24:3d:24:6c:24:40:24:31:24:40:24:68:21:23:1b:28:4a:0d:0a:[EOF]
 +
1b:24:42:24:34:24:4f:24:73:24:72:3f:29:24:59:24:3f:24:68:21:23:1b:28:4a:0d:0a:0d:0a:0d:0a:1b:24:42:24:3d:24:6c:24:40:24:31:24:40:24:68:21:23:1b:28:4a:0d:0a:[EOF]
 +
fpos-> 0052
 +
pReturnValue-> 0000
 +
nCloseErr->0
 +
 
 +
★ICU Code Detectorによるテキストの文字コード自動判定
 +
CodeName->ISO-2022-JP
 +
CodeLang->
 +
ごはんを食べたよ。
 +
 
 +
 
 +
それだけだよ。
 +
[EOF]
 +
</syntaxhighlight2>
 +
出力結果 ShiftJISのテキストを指定した場合。
 +
<syntaxhighlight2 lang="text">
 +
★テキストの読み込み
 +
Error?->0
 +
fpos-> 0000
 +
test.txtテキストファイルの中身
 +
82:b2:82:cd:82:f1:82:f0:90:48:82:d7:82:bd:82:e6:81:42:0d:0a:0d:0a:0d:0a:82:bb:82:ea:82:be:82:af:82:be:82:e6:81:42:0d:0a:[EOF]
 +
82:b2:82:cd:82:f1:82:f0:90:48:82:d7:82:bd:82:e6:81:42:0d:0a:0d:0a:0d:0a:82:bb:82:ea:82:be:82:af:82:be:82:e6:81:42:0d:0a:[EOF]
 +
fpos-> 0040
 +
pReturnValue-> 0000
 +
nCloseErr->0
 +
 
 +
★ICU Code Detectorによるテキストの文字コード自動判定
 +
CodeName->Shift_JIS
 +
CodeLang->ja
 +
ごはんを食べたよ。
 +
 
 +
 
 +
それだけだよ。
 +
[EOF]
 +
</syntaxhighlight2>
 +
とこのような感じになります。書き出すときには文字コード別にBOMを付与する処理が必要になりますが、自動判別によって、かなりたくさんの文字コードのテキストファイルを自動で読み込むことができるようになります。やや便利なコンソールアプリになったのかもしれません。そんな得体の知れないテキストファイルが転がっているかどうかは知りませんが…。BOMコードの種類にはUTF-16BEもあるので、このあたりにも対応したプログラムにするともっといいかもしれませんね。
 +
今回のサンプルでは完璧な変換をしてくれましたが、ややこしい文字構成ばかりのテキストファイルになってくると間違えることもあります。そのためICUでは文字コード一致率みたいなランキングを作ってくれる関数もありまして、ucsdet_detect関数の代わりにucsdet_detectAllという関数で UCharsetMatch**型を戻り値にするものがあります。ポインタのポインタってことは、配列ってことになります。ucsdete_getName関数で、引数のその配列の要素を渡せば、それぞれの文字コード名が一覧されます。具体的には以下のような要領になります。
 +
<syntaxhighlight2 lang="cpp" line start="1">
 +
  int32_t int32FindCharSetCnt = 0;
 +
  int32_t int32Confidence = 0;
 +
  const UCharsetMatch* pucsetmatchStrCode = ucsdet_detect(pucsetdetecDetector, &uerrorNum);
 +
  const UCharsetMatch** ppucsetmatchStrCode = ucsdet_detectAll(pucsetdetecDetector, &int32FindCharSetCnt, &uerrorNum);
 +
 
 +
  const char* cpcDetectStrCodeName;
 +
  const char* cpcDetectStrCodeLanguage;
 +
 
 +
  for(int i = 0; i < int32FindCharSetCnt; i++){
 +
    int32Confidence = ucsdet_getConfidence(ppucsetmatchStrCode[i], &uerrorNum);0~100で表される信頼値
 +
    cpcDetectStrCodeName = ucsdet_getName(ppucsetmatchStrCode[i], &uerrorNum);//文字コード名 ICUの文字コードセット名に適した形式。
 +
    cpcDetectStrCodeLanguage = ucsdet_getLanguage(ppucsetmatchStrCode[i], &uerrorNum);   
 +
    printf("CodeConf->%d\n",int32Confidence);
 +
    printf("CodeName->%s\n",cpcDetectStrCodeName);
 +
    printf("CodeLang->%s\n",cpcDetectStrCodeLanguage);//RFC3066コードを取得できる。
 +
  }
 +
</syntaxhighlight2>
 +
のようにするとConfidenceの値が大きいほど一致率が高いものとして確認ができます。全部を一覧するにはfor文で0~int32FindCharSetCnt -1までの要素を確認するとよいです。
 +
出力結果 UTF-16LEのファイル。
 +
<syntaxhighlight2 lang="text">
 +
CodeConf->100
 +
CodeName->UTF-16LE
 +
CodeLang->
 +
CodeConf->23
 +
CodeName->windows-1252
 +
CodeLang->es
 +
CodeConf->23
 +
CodeName->windows-1250
 +
CodeLang->cs
 +
CodeConf->10
 +
CodeName->UTF-16BE
 +
CodeLang->
 +
</syntaxhighlight2>
 +
となります。
  
 
=='''文字列と数値の変換'''==
 
=='''文字列と数値の変換'''==
 
実際のアプリケーションでは、数値の入力を行う部分でも、文字コードとして入力がなされ、各種のエディタや、エディットコントロール、入力画面からは文字としてテキストから渡されます。このように取り扱われる文字列としての数値を、プログラミング言語の数を扱う型に格納する技術が必要になります。
 
実際のアプリケーションでは、数値の入力を行う部分でも、文字コードとして入力がなされ、各種のエディタや、エディットコントロール、入力画面からは文字としてテキストから渡されます。このように取り扱われる文字列としての数値を、プログラミング言語の数を扱う型に格納する技術が必要になります。
 +
 +
atoi、atol、atofのような標準関数で簡単に文字列を数値に変換することができます。逆に数値を文字列に変換する関数もitoaやltoa、ftoaのように準備されていますが非標準関数となっています。ほぼ標準で準備されています。同じことがprintf関数のような関数でva_listという可変長引数の型を引数とするvsprintf(vscprintf:文字数カウント用)関数あるい通常のsprintf(scprintf:文字数カウント)関数を使って実現できます。ここでは、使い方のややこしいvsprintfを使ってみました。数値の文字列化に関してはitoaなどの関数よりも書式設定ができる分、応用が利くので、自分ならこういうものを活用します。atoiのような関数はC++ではstd::atoiのような名前空間の中に定義されています。使い方は同じです。
 +
 +
では、以下がサンプルになります。
 +
<syntaxhighlight2 lang="cpp" line start="1">
 +
#pragma once
 +
#include "stdafx.h"
 +
#include <stdlib.h>
 +
#include <string> //std::string型定義
 +
#include <mbstring.h> //mbs***関数
 +
#include <iostream> //cpp cout etc 一般入出力関数
 +
#include <locale> //Locale関数
 +
#include <tchar.h> //TCHAR型+_tcs***関数
 +
#include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ
 +
#include "atlbase.h" //同上
 +
#include "cstringt.h" //CStringTの定義プリプロセッサ
 +
#include <vector>
 +
 +
 +
//_bstr_t型を利用するプリプロセッサ
 +
#include "comutil.h"
 +
#ifdef _DEBUG
 +
#pragma comment(lib, "comsuppwd.lib")
 +
#else
 +
#pragma comment(lib, "comsuppw.lib")
 +
#endif
 +
//_bstr_t
 +
 +
//ICU ucnvプリプロセッサ
 +
#include <unicode/ucnv.h>
 +
#include <unicode/translit.h>
 +
#include <unicode/regex.h>
 +
#ifdef _DEBUG
 +
//#pragma comment(lib, "icudt.lib")
 +
#pragma comment(lib, "icuind.lib")//ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も
 +
#pragma comment(lib, "icuucd.lib")//ICU ucnvを使うために必要なライブラリ
 +
//#pragma comment(lib, "icuiod.lib")
 +
#else
 +
#pragma comment(lib, "icudt.lib")
 +
#pragma comment(lib, "icuind.lib")
 +
#pragma comment(lib, "icuuc.lib")
 +
#pragma comment(lib, "icuio.lib")
 +
#endif
 +
 +
 +
#include "UnicodeConverter.h"
 +
 +
 +
using namespace std;
 +
int getvscprintflen(char* format, ...){
 +
    va_list args;
 +
    int    len;
 +
 +
//可変長引数をargsに格納。引数formatの次から全てをva_list型のargsへ設定
 +
//引数文字列ポインタをformatの次に合わせる関数。
 +
    va_start( args, format );
 +
    len = _vscprintf( format, args );
 +
    return len;
 +
}
 +
 +
void getvsprintf(char* str, char* format, ...){
 +
    va_list args;
 +
    int    len;
 +
 +
    va_start( args, format );
 +
    len = _vscprintf( format, args );
 +
    vsprintf_s( str, len + 1, format, args );
 +
}
 +
int _tmain(int argc, _TCHAR* argv[])
 +
{
 +
char pcStrInt[]="-8192";
 +
const char pcStrFloat[]="-3.14";
 +
int nInteger;
 +
long lLong;
 +
double dDouble;
 +
char* pcStrNumeric;
 +
 +
int nLen;
 +
nInteger = atoi(pcStrFloat);
 +
lLong    = atol(pcStrFloat);
 +
dDouble  = atof(pcStrInt);
 +
 +
printf("★文字列の数値化 型違いの場合\n");
 +
printf("nInteger->%d\n",nInteger);
 +
printf("lLong  ->%d\n",lLong);
 +
printf("dDouble ->%f\n",dDouble);
 +
printf("\n");
 +
 +
nInteger = atoi(pcStrInt);
 +
lLong    = atol(pcStrInt);
 +
dDouble  = atof(pcStrFloat);
 +
 +
printf("★文字列の数値化 型一致の場合\n");
 +
printf("nInteger->%d\n",nInteger);
 +
printf("lLong  ->%d\n",lLong);
 +
printf("dDouble ->%f\n",dDouble);
 +
printf("\n");
 +
 +
 +
//文字列長を取得する
 +
nLen = getvscprintflen("%3.2f", dDouble );
 +
 +
pcStrNumeric = new char[nLen + 1];
 +
 +
//文字列を出力※同じ引数を2回与えているのは冗長なので
 +
//pcStrNumericをメンバ関数にしたクラスを作ると一度にまとめれる。
 +
getvsprintf( pcStrNumeric, "%3.2f", dDouble );
 +
 +
printf("★数値を文字列 vsprintf関数を利用する場合\n");
 +
printf( "%s\n", pcStrNumeric);
 +
 +
delete[] pcStrNumeric;
 +
  return 0;
 +
}
 +
</syntaxhighlight2>
 +
出力結果
 +
<syntaxhighlight2 lang="text">
 +
★文字列の数値化 型違いの場合
 +
nInteger->-3
 +
lLong  ->-3
 +
dDouble ->-8192.000000
 +
 +
★文字列の数値化 型一致の場合
 +
nInteger->-8192
 +
lLong  ->-8192
 +
dDouble ->-3.140000
 +
 +
★数値を文字列 vsprintf関数を利用する場合
 +
-3.14
 +
</syntaxhighlight2>
  
 
=='''文字列と日付・日時・時間の変換'''==
 
=='''文字列と日付・日時・時間の変換'''==
 
先述の数値の問題と同様、日付・日時・時間も文字列として与えられる場合があり、時制を扱う型との相互変換を行う技術も必要になります。
 
先述の数値の問題と同様、日付・日時・時間も文字列として与えられる場合があり、時制を扱う型との相互変換を行う技術も必要になります。
 +
 +
 +
時間処理については、また別の場所で考えたいと思いますが、自分が思うところによると、時間処理には、カレンダー日付を伴う日時の概念と、カレンダー日付を考慮しない、時間の概念の2つがあると思います。時間だけの概念ならば24時間を超えて、1週間=168時間、そして1年=8760時間(うるう年の1年は8784時間ですが…)という具合に表現できると思います。この時間の概念に24時間ごとに1日と数える方式として、1.5日(一日半)にあたる36時間だと「1日と12時間」という表現です。日にちを小数点で表すのは、あまり便利ではありませんが、概念としては存在していて、日付単位にすることもありますし、会話の中では具体的な時間を0.5日割り算として、余りを切り捨てる方式が使われると思います。さらには7日毎(168時間)に1週間として表し、「1週間と1日と12時間」の表現や時間を切り捨てる方式や、日付部分を1.5日と表現する方法。そして、ここから先はうるう年や月あたりに日数の関係であいまいな表現になりますが31日or30日で1カ月と表現する方式として「(およそ)1か月と23日」のような表現に365日毎に1年とした「(およそ)1年と(およそ)3カ月と1週間と2日と10時間」のような表現。大きな単位だけを採用して、小さいものを切り捨てるという概念。ここまでは時間についてでしたが更に細かいところでは時間と分と秒でも表現できて、1時間は60分ですが1時間以上の領域も分で表現し続ける方式として、2時間を120分、24時間を1440分と表すこともあります。1週間を超えるところまで分で表すと10080分でこの先も分で表すケースは人間の感覚による理解を超える表現になってくると思います。同じことを秒でも実施して、1分は60秒の領域を超えて1時間を3600秒そして1日は86400秒。秒の場合は1時間から2時間を超えたあたりで、秒での表現の感覚理解の限界を感じます。ここまでに述べた大きな単位と組み合わせて使う場合には分や秒は59分や59秒といった範囲以内で利用されます。長くなりましたが、こういったものがカレンダー日付を考慮しない時間という概念になると思います。1年や1カ月がどこの1か月か特定されないのが日常の1年や1カ月という表現になりますので、このあたりの表現は人間にわかりやすく説明するあいまいな表現としてだけ存在すると考えていいと思います。
 +
 +
 +
上記のカレンダー日付を考慮しない時間に加えて、カレンダー日付を考慮した時間の概念が存在し、これらを短い言葉で表現するなら非暦時間、暦時間と表したいと思います。暦時間の差分を考えることで非暦時間がうまれ、暦時間と非暦時間を結合させる場合には、かならず加減算して、暦時間に変化するということになります。計算機の暦時間の概念は、定義された基準時間を起点に秒単位で管理されていること、その起点が1970年1月1日00時00分00秒となっていて、世界協定時刻UTCとよばれる表現で表されていると理解しておくと良いです。そして、時刻をカウントする変数のbit数が32bitなら2038年までカウントできて、64bitなら3000億年までカウントできる仕組みです。これは個人的な希望になりますが、これからプログラムをする人は64bitの時間変数を扱って欲しいです。作成するプログラムが経済活動や、生活の基盤、生命活動を支えるものであれば尚更です。2038年は、執筆時点からあと24年でやってくるのです。経済的な損失、人的被害、労力を生まないために。各種コンパイラ提供元はそろそろ32bit時間変数のコンパイルをワーニングや使用宣言未定義エラーとかにする工夫を実施しても良いと思うのです。
 +
 +
 +
これが時間処理の全般になると思います。この暦時間と非暦時間の特殊ケースとして1秒よりも小さい時間であるミリ秒の存在があるといったところでしょうか?そして、文字列として時間を表現する場合には国際社会を含めたルールに基づいて出力します。まずは標準時間からの差が最も重要な概念になります。日本なら+9時間です。あまり日本では関係の無い概念ですがサマータイムという表現もあります。グローバルな展開をするプログラムなら重要な概念かもしれません。相手の時間を思いやる必要のある双方向通信アプリとかなら、なおさら重要です。そして、曜日、午前、午後、24時間表現、表現習慣も国、地域、組織、個人によって異なります。ここでは、日付処理は別の場で考えるとして、システム時間から得られた時刻を文字列にする方法、網羅はできないですが、時刻文字列をシステム時間変数に設定し、歴時間変数として扱う方法について確認したいと思います。この日付の表現に関しても、文字コード変換でお世話になったICUはかなり手広くサポートしています。国際的な文字の変換処理に関する部分の処理系を強くしていっている印象です。たしかに個人では抱えきれないほど国際的な表現は複雑ですので、特化した組織があるというのは、ありがたいことです。
 +
 +
<syntaxhighlight2 lang="cpp" line start="1">
 +
#pragma once
 +
#include "stdafx.h"
 +
#include <stdlib.h>
 +
#include <string> //std::string型定義
 +
#include <mbstring.h> //mbs***関数
 +
#include <iostream> //cpp cout etc 一般入出力関数
 +
#include <locale> //Locale関数
 +
#include <tchar.h> //TCHAR型+_tcs***関数
 +
#include "atlstr.h" //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ
 +
#include "atlbase.h" //同上
 +
#include "cstringt.h" //CStringTの定義プリプロセッサ
 +
#include <vector>
 +
 +
 +
//_bstr_t型を利用するプリプロセッサ
 +
#include "comutil.h"
 +
#ifdef _DEBUG
 +
#pragma comment(lib, "comsuppwd.lib")
 +
#else
 +
#pragma comment(lib, "comsuppw.lib")
 +
#endif
 +
//_bstr_t
 +
 +
//ICU ucnvプリプロセッサ
 +
#include <unicode/ucnv.h>
 +
#include <unicode/translit.h>
 +
#include <unicode/regex.h>
 +
#ifdef _DEBUG
 +
//#pragma comment(lib, "icudt.lib")
 +
#pragma comment(lib, "icuind.lib")//ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も
 +
#pragma comment(lib, "icuucd.lib")//ICU ucnvを使うために必要なライブラリ
 +
//#pragma comment(lib, "icuiod.lib")
 +
#else
 +
#pragma comment(lib, "icudt.lib")
 +
#pragma comment(lib, "icuind.lib")
 +
#pragma comment(lib, "icuuc.lib")
 +
#pragma comment(lib, "icuio.lib")
 +
#endif
 +
 +
 +
#include "UnicodeConverter.h"
 +
 +
 +
using namespace std;
 +
int _tmain(int argc, _TCHAR* argv[])
 +
{
 +
    //_tsetlocale(LC_ALL, _T("Japanese")); ロケールセットすると_l関数でロケール指定しなくても日本語が使われます。
 +
 +
_locale_t localeJpanease;
 +
localeJpanease = _create_locale(LC_ALL, "Japanese");
 +
 +
//日付や時刻を取り込む文字列の長さは大きくないため、一時的な文字列確保はこのような固定長の配列で問題はないと思います。
 +
//それでも動的に文字列長を決定してメモリを確保したいというプログラムの効率を無視する場合には、自作しなければいけない関数が増えるのかと思います。
 +
char tmpbuf[128], timebuf[26], ampm[] = "AM";
 +
    time_t ltime;
 +
    struct _timeb structtimebTime;
 +
    struct tm today, gmt, xmas = { 0, 0, 12, 25, 11, 93 };//秒, 分, 時間, 日, 月(0~11), 年(1900年基準)
 +
    errno_t err;
 +
 +
 +
//__timeb64型構造体変数のアドレスを引数とする_ftime64_s関数でtstructに現在時刻を設定。
 +
_ftime_s( &structtimebTime ); // _ftimeはC4996
 +
    //
 +
 +
//環境変数TZに設定されたタイムゾーンにしたがってグローバル変数_daylight(夏時間設定)、
 +
//_timezone(秒時差)、_tzname配列(要素1->タイムゾーン名 要素2->夏時間タイムゾーン名)を設定。
 +
    _tzset();
 +
 +
 +
    //strtimeは10文字で現在時刻を引数の文字列変数に格納する関数。
 +
    _strtime_s( tmpbuf, 128 );
 +
    printf( "OS 時間:\t\t\t\t%s\n", tmpbuf );
 +
    //strdateは9文字で現在日付を引数の文字列変数に格納する関数。
 +
    _strdate_s( tmpbuf, 128 );
 +
    printf( "OS 日付:\t\t\t\t%s\n", tmpbuf );
 +
 +
    // Get UNIX-style time and display as number and string.
 +
    //time_t型変数のアドレスを引数とするtime関数でltimeに現在日時秒数を協定世界時UTCで設定。
 +
time( &ltime );
 +
    printf( "秒数による日時情報 1970年1月1日基準:\t%ld\n", ltime );
 +
   
 +
//ctime_sは第三引数のtime_t型UTC秒数情報から第一引数の文字列ポインタへ現在のシステムのタイムゾーン時刻生成する関数。
 +
err = ctime_s(timebuf, 26, &ltime);
 +
    if (err)
 +
    {
 +
      printf("ctime_s failed due to an invalid argument.");
 +
      exit(1);
 +
    }
 +
    printf( "現在日時情報 曜日月(英語):\t\t%s", timebuf );
 +
 +
 +
    //_gmtime64_s関数は第一引数のtm型構造体に第二引数で取得したUTC秒数情報からグリニッジ平均時Greenwich Mean Timeすなわち協定世界時を生成する関数。
 +
//※GMTが天体観測によって管理される時間で1秒の長さが微変動するもの、UTCは原子時計でGMTの情報をもとにうるう秒を入れたりして調整が入る。
 +
    err = _gmtime64_s( &gmt, &ltime );
 +
    if (err)
 +
    {
 +
      printf("_gmtime64_s failed due to an invalid argument.");
 +
    }
 +
//asctime_sは第三引数のtm型構造体に格納された情報から第一引数の文字列ポインタへ生成する関数。
 +
    err = asctime_s(timebuf, 26, &gmt);
 +
    if (err)
 +
    {
 +
      printf("asctime_s failed due to an invalid argument.");
 +
      exit(1);
 +
    }
 +
    printf( "協定世界時 UTC:\t\t\t\t%s", timebuf );
 +
 +
    //_localtime64_sはtime_t型UTC秒数情報から第一引数のtm型構造体に現在のタイムゾーンの時刻を設定する関数。
 +
    err = _localtime64_s( &today, &ltime );
 +
    if (err)
 +
    {
 +
      printf("_localtime64_s failed due to an invalid argument.");
 +
      exit(1);
 +
    }
 +
//tm構造体のtoday変数の24時間形式を格納するメンバ変数tm_hourの値が12以上なら午後なので、午前午後情報格納文字列の内容をPMに。
 +
    if( today.tm_hour >= 12 )
 +
    {
 +
        strcpy_s( ampm, sizeof(ampm), "PM" );
 +
        today.tm_hour -= 12;//午後で表現するので、12を引いた。但し、この後tm構造体変数として違う関数への引数とかにすると時間が12時間前になるので用途に注意。
 +
    }
 +
 +
    err = asctime_s(timebuf, 26, &today);
 +
    if (err)
 +
    {
 +
      printf("asctime_s failed due to an invalid argument.");
 +
      exit(1);
 +
    }
 +
 +
//timebufの12文字目から8文字が時間なので、その部分だけを出力し、ampmの情報を付加する。
 +
    printf( "12時間表記 時間:\t\t\t%.8s %s\n", timebuf + 11, ampm);
 +
 +
 +
    //_timeb64構造体に取得したタイムゾーン現在時刻のメンバ変数出力
 +
    printf( "現在時刻のミリ秒:\t\t\t%03u[ミリ秒]\n", structtimebTime.millitm );
 +
    printf( "協定世界時とタイムゾーン時刻の差:\t%d\n", structtimebTime.timezone / 60 );
 +
 +
size_t* pReturnValue = new size_t;
 +
int index = structtimebTime.dstflag;
 +
 +
//タイムゾーン名の文字列長をpReturnValueに取得
 +
_get_tzname(pReturnValue, NULL, 0, index);
 +
 +
char* timeZoneName = new char[*pReturnValue + 1];
 +
size_t sizeInBytes = *pReturnValue + 1;
 +
 +
//タイムゾーン名の取得
 +
_get_tzname(pReturnValue, timeZoneName, sizeInBytes, index);
 +
 +
printf( "タイムゾーン名:\t\t\t\t%s\n", timeZoneName );
 +
    printf( "タイムゾーン名文字数:\t\t\t%d[byte]\n", *pReturnValue );
 +
    printf( "夏時間適用フラグ:\t\t\t%s\n", structtimebTime.dstflag ? "夏時間" : "夏時間非適用" );
 +
 +
    //mktime関数は初期値が与えられているtm型構造体の情報から日時情報を生成し、他のメンバ変数の設定を行う関数
 +
    if(mktime(&xmas) != (time_t)-1)
 +
    {
 +
      err = asctime_s(timebuf, 26, &xmas);
 +
      if (err)
 +
      {
 +
          printf("asctime_s failed due to an invalid argument.");
 +
          exit(1);
 +
      }
 +
      printf( "指定日付\t\t\t\t%s\n", timebuf );
 +
    }
 +
 +
    err = _localtime64_s( &today, &ltime );
 +
    if (err)
 +
    {
 +
        printf(" _localtime64_s failed due to invalid arguments.");
 +
        exit(1);
 +
    }
 +
 +
    //★時間変数を文字列に変換する関数 strftime 
 +
    *pReturnValue = strftime( tmpbuf, 128, "Today is %A, day %d of %B in the year %Y.\n", &today );
 +
printf("%d[byte]\n",* pReturnValue);
 +
//英語表記の曜日、月名が取得できる。
 +
strftime( tmpbuf, 128, "Today is %A, day %d of %B in the year %Y.\n", &today );
 +
    printf( tmpbuf );
 +
 +
*pReturnValue = _strftime_l(tmpbuf, 128, "今日は(%y年)%Y年%B(%b月)%d日(%A:%a;%w番目の曜日 %W回目の%A) %U週目 %j日目 現在時刻は(%p %I)%H:%M:%S\n", &today, localeJpanease );
 +
printf("%d[byte]\n",* pReturnValue);
 +
//ロケール設定により日本語表記の曜日、月名が取得できる。
 +
_strftime_l(tmpbuf, 128, "今日は(%y年)%Y年%B(%b月)%d日(%A:%a;%w番目の曜日 %W回目の%A) %U週目 %j日目 現在時刻は(%p %I)%H:%M:%S\n", &today, localeJpanease );
 +
    printf( tmpbuf );
 +
 +
*pReturnValue = _strftime_l(tmpbuf, 128, "%#c,%#x,%%,%#S,%#a,%#%,%z,%Z\n", &today, localeJpanease );
 +
printf("%d[byte]\n",* pReturnValue);
 +
//ロケール設定により日本語表記の曜日、月名が取得できる。
 +
_strftime_l(tmpbuf, 128, "%#c,%#x,%%,%#S,%#a,%#%,%z,%Z\n", &today, localeJpanease );
 +
    printf( tmpbuf );
 +
  return 0;
 +
}
 +
</syntaxhighlight2>
 +
 +
 +
出力結果
 +
OS 時間:                                20:18:03
 +
OS 日付:                                10/13/14
 +
秒数による日時情報 1970年1月1日基準:    1413199083
 +
現在日時情報 曜日月(英語):              Mon Oct 13 20:18:03 2014
 +
協定世界時 UTC:                        Mon Oct 13 11:18:03 2014
 +
12時間表記 時間:                        08:18:03 PM
 +
現在時刻のミリ秒:                      006[ミリ秒]
 +
協定世界時とタイムゾーン時刻の差:      -9
 +
タイムゾーン名:                        東京 (標準時)
 +
タイムゾーン名文字数:                  14[byte]
 +
夏時間適用フラグ:                      夏時間非適用
 +
指定日付                                Sat Dec 25 12:00:00 1993
 +
 +
53[byte]
 +
Today is Monday, day 13 of October in the year 2014.
 +
80[byte]
 +
今日は(14年)2014年10月(10月)13日(月曜日:月;1番目の曜日 41回目の月曜日) 41週目 286日目 現在時刻は(午後 08)20:18:03
 +
59[byte]
 +
2014年10月13日 20:18:03,2014年10月13日,,3,月,,東京 (標準時),東京 (標準時)
 +
 +
と上記のように時間の表記を文字列に変換できます。ICUによる変換は時間があれば、サンプルを作成したいと思います。
 +
 +
 +
それでICUによる時間の文字列化ですが、
 +
サンプルは以下にしめすような感じです。UCalendarというクラスとCalendar+SimpleFormatクラスの2通りがありまして、UCalendarの方はちょっと使いにくそうでした。あとは、タイムゾーンの対応がものすごくて、びっくりします。言語別にUnicodeで表記が出来ます。でも言語別を指定するためのキーワードを知るのが大変で、カレンダーのロケールについては、詳細な一覧方法は提供されていないようにも思います。オーソドックスなロケールは一覧できますが、これでは不十分でして、一番詳しいのは、英語のページになりますが、http://www.unicode.org/reports/tr35/ のサイトになります。長すぎる。日本語のロケールについては、"ja","ja-JP"の基本的な二つに加えてカレンダー用のロケールとして"ja_JP_TRADITIONAL","ja_JP@calendar=japanese"があり、こちらのロケールを使うと公年号(645年の大化から始まって明治 大正 昭和 平成)を使った表現に対応できます。他にも"ja"と同じですが、"japanese"や"jpn"でも良さそうでした。jpnはISO3表記ってことになるのでしょうか?難しいです。これが世界684の地域と620のタイムゾーンにわたって定義されているのでしょうから、なんつうか、やっぱ戦争でもして世界征服して一つの国になったほうがよかったんじゃないのかって思うくらい言語は分かれています。いや冗談冗談。戦争は駄目ですよ。不謹慎な冗談はやめた方がいいか…何の得にもならんしね。こうやって、全く面白くもないのに、おもしろいとおもって書いたことをつつかれて、社会的に抹殺されていくんだろうなぁ。有名人は大変だねぇ。あり得ない発言はだめなんですもんね。わけわからんことを言うと影響力ありますからね。そりゃ世間から指摘されますよね。全く思ってもないようなことを言うのだめだわな。
 +
 +
 +
まずは、UCalendarを使ったサンプル。
 +
<syntaxhighlight2 lang="cpp" line start="1">
 +
#pragma once
 +
#include "stdafx.h"
 +
#include <stdlib.h>
 +
#include <string>      //std::string型定義
 +
#include <mbstring.h> //mbs***関数
 +
#include <iostream>    //cpp cout etc 一般入出力関数
 +
#include <locale>      //Locale関数
 +
#include <tchar.h>    //TCHAR型+_tcs***関数
 +
#include "atlstr.h"    //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ
 +
#include "atlbase.h"  //同上
 +
#include "cstringt.h"  //CStringTの定義プリプロセッサ
 +
#include <vector>      //Vector型テンプレートクラス
 +
 +
#include <sys/timeb.h> //Timeb型構造体
 +
 +
//_bstr_t型を利用するプリプロセッサ(ライブラリはデバッグモードとリリースモード個別設定)
 +
#include "comutil.h"
 +
 +
#ifdef _DEBUG
 +
#pragma comment(lib, "comsuppwd.lib")
 +
#else
 +
#pragma comment(lib, "comsuppw.lib")
 +
#endif
 +
//_bstr_t _End
 +
 +
//ICU ucnvプリプロセッサ(ライブラリはデバッグモードとリリースモード個別設定)
 +
#include <unicode/ucnv.h>    //ucnv文字コード変換ライブラリヘッダ
 +
#include <unicode/translit.h> //文字変換ライブラリヘッダ
 +
#include <unicode/regex.h>    //正規表現
 +
#include <unicode/ucsdet.h>  //文字コード判定
 +
#include <unicode/ucal.h>  //文字コード判定
 +
#include <unicode/uclean.h> //u_cleanup関数
 +
/* for uloc_getDefault() */
 +
#include <unicode/uloc.h>
 +
#include <unicode/calendar.h>
 +
#include <unicode/smpdtfmt.h>
 +
 +
//#include "unicode/utypes.h"
 +
//#include "unicode/locid.h"
 +
//#include "unicode/unistr.h"
 +
//#include "unicode/tzfmt.h"
 +
//#include "unicode/tznames.h"
 +
 +
 +
#ifdef _DEBUG
 +
#pragma comment(lib, "icudt.lib")
 +
#pragma comment(lib, "icuucd.lib")  //ICU ucnvを使うために必要なライブラリ
 +
#pragma comment(lib, "icuind.lib")  //ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も
 +
#pragma comment(lib, "iculed.lib")
 +
#pragma comment(lib, "iculxd.lib") 
 +
#pragma comment(lib, "icuiod.lib") 
 +
#pragma comment(lib, "icutud.lib") 
 +
 +
#else
 +
//#pragma comment(lib, "icudt.lib")
 +
#pragma comment(lib, "icuind.lib")  //ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も
 +
#pragma comment(lib, "icuuc.lib")  //ICU ucnvを使うために必要なライブラリ
 +
//#pragma comment(lib, "icuio.lib")
 +
#endif
 +
//Data  Library                    icudtXX(d).dll icudt(d).lib
 +
//Common Library                    icuucXX(d).dll icuuc(d).lib
 +
//Internationalization(i18n) Library icuinXX(d).dll icuin(d).lib
 +
//Layout Engine                      iculeXX(d).dll icule(d).lib
 +
//Layout Extention Engine            iculxXX(d).dll iculx(d).lib
 +
//ICU I/O(Unicode stdio) Library    icuioXX(d).dll icuio(d).lib
 +
//Tool Utility Library              icutuXX(d).dll icutu(d).lib
 +
 +
//ICU ucnv _End
 +
 +
#include "UnicodeConverter.h"
 +
 +
using namespace std;
 +
 +
int _tmain(int argc, _TCHAR* argv[])
 +
{
 +
  _tsetlocale(LC_ALL, _T("Japanese")); //ロケールセットすると_l関数でロケール指定しなくても日本語が使われます。
 +
 +
  _locale_t localeJpanease;
 +
  localeJpanease = _create_locale(LC_ALL, "Japanese");
 +
 +
  int32_t int32TimeZoneID;
 +
  UChar* pucharResult = new UChar[1024];
 +
 +
  UErrorCode err = U_ZERO_ERROR;
 +
  printf("%s\n",uloc_getDefault());
 +
  UCalendar* cal = ucal_open(
 +
          L"Asia/Tokyo", 10, //TimezoneID と文字数
 +
          uloc_getDefault(), //Locale名 "ja_JP"
 +
          UCAL_TRADITIONAL,  //カレンダータイプ
 +
          &err);
 +
  printf("errorNum?->%d\n",err);
 +
  if (!cal)
 +
  {
 +
    err = U_ZERO_ERROR;
 +
    fprintf(stderr, "ICU error: %s\n", u_errorName(err));
 +
    u_cleanup();
 +
    return ;
 +
  }
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 +
  //★ここからしばらくは日付表示とは関係の無い、余計なプログラム
 +
 +
  //属性値取得関数 最初の曜日の番号は1
 +
  printf("★現在のオープンしているZoneIDの各種属性値を取得する関数。\n");
 +
  printf("Attrbute->%d\n", ucal_getAttribute(cal, UCAL_FIRST_DAY_OF_WEEK));
 +
  printf("\n");
 +
 +
 +
  //ゾーンIDを取得する関数。もちろんAsia/Tokyo。
 +
  printf("★現在のオープンしているZoneIDのTimeZoneIDをUchar型変数に取得し、その文字数を返す関数\n");
 +
  err = U_ZERO_ERROR;
 +
  int32TimeZoneID = ucal_getTimeZoneID(cal, pucharResult, 1024, &err);
 +
  wprintf(L"TimezoneID->%d[Byte]:%s\n",int32TimeZoneID,pucharResult);//10:Asia/Tokyo
 +
  printf("\n");
 +
 +
 +
  //タイプによるロケール名を取得。
 +
  //ULOC_ACTUAL_LOCALE->ja
 +
  //ULOC_VALID_LOCALE->ja_JP
 +
  //ULOC_REQUESTED_LOCALE->NULL
 +
  printf("★現在のオープンしているZoneIDのULocDataLocaleTypeによる名前を取得。\n");
 +
  err = U_ZERO_ERROR;
 +
  printf("TypeLocale->%s\n", ucal_getLocaleByType(cal, ULOC_VALID_LOCALE, &err));
 +
  printf("\n");
 +
 
 +
  //★ここまでが、かなり余計なプログラムでした。
 +
  //★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 +
 +
  //日付をセットする。
 +
  err = U_ZERO_ERROR;
 +
  ucal_setDateTime(cal, 2014, UCAL_OCTOBER, 17, 22, 45, 00, &err);//直接指定。
 +
  ucal_setMillis(cal, ucal_getNow(), &err);//現在日時での指定で上書き。ミリ秒単位で表現されるダブル型の数値。
 +
  //関数名がミリ秒だけを扱うみたいに見えるけど、これで日付時刻ミリ秒まで全部セットされる。
 +
 
 +
 +
 +
  //特定のフィールドの制限値取得 月の最大。11でした。年の最大は144683です。14万年…
 +
  printf("★現在のオープンしているZoneIDの各種フィールド制限値の取得関数\n");
 +
  int32_t int32TempLimitValue;
 +
  err = U_ZERO_ERROR;
 +
  int32TempLimitValue = ucal_getLimit(cal,UCAL_MILLISECOND,UCAL_MINIMUM, &err);
 +
  printf("Limit->%d\n",int32TempLimitValue);
 +
  printf("\n");
 +
 +
  //特定のフィールドのロール 時間を追加したりできる。3週間追加する例。コメント化してますけど。
 +
  printf("★現在のオープンしているZoneIDの各種フィールドロール関数\n");
 +
  int32_t int32Amount = 3;
 +
  err = U_ZERO_ERROR;
 +
  //ucal_roll(cal, UCAL_WEEK_OF_YEAR, int32Amount,&err);
 +
  printf("Limit->%d\n",int32Amount);
 +
  printf("\n");
 +
 +
  err = U_ZERO_ERROR;
 +
  UDate udateGetMillis;
 +
  err = U_ZERO_ERROR;
 +
  udateGetMillis = ucal_getMillis(cal, &err);
 +
  printf("★現在のオープンしているZoneIDのミリ秒を取得。\n");
 +
  err = U_ZERO_ERROR;
 +
  printf("GetMilli->%f %f %f\n", udateGetMillis , ucal_getNow(), ucal_getGregorianChange(cal, &err));
 +
  printf("\n");
 +
 
 +
  //日時の出力
 +
  printf("Date->%d/%d/%d\n",
 +
          ucal_get(cal, UCAL_YEAR, &err),
 +
          ucal_get(cal, UCAL_MONTH, &err) + 1,
 +
          ucal_get(cal, UCAL_DATE, &err));
 +
 +
  printf("Time->%d:%d:%d:%d\n",
 +
          ucal_get(cal, UCAL_HOUR_OF_DAY, &err),
 +
          ucal_get(cal, UCAL_MINUTE, &err) + 1,
 +
          ucal_get(cal, UCAL_SECOND, &err),
 +
          ucal_get(cal, UCAL_MILLISECOND, &err));
 +
 +
  printf("Othr->%d:%d:%d:%d\n",
 +
          ucal_get(cal, UCAL_DAY_OF_WEEK, &err),
 +
          ucal_get(cal, UCAL_AM_PM, &err) ,
 +
          ucal_get(cal, UCAL_ZONE_OFFSET, &err),
 +
          ucal_get(cal, UCAL_DST_OFFSET, &err));
 +
 +
  ucal_close(cal);
 +
  u_cleanup();
 +
  return 0;
 +
}
 +
</syntaxhighlight2>
 +
出力 大体こんな感じ
 +
<syntaxhighlight2 lang="text">
 +
★現在のオープンしているZoneIDの各種属性値を取得する関数。
 +
Attrbute->1
 +
 +
★現在のオープンしているZoneIDのTimeZoneIDをUchar型変数に取得し、その文字数を返す関数
 +
TimezoneID->10[Byte]:Asia/Tokyo
 +
 +
★現在のオープンしているZoneIDのULocDataLocaleTypeによる名前を取得。
 +
TypeLocale->ja_JP
 +
 +
★現在のオープンしているZoneIDの各種フィールド制限値の取得関数
 +
Limit->0
 +
 +
★現在のオープンしているZoneIDの各種フィールドロール関数
 +
Limit->3
 +
 +
★現在のオープンしているZoneIDのミリ秒を取得。
 +
GetMilli->1413654266519.000000 1413654266529.000000 -12219292800000.000000
 +
 +
Date->2014/10/19
 +
Time->2:45:26:519
 +
Othr->1:0:32400000:0
 +
</syntaxhighlight2>
 +
そして、Calendar+SimpleFormatクラスを使うサンプルは以下のような感じ。上記のプログラムの続きなので、インクルードとか飛ばします。
 +
<syntaxhighlight2 lang="cpp" line start="1">
 +
  UErrorCode status = U_ZERO_ERROR;
 +
  //Calendar *cals = Calendar::createInstance(status);//日本語カレンダーロケールは ja_JP@calendar=japanese ja_JP_TRADITIONAL ja_JP ja japaneseが指定可能
 +
  Calendar *cals = Calendar::createInstance("ja_JP@calendar=japanese", status);
 +
  SimpleDateFormat *fmt = new SimpleDateFormat(UnicodeString("SSS S U Q q W w e F D zzzz zzz zz z EEE EE E YYYY YYY YY Y yyyy yyy yy v GG G y.M.d vv HH:mm:ss vvvv K:mm a vvv hh:mm h:m KK:mm  H:m aaa yyyyy.MM.dd GGG"), status);
 +
  //SimpleDateFormat ★ja_JP(引数無し) ☆ja_JP_TRADITIONAL 1988年基準 年引数が1なら1989年で公元号1年 公元号名は表示されない。
 +
  //z    タイムゾーン名(★GMT+09:18:59 ☆JST)
 +
  //zz  タイムゾーン  (★GMT+09:18:59 ☆JST)
 +
  //zzz  タイムゾーン  (★GMT+09:18:59 ☆JST)
 +
  //zzzz タイムゾーン年-タイムゾーン名(★2014-GMT+09:18:59 ☆2014-日本標準時)
 +
  //v   タイムゾーン年-タイムゾーン名(★2014-日本時間 ☆2014-JST)
 +
  //vv  タイムゾーン  (★表記無し)
 +
  //vvv タイムゾーン  (★表記無し)
 +
  //vvvv タイムゾーン名(★日本時間 ☆日本標準時)
 +
  //G    グレゴリオ暦年-歴名(★2014-西暦 ☆平成)
 +
  //GG  グレゴリオ暦名(年数値無し★西暦 ☆平成)
 +
  //GGG  グレゴリオ暦名(年数値無し★西暦 ☆平成)
 +
  //YYYY グレゴリオ暦年-公元号年(★2014-0026 ☆2014-2014)
 +
  //YYY  公元号年orグレゴリオ暦年(3桁表現最小表現 0埋め★026 ☆2014)
 +
  //YY  公元号年orグレゴリオ暦年(2桁表現固定0埋め★26 ☆14)
 +
  //Y    公元号年orグレゴリオ暦年(最小文字列★26 ☆2014)
 +
  //yyyyy公元号年5桁数値のみ(0埋め)
 +
  //yyyy 公元号年4桁数値のみ(0埋め)
 +
  //yyy  公元号年3桁数値のみ(0埋め)
 +
  //yy  公元号年2桁数値のみ(0埋め)
 +
  //y    公元号年数値のみ
 +
  //M    数値表現の月(最小文字列)※小文字だと時間の分
 +
  //MM  数値表現の月(2桁表現)※小文字だと時間の分
 +
  //MMMMM数値表現の月(最小文字列)※小文字だと時間の分
 +
  //d    数値表現の日(最小文字列)
 +
  //dd  数値表現の日(2桁表現)
 +
  //EEE  曜日(★土 1日前の曜日 ☆日)
 +
  //EE  曜日(★土 1日前の曜日 ☆日)
 +
  //E    曜日(★土 1日前の曜日 ☆日)
 +
  //a  午前・午後表記(漢字日本語★午前)
 +
  //K    数値表現の時間(0時は0のまま 最小文字列)
 +
  //KK  数値表現の時間(0時は0のまま 2桁表現0埋め)
 +
  //H    数値表現の時間(24時間制 0時は0のまま 最小文字列)
 +
  //HH  数値表現の時間(24時間制 0時は0のまま 2桁表現0埋め)
 +
  //h    数値表現の時間(0時は12時 最小文字列)
 +
  //hh  数値表現の時間(0時は12時 2桁表現0埋め)
 +
  //m    数値用言の分(最小文字列)※大文字だと日付の月
 +
  //mm  数値用言の分(2桁表現0埋め)※大文字だと日付の月
 +
  //s    数値表現の秒(最小文字列)
 +
  //ss  数値表現の秒(2桁表現0埋め)
 +
  //その他
 +
  //S    ミリ秒
 +
  //u    extended年
 +
  //Q    四半期 テキスト&番号
 +
  //q
 +
  //w    週目 通年
 +
  //W    週目 月
 +
  //D    日目 通年   
 +
  //e    曜日番号
 +
  //F    何回目の曜日 月 
 +
  //
 +
 +
  fmt->adoptCalendar(cals);//フォーマットにカレンダーを設定。
 +
  for(int k=2014;k<2015;k++){
 +
    cals->set(k - 1988 , 10 - 1, 17, 14, 0, 0);//カレンダーの日付を数値で設定する方法 ja_JP_TRADITIONAは1988年基準 昭和元年が1989年
 +
    UDate now = cals->getTime(status);//nowに現在時間を取得。UDateはDouble型と同じです。
 +
    UnicodeString buf;
 +
    fmt->format(now, buf);//UnicodeString型のbufの内容をnowに設定されている時間を文字列にしたものに変換。変換は指定されているフォーマットの形式。
 +
    char* dst = new char[256];
 +
    std::string conv(buf.extract(0, buf.length(), 0, "shift_jis"), '\0');//string型convをbufの文字列のShiftJIS形式長さ分確保 初期値は\0で埋める
 +
    //UnicodeStringのextractはbufの中身を(第一引数 =0)文字目から、(第二引数 =buf.length())文字目までを第四引数にしていされた文字コードの型に変換して第三引数の変数に格納する関数
 +
    //変換先が指定されていない場合でも変換後の文字サイズが返却されます。ここでは文字サイズを取得してconvを初期化しています。
 +
    buf.extract(0, buf.length(), &conv[0], "shift_jis");//ここでconvに実際に変換後の文字を格納。
 +
    memcpy(dst, conv.c_str(), conv.size());//convの内容をchar型dstにコピー
 +
    printf("%d-%s ", k, conv.c_str());//convの内容を出力。
 +
    delete dst;
 +
  }
 +
  delete fmt;
 +
</syntaxhighlight2>
 +
出力 いろんな種類の出力をがっつり記述したので、わけわからないことになってますが
 +
<syntaxhighlight2 lang="text">
 +
2014-274 2 26 4 4 3 42 6 3 290 日本標準時 JST JST JST 金 金 金 2014 2014 14 2014 0026 026 26 JST 平成 平成 26.10.17  14:00:00 日本標準時 2:00 午後  02:00 2:0 02:00  14:0 午後 00026.10.17 平成
 +
</syntaxhighlight2>
 +
あとのほうのプログラムの方がタイムゾーン名を各国語で表示できる分、国際化には向いているかもしれませんが、そんなプログラム組む人いるのかなぁ。
 +
ロケール名一覧は後で示す日本語タイムゾーンの各ロケールごとの表示一覧に、タイムゾーン名一覧は各タイムゾーンの日本語表記一覧に記載しました。
 +
 +
 +
 +
UCalendarクラスやCalendarクラスの使い方はICUのサイトを確認して下さい。なんやかんやで長い記事になっているせいで忘れられているかもしれませんが、ここでは文字列操作に関する情報を中心に扱っています。ちなみにICUのサイトを見てもクラス仕様書がきっちりのっているものの個別の関数の具体的な使い方についてはあまり触れられていません。関数名と機能から、あぁこういう風に使って欲しいんだなっていうのを感じ取るスキルが求められます。なので自分もカレンダーのロケール名指定方法の詳細な一覧は入手できませんでした。もしわかった人がいたら、各自のブログやWikiで情報を発信して下さい。よろしくお願いします。たぶんICUをここまで掘り下げて使っている人はいないはず。上記に記述した各タイムゾーンやロケールの一覧を取得するにはStringEnumerationやUEnumerationクラスの使い方を理解したり、Locale、Timezoneクラスの構造を理解することが求められると思います。頑張ってください。
 +
 +
 +
それから、年号なんですけどサンプルプログラムのFor文では2014年だけの一回のループになってますが、ちょこっと変えて645年からにすると、まぁ素敵なほどに年号を羅列してくれます。他にも、日本のタイムゾーンが各国でどのように表示されているのか、あるいは、タイムゾーンがどれほどあるのかを一覧した、日本目線の一覧を貼っておきます。ICUは文字列操作の処理範囲をここまで広くかんがえているんだなあと考えさせられます。一種のデータベースと言えるかもしれません。うすっぺらな自分では調べきることは困難な範囲です。日本のことですらあまりわかっていないし…
 +
 +
 +
プログラムでUNICODE文字を出力してますが、コンソール表示のときにはSJISに変換されるため、SJISで表現できない文字は文字化け?というか変換先がないため正しく表示されません。正しく表示させたい場合は先の項目で説明したとおり、ファイル入出力をつかってUNICODE形式でテキストファイルに出力するといいです。Unicode対応のメモ帳で閲覧できます。Terapadは無理。自分は今回の機会にサクラエディタを導入しました。Unicodeも対応している優秀なエディタであることに気付かされました。UNICODEフォントですが、Windows標準のフォントファイルは実はUnicodeフォントになっています。すごいです。
 +
 +
年号サンプル <syntaxhighlight2 lang="text">
 +
645-大化1:646-大化2:647-大化3:648-大化4:649-大化5:650-白雉1:651-白雉2:652-白雉3:653-白雉4:654-白雉5:655-白雉6:656-白雉7:657-白雉8:658-白雉9:659-白雉10:660-白雉11:661-白雉12:662-白雉13:663-白雉14:664-白雉15:665-白雉16:666-白雉17:667-白雉18:668-白雉19:669-白雉20:670-白雉21:671-白雉22:672-白鳳1:673-白鳳2:674-白鳳3:675-白鳳4:676-白鳳5:677-白鳳6:678-白鳳7:679-白鳳8:680-白鳳9:681-白鳳10:682-白鳳11:683-白鳳12:684-白鳳13:685-白鳳14:686-朱鳥1:687-朱鳥2:688-朱鳥3:689-朱鳥4:690-朱鳥5:691-朱鳥6:692-朱鳥7:693-朱鳥8:694-朱鳥9:695-朱鳥10:696-朱鳥11:697-朱鳥12:698-朱鳥13:699-朱鳥14:700-朱鳥15:701-大宝1:702-大宝2:703-大宝3:704-慶雲1:705-慶雲2:706-慶雲3:707-慶雲4:708-和銅1:709-和銅2:710-和銅3:711-和銅4:712-和銅5:713-和銅6:714-和銅7:715-霊亀1:716-霊亀2:717-霊亀3:718-養老2:719-養老3:720-養老4:721-養老5:722-養老6:723-養老7:724-神亀1:725-神亀2:726-神亀3:727-神亀4:728-神亀5:729-天平1:730-天平2:731-天平3:732-天平4:733-天平5:734-天平6:735-天平7:736-天平8:737-天平9:738-天平10:739-天平11:740-天平12:741-天平13:742-天平14:743-天平15:744-天平16:745-天平17:746-天平18:747-天平19:748-天平20:749-天平勝宝1:750-天平勝宝2:751-天平勝宝3:752-天平勝宝4:753-天平勝宝5:754-天平勝宝6:755-天平勝宝7:756-天平勝宝8:757-天平宝字1:758-天平宝字2:759-天平宝字3:760-天平宝字4:761-天平宝字5:762-天平宝字6:763-天平宝字7:764-天平宝字8:765-天平神護1:766-天平神護2:767-神護景雲1:768-神護景雲2:769-神護景雲3:770-宝亀1:771-宝亀2:772-宝亀3:773-宝亀4:774-宝亀5:775-宝亀6:776-宝亀7:777-宝亀8:778-宝亀9:779-宝亀10:780-宝亀11:781-天応1:782-延暦1:783-延暦2:784-延暦3:785-延暦4:786-延暦5:787-延暦6:788-延暦7:789-延暦8:790-延暦9:791-延暦10:792-延暦11:793-延暦12:794-延暦13:795-延暦14:796-延暦15:797-延暦16:798-延暦17:799-延暦18:800-延暦19:801-延暦20:802-延暦21:803-延暦22:804-延暦23:805-延暦24:806-大同1:807-大同2:808-大同3:809-大同4:810-弘仁1:811-弘仁2:812-弘仁3:813-弘仁4:814-弘仁5:815-弘仁6:816-弘仁7:817-弘仁8:818-弘仁9:819-弘仁10:820-弘仁11:821-弘仁12:822-弘仁13:823-弘仁14:824-天長1:825-天長2:826-天長3:827-天長4:828-天長5:829-天長6:830-天長7:831-天長8:832-天長9:833-天長10:834-承和1:835-承和2:836-承和3:837-承和4:838-承和5:839-承和6:840-承和7:841-承和8:842-承和9:843-承和10:844-承和11:845-承和12:846-承和13:847-承和14:848-嘉祥1:849-嘉祥2:850-嘉祥3:851-仁寿1:852-仁寿2:853-仁寿3:854-仁寿4:855-斉衡2:856-斉衡3:857-天安1:858-天安2:859-貞観1:860-貞観2:861-貞観3:862-貞観4:863-貞観5:864-貞観6:865-貞観7:866-貞観8:867-貞観9:868-貞観10:869-貞観11:870-貞観12:871-貞観13:872-貞観14:873-貞観15:874-貞観16:875-貞観17:876-貞観18:877-元慶1:878-元慶2:879-元慶3:880-元慶4:881-元慶5:882-元慶6:883-元慶7:884-元慶8:885-仁和1:886-仁和2:887-仁和3:888-仁和4:889-寛平1:890-寛平2:891-寛平3:892-寛平4:893-寛平5:894-寛平6:895-寛平7:896-寛平8:897-寛平9:898-昌泰1:899-昌泰2:900-昌泰3:901-延喜1:902-延喜2:903-延喜3:904-延喜4:905-延喜5:906-延喜6:907-延喜7:908-延喜8:909-延喜9:910-延喜10:911-延喜11:912-延喜12:913-延喜13:914-延喜14:915-延喜15:916-延喜16:917-延喜17:918-延喜18:919-延喜19:920-延喜20:921-延喜21:922-延喜22:923-延長1:924-延長2:925-延長3:926-延長4:927-延長5:928-延長6:929-延長7:930-延長8:931-承平1:932-承平2:933-承平3:934-承平4:935-承平5:936-承平6:937-承平7:938-天慶1:939-天慶2:940-天慶3:941-天慶4:942-天慶5:943-天慶6:944-天慶7:945-天慶8:946-天慶9:947-天暦1:948-天暦2:949-天暦3:950-天暦4:951-天暦5:952-天暦6:953-天暦7:954-天暦8:955-天暦9:956-天暦10:957-天暦11:958-天徳2:959-天徳3:960-天徳4:961-応和1:962-応和2:963-応和3:964-康保1:965-康保2:966-康保3:967-康保4:968-安和1:969-安和2:970-天禄1:971-天禄2:972-天禄3:973-天禄4:974-天延2:975-天延3:976-貞元1:977-貞元2:978-貞元3:979-天元2:980-天元3:981-天元4:982-天元5:983-永観1:984-永観2:985-寛和1:986-寛和2:987-永延1:988-永延2:989-永祚1:990-永祚2:991-正暦2:992-正暦3:993-正暦4:994-正暦5:995-長徳1:996-長徳2:997-長徳3:998-長徳4:999-長保1:1000-長保2:1001-長保3:1002-長保4:1003-長保5:1004-寛弘1:1005-寛弘2:1006-寛弘3:1007-寛弘4:1008-寛弘5:1009-寛弘6:1010-寛弘7:1011-寛弘8:1012-寛弘9:1013-長和2:1014-長和3:1015-長和4:1016-長和5:1017-寛仁1:1018-寛仁2:1019-寛仁3:1020-寛仁4:1021-治安1:1022-治安2:1023-治安3:1024-万寿1:1025-万寿2:1026-万寿3:1027-万寿4:1028-長元1:1029-長元2:1030-長元3:1031-長元4:1032-長元5:1033-長元6:1034-長元7:1035-長元8:1036-長元9:1037-長暦1:1038-長暦2:1039-長暦3:1040-長暦4:1041-長久2:1042-長久3:1043-長久4:1044-長久5:1045-寛徳2:1046-永承1:1047-永承2:1048-永承3:1049-永承4:1050-永承5:1051-永承6:1052-永承7:1053-天喜1:1054-天喜2:1055-天喜3:1056-天喜4:1057-天喜5:1058-康平1:1059-康平2:1060-康平3:1061-康平4:1062-康平5:1063-康平6:1064-康平7:1065-治暦1:1066-治暦2:1067-治暦3:1068-治暦4:1069-延久1:1070-延久2:1071-延久3:1072-延久4:1073-延久5:1074-承保1:1075-承保2:1076-承保3:1077-承保4:1078-承暦2:1079-承暦3:1080-承暦4:1081-永保1:1082-永保2:1083-永保3:1084-応徳1:1085-応徳2:1086-応徳3:1087-寛治1:1088-寛治2:1089-寛治3:1090-寛治4:1091-寛治5:1092-寛治6:1093-寛治7:1094-寛治8:1095-嘉保2:1096-嘉保3:1097-永長2:1098-承徳2:1099-康和1:1100-康和2:1101-康和3:1102-康和4:1103-康和5:1104-長治1:1105-長治2:1106-嘉承1:1107-嘉承2:1108-天仁1:1109-天仁2:1110-天永1:1111-天永2:1112-天永3:1113-永久1:1114-永久2:1115-永久3:1116-永久4:1117-永久5:1118-元永1:1119-元永2:1120-保安1:1121-保安2:1122-保安3:1123-保安4:1124-天治1:1125-天治2:1126-大治1:1127-大治2:1128-大治3:1129-大治4:1130-大治5:1131-天承1:1132-長承1:1133-長承2:1134-長承3:1135-保延1:1136-保延2:1137-保延3:1138-保延4:1139-保延5:1140-保延6:1141-永治1:1142-康治1:1143-康治2:1144-天養1:1145-久安1:1146-久安2:1147-久安3:1148-久安4:1149-久安5:1150-久安6:1151-仁平1:1152-仁平2:1153-仁平3:1154-仁平4:1155-久寿2:1156-保元1:1157-保元2:1158-保元3:1159-平治1:1160-永暦1:1161-応保1:1162-応保2:1163-長寛1:1164-長寛2:1165-永万1:1166-仁安1:1167-仁安2:1168-仁安3:1169-嘉応1:1170-嘉応2:1171-承安1:1172-承安2:1173-承安3:1174-承安4:1175-安元1:1176-安元2:1177-治承1:1178-治承2:1179-治承3:1180-治承4:1181-養和1:1182-寿永1:1183-寿永2:1184-元暦1:1185-文治1:1186-文治2:1187-文治3:1188-文治4:1189-文治5:1190-建久1:1191-建久2:1192-建久3:1193-建久4:1194-建久5:1195-建久6:1196-建久7:1197-建久8:1198-建久9:1199-正治1:1200-正治2:1201-建仁1:1202-建仁2:1203-建仁3:1204-元久1:1205-元久2:1206-建永1:1207-建永2:1208-承元2:1209-承元3:1210-承元4:1211-建暦1:1212-建暦2:1213-建暦3:1214-建保2:1215-建保3:1216-建保4:1217-建保5:1218-建保6:1219-承久1:1220-承久2:1221-承久3:1222-貞応1:1223-貞応2:1224-貞応3:1225-嘉禄1:1226-嘉禄2:1227-嘉禄3:1228-安貞2:1229-寛喜1:1230-寛喜2:1231-寛喜3:1232-貞永1:1233-天福1:1234-天福2:1235-嘉禎1:1236-嘉禎2:1237-嘉禎3:1238-嘉禎4:1239-延応1:1240-仁治1:1241-仁治2:1242-仁治3:1243-寛元1:1244-寛元2:1245-寛元3:1246-寛元4:1247-宝治1:1248-宝治2:1249-建長1:1250-建長2:1251-建長3:1252-建長4:1253-建長5:1254-建長6:1255-建長7:1256-康元1:1257-正嘉1:1258-正嘉2:1259-正元1:1260-文応1:1261-弘長1:1262-弘長2:1263-弘長3:1264-文永1:1265-文永2:1266-文永3:1267-文永4:1268-文永5:1269-文永6:1270-文永7:1271-文永8:1272-文永9:1273-文永10:1274-文永11:1275-建治1:1276-建治2:1277-建治3:1278-弘安1:1279-弘安2:1280-弘安3:1281-弘安4:1282-弘安5:1283-弘安6:1284-弘安7:1285-弘安8:1286-弘安9:1287-弘安10:1288-正応1:1289-正応2:1290-正応3:1291-正応4:1292-正応5:1293-永仁1:1294-永仁2:1295-永仁3:1296-永仁4:1297-永仁5:1298-永仁6:1299-正安1:1300-正安2:1301-正安3:1302-正安4:1303-嘉元1:1304-嘉元2:1305-嘉元3:1306-嘉元4:1307-徳治2:1308-延慶1:1309-延慶2:1310-延慶3:1311-応長1:1312-正和1:1313-正和2:1314-正和3:1315-正和4:1316-正和5:1317-文保1:1318-文保2:1319-元応1:1320-元応2:1321-元亨1:1322-元亨2:1323-元亨3:1324-元亨4:1325-正中2:1326-嘉暦1:1327-嘉暦2:1328-嘉暦3:1329-元徳1:1330-元徳2:1331-元弘1:1332-元弘2:1333-元弘3:1334-建武1:1335-建武2:1336-延元1:1337-延元2:1338-延元3:1339-延元4:1340-興国1:1341-興国2:1342-興国3:1343-興国4:1344-興国5:1345-興国6:1346-興国7:1347-正平2:1348-正平3:1349-正平4:1350-正平5:1351-正平6:1352-正平7:1353-正平8:1354-正平9:1355-正平10:1356-正平11:1357-正平12:1358-正平13:1359-正平14:1360-正平15:1361-正平16:1362-正平17:1363-正平18:1364-正平19:1365-正平20:1366-正平21:1367-正平22:1368-正平23:1369-正平24:1370-建徳1:1371-建徳2:1372-文中1:1373-文中2:1374-文中3:1375-天授1:1376-天授2:1377-天授3:1378-天授4:1379-康暦1:1380-康暦2:1381-弘和1:1382-弘和2:1383-弘和3:1384-至徳1:1385-至徳2:1386-至徳3:1387-嘉慶1:1388-嘉慶2:1389-康応1:1390-明徳1:1391-明徳2:1392-明徳3:1393-明徳4:1394-応永1:1395-応永2:1396-応永3:1397-応永4:1398-応永5:1399-応永6:1400-応永7:1401-応永8:1402-応永9:1403-応永10:1404-応永11:1405-応永12:1406-応永13:1407-応永14:1408-応永15:1409-応永16:1410-応永17:1411-応永18:1412-応永19:1413-応永20:1414-応永21:1415-応永22:1416-応永23:1417-応永24:1418-応永25:1419-応永26:1420-応永27:1421-応永28:1422-応永29:1423-応永30:1424-応永31:1425-応永32:1426-応永33:1427-応永34:1428-正長1:1429-永享1:1430-永享2:1431-永享3:1432-永享4:1433-永享5:1434-永享6:1435-永享7:1436-永享8:1437-永享9:1438-永享10:1439-永享11:1440-永享12:1441-嘉吉1:1442-嘉吉2:1443-嘉吉3:1444-文安1:1445-文安2:1446-文安3:1447-文安4:1448-文安5:1449-宝徳1:1450-宝徳2:1451-宝徳3:1452-享徳1:1453-享徳2:1454-享徳3:1455-康正1:1456-康正2:1457-長禄1:1458-長禄2:1459-長禄3:1460-長禄4:1461-寛正2:1462-寛正3:1463-寛正4:1464-寛正5:1465-寛正6:1466-文正1:1467-応仁1:1468-応仁2:1469-文明1:1470-文明2:1471-文明3:1472-文明4:1473-文明5:1474-文明6:1475-文明7:1476-文明8:1477-文明9:1478-文明10:1479-文明11:1480-文明12:1481-文明13:1482-文明14:1483-文明15:1484-文明16:1485-文明17:1486-文明18:1487-長享1:1488-長享2:1489-延徳1:1490-延徳2:1491-延徳3:1492-明応1:1493-明応2:1494-明応3:1495-明応4:1496-明応5:1497-明応6:1498-明応7:1499-明応8:1500-明応9:1501-文亀1:1502-文亀2:1503-文亀3:1504-永正1:1505-永正2:1506-永正3:1507-永正4:1508-永正5:1509-永正6:1510-永正7:1511-永正8:1512-永正9:1513-永正10:1514-永正11:1515-永正12:1516-永正13:1517-永正14:1518-永正15:1519-永正16:1520-永正17:1521-大永1:1522-大永2:1523-大永3:1524-大永4:1525-大永5:1526-大永6:1527-大永7:1528-享禄1:1529-享禄2:1530-享禄3:1531-享禄4:1532-天文1:1533-天文2:1534-天文3:1535-天文4:1536-天文5:1537-天文6:1538-天文7:1539-天文8:1540-天文9:1541-天文10:1542-天文11:1543-天文12:1544-天文13:1545-天文14:1546-天文15:1547-天文16:1548-天文17:1549-天文18:1550-天文19:1551-天文20:1552-天文21:1553-天文22:1554-天文23:1555-天文24:1556-弘治2:1557-弘治3:1558-永禄1:1559-永禄2:1560-永禄3:1561-永禄4:1562-永禄5:1563-永禄6:1564-永禄7:1565-永禄8:1566-永禄9:1567-永禄10:1568-永禄11:1569-永禄12:1570-元亀1:1571-元亀2:1572-元亀3:1573-天正1:1574-天正2:1575-天正3:1576-天正4:1577-天正5:1578-天正6:1579-天正7:1580-天正8:1581-天正9:1582-天正10:1583-天正11:1584-天正12:1585-天正13:1586-天正14:1587-天正15:1588-天正16:1589-天正17:1590-天正18:1591-天正19:1592-天正20:1593-文禄2:1594-文禄3:1595-文禄4:1596-文禄5:1597-慶長2:1598-慶長3:1599-慶長4:1600-慶長5:1601-慶長6:1602-慶長7:1603-慶長8:1604-慶長9:1605-慶長10:1606-慶長11:1607-慶長12:1608-慶長13:1609-慶長14:1610-慶長15:1611-慶長16:1612-慶長17:1613-慶長18:1614-慶長19:1615-元和1:1616-元和2:1617-元和3:1618-元和4:1619-元和5:1620-元和6:1621-元和7:1622-元和8:1623-元和9:1624-寛永1:1625-寛永2:1626-寛永3:1627-寛永4:1628-寛永5:1629-寛永6:1630-寛永7:1631-寛永8:1632-寛永9:1633-寛永10:1634-寛永11:1635-寛永12:1636-寛永13:1637-寛永14:1638-寛永15:1639-寛永16:1640-寛永17:1641-寛永18:1642-寛永19:1643-寛永20:1644-寛永21:1645-正保2:1646-正保3:1647-正保4:1648-慶安1:1649-慶安2:1650-慶安3:1651-慶安4:1652-承応1:1653-承応2:1654-承応3:1655-明暦1:1656-明暦2:1657-明暦3:1658-万治1:1659-万治2:1660-万治3:1661-寛文1:1662-寛文2:1663-寛文3:1664-寛文4:1665-寛文5:1666-寛文6:1667-寛文7:1668-寛文8:1669-寛文9:1670-寛文10:1671-寛文11:1672-寛文12:1673-延宝1:1674-延宝2:1675-延宝3:1676-延宝4:1677-延宝5:1678-延宝6:1679-延宝7:1680-延宝8:1681-天和1:1682-天和2:1683-天和3:1684-貞享1:1685-貞享2:1686-貞享3:1687-貞享4:1688-元禄1:1689-元禄2:1690-元禄3:1691-元禄4:1692-元禄5:1693-元禄6:1694-元禄7:1695-元禄8:1696-元禄9:1697-元禄10:1698-元禄11:1699-元禄12:1700-元禄13:1701-元禄14:1702-元禄15:1703-元禄16:1704-宝永1:1705-宝永2:1706-宝永3:1707-宝永4:1708-宝永5:1709-宝永6:1710-宝永7:1711-正徳1:1712-正徳2:1713-正徳3:1714-正徳4:1715-正徳5:1716-享保1:1717-享保2:1718-享保3:1719-享保4:1720-享保5:1721-享保6:1722-享保7:1723-享保8:1724-享保9:1725-享保10:1726-享保11:1727-享保12:1728-享保13:1729-享保14:1730-享保15:1731-享保16:1732-享保17:1733-享保18:1734-享保19:1735-享保20:1736-元文1:1737-元文2:1738-元文3:1739-元文4:1740-元文5:1741-寛保1:1742-寛保2:1743-寛保3:1744-延享1:1745-延享2:1746-延享3:1747-延享4:1748-寛延1:1749-寛延2:1750-寛延3:1751-寛延4:1752-宝暦2:1753-宝暦3:1754-宝暦4:1755-宝暦5:1756-宝暦6:1757-宝暦7:1758-宝暦8:1759-宝暦9:1760-宝暦10:1761-宝暦11:1762-宝暦12:1763-宝暦13:1764-明和1:1765-明和2:1766-明和3:1767-明和4:1768-明和5:1769-明和6:1770-明和7:1771-明和8:1772-明和9:1773-安永2:1774-安永3:1775-安永4:1776-安永5:1777-安永6:1778-安永7:1779-安永8:1780-安永9:1781-天明1:1782-天明2:1783-天明3:1784-天明4:1785-天明5:1786-天明6:1787-天明7:1788-天明8:1789-寛政1:1790-寛政2:1791-寛政3:1792-寛政4:1793-寛政5:1794-寛政6:1795-寛政7:1796-寛政8:1797-寛政9:1798-寛政10:1799-寛政11:1800-寛政12:1801-享和1:1802-享和2:1803-享和3:1804-文化1:1805-文化2:1806-文化3:1807-文化4:1808-文化5:1809-文化6:1810-文化7:1811-文化8:1812-文化9:1813-文化10:1814-文化11:1815-文化12:1816-文化13:1817-文化14:1818-文政1:1819-文政2:1820-文政3:1821-文政4:1822-文政5:1823-文政6:1824-文政7:1825-文政8:1826-文政9:1827-文政10:1828-文政11:1829-文政12:1830-文政13:1831-天保2:1832-天保3:1833-天保4:1834-天保5:1835-天保6:1836-天保7:1837-天保8:1838-天保9:1839-天保10:1840-天保11:1841-天保12:1842-天保13:1843-天保14:1844-天保15:1845-弘化2:1846-弘化3:1847-弘化4:1848-嘉永1:1849-嘉永2:1850-嘉永3:1851-嘉永4:1852-嘉永5:1853-嘉永6:1854-嘉永7:1855-安政2:1856-安政3:1857-安政4:1858-安政5:1859-安政6:1860-万延1:1861-文久1:1862-文久2:1863-文久3:1864-元治1:1865-慶応1:1866-慶応2:1867-慶応3:1868-明治1:1869-明治2:1870-明治3:1871-明治4:1872-明治5:1873-明治6:1874-明治7:1875-明治8:1876-明治9:1877-明治10:1878-明治11:1879-明治12:1880-明治13:1881-明治14:1882-明治15:1883-明治16:1884-明治17:1885-明治18:1886-明治19:1887-明治20:1888-明治21:1889-明治22:1890-明治23:1891-明治24:1892-明治25:1893-明治26:1894-明治27:1895-明治28:1896-明治29:1897-明治30:1898-明治31:1899-明治32:1900-明治33:1901-明治34:1902-明治35:1903-明治36:1904-明治37:1905-明治38:1906-明治39:1907-明治40:1908-明治41:1909-明治42:1910-明治43:1911-明治44:1912-大正1:1913-大正2:1914-大正3:1915-大正4:1916-大正5:1917-大正6:1918-大正7:1919-大正8:1920-大正9:1921-大正10:1922-大正11:1923-大正12:1924-大正13:1925-大正14:1926-大正15:1927-昭和2:1928-昭和3:1929-昭和4:1930-昭和5:1931-昭和6:1932-昭和7:1933-昭和8:1934-昭和9:1935-昭和10:1936-昭和11:1937-昭和12:1938-昭和13:1939-昭和14:1940-昭和15:1941-昭和16:1942-昭和17:1943-昭和18:1944-昭和19:1945-昭和20:1946-昭和21:1947-昭和22:1948-昭和23:1949-昭和24:1950-昭和25:1951-昭和26:1952-昭和27:1953-昭和28:1954-昭和29:1955-昭和30:1956-昭和31:1957-昭和32:1958-昭和33:1959-昭和34:1960-昭和35:1961-昭和36:1962-昭和37:1963-昭和38:1964-昭和39:1965-昭和40:1966-昭和41:1967-昭和42:1968-昭和43:1969-昭和44:1970-昭和45:1971-昭和46:1972-昭和47:1973-昭和48:1974-昭和49:1975-昭和50:1976-昭和51:1977-昭和52:1978-昭和53:1979-昭和54:1980-昭和55:1981-昭和56:1982-昭和57:1983-昭和58:1984-昭和59:1985-昭和60:1986-昭和61:1987-昭和62:1988-昭和63:1989-平成1:1990-平成2:1991-平成3:1992-平成4:1993-平成5:1994-平成6:1995-平成7:1996-平成8:1997-平成9:1998-平成10:1999-平成11:2000-平成12:2001-平成13:2002-平成14:2003-平成15:2004-平成16:2005-平成17:2006-平成18:2007-平成19:2008-平成20:2009-平成21:2010-平成22:2011-平成23:2012-平成24:2013-平成25:2014-平成26
 +
</syntaxhighlight2>
 +
 +
タイムゾーン名
 +
<syntaxhighlight2 lang="text">
 +
ACT                              オーストラリア中部標準時
 +
AET                              オーストラリア東部標準時
 +
AGT                              アルゼンチン標準時
 +
ART                              東ヨーロッパ標準時
 +
AST                              アラスカ標準時
 +
Africa/Abidjan                  グリニッジ標準時
 +
Africa/Accra                    グリニッジ標準時
 +
Africa/Addis_Ababa              東アフリカ時間
 +
Africa/Algiers                  中央ヨーロッパ標準時
 +
Africa/Asmara                    東アフリカ時間
 +
Africa/Asmera                    東アフリカ時間
 +
Africa/Bamako                    グリニッジ標準時
 +
Africa/Bangui                    西アフリカ標準時
 +
Africa/Banjul                    グリニッジ標準時
 +
Africa/Bissau                    グリニッジ標準時
 +
Africa/Blantyre                  中央アフリカ時間
 +
Africa/Brazzaville              西アフリカ標準時
 +
Africa/Bujumbura                中央アフリカ時間
 +
Africa/Cairo                    東ヨーロッパ標準時
 +
Africa/Casablanca                西ヨーロッパ標準時
 +
Africa/Ceuta                    中央ヨーロッパ標準時
 +
Africa/Conakry                  グリニッジ標準時
 +
Africa/Dakar                    グリニッジ標準時
 +
Africa/Dar_es_Salaam            東アフリカ時間
 +
Africa/Djibouti                  東アフリカ時間
 +
Africa/Douala                    西アフリカ標準時
 +
Africa/El_Aaiun                  西ヨーロッパ標準時
 +
Africa/Freetown                  グリニッジ標準時
 +
Africa/Gaborone                  中央アフリカ時間
 +
Africa/Harare                    中央アフリカ時間
 +
Africa/Johannesburg              南アフリカ標準時
 +
Africa/Juba                      東アフリカ時間
 +
Africa/Kampala                  東アフリカ時間
 +
Africa/Khartoum                  東アフリカ時間
 +
Africa/Kigali                    中央アフリカ時間
 +
Africa/Kinshasa                  西アフリカ標準時
 +
Africa/Lagos                    西アフリカ標準時
 +
Africa/Libreville                西アフリカ標準時
 +
Africa/Lome                      グリニッジ標準時
 +
Africa/Luanda                    西アフリカ標準時
 +
Africa/Lubumbashi                中央アフリカ時間
 +
Africa/Lusaka                    中央アフリカ時間
 +
Africa/Malabo                    西アフリカ標準時
 +
Africa/Maputo                    中央アフリカ時間
 +
Africa/Maseru                    南アフリカ標準時
 +
Africa/Mbabane                  南アフリカ標準時
 +
Africa/Mogadishu                東アフリカ時間
 +
Africa/Monrovia                  グリニッジ標準時
 +
Africa/Nairobi                  東アフリカ時間
 +
Africa/Ndjamena                  西アフリカ標準時
 +
Africa/Niamey                    西アフリカ標準時
 +
Africa/Nouakchott                グリニッジ標準時
 +
Africa/Ouagadougou              グリニッジ標準時
 +
Africa/Porto-Novo                西アフリカ標準時
 +
Africa/Sao_Tome                  グリニッジ標準時
 +
Africa/Timbuktu                  グリニッジ標準時
 +
Africa/Tripoli                  東ヨーロッパ標準時
 +
Africa/Tunis                    中央ヨーロッパ標準時
 +
Africa/Windhoek                  西アフリカ標準時
 +
America/Adak                    ハワイ・アリューシャン標準時
 +
America/Anchorage                アラスカ標準時
 +
America/Anguilla                大西洋標準時
 +
America/Antigua                  大西洋標準時
 +
America/Araguaina                ブラジリア標準時
 +
America/Argentina/Buenos_Aires  アルゼンチン標準時
 +
America/Argentina/Catamarca      アルゼンチン標準時
 +
America/Argentina/ComodRivadavia アルゼンチン標準時
 +
America/Argentina/Cordoba        アルゼンチン標準時
 +
America/Argentina/Jujuy          アルゼンチン標準時
 +
America/Argentina/La_Rioja      アルゼンチン標準時
 +
America/Argentina/Mendoza        アルゼンチン標準時
 +
America/Argentina/Rio_Gallegos  アルゼンチン標準時
 +
America/Argentina/Salta          アルゼンチン標準時
 +
America/Argentina/San_Juan      アルゼンチン標準時
 +
America/Argentina/San_Luis      西部アルゼンチン標準時
 +
America/Argentina/Tucuman        アルゼンチン標準時
 +
America/Argentina/Ushuaia        アルゼンチン標準時
 +
America/Aruba                    大西洋標準時
 +
America/Asuncion                パラグアイ標準時
 +
America/Atikokan                アメリカ東部標準時
 +
America/Atka                    ハワイ・アリューシャン標準時
 +
America/Bahia                    ブラジリア標準時
 +
America/Bahia_Banderas          アメリカ中部標準時
 +
America/Barbados                大西洋標準時
 +
America/Belem                    ブラジリア標準時
 +
America/Belize                  アメリカ中部標準時
 +
America/Blanc-Sablon            大西洋標準時
 +
America/Boa_Vista                アマゾン標準時
 +
America/Bogota                  コロンビア標準時
 +
America/Boise                    アメリカ山地標準時
 +
America/Buenos_Aires            アルゼンチン標準時
 +
America/Cambridge_Bay            アメリカ山地標準時
 +
America/Campo_Grande            アマゾン標準時
 +
America/Cancun                  アメリカ中部標準時
 +
America/Caracas                  ベネズエラ時間
 +
America/Catamarca                アルゼンチン標準時
 +
America/Cayenne                  仏領ギアナ時間
 +
America/Cayman                  アメリカ東部標準時
 +
America/Chicago                  アメリカ中部標準時
 +
America/Chihuahua                メキシコ太平洋標準時
 +
America/Coral_Harbour            アメリカ東部標準時
 +
America/Cordoba                  アルゼンチン標準時
 +
America/Costa_Rica              アメリカ中部標準時
 +
America/Creston                  アメリカ山地標準時
 +
America/Cuiaba                  アマゾン標準時
 +
America/Curacao                  大西洋標準時
 +
America/Danmarkshavn            グリニッジ標準時
 +
America/Dawson                  アメリカ太平洋標準時
 +
America/Dawson_Creek            アメリカ山地標準時
 +
America/Denver                  アメリカ山地標準時
 +
America/Detroit                  アメリカ東部標準時
 +
America/Dominica                大西洋標準時
 +
America/Edmonton                アメリカ山地標準時
 +
America/Eirunepe                アクレ標準時
 +
America/El_Salvador              アメリカ中部標準時
 +
America/Ensenada                アメリカ太平洋標準時
 +
America/Fort_Wayne              アメリカ東部標準時
 +
America/Fortaleza                ブラジリア標準時
 +
America/Glace_Bay                大西洋標準時
 +
America/Godthab                  グリーンランド西部標準時
 +
America/Goose_Bay                大西洋標準時
 +
America/Grand_Turk              アメリカ東部標準時
 +
America/Grenada                  大西洋標準時
 +
America/Guadeloupe              大西洋標準時
 +
America/Guatemala                アメリカ中部標準時
 +
America/Guayaquil                エクアドル時間
 +
America/Guyana                  ガイアナ時間
 +
America/Halifax                  大西洋標準時
 +
America/Havana                  キューバ標準時
 +
America/Hermosillo              メキシコ太平洋標準時
 +
America/Indiana/Indianapolis    アメリカ東部標準時
 +
America/Indiana/Knox            アメリカ中部標準時
 +
America/Indiana/Marengo          アメリカ東部標準時
 +
America/Indiana/Petersburg      アメリカ東部標準時
 +
America/Indiana/Tell_City        アメリカ中部標準時
 +
America/Indiana/Vevay            アメリカ東部標準時
 +
America/Indiana/Vincennes        アメリカ東部標準時
 +
America/Indiana/Winamac          アメリカ東部標準時
 +
America/Indianapolis            アメリカ東部標準時
 +
America/Inuvik                  アメリカ山地標準時
 +
America/Iqaluit                  アメリカ東部標準時
 +
America/Jamaica                  アメリカ東部標準時
 +
America/Jujuy                    アルゼンチン標準時
 +
America/Juneau                  アラスカ標準時
 +
America/Kentucky/Louisville      アメリカ東部標準時
 +
America/Kentucky/Monticello      アメリカ東部標準時
 +
America/Knox_IN                  アメリカ中部標準時
 +
America/Kralendijk              大西洋標準時
 +
America/La_Paz                  ボリビア時間
 +
America/Lima                    ペルー標準時
 +
America/Los_Angeles              アメリカ太平洋標準時
 +
America/Louisville              アメリカ東部標準時
 +
America/Lower_Princes            大西洋標準時
 +
America/Maceio                  ブラジリア標準時
 +
America/Managua                  アメリカ中部標準時
 +
America/Manaus                  アマゾン標準時
 +
America/Marigot                  大西洋標準時
 +
America/Martinique              大西洋標準時
 +
America/Matamoros                アメリカ中部標準時
 +
America/Mazatlan                メキシコ太平洋標準時
 +
America/Mendoza                  アルゼンチン標準時
 +
America/Menominee                アメリカ中部標準時
 +
America/Merida                  アメリカ中部標準時
 +
America/Metlakatla              アメリカ太平洋標準時
 +
America/Mexico_City              アメリカ中部標準時
 +
America/Miquelon                サンピエール・ミクロン標準時
 +
America/Moncton                  大西洋標準時
 +
America/Monterrey                アメリカ中部標準時
 +
America/Montevideo              ウルグアイ標準時
 +
America/Montreal                GMT-05:00
 +
America/Montserrat              大西洋標準時
 +
America/Nassau                  アメリカ東部標準時
 +
America/New_York                アメリカ東部標準時
 +
America/Nipigon                  アメリカ東部標準時
 +
America/Nome                    アラスカ標準時
 +
America/Noronha                  フェルナンド・デ・ノローニャ標準時
 +
America/North_Dakota/Beulah      アメリカ中部標準時
 +
America/North_Dakota/Center      アメリカ中部標準時
 +
America/North_Dakota/New_Salem  アメリカ中部標準時
 +
America/Ojinaga                  アメリカ山地標準時
 +
America/Panama                  アメリカ東部標準時
 +
America/Pangnirtung              アメリカ東部標準時
 +
America/Paramaribo              スリナム時間
 +
America/Phoenix                  アメリカ山地標準時
 +
America/Port-au-Prince          アメリカ東部標準時
 +
America/Port_of_Spain            大西洋標準時
 +
America/Porto_Acre              アクレ標準時
 +
America/Porto_Velho              アマゾン標準時
 +
America/Puerto_Rico              大西洋標準時
 +
America/Rainy_River              アメリカ中部標準時
 +
America/Rankin_Inlet            アメリカ中部標準時
 +
America/Recife                  ブラジリア標準時
 +
America/Regina                  アメリカ中部標準時
 +
America/Resolute                アメリカ中部標準時
 +
America/Rio_Branco              アクレ標準時
 +
America/Rosario                  アルゼンチン標準時
 +
America/Santa_Isabel            メキシコ北西部標準時
 +
America/Santarem                ブラジリア標準時
 +
America/Santiago                チリ標準時
 +
America/Santo_Domingo            大西洋標準時
 +
America/Sao_Paulo                ブラジリア標準時
 +
America/Scoresbysund            グリーンランド東部標準時
 +
America/Shiprock                アメリカ山地標準時
 +
America/Sitka                    アラスカ標準時
 +
America/St_Barthelemy            大西洋標準時
 +
America/St_Johns                ニューファンドランド標準時
 +
America/St_Kitts                大西洋標準時
 +
America/St_Lucia                大西洋標準時
 +
America/St_Thomas                大西洋標準時
 +
America/St_Vincent              大西洋標準時
 +
America/Swift_Current            アメリカ中部標準時
 +
America/Tegucigalpa              アメリカ中部標準時
 +
America/Thule                    大西洋標準時
 +
America/Thunder_Bay              アメリカ東部標準時
 +
America/Tijuana                  アメリカ太平洋標準時
 +
America/Toronto                  アメリカ東部標準時
 +
America/Tortola                  大西洋標準時
 +
America/Vancouver                アメリカ太平洋標準時
 +
America/Virgin                  大西洋標準時
 +
America/Whitehorse              アメリカ太平洋標準時
 +
America/Winnipeg                アメリカ中部標準時
 +
America/Yakutat                  アラスカ標準時
 +
America/Yellowknife              アメリカ山地標準時
 +
Antarctica/Casey                オーストラリア西部標準時
 +
Antarctica/Davis                デービス基地時間
 +
Antarctica/DumontDUrville        デュモン・デュルヴィル基地時間
 +
Antarctica/Macquarie            マッコーリー島時間
 +
Antarctica/Mawson                モーソン基地時間
 +
Antarctica/McMurdo              ニュージーランド標準時
 +
Antarctica/Palmer                チリ標準時
 +
Antarctica/Rothera              ロゼラ基地時間
 +
Antarctica/South_Pole            ニュージーランド標準時
 +
Antarctica/Syowa                昭和基地時間
 +
Antarctica/Troll                グリニッジ標準時
 +
Antarctica/Vostok                ボストーク基地時間
 +
Arctic/Longyearbyen              中央ヨーロッパ標準時
 +
Asia/Aden                        アラビア標準時
 +
Asia/Almaty                      東カザフスタン時間
 +
Asia/Amman                      東ヨーロッパ標準時
 +
Asia/Anadyr                      マガダン標準時
 +
Asia/Aqtau                      西カザフスタン時間
 +
Asia/Aqtobe                      西カザフスタン時間
 +
Asia/Ashgabat                    トルクメニスタン標準時
 +
Asia/Ashkhabad                  トルクメニスタン標準時
 +
Asia/Baghdad                    アラビア標準時
 +
Asia/Bahrain                    アラビア標準時
 +
Asia/Baku                        アゼルバイジャン標準時
 +
Asia/Bangkok                    インドシナ時間
 +
Asia/Beirut                      東ヨーロッパ標準時
 +
Asia/Bishkek                    キルギスタン時間
 +
Asia/Brunei                      ブルネイ・ダルサラーム時間
 +
Asia/Calcutta                    インド標準時
 +
Asia/Chita                      ヤクーツク標準時
 +
Asia/Choibalsan                  チョイバルサン標準時
 +
Asia/Chongqing                  中国標準時
 +
Asia/Chungking                  中国標準時
 +
Asia/Colombo                    インド標準時
 +
Asia/Dacca                      バングラデシュ標準時
 +
Asia/Damascus                    東ヨーロッパ標準時
 +
Asia/Dhaka                      バングラデシュ標準時
 +
Asia/Dili                        東ティモール時間
 +
Asia/Dubai                      湾岸標準時
 +
Asia/Dushanbe                    タジキスタン時間
 +
Asia/Gaza                        東ヨーロッパ標準時
 +
Asia/Harbin                      中国標準時
 +
Asia/Hebron                      東ヨーロッパ標準時
 +
Asia/Ho_Chi_Minh                インドシナ時間
 +
Asia/Hong_Kong                  香港標準時
 +
Asia/Hovd                        ホブド標準時
 +
Asia/Irkutsk                    イルクーツク標準時
 +
Asia/Istanbul                    東ヨーロッパ標準時
 +
Asia/Jakarta                    インドネシア西部時間
 +
Asia/Jayapura                    インドネシア東部時間
 +
Asia/Jerusalem                  イスラエル標準時
 +
Asia/Kabul                      アフガニスタン時間
 +
Asia/Kamchatka                  マガダン標準時
 +
Asia/Karachi                    パキスタン標準時
 +
Asia/Kashgar                    GMT+06:00
 +
Asia/Kathmandu                  ネパール時間
 +
Asia/Katmandu                    ネパール時間
 +
Asia/Khandyga                    ヤクーツク標準時
 +
Asia/Kolkata                    インド標準時
 +
Asia/Krasnoyarsk                クラスノヤルスク標準時
 +
Asia/Kuala_Lumpur                マレーシア時間
 +
Asia/Kuching                    マレーシア時間
 +
Asia/Kuwait                      アラビア標準時
 +
Asia/Macao                      中国標準時
 +
Asia/Macau                      中国標準時
 +
Asia/Magadan                    マガダン標準時
 +
Asia/Makassar                    インドネシア中部時間
 +
Asia/Manila                      フィリピン標準時
 +
Asia/Muscat                      湾岸標準時
 +
Asia/Nicosia                    東ヨーロッパ標準時
 +
Asia/Novokuznetsk                ノヴォシビルスク標準時
 +
Asia/Novosibirsk                ノヴォシビルスク標準時
 +
Asia/Omsk                        オムスク標準時
 +
Asia/Oral                        西カザフスタン時間
 +
Asia/Phnom_Penh                  インドシナ時間
 +
Asia/Pontianak                  インドネシア西部時間
 +
Asia/Pyongyang                  韓国標準時
 +
Asia/Qatar                      アラビア標準時
 +
Asia/Qyzylorda                  東カザフスタン時間
 +
Asia/Rangoon                    ミャンマー時間
 +
Asia/Riyadh                      アラビア標準時
 +
Asia/Saigon                      インドシナ時間
 +
Asia/Sakhalin                    サハリン標準時
 +
Asia/Samarkand                  ウズベキスタン標準時
 +
Asia/Seoul                      韓国標準時
 +
Asia/Shanghai                    中国標準時
 +
Asia/Singapore                  シンガポール標準時
 +
Asia/Srednekolymsk              マガダン標準時
 +
Asia/Taipei                      台北標準時
 +
Asia/Tashkent                    ウズベキスタン標準時
 +
Asia/Tbilisi                    グルジア標準時
 +
Asia/Tehran                      イラン標準時
 +
Asia/Tel_Aviv                    イスラエル標準時
 +
Asia/Thimbu                      ブータン時間
 +
Asia/Thimphu                    ブータン時間
 +
Asia/Tokyo                      日本標準時
 +
Asia/Ujung_Pandang              インドネシア中部時間
 +
Asia/Ulaanbaatar                ウランバートル標準時
 +
Asia/Ulan_Bator                  ウランバートル標準時
 +
Asia/Urumqi                      GMT+06:00
 +
Asia/Ust-Nera                    ウラジオストク標準時
 +
Asia/Vientiane                  インドシナ時間
 +
Asia/Vladivostok                ウラジオストク標準時
 +
Asia/Yakutsk                    ヤクーツク標準時
 +
Asia/Yekaterinburg              エカテリンブルグ標準時
 +
Asia/Yerevan                    アルメニア標準時
 +
Atlantic/Azores                  アゾレス標準時
 +
Atlantic/Bermuda                大西洋標準時
 +
Atlantic/Canary                  西ヨーロッパ標準時
 +
Atlantic/Cape_Verde              カーボベルデ標準時
 +
Atlantic/Faeroe                  西ヨーロッパ標準時
 +
Atlantic/Faroe                  西ヨーロッパ標準時
 +
Atlantic/Jan_Mayen              中央ヨーロッパ標準時
 +
Atlantic/Madeira                西ヨーロッパ標準時
 +
Atlantic/Reykjavik              グリニッジ標準時
 +
Atlantic/South_Georgia          サウスジョージア時間
 +
Atlantic/St_Helena              グリニッジ標準時
 +
Atlantic/Stanley                フォークランド諸島標準時
 +
Australia/ACT                    オーストラリア東部標準時
 +
Australia/Adelaide              オーストラリア中部標準時
 +
Australia/Brisbane              オーストラリア東部標準時
 +
Australia/Broken_Hill            オーストラリア中部標準時
 +
Australia/Canberra              オーストラリア東部標準時
 +
Australia/Currie                オーストラリア東部標準時
 +
Australia/Darwin                オーストラリア中部標準時
 +
Australia/Eucla                  オーストラリア中西部標準時
 +
Australia/Hobart                オーストラリア東部標準時
 +
Australia/LHI                    ロードハウ標準時
 +
Australia/Lindeman              オーストラリア東部標準時
 +
Australia/Lord_Howe              ロードハウ標準時
 +
Australia/Melbourne              オーストラリア東部標準時
 +
Australia/NSW                    オーストラリア東部標準時
 +
Australia/North                  オーストラリア中部標準時
 +
Australia/Perth                  オーストラリア西部標準時
 +
Australia/Queensland            オーストラリア東部標準時
 +
Australia/South                  オーストラリア中部標準時
 +
Australia/Sydney                オーストラリア東部標準時
 +
Australia/Tasmania              オーストラリア東部標準時
 +
Australia/Victoria              オーストラリア東部標準時
 +
Australia/West                  オーストラリア西部標準時
 +
Australia/Yancowinna            オーストラリア中部標準時
 +
BET                              ブラジリア標準時
 +
BST                              バングラデシュ標準時
 +
Brazil/Acre                      アクレ標準時
 +
Brazil/DeNoronha                フェルナンド・デ・ノローニャ標準時
 +
Brazil/East                      ブラジリア標準時
 +
Brazil/West                      アマゾン標準時
 +
CAT                              中央アフリカ時間
 +
CET                              GMT+01:00
 +
CNT                              ニューファンドランド標準時
 +
CST                              アメリカ中部標準時
 +
CST6CDT                          アメリカ中部標準時
 +
CTT                              中国標準時
 +
Canada/Atlantic                  大西洋標準時
 +
Canada/Central                  アメリカ中部標準時
 +
Canada/East-Saskatchewan        アメリカ中部標準時
 +
Canada/Eastern                  アメリカ東部標準時
 +
Canada/Mountain                  アメリカ山地標準時
 +
Canada/Newfoundland              ニューファンドランド標準時
 +
Canada/Pacific                  アメリカ太平洋標準時
 +
Canada/Saskatchewan              アメリカ中部標準時
 +
Canada/Yukon                    アメリカ太平洋標準時
 +
Chile/Continental                チリ標準時
 +
Chile/EasterIsland              イースター島標準時
 +
Cuba                            キューバ標準時
 +
EAT                              東アフリカ時間
 +
ECT                              中央ヨーロッパ標準時
 +
EET                              GMT+02:00
 +
EST                              GMT-05:00
 +
EST5EDT                          アメリカ東部標準時
 +
Egypt                            東ヨーロッパ標準時
 +
Eire                            グリニッジ標準時
 +
Etc/GMT                          GMT
 +
Etc/GMT+0                        GMT
 +
Etc/GMT+1                        GMT-01:00
 +
Etc/GMT+10                      GMT-10:00
 +
Etc/GMT+11                      GMT-11:00
 +
Etc/GMT+12                      GMT-12:00
 +
Etc/GMT+2                        GMT-02:00
 +
Etc/GMT+3                        GMT-03:00
 +
Etc/GMT+4                        GMT-04:00
 +
Etc/GMT+5                        GMT-05:00
 +
Etc/GMT+6                        GMT-06:00
 +
Etc/GMT+7                        GMT-07:00
 +
Etc/GMT+8                        GMT-08:00
 +
Etc/GMT+9                        GMT-09:00
 +
Etc/GMT-0                        GMT
 +
Etc/GMT-1                        GMT+01:00
 +
Etc/GMT-10                      GMT+10:00
 +
Etc/GMT-11                      GMT+11:00
 +
Etc/GMT-12                      GMT+12:00
 +
Etc/GMT-13                      GMT+13:00
 +
Etc/GMT-14                      GMT+14:00
 +
Etc/GMT-2                        GMT+02:00
 +
Etc/GMT-3                        GMT+03:00
 +
Etc/GMT-4                        GMT+04:00
 +
Etc/GMT-5                        GMT+05:00
 +
Etc/GMT-6                        GMT+06:00
 +
Etc/GMT-7                        GMT+07:00
 +
Etc/GMT-8                        GMT+08:00
 +
Etc/GMT-9                        GMT+09:00
 +
Etc/GMT0                        GMT
 +
Etc/Greenwich                    GMT
 +
Etc/UCT                          GMT
 +
Etc/UTC                          GMT
 +
Etc/Universal                    GMT
 +
Etc/Zulu                        GMT
 +
Europe/Amsterdam                中央ヨーロッパ標準時
 +
Europe/Andorra                  中央ヨーロッパ標準時
 +
Europe/Athens                    東ヨーロッパ標準時
 +
Europe/Belfast                  グリニッジ標準時
 +
Europe/Belgrade                  中央ヨーロッパ標準時
 +
Europe/Berlin                    中央ヨーロッパ標準時
 +
Europe/Bratislava                中央ヨーロッパ標準時
 +
Europe/Brussels                  中央ヨーロッパ標準時
 +
Europe/Bucharest                東ヨーロッパ標準時
 +
Europe/Budapest                  中央ヨーロッパ標準時
 +
Europe/Busingen                  中央ヨーロッパ標準時
 +
Europe/Chisinau                  東ヨーロッパ標準時
 +
Europe/Copenhagen                中央ヨーロッパ標準時
 +
Europe/Dublin                    グリニッジ標準時
 +
Europe/Gibraltar                中央ヨーロッパ標準時
 +
Europe/Guernsey                  グリニッジ標準時
 +
Europe/Helsinki                  東ヨーロッパ標準時
 +
Europe/Isle_of_Man              グリニッジ標準時
 +
Europe/Istanbul                  東ヨーロッパ標準時
 +
Europe/Jersey                    グリニッジ標準時
 +
Europe/Kaliningrad              極東ヨーロッパ時間
 +
Europe/Kiev                      東ヨーロッパ標準時
 +
Europe/Lisbon                    西ヨーロッパ標準時
 +
Europe/Ljubljana                中央ヨーロッパ標準時
 +
Europe/London                    グリニッジ標準時
 +
Europe/Luxembourg                中央ヨーロッパ標準時
 +
Europe/Madrid                    中央ヨーロッパ標準時
 +
Europe/Malta                    中央ヨーロッパ標準時
 +
Europe/Mariehamn                東ヨーロッパ標準時
 +
Europe/Minsk                    極東ヨーロッパ時間
 +
Europe/Monaco                    中央ヨーロッパ標準時
 +
Europe/Moscow                    モスクワ標準時
 +
Europe/Nicosia                  東ヨーロッパ標準時
 +
Europe/Oslo                      中央ヨーロッパ標準時
 +
Europe/Paris                    中央ヨーロッパ標準時
 +
Europe/Podgorica                中央ヨーロッパ標準時
 +
Europe/Prague                    中央ヨーロッパ標準時
 +
Europe/Riga                      東ヨーロッパ標準時
 +
Europe/Rome                      中央ヨーロッパ標準時
 +
Europe/Samara                    モスクワ標準時
 +
Europe/San_Marino                中央ヨーロッパ標準時
 +
Europe/Sarajevo                  中央ヨーロッパ標準時
 +
Europe/Simferopol                モスクワ標準時
 +
Europe/Skopje                    中央ヨーロッパ標準時
 +
Europe/Sofia                    東ヨーロッパ標準時
 +
Europe/Stockholm                中央ヨーロッパ標準時
 +
Europe/Tallinn                  東ヨーロッパ標準時
 +
Europe/Tirane                    中央ヨーロッパ標準時
 +
Europe/Tiraspol                  東ヨーロッパ標準時
 +
Europe/Uzhgorod                  東ヨーロッパ標準時
 +
Europe/Vaduz                    中央ヨーロッパ標準時
 +
Europe/Vatican                  中央ヨーロッパ標準時
 +
Europe/Vienna                    中央ヨーロッパ標準時
 +
Europe/Vilnius                  東ヨーロッパ標準時
 +
Europe/Volgograd                モスクワ標準時
 +
Europe/Warsaw                    中央ヨーロッパ標準時
 +
Europe/Zagreb                    中央ヨーロッパ標準時
 +
Europe/Zaporozhye                東ヨーロッパ標準時
 +
Europe/Zurich                    中央ヨーロッパ標準時
 +
Factory                          GMT
 +
GB                              グリニッジ標準時
 +
GB-Eire                          グリニッジ標準時
 +
GMT                              GMT
 +
GMT+0                            GMT
 +
GMT-0                            GMT
 +
GMT0                            GMT
 +
Greenwich                        GMT
 +
HST                              GMT-10:00
 +
Hongkong                        香港標準時
 +
IET                              アメリカ東部標準時
 +
IST                              インド標準時
 +
Iceland                          グリニッジ標準時
 +
Indian/Antananarivo              東アフリカ時間
 +
Indian/Chagos                    インド洋時間
 +
Indian/Christmas                クリスマス島時間
 +
Indian/Cocos                    ココス諸島時間
 +
Indian/Comoro                    東アフリカ時間
 +
Indian/Kerguelen                仏領南方南極時間
 +
Indian/Mahe                      セーシェル時間
 +
Indian/Maldives                  モルディブ時間
 +
Indian/Mauritius                モーリシャス標準時
 +
Indian/Mayotte                  東アフリカ時間
 +
Indian/Reunion                  レユニオン時間
 +
Iran                            イラン標準時
 +
Israel                          イスラエル標準時
 +
JST                              日本標準時
 +
Jamaica                          アメリカ東部標準時
 +
Japan                            日本標準時
 +
Kwajalein                        マーシャル諸島時間
 +
Libya                            東ヨーロッパ標準時
 +
MET                              GMT+01:00
 +
MIT                              アピーア標準時
 +
MST                              GMT-07:00
 +
MST7MDT                          アメリカ山地標準時
 +
Mexico/BajaNorte                アメリカ太平洋標準時
 +
Mexico/BajaSur                  メキシコ太平洋標準時
 +
Mexico/General                  アメリカ中部標準時
 +
NET                              アルメニア標準時
 +
NST                              ニュージーランド標準時
 +
NZ                              ニュージーランド標準時
 +
NZ-CHAT                          チャタム標準時
 +
Navajo                          アメリカ山地標準時
 +
PLT                              パキスタン標準時
 +
PNT                              アメリカ山地標準時
 +
PRC                              中国標準時
 +
PRT                              大西洋標準時
 +
PST                              アメリカ太平洋標準時
 +
PST8PDT                          アメリカ太平洋標準時
 +
Pacific/Apia                    アピーア標準時
 +
Pacific/Auckland                ニュージーランド標準時
 +
Pacific/Chatham                  チャタム標準時
 +
Pacific/Chuuk                    チューク時間
 +
Pacific/Easter                  イースター島標準時
 +
Pacific/Efate                    バヌアツ標準時
 +
Pacific/Enderbury                フェニックス諸島時間
 +
Pacific/Fakaofo                  トケラウ時間
 +
Pacific/Fiji                    フィジー標準時
 +
Pacific/Funafuti                ツバル時間
 +
Pacific/Galapagos                ガラパゴス時間
 +
Pacific/Gambier                  ガンビエ諸島時間
 +
Pacific/Guadalcanal              ソロモン諸島時間
 +
Pacific/Guam                    チャモロ時間
 +
Pacific/Honolulu                ハワイ・アリューシャン標準時
 +
Pacific/Johnston                ハワイ・アリューシャン標準時
 +
Pacific/Kiritimati              ライン諸島時間
 +
Pacific/Kosrae                  コスラエ時間
 +
Pacific/Kwajalein                マーシャル諸島時間
 +
Pacific/Majuro                  マーシャル諸島時間
 +
Pacific/Marquesas                マルキーズ時間
 +
Pacific/Midway                  サモア標準時
 +
Pacific/Nauru                    ナウル時間
 +
Pacific/Niue                    ニウエ時間
 +
Pacific/Norfolk                  ノーフォーク島時間
 +
Pacific/Noumea                  ニューカレドニア標準時
 +
Pacific/Pago_Pago                サモア標準時
 +
Pacific/Palau                    パラオ時間
 +
Pacific/Pitcairn                ピトケアン時間
 +
Pacific/Pohnpei                  ポナペ時間
 +
Pacific/Ponape                  ポナペ時間
 +
Pacific/Port_Moresby            パプアニューギニア時間
 +
Pacific/Rarotonga                クック諸島標準時
 +
Pacific/Saipan                  チャモロ時間
 +
Pacific/Samoa                    サモア標準時
 +
Pacific/Tahiti                  タヒチ時間
 +
Pacific/Tarawa                  ギルバート諸島時間
 +
Pacific/Tongatapu                トンガ標準時
 +
Pacific/Truk                    チューク時間
 +
Pacific/Wake                    ウェーク島時間
 +
Pacific/Wallis                  ウォリス・フツナ時間
 +
Pacific/Yap                      チューク時間
 +
Poland                          中央ヨーロッパ標準時
 +
Portugal                        西ヨーロッパ標準時
 +
ROC                              台北標準時
 +
ROK                              韓国標準時
 +
SST                              ソロモン諸島時間
 +
Singapore                        シンガポール標準時
 +
SystemV/AST4                    GMT-04:00
 +
SystemV/AST4ADT                  GMT-04:00
 +
SystemV/CST6                    GMT-06:00
 +
SystemV/CST6CDT                  GMT-06:00
 +
SystemV/EST5                    GMT-05:00
 +
SystemV/EST5EDT                  GMT-05:00
 +
SystemV/HST10                    GMT-10:00
 +
SystemV/MST7                    GMT-07:00
 +
SystemV/MST7MDT                  GMT-07:00
 +
SystemV/PST8                    GMT-08:00
 +
SystemV/PST8PDT                  GMT-08:00
 +
SystemV/YST9                    GMT-09:00
 +
SystemV/YST9YDT                  GMT-09:00
 +
Turkey                          東ヨーロッパ標準時
 +
UCT                              GMT
 +
US/Alaska                        アラスカ標準時
 +
US/Aleutian                      ハワイ・アリューシャン標準時
 +
US/Arizona                      アメリカ山地標準時
 +
US/Central                      アメリカ中部標準時
 +
US/East-Indiana                  アメリカ東部標準時
 +
US/Eastern                      アメリカ東部標準時
 +
US/Hawaii                        ハワイ・アリューシャン標準時
 +
US/Indiana-Starke                アメリカ中部標準時
 +
US/Michigan                      アメリカ東部標準時
 +
US/Mountain                      アメリカ山地標準時
 +
US/Pacific                      アメリカ太平洋標準時
 +
US/Pacific-New                  アメリカ太平洋標準時
 +
US/Samoa                        サモア標準時
 +
UTC                              GMT
 +
Universal                        GMT
 +
VST                              インドシナ時間
 +
W-SU                            モスクワ標準時
 +
WET                              GMT
 +
Zulu                            GMT
 +
 +
</syntaxhighlight2>
 +
 +
各言語での日本時間の表記
 +
<syntaxhighlight2 lang="text">
 +
Asia/Tokyo af          Japan-standaardtyd
 +
Asia/Tokyo af_NA      Japan-standaardtyd
 +
Asia/Tokyo af_ZA      Japan-standaardtyd
 +
Asia/Tokyo agq        GMT+09:00
 +
Asia/Tokyo agq_CM      GMT+09:00
 +
Asia/Tokyo ak          GMT+09:00
 +
Asia/Tokyo ak_GH      GMT+09:00
 +
Asia/Tokyo am          የጃፓን መደበኛ ሰዓት
 +
Asia/Tokyo am_ET      የጃፓን መደበኛ ሰዓት
 +
Asia/Tokyo ar          توقيت اليابان الرسمي
 +
Asia/Tokyo ar_001      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_AE      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_BH      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_DJ      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_DZ      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_EG      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_EH      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_ER      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_IL      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_IQ      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_JO      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_KM      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_KW      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_LB      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_LY      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_MA      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_MR      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_OM      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_PS      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_QA      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_SA      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_SD      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_SO      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_SS      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_SY      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_TD      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_TN      توقيت اليابان الرسمي
 +
Asia/Tokyo ar_YE      توقيت اليابان الرسمي
 +
Asia/Tokyo as          GMT+০৯:০০
 +
Asia/Tokyo as_IN      GMT+০৯:০০
 +
Asia/Tokyo asa        GMT+09:00
 +
Asia/Tokyo asa_TZ      GMT+09:00
 +
Asia/Tokyo az          Yaponiya Standart Vaxtı
 +
Asia/Tokyo az_Cyrl    GMT+09:00
 +
Asia/Tokyo az_Cyrl_AZ  GMT+09:00
 +
Asia/Tokyo az_Latn    Yaponiya Standart Vaxtı
 +
Asia/Tokyo az_Latn_AZ  Yaponiya Standart Vaxtı
 +
Asia/Tokyo bas        GMT+09:00
 +
Asia/Tokyo bas_CM      GMT+09:00
 +
Asia/Tokyo be          GMT+09:00
 +
Asia/Tokyo be_BY      GMT+09:00
 +
Asia/Tokyo bem        GMT+09:00
 +
Asia/Tokyo bem_ZM      GMT+09:00
 +
Asia/Tokyo bez        GMT+09:00
 +
Asia/Tokyo bez_TZ      GMT+09:00
 +
Asia/Tokyo bg          Японско стандартно време
 +
Asia/Tokyo bg_BG      Японско стандартно време
 +
Asia/Tokyo bm          GMT+09:00
 +
Asia/Tokyo bm_Latn    GMT+09:00
 +
Asia/Tokyo bm_Latn_ML  GMT+09:00
 +
Asia/Tokyo bn          জাপান মানক সময়
 +
Asia/Tokyo bn_BD      জাপান মানক সময়
 +
Asia/Tokyo bn_IN      জাপান মানক সময়
 +
Asia/Tokyo bo          GMT+09:00
 +
Asia/Tokyo bo_CN      GMT+09:00
 +
Asia/Tokyo bo_IN      GMT+09:00
 +
Asia/Tokyo br          GMT+09:00
 +
Asia/Tokyo br_FR      GMT+09:00
 +
Asia/Tokyo brx        जपान स्टैंडर्ड टाईम
 +
Asia/Tokyo brx_IN      जपान स्टैंडर्ड टाईम
 +
Asia/Tokyo bs          Standardno japansko vrijeme
 +
Asia/Tokyo bs_Cyrl    Јапанско стандардно време
 +
Asia/Tokyo bs_Cyrl_BA  Јапанско стандардно време
 +
Asia/Tokyo bs_Latn    Standardno japansko vrijeme
 +
Asia/Tokyo bs_Latn_BA  Standardno japansko vrijeme
 +
Asia/Tokyo ca          Hora estàndard del Japó
 +
Asia/Tokyo ca_AD      Hora estàndard del Japó
 +
Asia/Tokyo ca_ES      Hora estàndard del Japó
 +
Asia/Tokyo ca_FR      Hora estàndard del Japó
 +
Asia/Tokyo ca_IT      Hora estàndard del Japó
 +
Asia/Tokyo cgg        GMT+09:00
 +
Asia/Tokyo cgg_UG      GMT+09:00
 +
Asia/Tokyo chr        GMT+09:00
 +
Asia/Tokyo chr_US      GMT+09:00
 +
Asia/Tokyo cs          Japonský standardní čas
 +
Asia/Tokyo cs_CZ      Japonský standardní čas
 +
Asia/Tokyo cy          Amser Safonol Japan
 +
Asia/Tokyo cy_GB      Amser Safonol Japan
 +
Asia/Tokyo da          Japansk normaltid
 +
Asia/Tokyo da_DK      Japansk normaltid
 +
Asia/Tokyo da_GL      Japansk normaltid
 +
Asia/Tokyo dav        GMT+09:00
 +
Asia/Tokyo dav_KE      GMT+09:00
 +
Asia/Tokyo de          Japanische Normalzeit
 +
Asia/Tokyo de_AT      Japanische Normalzeit
 +
Asia/Tokyo de_BE      Japanische Normalzeit
 +
Asia/Tokyo de_CH      Japanische Normalzeit
 +
Asia/Tokyo de_DE      Japanische Normalzeit
 +
Asia/Tokyo de_LI      Japanische Normalzeit
 +
Asia/Tokyo de_LU      Japanische Normalzeit
 +
Asia/Tokyo dje        GMT+09:00
 +
Asia/Tokyo dje_NE      GMT+09:00
 +
Asia/Tokyo dsb        Japański standardny cas
 +
Asia/Tokyo dsb_DE      Japański standardny cas
 +
Asia/Tokyo dua        GMT+09:00
 +
Asia/Tokyo dua_CM      GMT+09:00
 +
Asia/Tokyo dyo        GMT+09:00
 +
Asia/Tokyo dyo_SN      GMT+09:00
 +
Asia/Tokyo dz          ཇ་པཱན་ཚད་ལྡན་ཆུ་ཚོད
 +
Asia/Tokyo dz_BT      ཇ་པཱན་ཚད་ལྡན་ཆུ་ཚོད
 +
Asia/Tokyo ebu        GMT+09:00
 +
Asia/Tokyo ebu_KE      GMT+09:00
 +
Asia/Tokyo ee          GMT+09:00
 +
Asia/Tokyo ee_GH      GMT+09:00
 +
Asia/Tokyo ee_TG      GMT+09:00
 +
Asia/Tokyo el          Χειμερινή ώρα Ιαπωνίας
 +
Asia/Tokyo el_CY      Χειμερινή ώρα Ιαπωνίας
 +
Asia/Tokyo el_GR      Χειμερινή ώρα Ιαπωνίας
 +
Asia/Tokyo en          Japan Standard Time
 +
Asia/Tokyo en_001      Japan Standard Time
 +
Asia/Tokyo en_150      Japan Standard Time
 +
Asia/Tokyo en_AG      Japan Standard Time
 +
Asia/Tokyo en_AI      Japan Standard Time
 +
Asia/Tokyo en_AS      Japan Standard Time
 +
Asia/Tokyo en_AU      Japan Standard Time
 +
Asia/Tokyo en_BB      Japan Standard Time
 +
Asia/Tokyo en_BE      Japan Standard Time
 +
Asia/Tokyo en_BM      Japan Standard Time
 +
Asia/Tokyo en_BS      Japan Standard Time
 +
Asia/Tokyo en_BW      Japan Standard Time
 +
Asia/Tokyo en_BZ      Japan Standard Time
 +
Asia/Tokyo en_CA      Japan Standard Time
 +
Asia/Tokyo en_CC      Japan Standard Time
 +
Asia/Tokyo en_CK      Japan Standard Time
 +
Asia/Tokyo en_CM      Japan Standard Time
 +
Asia/Tokyo en_CX      Japan Standard Time
 +
Asia/Tokyo en_DG      Japan Standard Time
 +
Asia/Tokyo en_DM      Japan Standard Time
 +
Asia/Tokyo en_ER      Japan Standard Time
 +
Asia/Tokyo en_FJ      Japan Standard Time
 +
Asia/Tokyo en_FK      Japan Standard Time
 +
Asia/Tokyo en_FM      Japan Standard Time
 +
Asia/Tokyo en_GB      Japan Standard Time
 +
Asia/Tokyo en_GD      Japan Standard Time
 +
Asia/Tokyo en_GG      Japan Standard Time
 +
Asia/Tokyo en_GH      Japan Standard Time
 +
Asia/Tokyo en_GI      Japan Standard Time
 +
Asia/Tokyo en_GM      Japan Standard Time
 +
Asia/Tokyo en_GU      Japan Standard Time
 +
Asia/Tokyo en_GY      Japan Standard Time
 +
Asia/Tokyo en_HK      Japan Standard Time
 +
Asia/Tokyo en_IE      Japan Standard Time
 +
Asia/Tokyo en_IM      Japan Standard Time
 +
Asia/Tokyo en_IN      Japan Standard Time
 +
Asia/Tokyo en_IO      Japan Standard Time
 +
Asia/Tokyo en_JE      Japan Standard Time
 +
Asia/Tokyo en_JM      Japan Standard Time
 +
Asia/Tokyo en_KE      Japan Standard Time
 +
Asia/Tokyo en_KI      Japan Standard Time
 +
Asia/Tokyo en_KN      Japan Standard Time
 +
Asia/Tokyo en_KY      Japan Standard Time
 +
Asia/Tokyo en_LC      Japan Standard Time
 +
Asia/Tokyo en_LR      Japan Standard Time
 +
Asia/Tokyo en_LS      Japan Standard Time
 +
Asia/Tokyo en_MG      Japan Standard Time
 +
Asia/Tokyo en_MH      Japan Standard Time
 +
Asia/Tokyo en_MO      Japan Standard Time
 +
Asia/Tokyo en_MP      Japan Standard Time
 +
Asia/Tokyo en_MS      Japan Standard Time
 +
Asia/Tokyo en_MT      Japan Standard Time
 +
Asia/Tokyo en_MU      Japan Standard Time
 +
Asia/Tokyo en_MW      Japan Standard Time
 +
Asia/Tokyo en_MY      Japan Standard Time
 +
Asia/Tokyo en_NA      Japan Standard Time
 +
Asia/Tokyo en_NF      Japan Standard Time
 +
Asia/Tokyo en_NG      Japan Standard Time
 +
Asia/Tokyo en_NR      Japan Standard Time
 +
Asia/Tokyo en_NU      Japan Standard Time
 +
Asia/Tokyo en_NZ      Japan Standard Time
 +
Asia/Tokyo en_PG      Japan Standard Time
 +
Asia/Tokyo en_PH      Japan Standard Time
 +
Asia/Tokyo en_PK      Japan Standard Time
 +
Asia/Tokyo en_PN      Japan Standard Time
 +
Asia/Tokyo en_PR      Japan Standard Time
 +
Asia/Tokyo en_PW      Japan Standard Time
 +
Asia/Tokyo en_RW      Japan Standard Time
 +
Asia/Tokyo en_SB      Japan Standard Time
 +
Asia/Tokyo en_SC      Japan Standard Time
 +
Asia/Tokyo en_SD      Japan Standard Time
 +
Asia/Tokyo en_SG      Japan Standard Time
 +
Asia/Tokyo en_SH      Japan Standard Time
 +
Asia/Tokyo en_SL      Japan Standard Time
 +
Asia/Tokyo en_SS      Japan Standard Time
 +
Asia/Tokyo en_SX      Japan Standard Time
 +
Asia/Tokyo en_SZ      Japan Standard Time
 +
Asia/Tokyo en_TC      Japan Standard Time
 +
Asia/Tokyo en_TK      Japan Standard Time
 +
Asia/Tokyo en_TO      Japan Standard Time
 +
Asia/Tokyo en_TT      Japan Standard Time
 +
Asia/Tokyo en_TV      Japan Standard Time
 +
Asia/Tokyo en_TZ      Japan Standard Time
 +
Asia/Tokyo en_UG      Japan Standard Time
 +
Asia/Tokyo en_UM      Japan Standard Time
 +
Asia/Tokyo en_US      Japan Standard Time
 +
Asia/Tokyo en_US_POSIX Japan Standard Time
 +
Asia/Tokyo en_VC      Japan Standard Time
 +
Asia/Tokyo en_VG      Japan Standard Time
 +
Asia/Tokyo en_VI      Japan Standard Time
 +
Asia/Tokyo en_VU      Japan Standard Time
 +
Asia/Tokyo en_WS      Japan Standard Time
 +
Asia/Tokyo en_ZA      Japan Standard Time
 +
Asia/Tokyo en_ZM      Japan Standard Time
 +
Asia/Tokyo en_ZW      Japan Standard Time
 +
Asia/Tokyo eo          GMT+09:00
 +
Asia/Tokyo es          hora estándar de Japón
 +
Asia/Tokyo es_419      hora estándar de Japón
 +
Asia/Tokyo es_AR      hora estándar de Japón
 +
Asia/Tokyo es_BO      hora estándar de Japón
 +
Asia/Tokyo es_CL      hora estándar de Japón
 +
Asia/Tokyo es_CO      hora estándar de Japón
 +
Asia/Tokyo es_CR      hora estándar de Japón
 +
Asia/Tokyo es_CU      hora estándar de Japón
 +
Asia/Tokyo es_DO      hora estándar de Japón
 +
Asia/Tokyo es_EA      hora estándar de Japón
 +
Asia/Tokyo es_EC      hora estándar de Japón
 +
Asia/Tokyo es_ES      hora estándar de Japón
 +
Asia/Tokyo es_GQ      hora estándar de Japón
 +
Asia/Tokyo es_GT      hora estándar de Japón
 +
Asia/Tokyo es_HN      hora estándar de Japón
 +
Asia/Tokyo es_IC      hora estándar de Japón
 +
Asia/Tokyo es_MX      Hora estándar de Japón
 +
Asia/Tokyo es_NI      hora estándar de Japón
 +
Asia/Tokyo es_PA      hora estándar de Japón
 +
Asia/Tokyo es_PE      hora estándar de Japón
 +
Asia/Tokyo es_PH      hora estándar de Japón
 +
Asia/Tokyo es_PR      hora estándar de Japón
 +
Asia/Tokyo es_PY      hora estándar de Japón
 +
Asia/Tokyo es_SV      hora estándar de Japón
 +
Asia/Tokyo es_US      hora estándar de Japón
 +
Asia/Tokyo es_UY      hora estándar de Japón
 +
Asia/Tokyo es_VE      hora estándar de Japón
 +
Asia/Tokyo et          Jaapani standardaeg
 +
Asia/Tokyo et_EE      Jaapani standardaeg
 +
Asia/Tokyo eu          Japoniako ordu estandarra
 +
Asia/Tokyo eu_ES      Japoniako ordu estandarra
 +
Asia/Tokyo ewo        GMT+09:00
 +
Asia/Tokyo ewo_CM      GMT+09:00
 +
Asia/Tokyo fa          وقت عادی ژاپن
 +
Asia/Tokyo fa_AF      وقت عادی ژاپن
 +
Asia/Tokyo fa_IR      وقت عادی ژاپن
 +
Asia/Tokyo ff          GMT+09:00
 +
Asia/Tokyo ff_CM      GMT+09:00
 +
Asia/Tokyo ff_GN      GMT+09:00
 +
Asia/Tokyo ff_MR      GMT+09:00
 +
Asia/Tokyo ff_SN      GMT+09:00
 +
Asia/Tokyo fi          Japanin normaaliaika
 +
Asia/Tokyo fi_FI      Japanin normaaliaika
 +
Asia/Tokyo fil        Standard Time ng Japan
 +
Asia/Tokyo fil_PH      Standard Time ng Japan
 +
Asia/Tokyo fo          GMT+09:00
 +
Asia/Tokyo fo_FO      GMT+09:00
 +
Asia/Tokyo fr          heure normale du Japon
 +
Asia/Tokyo fr_BE      heure normale du Japon
 +
Asia/Tokyo fr_BF      heure normale du Japon
 +
Asia/Tokyo fr_BI      heure normale du Japon
 +
Asia/Tokyo fr_BJ      heure normale du Japon
 +
Asia/Tokyo fr_BL      heure normale du Japon
 +
Asia/Tokyo fr_CA      heure normale du Japon
 +
Asia/Tokyo fr_CD      heure normale du Japon
 +
Asia/Tokyo fr_CF      heure normale du Japon
 +
Asia/Tokyo fr_CG      heure normale du Japon
 +
Asia/Tokyo fr_CH      heure normale du Japon
 +
Asia/Tokyo fr_CI      heure normale du Japon
 +
Asia/Tokyo fr_CM      heure normale du Japon
 +
Asia/Tokyo fr_DJ      heure normale du Japon
 +
Asia/Tokyo fr_DZ      heure normale du Japon
 +
Asia/Tokyo fr_FR      heure normale du Japon
 +
Asia/Tokyo fr_GA      heure normale du Japon
 +
Asia/Tokyo fr_GF      heure normale du Japon
 +
Asia/Tokyo fr_GN      heure normale du Japon
 +
Asia/Tokyo fr_GP      heure normale du Japon
 +
Asia/Tokyo fr_GQ      heure normale du Japon
 +
Asia/Tokyo fr_HT      heure normale du Japon
 +
Asia/Tokyo fr_KM      heure normale du Japon
 +
Asia/Tokyo fr_LU      heure normale du Japon
 +
Asia/Tokyo fr_MA      heure normale du Japon
 +
Asia/Tokyo fr_MC      heure normale du Japon
 +
Asia/Tokyo fr_MF      heure normale du Japon
 +
Asia/Tokyo fr_MG      heure normale du Japon
 +
Asia/Tokyo fr_ML      heure normale du Japon
 +
Asia/Tokyo fr_MQ      heure normale du Japon
 +
Asia/Tokyo fr_MR      heure normale du Japon
 +
Asia/Tokyo fr_MU      heure normale du Japon
 +
Asia/Tokyo fr_NC      heure normale du Japon
 +
Asia/Tokyo fr_NE      heure normale du Japon
 +
Asia/Tokyo fr_PF      heure normale du Japon
 +
Asia/Tokyo fr_PM      heure normale du Japon
 +
Asia/Tokyo fr_RE      heure normale du Japon
 +
Asia/Tokyo fr_RW      heure normale du Japon
 +
Asia/Tokyo fr_SC      heure normale du Japon
 +
Asia/Tokyo fr_SN      heure normale du Japon
 +
Asia/Tokyo fr_SY      heure normale du Japon
 +
Asia/Tokyo fr_TD      heure normale du Japon
 +
Asia/Tokyo fr_TG      heure normale du Japon
 +
Asia/Tokyo fr_TN      heure normale du Japon
 +
Asia/Tokyo fr_VU      heure normale du Japon
 +
Asia/Tokyo fr_WF      heure normale du Japon
 +
Asia/Tokyo fr_YT      heure normale du Japon
 +
Asia/Tokyo fur        GMT+09:00
 +
Asia/Tokyo fur_IT      GMT+09:00
 +
Asia/Tokyo fy          Japanske standerttiid
 +
Asia/Tokyo fy_NL      Japanske standerttiid
 +
Asia/Tokyo ga          Am Caighdeánach na Seapáine
 +
Asia/Tokyo ga_IE      Am Caighdeánach na Seapáine
 +
Asia/Tokyo gd          Bun-àm na Seapaine
 +
Asia/Tokyo gd_GB      Bun-àm na Seapaine
 +
Asia/Tokyo gl          Horario estándar de Xapón
 +
Asia/Tokyo gl_ES      Horario estándar de Xapón
 +
Asia/Tokyo gsw        GMT+09:00
 +
Asia/Tokyo gsw_CH      GMT+09:00
 +
Asia/Tokyo gsw_FR      GMT+09:00
 +
Asia/Tokyo gsw_LI      GMT+09:00
 +
Asia/Tokyo gu          જાપાન માનક સમય
 +
Asia/Tokyo gu_IN      જાપાન માનક સમય
 +
Asia/Tokyo guz        GMT+09:00
 +
Asia/Tokyo guz_KE      GMT+09:00
 +
Asia/Tokyo gv          GMT+09:00
 +
Asia/Tokyo gv_IM      GMT+09:00
 +
Asia/Tokyo ha          GMT+09:00
 +
Asia/Tokyo ha_Latn    GMT+09:00
 +
Asia/Tokyo ha_Latn_GH  GMT+09:00
 +
Asia/Tokyo ha_Latn_NE  GMT+09:00
 +
Asia/Tokyo ha_Latn_NG  GMT+09:00
 +
Asia/Tokyo haw        GMT+09:00
 +
Asia/Tokyo haw_US      GMT+09:00
 +
Asia/Tokyo he          שעון יפן (חורף)
 +
Asia/Tokyo he_IL      שעון יפן (חורף)
 +
Asia/Tokyo hi          जापान मानक समय
 +
Asia/Tokyo hi_IN      जापान मानक समय
 +
Asia/Tokyo hr          japansko standardno vrijeme
 +
Asia/Tokyo hr_BA      japansko standardno vrijeme
 +
Asia/Tokyo hr_HR      japansko standardno vrijeme
 +
Asia/Tokyo hsb        japanski standardny čas
 +
Asia/Tokyo hsb_DE      japanski standardny čas
 +
Asia/Tokyo hu          japán téli idő
 +
Asia/Tokyo hu_HU      japán téli idő
 +
Asia/Tokyo hy          Ճապոնիայի ստանդարտ ժամանակ
 +
Asia/Tokyo hy_AM      Ճապոնիայի ստանդարտ ժամանակ
 +
Asia/Tokyo id          Waktu Standar Jepang
 +
Asia/Tokyo id_ID      Waktu Standar Jepang
 +
Asia/Tokyo ig          GMT+09:00
 +
Asia/Tokyo ig_NG      GMT+09:00
 +
Asia/Tokyo ii          GMT+09:00
 +
Asia/Tokyo ii_CN      GMT+09:00
 +
Asia/Tokyo is          Staðaltími í Japan
 +
Asia/Tokyo is_IS      Staðaltími í Japan
 +
Asia/Tokyo it          Ora standard del Giappone
 +
Asia/Tokyo it_CH      Ora standard del Giappone
 +
Asia/Tokyo it_IT      Ora standard del Giappone
 +
Asia/Tokyo it_SM      Ora standard del Giappone
 +
Asia/Tokyo ja          日本標準時
 +
Asia/Tokyo ja_JP      日本標準時
 +
Asia/Tokyo jgo        GMT+09:00
 +
Asia/Tokyo jgo_CM      GMT+09:00
 +
Asia/Tokyo jmc        GMT+09:00
 +
Asia/Tokyo jmc_TZ      GMT+09:00
 +
Asia/Tokyo ka          იაპონიის სტანდარტული დრო
 +
Asia/Tokyo ka_GE      იაპონიის სტანდარტული დრო
 +
Asia/Tokyo kab        GMT+09:00
 +
Asia/Tokyo kab_DZ      GMT+09:00
 +
Asia/Tokyo kam        GMT+09:00
 +
Asia/Tokyo kam_KE      GMT+09:00
 +
Asia/Tokyo kde        GMT+09:00
 +
Asia/Tokyo kde_TZ      GMT+09:00
 +
Asia/Tokyo kea        GMT+09:00
 +
Asia/Tokyo kea_CV      GMT+09:00
 +
Asia/Tokyo khq        GMT+09:00
 +
Asia/Tokyo khq_ML      GMT+09:00
 +
Asia/Tokyo ki          GMT+09:00
 +
Asia/Tokyo ki_KE      GMT+09:00
 +
Asia/Tokyo kk          Жапония стандартты уақыты
 +
Asia/Tokyo kk_Cyrl    Жапония стандартты уақыты
 +
Asia/Tokyo kk_Cyrl_KZ  Жапония стандартты уақыты
 +
Asia/Tokyo kkj        GMT+09:00
 +
Asia/Tokyo kkj_CM      GMT+09:00
 +
Asia/Tokyo kl          GMT+09:00
 +
Asia/Tokyo kl_GL      GMT+09:00
 +
Asia/Tokyo kln        GMT+09:00
 +
Asia/Tokyo kln_KE      GMT+09:00
 +
Asia/Tokyo km          ម៉ោង​ស្តង់ដារ​នៅ​ជប៉ុន
 +
Asia/Tokyo km_KH      ម៉ោង​ស្តង់ដារ​នៅ​ជប៉ុន
 +
Asia/Tokyo kn          ಜಪಾನ್ ಪ್ರಮಾಣಿತ ಸಮಯ
 +
Asia/Tokyo kn_IN      ಜಪಾನ್ ಪ್ರಮಾಣಿತ ಸಮಯ
 +
Asia/Tokyo ko          일본 표준시
 +
Asia/Tokyo ko_KP      일본 표준시
 +
Asia/Tokyo ko_KR      일본 표준시
 +
Asia/Tokyo kok        GMT+09:00
 +
Asia/Tokyo kok_IN      GMT+09:00
 +
Asia/Tokyo ks          جاپٲنۍ سٹینڑاڑ ٹایِم
 +
Asia/Tokyo ks_Arab    جاپٲنۍ سٹینڑاڑ ٹایِم
 +
Asia/Tokyo ks_Arab_IN  جاپٲنۍ سٹینڑاڑ ٹایِم
 +
Asia/Tokyo ksb        GMT+09:00
 +
Asia/Tokyo ksb_TZ      GMT+09:00
 +
Asia/Tokyo ksf        GMT+09:00
 +
Asia/Tokyo ksf_CM      GMT+09:00
 +
Asia/Tokyo ksh        GMT+09:00
 +
Asia/Tokyo ksh_DE      GMT+09:00
 +
Asia/Tokyo kw          GMT+09:00
 +
Asia/Tokyo kw_GB      GMT+09:00
 +
Asia/Tokyo ky          Жапан стандарт убактысы
 +
Asia/Tokyo ky_Cyrl    Жапан стандарт убактысы
 +
Asia/Tokyo ky_Cyrl_KG  Жапан стандарт убактысы
 +
Asia/Tokyo lag        GMT+09:00
 +
Asia/Tokyo lag_TZ      GMT+09:00
 +
Asia/Tokyo lb          Japanesch Normalzäit
 +
Asia/Tokyo lb_LU      Japanesch Normalzäit
 +
Asia/Tokyo lg          GMT+09:00
 +
Asia/Tokyo lg_UG      GMT+09:00
 +
Asia/Tokyo lkt        GMT+09:00
 +
Asia/Tokyo lkt_US      GMT+09:00
 +
Asia/Tokyo ln          GMT+09:00
 +
Asia/Tokyo ln_AO      GMT+09:00
 +
Asia/Tokyo ln_CD      GMT+09:00
 +
Asia/Tokyo ln_CF      GMT+09:00
 +
Asia/Tokyo ln_CG      GMT+09:00
 +
Asia/Tokyo lo          ເວ​ລາ​ມາດ​ຕະ​ຖານ​ຍີ່​ປຸ່ນ
 +
Asia/Tokyo lo_LA      ເວ​ລາ​ມາດ​ຕະ​ຖານ​ຍີ່​ປຸ່ນ
 +
Asia/Tokyo lt          Japonijos žiemos laikas
 +
Asia/Tokyo lt_LT      Japonijos žiemos laikas
 +
Asia/Tokyo lu          GMT+09:00
 +
Asia/Tokyo lu_CD      GMT+09:00
 +
Asia/Tokyo luo        GMT+09:00
 +
Asia/Tokyo luo_KE      GMT+09:00
 +
Asia/Tokyo luy        GMT+09:00
 +
Asia/Tokyo luy_KE      GMT+09:00
 +
Asia/Tokyo lv          Japānas ziemas laiks
 +
Asia/Tokyo lv_LV      Japānas ziemas laiks
 +
Asia/Tokyo mas        GMT+09:00
 +
Asia/Tokyo mas_KE      GMT+09:00
 +
Asia/Tokyo mas_TZ      GMT+09:00
 +
Asia/Tokyo mer        GMT+09:00
 +
Asia/Tokyo mer_KE      GMT+09:00
 +
Asia/Tokyo mfe        GMT+09:00
 +
Asia/Tokyo mfe_MU      GMT+09:00
 +
Asia/Tokyo mg          GMT+09:00
 +
Asia/Tokyo mg_MG      GMT+09:00
 +
Asia/Tokyo mgh        GMT+09:00
 +
Asia/Tokyo mgh_MZ      GMT+09:00
 +
Asia/Tokyo mgo        GMT+09:00
 +
Asia/Tokyo mgo_CM      GMT+09:00
 +
Asia/Tokyo mk          Стандардно време во Јапонија
 +
Asia/Tokyo mk_MK      Стандардно време во Јапонија
 +
Asia/Tokyo ml          ജപ്പാൻ സ്റ്റാൻഡേർഡ് സമയം
 +
Asia/Tokyo ml_IN      ജപ്പാൻ സ്റ്റാൻഡേർഡ് സമയം
 +
Asia/Tokyo mn          Японы стандарт цаг
 +
Asia/Tokyo mn_Cyrl    Японы стандарт цаг
 +
Asia/Tokyo mn_Cyrl_MN  Японы стандарт цаг
 +
Asia/Tokyo mr          जपान प्रमाण वेळ
 +
Asia/Tokyo mr_IN      जपान प्रमाण वेळ
 +
Asia/Tokyo ms          Waktu Piawai Jepun
 +
Asia/Tokyo ms_Latn    Waktu Piawai Jepun
 +
Asia/Tokyo ms_Latn_BN  Waktu Piawai Jepun
 +
Asia/Tokyo ms_Latn_MY  Waktu Piawai Jepun
 +
Asia/Tokyo ms_Latn_SG  Waktu Piawai Jepun
 +
Asia/Tokyo mt          GMT+09:00
 +
Asia/Tokyo mt_MT      GMT+09:00
 +
Asia/Tokyo mua        GMT+09:00
 +
Asia/Tokyo mua_CM      GMT+09:00
 +
Asia/Tokyo my          ဂျပန် စံတော်ချိန်
 +
Asia/Tokyo my_MM      ဂျပန် စံတော်ချိန်
 +
Asia/Tokyo naq        GMT+09:00
 +
Asia/Tokyo naq_NA      GMT+09:00
 +
Asia/Tokyo nb          japansk normaltid
 +
Asia/Tokyo nb_NO      japansk normaltid
 +
Asia/Tokyo nb_SJ      japansk normaltid
 +
Asia/Tokyo nd          GMT+09:00
 +
Asia/Tokyo nd_ZW      GMT+09:00
 +
Asia/Tokyo ne          जापान मानक समय
 +
Asia/Tokyo ne_IN      जापान मानक समय
 +
Asia/Tokyo ne_NP      जापान मानक समय
 +
Asia/Tokyo nl          Japanse standaardtijd
 +
Asia/Tokyo nl_AW      Japanse standaardtijd
 +
Asia/Tokyo nl_BE      Japanse standaardtijd
 +
Asia/Tokyo nl_BQ      Japanse standaardtijd
 +
Asia/Tokyo nl_CW      Japanse standaardtijd
 +
Asia/Tokyo nl_NL      Japanse standaardtijd
 +
Asia/Tokyo nl_SR      Japanse standaardtijd
 +
Asia/Tokyo nl_SX      Japanse standaardtijd
 +
Asia/Tokyo nmg        GMT+09:00
 +
Asia/Tokyo nmg_CM      GMT+09:00
 +
Asia/Tokyo nn          GMT+09:00
 +
Asia/Tokyo nn_NO      GMT+09:00
 +
Asia/Tokyo nnh        GMT+09:00
 +
Asia/Tokyo nnh_CM      GMT+09:00
 +
Asia/Tokyo nus        GMT+09:00
 +
Asia/Tokyo nus_SD      GMT+09:00
 +
Asia/Tokyo nyn        GMT+09:00
 +
Asia/Tokyo nyn_UG      GMT+09:00
 +
Asia/Tokyo om          GMT+09:00
 +
Asia/Tokyo om_ET      GMT+09:00
 +
Asia/Tokyo om_KE      GMT+09:00
 +
Asia/Tokyo or          GMT+09:00
 +
Asia/Tokyo or_IN      GMT+09:00
 +
Asia/Tokyo os          GMT+09:00
 +
Asia/Tokyo os_GE      GMT+09:00
 +
Asia/Tokyo os_RU      GMT+09:00
 +
Asia/Tokyo pa          ਜਪਾਨ ਮਿਆਰੀ ਸਮਾਂ
 +
Asia/Tokyo pa_Arab    GMT+۰۹:۰۰
 +
Asia/Tokyo pa_Arab_PK  GMT+۰۹:۰۰
 +
Asia/Tokyo pa_Guru    ਜਪਾਨ ਮਿਆਰੀ ਸਮਾਂ
 +
Asia/Tokyo pa_Guru_IN  ਜਪਾਨ ਮਿਆਰੀ ਸਮਾਂ
 +
Asia/Tokyo pl          Japonia (czas standardowy)
 +
Asia/Tokyo pl_PL      Japonia (czas standardowy)
 +
Asia/Tokyo ps          GMT+۰۹:۰۰
 +
Asia/Tokyo ps_AF      GMT+۰۹:۰۰
 +
Asia/Tokyo pt          Horário Padrão do Japão
 +
Asia/Tokyo pt_AO      Hora Padrão do Japão
 +
Asia/Tokyo pt_BR      Horário Padrão do Japão
 +
Asia/Tokyo pt_CV      Hora Padrão do Japão
 +
Asia/Tokyo pt_GW      Hora Padrão do Japão
 +
Asia/Tokyo pt_MO      Hora Padrão do Japão
 +
Asia/Tokyo pt_MZ      Hora Padrão do Japão
 +
Asia/Tokyo pt_PT      Hora Padrão do Japão
 +
Asia/Tokyo pt_ST      Hora Padrão do Japão
 +
Asia/Tokyo pt_TL      Hora Padrão do Japão
 +
Asia/Tokyo qu          GMT+09:00
 +
Asia/Tokyo qu_BO      GMT+09:00
 +
Asia/Tokyo qu_EC      GMT+09:00
 +
Asia/Tokyo qu_PE      GMT+09:00
 +
Asia/Tokyo rm          GMT+09:00
 +
Asia/Tokyo rm_CH      GMT+09:00
 +
Asia/Tokyo rn          GMT+09:00
 +
Asia/Tokyo rn_BI      GMT+09:00
 +
Asia/Tokyo ro          Ora standard a Japoniei
 +
Asia/Tokyo ro_MD      Ora standard a Japoniei
 +
Asia/Tokyo ro_RO      Ora standard a Japoniei
 +
Asia/Tokyo rof        GMT+09:00
 +
Asia/Tokyo rof_TZ      GMT+09:00
 +
Asia/Tokyo ru          Япония, стандартное время
 +
Asia/Tokyo ru_BY      Япония, стандартное время
 +
Asia/Tokyo ru_KG      Япония, стандартное время
 +
Asia/Tokyo ru_KZ      Япония, стандартное время
 +
Asia/Tokyo ru_MD      Япония, стандартное время
 +
Asia/Tokyo ru_RU      Япония, стандартное время
 +
Asia/Tokyo ru_UA      Япония, стандартное время
 +
Asia/Tokyo rw          GMT+09:00
 +
Asia/Tokyo rw_RW      GMT+09:00
 +
Asia/Tokyo rwk        GMT+09:00
 +
Asia/Tokyo rwk_TZ      GMT+09:00
 +
Asia/Tokyo sah        GMT+09:00
 +
Asia/Tokyo sah_RU      GMT+09:00
 +
Asia/Tokyo saq        GMT+09:00
 +
Asia/Tokyo saq_KE      GMT+09:00
 +
Asia/Tokyo sbp        GMT+09:00
 +
Asia/Tokyo sbp_TZ      GMT+09:00
 +
Asia/Tokyo se          UTC+09:00
 +
Asia/Tokyo se_FI      UTC+09:00
 +
Asia/Tokyo se_NO      UTC+09:00
 +
Asia/Tokyo se_SE      UTC+09:00
 +
Asia/Tokyo seh        GMT+09:00
 +
Asia/Tokyo seh_MZ      GMT+09:00
 +
Asia/Tokyo ses        GMT+09:00
 +
Asia/Tokyo ses_ML      GMT+09:00
 +
Asia/Tokyo sg          GMT+09:00
 +
Asia/Tokyo sg_CF      GMT+09:00
 +
Asia/Tokyo shi        GMT+09:00
 +
Asia/Tokyo shi_Latn    GMT+09:00
 +
Asia/Tokyo shi_Latn_MA GMT+09:00
 +
Asia/Tokyo shi_Tfng    GMT+09:00
 +
Asia/Tokyo shi_Tfng_MA GMT+09:00
 +
Asia/Tokyo si          ජපාන සම්මත වේලාව
 +
Asia/Tokyo si_LK      ජපාන සම්මත වේලාව
 +
Asia/Tokyo sk          Japonský štandardný čas
 +
Asia/Tokyo sk_SK      Japonský štandardný čas
 +
Asia/Tokyo sl          Japonski standardni čas
 +
Asia/Tokyo sl_SI      Japonski standardni čas
 +
Asia/Tokyo smn        GMT+09:00
 +
Asia/Tokyo smn_FI      GMT+09:00
 +
Asia/Tokyo sn          GMT+09:00
 +
Asia/Tokyo sn_ZW      GMT+09:00
 +
Asia/Tokyo so          GMT+09:00
 +
Asia/Tokyo so_DJ      GMT+09:00
 +
Asia/Tokyo so_ET      GMT+09:00
 +
Asia/Tokyo so_KE      GMT+09:00
 +
Asia/Tokyo so_SO      GMT+09:00
 +
Asia/Tokyo sq          Ora standarde e Japonisë
 +
Asia/Tokyo sq_AL      Ora standarde e Japonisë
 +
Asia/Tokyo sq_MK      Ora standarde e Japonisë
 +
Asia/Tokyo sq_XK      Ora standarde e Japonisë
 +
Asia/Tokyo sr          Јапанско стандардно време
 +
Asia/Tokyo sr_Cyrl    Јапанско стандардно време
 +
Asia/Tokyo sr_Cyrl_BA  Јапанско стандардно време
 +
Asia/Tokyo sr_Cyrl_ME  Јапанско стандардно време
 +
Asia/Tokyo sr_Cyrl_RS  Јапанско стандардно време
 +
Asia/Tokyo sr_Cyrl_XK  Јапанско стандардно време
 +
Asia/Tokyo sr_Latn    Japansko standardno vreme
 +
Asia/Tokyo sr_Latn_BA  Japansko standardno vreme
 +
Asia/Tokyo sr_Latn_ME  Japansko standardno vreme
 +
Asia/Tokyo sr_Latn_RS  Japansko standardno vreme
 +
Asia/Tokyo sr_Latn_XK  Japansko standardno vreme
 +
Asia/Tokyo sv          japansk normaltid
 +
Asia/Tokyo sv_AX      japansk normaltid
 +
Asia/Tokyo sv_FI      japansk normaltid
 +
Asia/Tokyo sv_SE      japansk normaltid
 +
Asia/Tokyo sw          Saa Wastani za Japani
 +
Asia/Tokyo sw_KE      Saa Wastani za Japani
 +
Asia/Tokyo sw_TZ      Saa Wastani za Japani
 +
Asia/Tokyo sw_UG      Saa Wastani za Japani
 +
Asia/Tokyo swc        GMT+09:00
 +
Asia/Tokyo swc_CD      GMT+09:00
 +
Asia/Tokyo ta          ஜப்பான் நிலையான நேரம்
 +
Asia/Tokyo ta_IN      ஜப்பான் நிலையான நேரம்
 +
Asia/Tokyo ta_LK      ஜப்பான் நிலையான நேரம்
 +
Asia/Tokyo ta_MY      ஜப்பான் நிலையான நேரம்
 +
Asia/Tokyo ta_SG      ஜப்பான் நிலையான நேரம்
 +
Asia/Tokyo te          జపాన్ ప్రామాణిక సమయం
 +
Asia/Tokyo te_IN      జపాన్ ప్రామాణిక సమయం
 +
Asia/Tokyo teo        GMT+09:00
 +
Asia/Tokyo teo_KE      GMT+09:00
 +
Asia/Tokyo teo_UG      GMT+09:00
 +
Asia/Tokyo th          เวลามาตรฐานญี่ปุ่น
 +
Asia/Tokyo th_TH      เวลามาตรฐานญี่ปุ่น
 +
Asia/Tokyo ti          GMT+09:00
 +
Asia/Tokyo ti_ER      GMT+09:00
 +
Asia/Tokyo ti_ET      GMT+09:00
 +
Asia/Tokyo to          houa fakasiapani taimi totonu
 +
Asia/Tokyo to_TO      houa fakasiapani taimi totonu
 +
Asia/Tokyo tr          Japonya Standart Saati
 +
Asia/Tokyo tr_CY      Japonya Standart Saati
 +
Asia/Tokyo tr_TR      Japonya Standart Saati
 +
Asia/Tokyo twq        GMT+09:00
 +
Asia/Tokyo twq_NE      GMT+09:00
 +
Asia/Tokyo tzm        GMT+09:00
 +
Asia/Tokyo tzm_Latn    GMT+09:00
 +
Asia/Tokyo tzm_Latn_MA GMT+09:00
 +
Asia/Tokyo ug          ياپونىيە ئۆلچەملىك ۋاقتى
 +
Asia/Tokyo ug_Arab    ياپونىيە ئۆلچەملىك ۋاقتى
 +
Asia/Tokyo ug_Arab_CN  ياپونىيە ئۆلچەملىك ۋاقتى
 +
Asia/Tokyo uk          за японським стандартним часом
 +
Asia/Tokyo uk_UA      за японським стандартним часом
 +
Asia/Tokyo ur          جاپان سٹینڈرڈ ٹائم
 +
Asia/Tokyo ur_IN      جاپان سٹینڈرڈ ٹائم
 +
Asia/Tokyo ur_PK      جاپان سٹینڈرڈ ٹائم
 +
Asia/Tokyo uz          Yaponiya standart vaqti
 +
Asia/Tokyo uz_Arab    GMT+۰۹:۰۰
 +
Asia/Tokyo uz_Arab_AF  GMT+۰۹:۰۰
 +
Asia/Tokyo uz_Cyrl    Япония стандарт вақти
 +
Asia/Tokyo uz_Cyrl_UZ  Япония стандарт вақти
 +
Asia/Tokyo uz_Latn    Yaponiya standart vaqti
 +
Asia/Tokyo uz_Latn_UZ  Yaponiya standart vaqti
 +
Asia/Tokyo vai        GMT+09:00
 +
Asia/Tokyo vai_Latn    GMT+09:00
 +
Asia/Tokyo vai_Latn_LR GMT+09:00
 +
Asia/Tokyo vai_Vaii    GMT+09:00
 +
Asia/Tokyo vai_Vaii_LR GMT+09:00
 +
Asia/Tokyo vi          Giờ Chuẩn Nhật Bản
 +
Asia/Tokyo vi_VN      Giờ Chuẩn Nhật Bản
 +
Asia/Tokyo vun        GMT+09:00
 +
Asia/Tokyo vun_TZ      GMT+09:00
 +
Asia/Tokyo wae        GMT+09:00
 +
Asia/Tokyo wae_CH      GMT+09:00
 +
Asia/Tokyo xog        GMT+09:00
 +
Asia/Tokyo xog_UG      GMT+09:00
 +
Asia/Tokyo yav        GMT+09:00
 +
Asia/Tokyo yav_CM      GMT+09:00
 +
Asia/Tokyo yi          GMT+09:00
 +
Asia/Tokyo yi_001      GMT+09:00
 +
Asia/Tokyo yo          GMT+09:00
 +
Asia/Tokyo yo_BJ      GMT+09:00
 +
Asia/Tokyo yo_NG      GMT+09:00
 +
Asia/Tokyo zgh        GMT+09:00
 +
Asia/Tokyo zgh_MA      GMT+09:00
 +
Asia/Tokyo zh          日本标准时间
 +
Asia/Tokyo zh_Hans    日本标准时间
 +
Asia/Tokyo zh_Hans_CN  日本标准时间
 +
Asia/Tokyo zh_Hans_HK  日本标准时间
 +
Asia/Tokyo zh_Hans_MO  日本标准时间
 +
Asia/Tokyo zh_Hans_SG  日本标准时间
 +
Asia/Tokyo zh_Hant    日本標準時間
 +
Asia/Tokyo zh_Hant_HK  日本標準時間
 +
Asia/Tokyo zh_Hant_MO  日本標準時間
 +
Asia/Tokyo zh_Hant_TW  日本標準時間
 +
Asia/Tokyo zu          Isikhathi esivamile sase-Japan
 +
Asia/Tokyo zu_ZA      Isikhathi esivamile sase-Japan
 +
</syntaxhighlight2>
 +
 +
=='''文字列の抽出'''==
 +
文字列のコピーでコピーする文字数を限定する関数***ncpy系の関数がありましたので、前方抽出はできまるようになったと思います。他にもtokenを使ったり、正規表現を使う事でも抽出ができました。これらの文字の位置を示す関数と、この他にも存在する文字の位置に関する関数を活用することで、もっと他の抽出方法を考えることもできます。前方から何文字目~n文字。前方のnバイト目に目的の文字開始位置があれば、そこからn文字、前方のnバイト目に目的の文字開始位置があって、次のmバイト目に終端位置があって、その間にあるn文字を抽出といった具合です。これらはマルチバイト文字がおさめられた文字列変数ではバイト数と文字数が一致しないことから慎重に処理する必要があります。またワイド文字も2バイト固定のように感じてしまいますが、実際は4バイトの文字である可能性も0ではないので、きちんと文字数とバイト数を計算して、開始位置に文字型ポインターを格納したりする必要があります。配列によって決まった長さの実体のある文字列で終端に\0が入っているような構造の先頭を指し示すポインタと、そのポインタの型と同じだけど実体は持たないポインタの変数を利用して、実体を持たないポインタ変数が、文字の抽出開始位置を指し示すようにすること、そこらからコピーする文字数を正確に数えることがポイントになります。ポイントというとポインタと紛らわしいので、ミソになりますとでも言った方がいいのかもしれません。ここで紹介する抽出と、これまでに紹介した正規表現やtokenを活用すると更に操作の幅が広がります。
 +
 +
 +
とにかく文字を数えて、文字列ポインタを移動させ、サロゲートペアなら4バイト、通常のワイド文字範囲なら2byteってなかんじで数えます。面倒ですが、サロゲートペアのことを考えると文字数での抽出はこのような気遣いが必要です。マルチバイト文字でやるときは、また違った対応が必要になります。仕組みとしては文字数とバイト数をきちんと数えて、先頭文字にポインタを合わせる。***ncpy系の関数でそこから必要なバイト数をコピーするという感じになります。コンソール画面ではShiftJISなので文字化けしますから、Unicode文字としてテキストに出力するプログラムになっています。今回のプログラムでは対応しませんでしたが、異体字セレクタに対応すると、2バイト文字にはさらに DB40 DD00 の4バイトが付与されていますので、次の4バイトの値がDB40 DD**になっていないか確認をする必要があり、そのようになっている場合は+4バイトするような計算も必要です。テキストエディタを作成する場合にはフォントを異体字セレクタにしたがって切り替える試みが必要になります。フォントが対応していなければ切り替えることはできないので、処理としては元の文字を表示するだけになります。DB40 DD** のような異体字補助番号は文字コードとして使われないことになっています。
 +
<syntaxhighlight2 lang="cpp" line start="1">
 +
#pragma once
 +
#include "stdafx.h"
 +
#include <stdlib.h>
 +
#include <string>      //std::string型定義
 +
#include <mbstring.h> //mbs***関数
 +
#include <iostream>    //cpp cout etc 一般入出力関数
 +
#include <locale>      //Locale関数
 +
#include <tchar.h>    //TCHAR型+_tcs***関数
 +
#include "atlstr.h"    //CString,CStringA,CStringWおよびLPTSTR,LPWSTR,LPSTR,LPCTSTR,LPCWSTR,LPCSTRの定義プリプロセッサ
 +
#include "atlbase.h"  //同上
 +
#include "cstringt.h"  //CStringTの定義プリプロセッサ
 +
#include <vector>      //Vector型テンプレートクラス
 +
 +
#include <sys/timeb.h> //Timeb型構造体
 +
 +
//_bstr_t型を利用するプリプロセッサ(ライブラリはデバッグモードとリリースモード個別設定)
 +
#include "comutil.h"
 +
 +
#ifdef _DEBUG
 +
#pragma comment(lib, "comsuppwd.lib")
 +
#else
 +
#pragma comment(lib, "comsuppw.lib")
 +
#endif
 +
//_bstr_t _End
 +
 +
//ICU ucnvプリプロセッサ(ライブラリはデバッグモードとリリースモード個別設定)
 +
#include <unicode/ucnv.h>    //ucnv文字コード変換ライブラリヘッダ
 +
#include <unicode/translit.h> //文字変換ライブラリヘッダ
 +
#include <unicode/regex.h>    //正規表現
 +
#include <unicode/ucsdet.h>  //文字コード判定
 +
#include <unicode/ucal.h>  //文字コード判定
 +
#include <unicode/uclean.h> //u_cleanup関数
 +
/* for uloc_getDefault() */
 +
#include <unicode/uloc.h>
 +
#include <unicode/calendar.h>
 +
#include <unicode/smpdtfmt.h>
 +
 +
//#include "unicode/utypes.h"
 +
//#include "unicode/locid.h"
 +
//#include "unicode/unistr.h"
 +
//#include "unicode/tzfmt.h"
 +
//#include "unicode/tznames.h"
 +
 +
 +
#ifdef _DEBUG
 +
#pragma comment(lib, "icudt.lib")
 +
#pragma comment(lib, "icuucd.lib")  //ICU ucnvを使うために必要なライブラリ
 +
#pragma comment(lib, "icuind.lib")  //ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も
 +
#pragma comment(lib, "iculed.lib")
 +
#pragma comment(lib, "iculxd.lib") 
 +
#pragma comment(lib, "icuiod.lib") 
 +
#pragma comment(lib, "icutud.lib") 
 +
 +
#else
 +
//#pragma comment(lib, "icudt.lib")
 +
#pragma comment(lib, "icuind.lib")  //ICU Transliterate関数を使うために必要なライブラリ 正規表現関数も
 +
#pragma comment(lib, "icuuc.lib")  //ICU ucnvを使うために必要なライブラリ
 +
//#pragma comment(lib, "icuio.lib")
 +
#endif
 +
//Data  Library                    icudtXX(d).dll icudt(d).lib
 +
//Common Library                    icuucXX(d).dll icuuc(d).lib
 +
//Internationalization(i18n) Library icuinXX(d).dll icuin(d).lib
 +
//Layout Engine                      iculeXX(d).dll icule(d).lib
 +
//Layout Extention Engine            iculxXX(d).dll iculx(d).lib
 +
//ICU I/O(Unicode stdio) Library    icuioXX(d).dll icuio(d).lib
 +
//Tool Utility Library              icutuXX(d).dll icutu(d).lib
 +
 +
//ICU ucnv _End
 +
 +
#include "UnicodeConverter.h"
 +
 +
using namespace std;
 +
 +
int _tmain(int argc, _TCHAR* argv[])
 +
{
 +
  _tsetlocale(LC_ALL, _T("Japanese")); //ロケールセットすると_l関数でロケール指定しなくても日本語が使われます。
 +
 +
_locale_t localeJpanease;
 +
localeJpanease = _create_locale(LC_ALL, "Japanese");
 +
 +
  FILE* pfileText;
 +
  fpos_t* fposPos = new fpos_t;
 +
  errno_t errNo;
 +
  size_t* psizeRuturnValue = new size_t;
 +
 
 +
  wchar_t pwcStrFilePath[]            = L"C:\\...\\...\\...\\test_new_Extract.txt";
 +
  char* pcStrStream;
 +
  pcStrStream = new char[1024];
 +
  int nCloseResult = 0;
 +
 
 +
  wchar_t pwcStrSurrogate[] = L"\xD840\xDC0B\xD867\xDE3Dごはん\xD840\xDC0B\xD842\xDFB7を食べたYo。";//L"𠀋𩸽ごはん𠀋𠮷を食べたYo。"と同じ。
 +
  const wchar_t* pwcStrPos;//実体は持たない文字位置格納変数
 +
  const wchar_t* pwcStrStPos;//実体は持たない文字位置格納変数
 +
  wchar_t* pwcStrSurrogateExtract;
 +
 +
  pwcStrPos = pwcStrSurrogate;
 +
  int nSize =  wcslen(pwcStrSurrogate);
 +
  int nByteCnt = 0;
 +
  int nCharCnt = 0;
 +
  int nStPos = 2;//文字位置では0文字目からカウントする仕組みなので、3文字目にポインタが合います。
 +
  printf("%d\n",nSize);
 +
  while (nByteCnt < nSize && nCharCnt < nStPos){
 +
    unsigned int unValue = _wcsnextc(pwcStrPos);
 +
    pwcStrPos++;
 +
    printf("%0x:",unValue);
 +
    if(unValue >= 0xD800 && unValue <= 0xDFFF){ 
 +
      pwcStrPos++;
 +
      nByteCnt++;
 +
    }
 +
    nCharCnt++;
 +
    nByteCnt++;
 +
  }
 +
  pwcStrStPos = pwcStrPos;//先頭の文字列にポインタを合わせる。
 +
  printf("\n");
 +
  printf("%d[Byte],%d[文字]\n",nByteCnt,nCharCnt);
 +
  int nEnPos = 5;//先頭文字から5文字目までのバイト数を数えます。そういう意味では最初の先頭文字の指定と合わせた方が良かったかも。
 +
  nByteCnt = 0;
 +
  nCharCnt = 0;
 +
  nSize =  wcslen(pwcStrPos);
 +
 +
  printf("%d\n",nSize);
 +
  while (nByteCnt < nSize && nCharCnt < nEnPos){
 +
    unsigned int unValue = _wcsnextc(pwcStrPos);
 +
    pwcStrPos++;
 +
    printf("%0x:",unValue);
 +
    if(unValue >= 0xD800 && unValue <= 0xDFFF){ 
 +
      pwcStrPos++;
 +
      nByteCnt++;
 +
    }
 +
    nCharCnt++;
 +
    nByteCnt++;
 +
  }
 +
  printf("\n");
 +
 +
  pwcStrSurrogateExtract = new wchar_t[nByteCnt + 1];
 +
  wcsncpy_s(pwcStrSurrogateExtract, nByteCnt + 1, pwcStrStPos, nByteCnt);//5文字分のバイト数をコピーする。7バイトだね。
 +
 +
  printf("%d[Byte],%d[文字]\n",nByteCnt,nCharCnt);
 +
  wprintf(L"%s",pwcStrPos);
 +
  printf("\n");
 +
 +
  fpos_t* pfposStartPos = new fpos_t;
 +
  printf("★テキストの新規書き込み\n");
 +
  errNo = _wfopen_s( &pfileText, pwcStrFilePath, L"w,ccs=UTF-16LE");
 +
  printf("Error?->%d\n", errNo);
 +
 
 +
  fputws(pwcStrSurrogate,pfileText);
 +
  fputws(L"\n",pfileText);
 +
 +
  fputws(pwcStrStPos,pfileText);
 +
  fputws(L"\n",pfileText);
 +
 +
  fputws(pwcStrPos,pfileText);
 +
  fputws(L"\n",pfileText);
 +
 +
  fputws(pwcStrSurrogateExtract,pfileText);
 +
 +
  fclose(pfileText);
 +
  return 0;
 +
}
 +
</syntaxhighlight2>
 +
コンソール側出力
 +
<syntaxhighlight2 lang="text">
 +
18
 +
d840:d842:
 +
4[Byte],2[文字]
 +
14
 +
3054:306f:3093:d840:d842:
 +
7[Byte],5[文字]
 +
を食べたYo。
 +
★テキストの新規書き込み
 +
Error?->0
 +
</syntaxhighlight2>
 +
テキスト出力
 +
<syntaxhighlight2 lang="text">
 +
𠀋𩸽ごはん𠀋𠮷を食べたYo。
 +
ごはん𠀋𠮷を食べたYo。
 +
を食べたYo。
 +
ごはん𠀋𠮷
 +
</syntaxhighlight2>
 +
 +
 +
という感じで、以上ですかね。
 +
 +
 +
基本機能を用いて、文字列操作のすべてを掌握できるような、異常なまでに長い記事を書いたつもりです。それくらい文字列操作はコンピュータを使う人から喜ばれるプログラミングだと思います。文字を扱うプログラムは意思を疎通したり記録したり、人間文化の中枢にある処理です。プログラムによって文字情報をうまく表示してくれたり、編集してくれたり、閲覧できるようになることは、ありがたいこと、この上ない機能でしょう。ここで紹介したものだけでは文字処理の効率はイマイチかもしれません。便利な文字列クラスはこのWebの世界をたぐり探せば存在するかもしれません。ですが、C++範疇の文字列操作のエッセンスとしては、ここで紹介したものがほとんど全てとなります。この長い記事を参考に理解する努力をしてみたのなら、やりたい文字列操作をどういう具合にやっていけばいいのかという基本というかコツみたいなものはつかめたと思います。つかめなかった人もヒントくらいにはなったのではないでしょうか?ここから先はプログラムされる人のそれぞれの文字列操作感覚に従って、プログラムを作りこんでいっていただければと思います。基本がわかっていれば、Webで検索してでてくるようなややこしい説明も理解していけるでしょう。やりたいことを実現するのは面倒で手数も多いと実感したと思います。効率よくやりたいことができるようになるまで、知恵を振り絞って、頑張ってみてください。ここまで理解しようとしたならきっとできるはずです。
 +
 +
 +
ここを参照してくれたみなさんが作れってくれたアプリが使いやすいものになって、いろんな人の人生を充実させるものになることを願います。
 +
 +
 +
[[C PlusPlus#Cにもあった技術|C++]]へ戻る
 +
 +
 
<!--
 
<!--
 
{|class="wikitable"
 
{|class="wikitable"

2022年9月5日 (月) 00:00時点における最新版



個人用ツール
名前空間

変種
操作
案内
ツールボックス