2009-11-16 105 views
0

我的工作再使用.NET編寫現有的Java軟件解決方案。在一個點上,Java解決方案在一個字符串的開始讀取時間標記,只要是這樣的:時間戳解析在C#

SimpleDateFormat dateFormat = new SimpleDateFormat(timeFormat); 
dateFormat.setLenient(false); 

try 
{ 
    timeStamp = dateFormat.parse(line); 
} 
catch (ParseException e) 
{ 
    //... 
} 

現在我試圖做同樣的在C#:

DateTimeFormatInfo dateTimeFormatInfo = new DateTimeFormatInfo(); 
dateTimeFormatInfo.FullDateTimePattern = format; 

try 
{ 
    timeStamp = DateTime.Parse(line, dateTimeFormatInfo); 
} 
catch (FormatException ex) 
{ 
    //... 
} 

兩種語言工作直到我在行變量中的時間戳之後添加一些隨機文本。 Java會忽略它,但C#在行中的時間戳文本之後將不允許其他任何內容。

因此,儘管Java是幸福的解析 「01/01/01 01:01:01001的Hello World」作爲時間戳,C#不是,因爲「Hello World!」未在格式字符串中指定。

然而,正如我不能做什麼可能來我的琴絃裏面的時間戳之後的任何說法,我不能將其包含在我的格式字符串。

任何想法?

預先感謝您。

+0

你能保證的日期格式將永遠是文件中的一樣嗎?只需取該行的前N個字符並解析該字符。 – 2009-11-16 14:21:31

+0

我可以保證日期格式是相同的,但是,您的解決方案不考慮日期格式,例如「2009年5月1日」。長度可能會大不相同。 – Callash 2009-11-16 14:24:00

+0

不是你的問題的答案,但如果可能的話,你應該使用DateTime.TryParse而不是try ... DateTime.Parse ... catch。 http://msdn.microsoft.com/en-us/library/system.datetime.tryparse.aspx – LukeH 2009-11-16 14:25:27

回答

1

如果你知道你的日期會在什麼樣的格式,並與它的存儲上下文那麼這是一個優勢。

舉例來說,如果你知道你是存儲昨天的日誌或類似的東西:

DateTime yesterday = DateTime.Today.AddDays(-1); 
timestamp = DateTime.Parse(
    line.SubString(0, line.IndexOf(yesterday.Year.ToString()) + 4)); 

編輯:有沒有什麼日期(甚至有一個空格)後劃定的文本?

如果有,你可以做這樣的事情:

private static DateTime GetDate(string line) 
{ 
    int index = 0; 
    DateTime theDate; 
    string s = line; 

    while(!DateTime.TryParse(s, out theDate)) 
    { 
     index = line.IndexOf(" ", index); 
     s = line.Substring(0, index); 
    } 

    return theDate; 
} 

注意:這將無法得到時候如果有日期後的文本(因爲它能夠解析出的日期不搜索時成功)。您可以通過從行尾開始獲取空格索引並向後移動來解決這個問題。我會把它留給你。

+0

不幸的是,我不這樣做。時間格式模式由配置給出,但日期可能是昨天,一個月前,一年前的任何事情。 – Callash 2009-11-16 14:23:00

0

看起來.NET是要分析整個字符串,你不控制整個字符串。我會說使用TryParse(),如果失敗,剝離字符串中最右邊的「單詞」,然後重試。我對Java並不熟悉,但它可能會在下面做到。

2

試試這個:

Dictionary<string, string> tests = new Dictionary<string,string>() 
{ 
    { "yy/MM/dd HH:mm:ss,fff", "01/01/01 01:01:01,001 Hello World!"}, 
    { "yyyyMMddHHmmssfff", "2009111615413829403 Hello World!"}, 
    { "d.M.yyyy H:m:s,fff", "8.10.2009 8:17:26,338 Hello World!" } 
}; 

foreach(KeyValuePair<string, string> test in tests) 
{ 
    string pattern = test.Key; 
    string format = test.Value; 

    DateTimeFormatInfo dateTimeFormatInfo = new DateTimeFormatInfo(); 
    dateTimeFormatInfo.FullDateTimePattern = pattern; 

    Console.WriteLine("{0} - {1}", pattern, format); 
    DateTime timeStamp = DateTime.MinValue; 
    if (pattern.Contains(' ')) // approach 1: split and conquer 
    { 
     format = String.Join(" ", format 
      .Split(" ".ToCharArray()) 
      .Take(pattern.Count(c => c == ' ') + 1)); 
    } 
    else 
    { 
     format = format.Substring(0, pattern.Length); 
    } 


    if (!DateTime.TryParseExact(
     format, pattern, dateTimeFormatInfo, 
     DateTimeStyles.AllowWhiteSpaces, out timeStamp)) 
    { 
     Console.WriteLine("\tSomething sad happened"); 
    } 
    else 
    { 
     Console.WriteLine("\t{0}", timeStamp.ToString(pattern)); 
    } 
} 
Console.Read(); 

注意我不使用DateTime.Parse,因爲它拋出一個異常,如果字符串不是有效DateTime格式化字符串。

UPDATE 1:更好的輸入處理,如不期望的空白,但使用模式長度

UPDATE 2:兩個先前方法合併到此的代碼;我知道在測試#2中使用一個d,但我認爲我們不能對此做任何事情。

+0

去那裏,但如果我看到它正確,這假定在時間戳後總是有一個空白。我可能遇到的一行代碼如下所示:「2009111615413829403」,即「yyyyMMddHHmmssfff」後跟兩位數的錯誤代碼。 – Callash 2009-11-16 14:42:06

+0

仍然不是,因爲您的解決方案期望時間模式和時間戳具有相同的長度。我的模式可能是「d.M.yyyy H:m:s,fff」(長度爲18),解析的時間戳可能是「8.10.2009 8:17:26,338」(長度爲21)。 – Callash 2009-11-16 15:08:18

+0

你是對的;該模式總是有效的? – 2009-11-16 15:22:30