从C#中的字符串开头解析时间戳

时间:2009-11-16 14:16:38

标签: c# .net datetime parsing timestamp

我正在努力用.NET重写现有的Java软件解决方案。有一次,Java解决方案在字符串的开头读取时间戳,就像这样:

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:01,001 Hello World!”作为时间戳,C#不是,因为“Hello World!”未在格式字符串中指定。

但是,由于我无法对字符串中的时间戳之后可能出现的内容做出任何声明,因此我无法将其包含在我的格式字符串中。

有什么想法吗?

提前谢谢。

3 个答案:

答案 0 :(得分: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,因为如果String不是有效的DateTime格式化字符串,它会抛出异常。

UPDATE 1 :更好的输入处理,因为不要指望空格,但使用模式长度

更新2 :前两个方法合并到此代码中;我知道在测试#2中使用单个d,但我认为我们无法对此做任何事情。

答案 1 :(得分: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;
}

注意:如果日期之后有文本,这将无法获得时间(因为它可以在搜索时成功解析日期)。您可以通过获取从行尾开始并向后移动的空格索引来解决此问题。我会留给你的。

答案 2 :(得分:0)

看起来.Net将解析整个字符串而你无法控制整个字符串。我会说使用TryParse(),如果失败,从你的字符串中删除最右边的“单词”并重新尝试。我不熟悉Java,但它可以在幕后完成。