0

私はインド出身で、ここではdd-mm-yyyy日付形式に従います。

私の問題は、さまざまなクライアントが上記の形式で日時を表示する必要があることです。しかし、バックエンドとして使用する SQL Server は、dd-mm-yyyy を有効な日時形式として認識しません。私たちが通常行うことは、指定された日付を mm-dd-yyyy に変換することですCultureInfoConvert.ToDateTime() or DateTime.Parse or DateTime.TryParse()

また、入力日付が正しい形式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;
    }

上記の変更を提案して、私のメソッドが任意の日時を yyyy-mm-dd などの SQL Server 互換形式に自動的に変換するようにします。

使用法は次のようになります。

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)

注意: 日時の変換は、システム クロックに依存しないようにする必要があります。

前もって感謝します

4

5 に答える 5

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",
    };
}
于 2014-01-29T02:58:23.870 に答える
0

Habib が言うように、データベースに保存するために形式を知る必要はありません。DateTimeオブジェクトを保存するだけで、ado.net コネクタはそれを処理することを認識します。

問題は、ユーザーの入力文字列を .NETDateTimeオブジェクトに解析する時点にあるはずです。ユーザーの文化固有の設定を知らなければ、あなたは運命づけられています。それを処理する普遍的な方法を持つことはできません。日付を考えてみてください。またはその他の組み合わせ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-GBen-IN12/12/12dd/MM/yy

次のように呼び出します。

Common.ParseOrDefault(yourDateString);

もう 1 つのオプションは、競合する形式を除いて、既知のすべての可能な形式と照合することです。たとえば、フォーマットのみを考慮したい場合は、フォーマット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);
}
于 2014-01-23T05:30:03.080 に答える
0

日付を形式に解析する必要はありません。DateTime形式に関係なく、フィールドには SQL Server のデータ型を使用します。また、C# を介して SQL Server とやり取りする場合は、 SqlParameterを使用してください。DateTime形式は、日付の表示にのみ使用してください。お気に入り:

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;
    //.....
}
于 2013-04-25T10:00:52.020 に答える
0

個人的にはパラメータを使用します。それ以外の場合は、SQL Server で特定の DateTime 形式を強制できます。

于 2013-04-25T10:02:25.427 に答える