11

C# プログラムに読み込んでいる .CSV ファイルがあります。列の 1 つに日付がありますが、これは「一般的な」形式であるため、.CSV では数値と​​して表示されます。例: 41172。

この数値をC#でdd/mm/yyyy形式の日付に変換するにはどうすればよいですか? 41172 は 2012 年 9 月 20 日と同等です。

4

5 に答える 5

33

「Excel 形式」の DateTime から C# Date Time に移行するには、DateTime.FromOADate関数を使用できます。

上記の例では:

   DateTime myDate = DateTime.FromOADate(41172);

目的の形式で表示するために書き出すには、次を使用します。

   myDate.ToString("dd/MM/yyyy");

Excel の日付処理の不一致がどこから来るのか疑問に思っている場合、それは意図的なものであるはずです:

Lotus 1-2-3 が最初にリリースされたとき、プログラムは 1900 年が実際にはうるう年ではなくても、うるう年であると想定していました。これにより、プログラムはうるう年を簡単に処理できるようになり、Lotus 1-2-3 のほぼすべての日付計算に悪影響を与えることはありませんでした。

Microsoft Multiplan と Microsoft Excel がリリースされたときも、1900 年がうるう年であると想定されていました。これにより、Microsoft Multiplan と Microsoft Excel は、Lotus 1-2-3 と同じシリアル日付システムを使用できるようになり、Lotus 1-2-3 との互換性が向上しました。1900 年をうるう年として扱うことで、ユーザーはワークシートをあるプログラムから別のプログラムに移動しやすくなりました。

現在のバージョンの Microsoft Excel で 1900 年がうるう年であると想定されないように、この動作を修正することは技術的に可能ですが、その欠点は利点を上回ります。

ソース: http://www.ozgrid.com/Excel/ExcelDateandTimes.htm

于 2012-08-15T11:53:58.377 に答える
15

編集:コメントやその他の回答に記載されているようにDateTime.FromOADate、はるかに優れたアプローチです。受け入れられない場合は、この回答を削除します。(ただし、サポートされていない .NET Core のようなプラットフォームFromOADateがまだあるため、これらのプラットフォームを使用しているユーザーにとっては依然として有用です。)

私はあなたが欲しいと思う:

DateTime date = new DateTime(1900, 1, 1).AddDays(days - 2);

(2を引く必要がある理由については、他の回答を参照してください。)

于 2012-08-15T11:42:47.160 に答える
3

FromOADate.Net Core で探している場合、そこにはありません。

.Net Framework の実装を逆アセンブルし、拡張メソッドを作成しました。

        public static DateTime FromOADate(this double date)
        {
            return new DateTime(DoubleDateToTicks(date), DateTimeKind.Unspecified);
        }

        internal static long DoubleDateToTicks(double value)
        {
            if (value >= 2958466.0 || value <= -657435.0)
                throw new ArgumentException("Not a valid value");
            long num1 = (long)(value * 86400000.0 + (value >= 0.0 ? 0.5 : -0.5));
            if (num1 < 0L)
                num1 -= num1 % 86400000L * 2L;
            long num2 = num1 + 59926435200000L;
            if (num2 < 0L || num2 >= 315537897600000L)
                throw new ArgumentException("Not a valid value");
            return num2 * 10000L;
        }

まだテストする必要があります。

于 2017-04-26T06:49:57.727 に答える
2

Excel で使用される日付形式は古いものですが、この数値を変換するために使用できるDateTime.FromOADate関数で引き続きサポートされています。次のように定義されます。

基準日である 1899 年 12 月 30 日の午前 0 時からの前後の日数

于 2012-08-15T11:52:36.713 に答える
-1

MSDN からこれを見たことがあります: http://msdn.microsoft.com/en-us/library/system.datetime.fromoadate.aspx、しかし実際には間違っていると思います。

本当の問題は、Excel が世紀の年 (1900 年) を閏年であると誤って想定しているのに対し、実際には閏年ではなく、2000 年だったことです。

これを確認するには、Excel でセルを日付としてフォーマットしてから入力1してみてください1 Jan 1900。入力する59と、 が得られ28 Feb 1900ます。(実際の日付ではない) を与え、次に60を与えます。29 Feb 19006101 March 1900

そう...

switch (days)
{
   case < 1:
     // Not valid. Do whatever...
   break;
   case < 59:
     DateTime date = new DateTime(1900, 1, 1).AddDays(days);
   break;
   default:
     // Knock off the extra days caused by 29 Feb 1900 and 29 Feb 2000
     DateTime date = new DateTime(1900, 1, 1).AddDays(days-2);
   break;
}
于 2012-08-15T11:54:49.757 に答える