2010-03-10 2 views
0

dateTimePicker.Value.Date.ToShortDateString();은 Windows 7 x64 PL, Windows Vista x32 PL 및 Windows XP PL에서 다르게 동작 할 수있는 이유는 정확한 지역 설정입니다. 나는 그것을 DB에 입력하기 전에이 변환을하는 것이 어렵다는 것을 발견했습니다.C# 및 SQL 데이터베이스의 지역적 문제

Windows 7 (내 개발 컴퓨터), 동료 VISTA 시스템에서 제대로 작동했지만 Windows XP에서 작동하지 못했습니다 (하루가 항상 월로 전환됨). 또한 상위 시스템에서는 2010 년 1 월 13 일을 ListView에 표시하고 자신의 시스템에는 13-01-2010을 표시합니다.

나는 내 옛날 코드에서 더 많은 타입 변환을 할 수 있다고 상상해 본다. 그리고 나는 그것을 통과해야만 할 것이다. 그러나 나는 그것이 같은 지역 설정에서 그렇게 행동하는 이유를 알고 싶다. 나는 결코 그런 전환을해서는 안된다고 생각하지만 오랜 시간이 지나면 잘 작동하는 것을 힘든 방법으로 배웠습니다.

편집

: 나는이 방법을 사용했다

(문제를 일으키는 코드를 주석). 위로 옛날 나는 ToShortDateString이 Time (DateTimePicker를 읽었을 때부터)없이 DB에 넣을 수있는 유일한 방법이라고 생각했습니다. 나는 DateTimePicker에서 .Date를 사용 했어야했음을 알았지 만 이제는 나에게 불어났다. 코드는 다음과 같습니다.

