- 題名: 和暦の未来対応
- 日時: 2004/02/12 18:46:51
- ID: 2481
- この記事の返信元:
- (なし)
- この記事への返信:
- [2607] Re[1]: 和暦の未来対応2004/02/20 6:20:00
- ツリーを表示
チョコさん、こんばんは。深山と申します。
いろい試してみたのですけど、なかなか難しいようですね(^_^;)
どうやったらいいのかは判りませんでしたけど、レスがつかないようなので参考までに。
http://www.ailight.jp/Wareki_2.aspx
の内容を参考にウォッチとにらめっこしたところ、
JapaneseCalendar クラス(というより GregorianCalendarHelper のかも?)
・m_EraInfo フィールド
年号毎の期間(何年何月何日からその年号になるのか、
その年号は何年まであるのか等)を保持
・m_eras フィールド
Eras プロパティの値を保持
DateTimeFormatInfo クラス
・m_eraNames フィールド
"明治" 、 "大正" 等の元号名を保持
・m_abbrevEraNames フィールド
"明" 、 "大" 等の元号名略称を保持
・m_abbrevEnglishEraNames フィールド
"M" 、 "T" 等の元号名略称(アルファベット)を保持
あたりに情報を追加できればなんとかなるかも知れないなぁ、という印象でした。
なので、 DateTimeFormatInfo オブジェクトを作成、リフレクションを使ってこの辺を
書き換えてみるとかしたものを使用すれば、あるいは期待する動きになるかも知れません。
‥‥もちろん、ならないかも知れませんが。
# というよりならない可能性のが大きいですよね(汗)
# シェアードコードを落としてきて解析した方が確実な気も‥‥。
以下、個人的で素朴な疑問なのですけども。
この機能、ほんとに必要なのでしょうか?
Windows Update ができる、できない以前に、元号なんて頻繁に増えるものではありません。
場合によっては十数年、数十年も変わらないこともあるわけです。
マシンの耐用年数や OS の保障期間等よりも長い期間使用しないことになる可能性のある
機能って一体‥‥というのが正直な感想だったりします。
# それとも、そんなに長期の運用を求められるシステムなのでしょうか?
それからもう一点。
JapaneseCalendar クラスを使用して表示を行っている箇所というのはどの程度あるの
でしょう? 場合によっては、変換用の関数を自作した方が早いということもあります。
# もしかしたら、もうそのように対応されてるのかも知れませんけど(^_^;)
2004/02/25(Wed) 03:15:46 編集(投稿者)
チョコさん、こんにちは。
> シェアードコード、、、やっぱりそうですよね。
お力になれず申し訳ないですm(__)m
> 実はInputManという市販ツールを使用して元号を未来に対応させようしています。
> そこで調べてみたところ、このツールはカレンダ情報をJapaneseCalendarから
> 取得しているとわかり、今回の疑問に辿り着きました。
.NET 用の InputMan は使用したことがないので兼ね合いは判らないのですけども。
上記の方法で実験したら何となく上手くいったようですので、(参考にならないような気もしますけど/汗)
コードを掲載いたします。
尚、この Test メソッドの最後で m_currentEraValue を変更する処理をコメントアウトしていますが、
これは '現在' が '平成' ではなくなったら加える必要があります。
# コードはあまり整理されておらず、コメントも先ほど追加したものなので間違ってるかも‥‥(^_^;)
■設定
2010/7/30 から新元号 "どぼん" に変わった
# 管理人さま、勝手に屋号(?)を使用してごめんなさいm(__)m
static void Main()
{
DateTimeFormatInfo format = Form1.Test();
DateTime dt1 = DateTime.Parse("どぼん3年 12月 3日", format);
DateTime dt2 = new DateTime(2010, 7, 30);
DateTime dt3 = new DateTime(2010, 7, 29);
Console.WriteLine(dt1); // 2012/12/03 0:00:00 と出力
Console.WriteLine(dt2.ToString("gyy年MM月dd日", format)); // どぼん01年07月30日 と出力
Console.WriteLine(dt3.ToString("gyy年MM月dd日", format)); // 平成22年07月29日 と出力
}
private static DateTimeFormatInfo Test()
{
// DateTimeFormatInfo 作成
JapaneseCalendar japaneseCalendar = new JapaneseCalendar();
CultureInfo cultureInfo = new CultureInfo("ja-JP");
DateTimeFormatInfo dateTimeFormatInfo = cultureInfo.DateTimeFormat;
dateTimeFormatInfo.Calendar = japaneseCalendar;
// JapaneseCalendar の Type を取得
Type japaneseCalendarType = typeof(System.Globalization.JapaneseCalendar);
// helper を取得
FieldInfo helperFieldInfo = japaneseCalendarType.GetField("helper", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
object helper = helperFieldInfo.GetValue(dateTimeFormatInfo.Calendar);
// GregorianCalendarHelper の Type を取得
Type helperType = helperFieldInfo.FieldType;
// m_EraInfo を取得
FieldInfo eraInfoFieldInfo = helperType.GetField("m_EraInfo", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
Array eraInfo = (Array)eraInfoFieldInfo.GetValue(helper);
// EraInfo の Type を取得
Type eraInfoType = eraInfo.GetValue(0).GetType();
// m_EraInfo に設定する配列を作成
Array new_EraInfo = Array.CreateInstance(eraInfoType, 5);
// 要素 0 に新しく作成した EraInfo を設定
// 2010/7/30 から新しい元号に
new_EraInfo.SetValue(eraInfoType.Assembly.CreateInstance(eraInfoType.FullName, false, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, null, new object[] {5, (new DateTime(2010, 7, 30)).Ticks, 2009, 1, 7990}, cultureInfo, null), 0);
// '平成' の最終年を 22 (= 2010 - 1989 + 1) に変更
FieldInfo maxEraYearFieldInfo = eraInfoType.GetField("maxEraYear", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
maxEraYearFieldInfo.SetValue(eraInfo.GetValue(0), 22);
// 明治〜平成の分をコピーして m_EraInfo (GregorianCalendarHelper) に設定
eraInfo.CopyTo(new_EraInfo, 1);
eraInfo = new_EraInfo;
eraInfoFieldInfo.SetValue(helper, eraInfo);
// m_EraInfo (JapaneseCalendar) に設定
FieldInfo eraInfoFieldInfo2 = japaneseCalendarType.GetField("m_EraInfo", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
eraInfoFieldInfo2.SetValue(japaneseCalendar, eraInfo);
// m_eras
FieldInfo erasFieldInfo = helperType.GetField("m_eras", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
int[] eras = (int[])erasFieldInfo.GetValue(helper); // 取得
eras = new int[] {5, 4, 3, 2, 1}; // 編集
erasFieldInfo.SetValue(helper, eras); // 設定
// DateTimeFormatInfo の Type を取得
Type dateTimeFormatInfoType = typeof(System.Globalization.DateTimeFormatInfo);
// m_eraNames を取得 (Porperty Get されるまで Null のようなのでプロパティから読み出し)
PropertyInfo eraNamesPropertyInfo = dateTimeFormatInfoType.GetProperty("EraNames", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
string[] eraNames = (string[])eraNamesPropertyInfo.GetValue(dateTimeFormatInfo, null);
// 新元号 "どぼん" を追加
string[] new_eraNames = new string[5];
new_eraNames[4] = "どぼん";
eraNames.CopyTo(new_eraNames, 0);
// m_eraNames に設定
FieldInfo eraNamesFieldInfo = dateTimeFormatInfoType.GetField("m_eraNames", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
eraNamesFieldInfo.SetValue(dateTimeFormatInfo, new_eraNames);
// m_abbrevEraNames を取得 (Porperty Get されるまで Null のようなのでプロパティから読み出し)
PropertyInfo abbrevEraNamesPropertyInfo = dateTimeFormatInfoType.GetProperty("AbbreviatedEraNames", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
string[] abbrevEraNames = (string[])abbrevEraNamesPropertyInfo.GetValue(dateTimeFormatInfo, null);
// 新元号の略称 "ど" を追加
string[] new_abbrevEraNames = new string[5];
new_abbrevEraNames[4] = "ど";
abbrevEraNames.CopyTo(new_abbrevEraNames, 0);
// m_abbrevEraNames に設定
FieldInfo abbrevEraNamesFieldInfo = dateTimeFormatInfoType.GetField("m_abbrevEraNames", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
abbrevEraNamesFieldInfo.SetValue(dateTimeFormatInfo, new_abbrevEraNames);
// m_abbrevEnglishEraNames を取得 (Porperty Get されるまで Null のようなのでプロパティから読み出し)
PropertyInfo abbreviatedEnglishEraNamesPropertyInfo = dateTimeFormatInfoType.GetProperty("AbbreviatedEnglishEraNames", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
string[] abbreviatedEnglishEraNames = (string[])abbreviatedEnglishEraNamesPropertyInfo.GetValue(dateTimeFormatInfo, null);
// 新元号の略称(アルファベット) "D" を追加
string[] new_abbreviatedEnglishEraNames = new string[5];
new_abbreviatedEnglishEraNames[4] = "D";
abbreviatedEnglishEraNames.CopyTo(new_abbreviatedEnglishEraNames, 0);
// m_abbrevEnglishEraNames に設定
FieldInfo abbreviatedEnglishEraNamesFieldInfo = dateTimeFormatInfoType.GetField("m_abbrevEnglishEraNames", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
abbreviatedEnglishEraNamesFieldInfo.SetValue(dateTimeFormatInfo, new_abbreviatedEnglishEraNames);
// // Calendar の Type を取得
// Type calendarType = typeof(System.Globalization.Calendar);
//
// // m_currentEraValue を設定
// PropertyInfo currentEraValuePropertyInfo = calendarType.GetProperty("CurrentEraValue", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
// int currentEraValue = (int)currentEraValuePropertyInfo.GetValue(japaneseCalendar, null);
// FieldInfo currentEraValueFieldInfo = japaneseCalendarType.GetField("m_currentEraValue", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
// currentEraValueFieldInfo.SetValue(japaneseCalendar, 5);
return dateTimeFormatInfo;
}
> あと、なぜしなくてはいけないのか、、、大人の事情ってやつだそうです:;
なるほど。なっとくです(^_^;;;)
# 関係ないリンクを入れてしまってたようなので削除(汗)
分類:[.NET]
日本語版Windows基本クラスの「JapaneseCalendar」クラスについて教えて下さい。
現在、このクラスを使用して年号表示を行っているのですが、
これに未来の元号に対応させてプログラムを追加させようと思っています。
調べてみたところ、未来の元号を追加するためにはWindowsUpdateで
対応できるらしいのですが、諸事情によりコードで作成する必要があります。
色々と調べているのですが、足がかりがなく困っていますので宜しくお願いします。