2013-04-25 48 views
0

我来自印度,在这里我们遵循dd-mm-yyyy日期格式。解析任何有效的DateTime格式为SQL Server兼容格式?

我的问题是,我们的各种客户需要他们的日期时间以上述格式显示。但是我们用作后端的SQL Server不会将dd-mm-yyyy识别为有效的日期时间格式。我们通常做的是无论是使用Convert.ToDateTime() or DateTime.Parse or DateTime.TryParse()

而且使用CultureInfo给定的日期,以MM-DD-YYYY转换,我就翻过另一种情况,当我输入的日期是正确的格式说MM-dd-yyyy or MM/dd/yyyy or yyyy-MM-dd,但我的本地系统日期除上述以外,则为it throws exception, input string in not in correct format。我无法弄清楚如何自动解决它。

存在自定义方法:但是这在大多数情况下都会失败。

/// <summary> 
    /// Parses string value from a supplied value to DateTime. 
    /// Usage: var i = Common.ParseDate(yourDateString); 
    /// </summary> 
    /// <param name="value"></param> 
    /// <returns></returns> 
    private static DateTime ParseDate(string value) 
    { 
     DateTime i; 
     if (!DateTime.TryParse(value, out i)) 
      return Convert.ToDateTime("01/01/1700",CultureInfo.InvariantCulture); 
// Assuming 01/01/1700 as default value instead of null. 
     return i; 
    } 

请提出上述变化,这样,我的方法会自动地将时间值转换到SQL Server兼容的格式一样YYYY-MM-DD。

用法应该是这样的:

Input: 
DateTime dt = DateTimeParser("29-12-2013"); // in case or double figure months and dates 

Output of dt: either 2013-12-29 or 12/29/2013 

DateTime dt = DateTimeParser("9-2-2013"); // in case or single figure months and dates 

Output of dt: either 2013-2-9 or 2/9/2013 (sql-server compatible) 

请注意:日期时间的转换应该是独立的系统时钟。

在此先感谢

+0

用户输入日期的方式是什么? – lavrik 2013-04-25 10:02:56

+0

@lavrik dd/mm/yyyy或dd-mm-yyyy。另一个主要问题是我的Windows时钟日期时间格式。如果它与用户输入不同,则会引发异常 – 2013-04-25 10:30:44

+1

因此,视图和逻辑之间没有层。值得为适当的日期时间输入创建用户控件。这是我认为的最好的方式:为了允许用户在相同的应用程序范围内输入数据,所以您的逻辑输入应该是DateTime实例,而不是最早执行步骤中的字符串。你创建了什么样的应用程序 - 网络桌面等? – lavrik 2013-04-25 10:58:48

回答

0

你并不需要解析日期的格式。在字段中使用DateTime数据类型,该字段为格式的字段。当通过C#与SQL Server进行交互时,请确保使用SqlParameterDateTime格式只能用于显示日期。像:

using(SqlConnection conn = new SqlConnection("connectionstring")) 
using (SqlCommand cmd = new SqlCommand()) 
{ 
    cmd.CommandText = "Insert into yourtable(datecolumn) VALUES (@pDate);"; 
    cmd.Parameters.AddWithValue("@pDate", DateTime.Now); 
    cmd.Connection = conn; 
    //..... 
} 
+0

我已经试过了。但是我的代码本身抛出了后面代码的异常。我不在这里讨论SQL异常。 – 2013-04-25 10:03:05

+0

@AmitRanjan,我不明白。 SQL日期时间是格式的,所以。NET日期时间。您是否在客户解析日期输入时遇到异常? – Habib 2013-04-25 10:04:05

+0

是的,我在代码级别出现错误,当我们显示我的本地格式的SQL日期并将它们保存回它们相应的DateTime属性时。 – 2013-04-25 10:08:29

0

试试这个代码如果你的输入日期是“dd/mm/yyyy”,那么它会转换Sql complient格式,否则它给你的消息日期格式不是预期的格式。

