LoginSignup
1
3

More than 5 years have passed since last update.

C++ Builder / TDateTime > from/to[新しい元号]変換処理 > .NET Framework関連の処理でVarToDateTime()が正常動作しないので自前変換した

Last updated at Posted at 2017-01-11
動作環境
C++ Builder XE4
Windows 7 pro (32bit)
.NET Framework: v4.5.1を有効化

VarToDateTimeの追加元号への対応について @ Delphi freeml

前準備

レジストリに新しい元号を登録する。
「宇宙_宇_Uchyu_U」とした。

qiita.png

v0.1 > エラー

code

FormatDateTime()とVarToDateTime()で実装。

Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    TDateTime startdt = VarToDateTime("2017/01/11 12:30:45");

    String strdt = FormatDateTime(L"ggee年mm月dd日", startdt);
    OutputDebugString(strdt.c_str());
    int nop1=1;

    TDateTime backdt = VarToDateTime(strdt);
    int nop2=1;

    OutputDebugString( DateTimeToStr(backdt).c_str() );
}
//---------------------------------------------------------------------------

実行

FormatDateTime()の部分ではレジストリの情報が使用されている。
VarToDateTime()の部分で以下のエラーとなった。

qiita.png

関連情報

https://social.msdn.microsoft.com/Forums/ja-JP/a93ec79d-69a5-4bb7-ae5d-a8aabfdcb9dd/systemglobalizationcultureinfo?forum=netfxgeneralja
を見ると

と説明されているとおりで、Windows 7以降でのネイティブアプリもしくは.NET 4.0を使用した場合にしか機能しません。手元でレジストリ設定して試してみましたが、Windows 10 + .NET 3.5ではやはり新しい元号は表示されませんでした。(Windows 10 + .NET 4以降では表示されました。)

C++ Builder XE4で実装したものは、.NET Frameworkとは関係ないのかと思っている。
そのため、上記のコメントのように設定したレジストリの文字列は使われていない(か正しく動作しない)のだろう。

v0.2 > 自前変換

Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <DateUtils.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------

static const TDate kDate_startNewEra = VarToDateTime("2016/01/01");


void __fastcall TForm1::Button1Click(TObject *Sender)
{
    TDateTime startdt = VarToDateTime("2017/01/11 12:30:45");

    String strdt = FormatDateTime(L"ggee年mm月dd日", startdt);
    OutputDebugString(strdt.c_str());

    TDateTime backdt;
    try {
        backdt = VarToDateTime(strdt);
    } catch (...) {
        // Not (.NET Framework 4 or native)
        String wrk = strdt.SubString(3, MAXINT); // 元号2文字を除去
        int startYear = kDate_startNewEra.FormatString(L"YYYY").ToInt();
        int addYear = startYear - 2000 - 1;
        backdt = VarToDateTime(wrk);
        backdt = IncYear(backdt, addYear);
    }

    OutputDebugString( DateTimeToStr(backdt).c_str() );
}
//---------------------------------------------------------------------------
結果
デバッグ出力: 宇宙02年01月11日 プロセス Project1.exe (3668)
デバッグ出力: 2017/01/11 プロセス Project1.exe (3668)

力技で変換できた。

もっと良い実装は他者にゆずる。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3