private static void sqlWpiszDaneSwieta(DateTime varData, string varDataNazwa) { 
     //string varDataSwieto = varData.ToShortDateString(); 
     const string preparedCommand = @"INSERT INTO [dbo].[TypyDatySwiat] 
              ([SwietaData] 
              ,[SwietaNazwa]) 
            VALUES 
              (@varData 
              ,@varDataNazwa)"; 
      using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails)) 
     using (SqlCommand sqlWrite = new SqlCommand(preparedCommand, varConnection)) { 
      sqlWrite.Prepare(); 
      sqlWrite.Parameters.AddWithValue("@varData", varData); 
      sqlWrite.Parameters.AddWithValue("@varDataNazwa", varDataNazwa); 
      try { 
       sqlWrite.ExecuteNonQuery(); 
      } catch (SqlException sqlEx) { 
       if (sqlEx.Message.Contains("Violation of PRIMARY KEY constraint")) { 
        MessageBox.Show("Dodanie podanego święta jest niemożliwe. Podane święto istnieje już w bazie danych!", "Bład", MessageBoxButtons.OK, MessageBoxIcon.Error); 
       } else { 
        MessageBox.Show(sqlEx.ToString(), "Bład SQL", MessageBoxButtons.OK, MessageBoxIcon.Error); 
       } 
      } catch (Exception ex) { 
       MessageBox.Show(ex.ToString(), "Bład", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      } 
     } 

그렇기 때문에 구체적인 방법은 묻지 않습니다. 나는 그것을 어떻게하는지, 그리고 DateTime을 사용하여 db에 직접 전달할 수 있음을 알고있다. 그냥 내가 왜 1 기계에서 다르게 행동 할 것인지 알고 싶습니다. 즉,이 날짜에 대한 일반적인 방법이기 때문에

+0

왜 'DateTime'을 문자열로 변환해야합니까? 매개 변수를 사용한다면'DateTime' 인스턴스를 직접 전달할 수 있습니다. (그리고 매개 변수를 사용하지 않는다면 ... 왜 안 되니?) –

+0

글쎄, 내 옛날 코드라고 했지. 많은 일을하기 전에는 안됩니다. DateTime을 올바르게 전달하기 위해 매개 변수를 사용하고 있습니다. 올바르게 작동 했으므로 변경하지 않아도되었습니다. 나는 그것을 배우고있는 동안 내가했던 모든 '나쁜'것들을 고치고 교정 할 달 청소에 그것을하기 위해 그것을 계획했다. – MadBoy

답변

5

일는 달에 의심 동료가 자신의 XP 시스템에서 영국의 로케일을 사용하고 같은 소리 모든 시간

을 전환했다.

는 그러나 나는 이것에 대해 더 걱정 :

사전 DB에 입력합니다.

DB에 넣는다면 왜 .ToShortDateString()으로 전화를 걸까요? 그게 나에게 동적 SQL의 냄새, 그리고 그 SQL 주입 취약점을 의미합니다. 대신 같은 뭔가 :

string sql = "INSERT INTO [MyTable] (MyDateColumn) VALUES (" + MyDateVar.ToShortDateString() + ")"; 
//sql command/connection code omitted from this sample 

당신이 뭔가를 할 필요가 :

string sql = "INSERT INTO [MyTable] (MyDateColumn) VALUES (@MyDate)" 
using (var cn = new SqlConnection("..connection string..")) 
using (var cmd = new SqlCommand(sql, cn)) 
{ 
    cmd.Parameters.Add("@MyDate", SqlDbType.DateTime).Value = MydateVar; 

//remain code omitted 

주의는 후자의 샘플은 결코 문자열로 날짜 변수를 변환하지 않습니다. 사용자가 설정 한 로케일에 상관없이 작동합니다.

+0

메인 포스트를 편집하여 사용 방법을 보여줍니다 (잘못된 코드를 주석 처리했습니다). 그래서 동적 SQL을 사용하고 있었는데 DateTime을 DB로 변환하기 전에 ShortDateString()으로 변환하면 이런 일이 발생했습니다. 나는 내가 전환을해서는 안된다는 것을 알고 있지만 나는 그 때 그 사실을 몰랐다. 나는 날짜 만 기입하고 싶었 기 때문에 그 때 그 일을하는 가장 좋은 방법이라고 생각했습니다. – MadBoy

+0

영국 설정을 사용하고 있지 않습니다. 그의 XP는 PL이고, 폴란드어 설정도 사용하고 있습니다. – MadBoy

0

소리는 지역 설정과 매우 유사합니다. 응용 프로그램이 실행중인 계정의 국가 별 설정을 확인하여 설명을 제공하는지 확인합니다.

문제를 처리하는 경우 DateTimeToBinary 메서드는 값을 나중에 다시 만들 수있는 방식으로 내보내는 안전한 방법을 제공합니다. 더 좋은 점은 이것이 데이터베이스에 들어가는 것을 고려할 때 다른 사람들이 제안한 것처럼 SQLCommand에 값을 전달하는 것입니다.

1

불변 문화를 사용하여 데이터베이스에 날짜/시간 같은 것을 저장하는 것이 더 좋을 것이라고 생각했을 것입니다. 지역 설정에 대해 염려해야하는 것은 사용자에게 표시하기 위해 데이터베이스에서 가져 오는 것입니다.

데이터베이스에 ShortDateString을 저장하는 대신 DateTime.ToString(System.Globalization.CultureInfo.InvariantCulture)을 사용해야합니다.

사용중인 문화를 (코드에서) 보려면 System.Globalization.CultureInfo.CurrentCulture.Name을 사용하십시오.

+0

방금 ​​System.Globalization.CultureInfo.CurrentCulture.Name 코드를 사용하여 시스템에서 pl-PL이라고 표시하고 xp를 win이 정확히 동일하다는 것을 확인했습니다. – MadBoy

+0

@MadBoy -'System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat'을 체크하면 어떻게 될까요? –

+0

System.Globalization.CultureInfo.CurrentCulture.DateTimeFormat.FullDateTimePattern = d MMMM yyyy 두 시스템에서 모두 HH : mm : ss입니다. 만약 내가 원하는 ToString() 정확하게 당신이 원하는 System.Globalization.DateTimeFormatInfo 결과로 얻고 나는 당신이 원하는 것 같아요;) – MadBoy