var dd = string.Empty; 
    var mm = string.Empty; 
    var yy = string.Empty; 
    string actualDate = "18/07/2012"; 
    string finalDate = string.Empty; 
    if (actualDate.ToString().Contains('/')) 
    { 
     dd = string.Format("{0:00}", Convert.ToInt32(actualDate.ToString().Split('/')[0])); 
     mm = string.Format("{0:00}", Convert.ToInt32(actualDate.ToString().Split('/')[1])); 
     yy = string.Format("{0:0000}", Convert.ToInt32(actualDate.ToString().Split('/')[2])); 
     finalDate = dd + "/" + mm + "/" + yy; 
    } 

    string dateString = finalDate; // <-- Valid 
    string format = "dd/MM/yyyy"; 
    DateTime dateTime; 
    if (!DateTime.TryParseExact(dateString, format, CultureInfo.InvariantCulture, 
     DateTimeStyles.None, out dateTime)) 
    { 
     lblDate.Text= "Excel Date is not correct format.it should be in dd/mm/yyyy"; 
    } 
    else 
    { 
     actualDate = 
      DateTime.ParseExact(dateString, format, 
            CultureInfo.InvariantCulture, 
            DateTimeStyles.None).ToString(); 
    } 

    Label1.Text = actualDate; 
0

由于哈比卜说,将其保存在数据库中,你不需要了解任何格式,只需保存DateTime对象和您的ado.net连接器知道来处理它。

您的问题应该是在解析用户的输入字符串到.NET DateTime对象。现在不知道用户的文化特定设置,你注定要失败。你不能有一种通用的方式来处理它。考虑日期12/12/12,这可能意味着dd/MM/yyMM/dd/yy或任何其他组合。


您最好的选择是获取有关用户,他的文化和相应的解析信息。或要求他以您特别指定的格式输入。


嗯,你可以依靠一些启发来匹配常见的格式,通过假设格式但其完全脆。只有在精度不是问题的情况下,这可以是方便的。

private static DateTime ParseOrDefault(string value) 
{ 
    DateTime result; 
    var sett = DateTimeStyles.AllowWhiteSpaces; //and whatever that is 
    var formats = GetDateTimeFormats //whatever cultures that you want to consider. 
    (
     new CultureInfo("en-GB"), //prioritize your order 
     new CultureInfo("en-IN"), 
     CultureInfo.CurrentCulture, 
     CultureInfo.InvariantCulture 
    ); 

    if (!DateTime.TryParseExact(value, formats, CultureInfo.InvariantCulture, sett, out result)) 
     return Convert.ToDateTime("01/01/1700", CultureInfo.InvariantCulture); 

    return result; 
} 

string[] GetDateTimeFormats(params CultureInfo[] cultures) 
{ 
    return cultures.SelectMany(x => x.DateTimeFormat.GetAllDateTimePatterns()) 
        .Distinct() 
        .ToArray(); 
} 

DateTime.ParseExactDateTime.TryParseExact有过载来实现对多种格式匹配。以上方法假定来自用户的输入字符串首先在en-GB,en-IN等文化中,即在12/12/12的情况下,它将其视为dd/MM/yy。这是一个假设,但它可以在不知道输入的情况下得到尽可能的接近,并且唯一的选择就是假设。 已提醒。

这样称呼它:

Common.ParseOrDefault(yourDateString); 

另一种选择可能是因为你对阵你知道排除冲突格式的所有可能的格式。例如,如果您只想考虑dd/MM/yy格式,则可以筛选出MM/dd/yyyy/MM/dd格式。现在您可以获得大量格式并避免冲突。可以稍微好点。

static string[] formats; //made static for performance reasons 

private static DateTime ParseOrDefault(string value) 
{ 
    formats = formats ?? GetDateTimeFormats(); 

    DateTime result; 
    var sett = DateTimeStyles.AllowWhiteSpaces; //and whatever that is 

    if (!DateTime.TryParseExact(value, formats, CultureInfo.InvariantCulture, sett, out result)) 
     return Convert.ToDateTime("01/01/1700", CultureInfo.InvariantCulture); 

    return result; 
} 

static string[] GetDateTimeFormats() 
{ 
    var allFormats = CultureInfo.GetCultures(CultureTypes.AllCultures) 
           .SelectMany(x => x.DateTimeFormat.GetAllDateTimePatterns()) 
           .Distinct(); //to speed up things 

    //discard some formats that're not worthy of consideration 
    var goodFormats = allFormats.Where(x => !IsConflictingFormat(x)); 

    return goodFormats.ToArray(); 
} 

//to remove conflicting date formats, for example, 
//formats like MM-dd-yy, yy-MM-dd, dd-MM-yy etc can be conflicting 
static bool IsConflictingFormat(string format) 
{ 
    //in this example we discard formats like M-d-yy, yy-MM-dd etc, but keep dd-MM-yy 
    //in case you want to keep MM-dd-yy, the placeholders array should be { 'd', 'y' }, 
    //and similarly if the preferred format is yy-MM-dd, array should be { 'M', 'd' } 
    var placeholders = new[] { 'M', 'y' }; 

    var separators = new[] { ' ', '.', '-', '/' }; 

    var patterns = placeholders.Select(x => x.ToString()) 
           .SelectMany(x => new[] { x, x + x }) 
           .SelectMany(x => separators, (x, y) => x + y); 

    return patterns.Any(format.StartsWith); 
} 
1

