我有一個.CSV文件,我正在讀入一個C#程序。在其中一列中,有一個日期,但是它是「一般」格式,因此它在.CSV中顯示爲一個數字。例如:41172.將Double轉換爲DateTime?
如何將此數字轉換爲格式爲dd/mm/yyyy的C#中的日期? 41172相當於20/09/2012。
我有一個.CSV文件,我正在讀入一個C#程序。在其中一列中,有一個日期,但是它是「一般」格式,因此它在.CSV中顯示爲一個數字。例如:41172.將Double轉換爲DateTime?
如何將此數字轉換爲格式爲dd/mm/yyyy的C#中的日期? 41172相當於20/09/2012。
編輯:正如在評論和其他答案中指出的,DateTime.FromOADate
是一個更好的方法。如果它不被接受,我會刪除這個答案。 (但是,仍然有像.NET核心在不支持FromOADate
平臺所以還是使用這些平臺的人有用。)
我懷疑你想:
DateTime date = new DateTime(1900, 1, 1).AddDays(days - 2);
(見爲什麼其他答案您需要減去2.)
Excel使用的日期格式舊,但DateTime.FromOADate函數仍支持該函數,您可以使用該函數轉換此數字。它被定義爲
數天前,或在基準日期後,午夜,12月30日 1899年
這就是我們通常使用Excel日期的方式。 – dash 2012-08-15 11:55:25
若要從日期時間去在「Excel的格式」的C#日期時間,你可以使用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.joelonsoftware.com/items/2006/06/16.html – CrazyPyro 2014-07-02 17:25:22
我已經看到了這個來自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 1900
(不是真實日期),然後61
給出01 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;
}
2000這是一個閏年。就像1600和2400一樣。所以你只有1900左右。 – 2012-08-15 12:01:15
@亨克:謝謝!我確實知道這一點,但不知何故忘了。哈哈,我是個白癡!我會編輯我的答案... – 2012-08-15 12:02:55
如果你正在尋找的.Net核心FromOADate
它不存在。
我分解了實現.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;
}
還需要測試它。
我同意沒有這樣的日期格式,因爲我知道我的asp.net!它只是一個隨機數!你sholud嘗試導出一個有效的日期到CSV文件。什麼程序正在創建CSV文件? – Haris 2012-08-15 11:40:01
DateTime.FromOADate(41172)是否適合您? – dash 2012-08-15 11:48:49