我有这个确切的事情想一次,虽然我们是在一个位置,承担用户的意思,因为正确并不重要(对于像MS Excel没有,当你输入一个文本日期时间) 。

实际上,您可以从内置的文化中收集所有可能的日期时间格式,以及您可以自定义的许多自定义格式。我曾经想要一个非常全面的日期时间格式匹配。

我做了一些非常类似于nawfal的答案。这是一个解决方案,他的答案与我的大量格式相结合:

static string[] GetDateTimeFormats() 
{ 
    var defaultFormats = CultureInfo.GetCultures(CultureTypes.AllCultures) 
            .SelectMany(x => x.DateTimeFormat.GetAllDateTimePatterns()) 
            .Distinct(); //to speed up things 

    //discard some formats that're not worthy of consideration 
    var goodDefaultFormats = defaultFormats.Where(x => !IsPoorFormat(x) && !IsConflictingFormat(x)); 

    var customFormats = GetCustomDateTimeFormats(); 

    var allFormats = goodDefaultFormats.Concat(customFormats).ToArray(); 

    //a technique to get comma separated time formats, 
    //for eg, from dd-MM-yyyy h:mm:ss tt we get -> dd-MM-yyyy, h:mm:ss tt 
    var moreCustomFormats = allFormats.Select(f => new 
             { 
              f, 
              i = f.IndexOf(" h", StringComparison.OrdinalIgnoreCase) 
             }) 
             .Where(x => x.i >= 0) 
             .Select(x => new { x.f, c = x.f[x.i - 1], x.i }) 
             .Where(x => !char.IsPunctuation(x.c) && x.c != 't') 
             .Select(x => x.f.Insert(x.i, ",")); 

    allFormats = allFormats.Union(moreCustomFormats).ToArray(); //Union removes duplicates 

    return allFormats; 
} 

static bool IsPoorFormat(string format) 
{ 
    //all discardable formats in case any 
    string[] ignorables = { "HH", "MMMM yyyy", "MMMM, yyyy", "yyyy MMMM", "yyyy.M", "yyyy-MM", 
          "MMMM,yy", "MMMM, yy", "MMMM,yyyy", "MMMM, yyyy", "yyyy. MMMM" }; 

    return ignorables.Contains(format); 
} 

//to remove conflicting date formats, for example, 
//formats like MM-dd-yy, yy-MM-dd, dd-MM-yy etc can be conflicting 
static bool IsConflictingFormat(string format) 
{ 
    //in this example we discard formats like M-d-yy, yy-MM-dd etc, but keep dd-MM-yy 
    //in case you want to keep MM-dd-yy, the placeholders array should be { 'd', 'y' }, 
    //and similarly if the preferred format is yy-MM-dd, array should be { 'M', 'd' } 
    var placeholders = new[] { 'M', 'y' }; 

    var separators = new[] { ' ', '.', '-', '/' }; 

    var patterns = placeholders.Select(x => x.ToString()) 
           .SelectMany(x => new[] { x, x + x }) 
           .SelectMany(x => separators, (x, y) => x + y); 

    return patterns.Any(format.StartsWith); 
} 

static string[] GetCustomDateTimeFormats() 
{ 
    return new[] 
    { 
     "dddd, MMMM d, yyyy h:mm:ss tt", 
     "dddd, MMMM d, yyyy H:mm:ss", 
     "dddd, MMMM d, yyyy h:mm tt", 
     "dddd, MMMM d, yyyy H:mm", 

     "dddd, MMM d, yyyy h:mm:ss tt", 
     "dddd, MMM d, yyyy H:mm:ss", 
     "dddd, MMM d, yyyy h:mm tt", 
     "dddd, MMM d, yyyy H:mm", 

     "ddd, MMMM d, yyyy h:mm:ss tt", 
     "ddd, MMMM d, yyyy H:mm:ss", 
     "ddd, MMMM d, yyyy h:mm tt", 
     "ddd, MMMM d, yyyy H:mm", 

     "ddd, MMM d, yyyy h:mm:ss tt", 
     "ddd, MMM d, yyyy H:mm:ss", 
     "ddd, MMM d, yyyy h:mm tt", 
     "ddd, MMM d, yyyy H:mm", 



     "dddd, MMMM d yyyy h:mm:ss tt", 
     "dddd, MMMM d yyyy H:mm:ss", 
     "dddd, MMMM d yyyy h:mm tt", 
     "dddd, MMMM d yyyy H:mm", 

     "dddd, MMM d yyyy h:mm:ss tt", 
     "dddd, MMM d yyyy H:mm:ss", 
     "dddd, MMM d yyyy h:mm tt", 
     "dddd, MMM d yyyy H:mm", 

     "ddd, MMMM d yyyy h:mm:ss tt", 
     "ddd, MMMM d yyyy H:mm:ss", 
     "ddd, MMMM d yyyy h:mm tt", 
     "ddd, MMMM d yyyy H:mm", 

     "ddd, MMM d yyyy h:mm:ss tt", 
     "ddd, MMM d yyyy H:mm:ss", 
     "ddd, MMM d yyyy h:mm tt", 
     "ddd, MMM d yyyy H:mm", 

     /////////////////////////// 

     "dddd, d MMMM, yyyy h:mm:ss tt", 
     "dddd, d MMMM, yyyy H:mm:ss", 
     "dddd, d MMMM, yyyy h:mm tt", 
     "dddd, d MMMM, yyyy H:mm", 

     "dddd, d MMM, yyyy h:mm:ss tt", 
     "dddd, d MMM, yyyy H:mm:ss", 
     "dddd, d MMM, yyyy h:mm tt", 
     "dddd, d MMM, yyyy H:mm", 

     "ddd, d MMMM, yyyy h:mm:ss tt", 
     "ddd, d MMMM, yyyy H:mm:ss", 
     "ddd, d MMMM, yyyy h:mm tt", 
     "ddd, d MMMM, yyyy H:mm", 

     "ddd, d MMM, yyyy h:mm:ss tt", 
     "ddd, d MMM, yyyy H:mm:ss", 
     "ddd, d MMM, yyyy h:mm tt", 
     "ddd, d MMM, yyyy H:mm", 



     "dddd, d MMMM yyyy h:mm:ss tt", 
     "dddd, d MMMM yyyy H:mm:ss", 
     "dddd, d MMMM yyyy h:mm tt", 
     "dddd, d MMMM yyyy H:mm", 

     "dddd, d MMM yyyy h:mm:ss tt", 
     "dddd, d MMM yyyy H:mm:ss", 
     "dddd, d MMM yyyy h:mm tt", 
     "dddd, d MMM yyyy H:mm", 

     "ddd, d MMMM yyyy h:mm:ss tt", 
     "ddd, d MMMM yyyy H:mm:ss", 
     "ddd, d MMMM yyyy h:mm tt", 
     "ddd, d MMMM yyyy H:mm", 

     "ddd, d MMM yyyy h:mm:ss tt", 
     "ddd, d MMM yyyy H:mm:ss", 
     "ddd, d MMM yyyy h:mm tt", 
     "ddd, d MMM yyyy H:mm", 

     ///////////////////////////////// 

     "yyyy, MMMM d h:mm:ss tt", 
     "yyyy, MMMM d H:mm:ss", 
     "yyyy, MMMM d h:mm tt", 
     "yyyy, MMMM d H:mm", 

     "yyyy, MMM d h:mm:ss tt", 
     "yyyy, MMM d H:mm:ss", 
     "yyyy, MMM d h:mm tt", 
     "yyyy, MMM d H:mm", 

     "yyyy, MM d h:mm:ss tt", 
     "yyyy, MM d H:mm:ss", 
     "yyyy, MM d h:mm tt", 
     "yyyy, MM d H:mm", 



     "yyyy MMMM d h:mm:ss tt", 
     "yyyy MMMM d H:mm:ss", 
     "yyyy MMMM d h:mm tt", 
     "yyyy MMMM d H:mm", 

     "yyyy MMM d h:mm:ss tt", 
     "yyyy MMM d H:mm:ss", 
     "yyyy MMM d h:mm tt", 
     "yyyy MMM d H:mm", 

     "yyyy MM d h:mm:ss tt", 
     "yyyy MM d H:mm:ss", 
     "yyyy MM d h:mm tt", 
     "yyyy MM d H:mm", 

     /////////////////////// 

     "yyyy, d MMMM h:mm:ss tt", 
     "yyyy, d MMMM H:mm:ss", 
     "yyyy, d MMMM h:mm tt", 
     "yyyy, d MMMM H:mm", 

     "yyyy, d MMM h:mm:ss tt", 
     "yyyy, d MMM H:mm:ss", 
     "yyyy, d MMM h:mm tt", 
     "yyyy, d MMM H:mm", 

     "yyyy, d MM h:mm:ss tt", 
     "yyyy, d MM H:mm:ss", 
     "yyyy, d MM h:mm tt", 
     "yyyy, d MM H:mm", 



     "yyyy d MMMM h:mm:ss tt", 
     "yyyy d MMMM H:mm:ss", 
     "yyyy d MMMM h:mm tt", 
     "yyyy d MMMM H:mm", 

     "yyyy d MMM h:mm:ss tt", 
     "yyyy d MMM H:mm:ss", 
     "yyyy d MMM h:mm tt", 
     "yyyy d MMM H:mm", 

     "yyyy d MM h:mm:ss tt", 
     "yyyy d MM H:mm:ss", 
     "yyyy d MM h:mm tt", 
     "yyyy d MM H:mm", 

     //////////////////////////////// 

     "MMMM d, yyyy h:mm:ss tt", 
     "MMMM d, yyyy H:mm:ss", 
     "MMMM d, yyyy h:mm tt", 
     "MMMM d, yyyy H:mm", 

     "MMM d, yyyy h:mm:ss tt", 
     "MMM d, yyyy H:mm:ss", 
     "MMM d, yyyy h:mm tt", 
     "MMM d, yyyy H:mm", 



     "MMMM d yyyy h:mm:ss tt", 
     "MMMM d yyyy H:mm:ss", 
     "MMMM d yyyy h:mm tt", 
     "MMMM d yyyy H:mm", 

     "MMM d yyyy h:mm:ss tt", 
     "MMM d yyyy H:mm:ss", 
     "MMM d yyyy h:mm tt", 
     "MMM d yyyy H:mm", 

     //////////////////////////////////// 

     "d MMMM, yyyy h:mm:ss tt", 
     "d MMMM, yyyy H:mm:ss", 
     "d MMMM, yyyy h:mm tt", 
     "d MMMM, yyyy H:mm", 

     "d MMM, yyyy h:mm:ss tt", 
     "d MMM, yyyy H:mm:ss", 
     "d MMM, yyyy h:mm tt", 
     "d MMM, yyyy H:mm", 



     "d MMMM yyyy h:mm:ss tt", 
     "d MMMM yyyy H:mm:ss", 
     "d MMMM yyyy h:mm tt", 
     "d MMMM yyyy H:mm", 

     "d MMM yyyy h:mm:ss tt", 
     "d MMM yyyy H:mm:ss", 
     "d MMM yyyy h:mm tt", 
     "d MMM yyyy H:mm", 

     ///////////////////////// 

     "dddd, MMMM d, yyyy", 
     "dddd, MMM d, yyyy", 

     "ddd, MMMM d, yyyy", 
     "ddd, MMM d, yyyy", 



     "dddd, MMMM d yyyy", 
     "dddd, MMM d yyyy", 

     "ddd, MMMM d yyyy", 
     "ddd, MMM d yyyy", 

     ////////////////////////// 

     "dddd, d MMMM, yyyy", 
     "dddd, d MMM, yyyy", 

     "ddd, d MMMM, yyyy", 
     "ddd, d MMM, yyyy", 



     "dddd, d MMMM yyyy", 
     "dddd, d MMM yyyy", 

     "ddd, d MMMM yyyy", 
     "ddd, d MMM yyyy", 

     /////////////////////////// 

     "MMMM d, yyyy", 
     "MMM d, yyyy", 

     "MMMM d yyyy", 
     "MMM d yyyy", 

     ////////////////////////// 

     "d MMMM, yyyy", 
     "d MMM, yyyy", 

     "d MMMM yyyy", 
     "d MMM yyyy", 

     ////////////////////////// 

     "yyyy, MMMM d", 
     "yyyy, MMM d", 

     "yyyy MMMM d", 
     "yyyy MMM d", 

     ////////////////////////// 

     "yyyy d MMMM", 
     "yyyy d MMM", 

     "yyyy, d MMMM", 
     "yyyy, d MMM", 

     /////////////////////////// 

     "d MMMM", 
     "d MMM", 

     ///////////////////////////// 

     "MMMM d", 
     "MMM d", 

     //////////////////////////// 

     "dd", 
    }; 
}