2017-05-31 21 views
1

我有一個頁面在asp.net MVC獲取波斯的日期時間,並將其存儲在數據庫中的聖誕節datetime.I改變我的文化波斯爲了顯示波斯語言的日期和時間,一切工作正常,我可以存儲日期時間DateTime.Now在數據庫中,但是當我想從用戶在文本框中獲取日期時間(用戶輸入帶有波斯日期時間)並存儲它時,我得到一個超出範圍錯誤說存儲日期時間與自定義文化

一個DATETIME2數據類型爲datetime數據類型的轉換導致外的範圍內的值

我試圖噸Ø從的FormCollection對象獲取時間值,並將其轉換爲datetime,但我沒有運氣,

這是我的看法:

<form action="/Accounting/TempDocument/Insert" method="post" id="insert-form"> 
    <div class="modal-body"> 
     <div class="row"> 
     <div class="form-body"> 
      @Html.AntiForgeryToken() 
      <div class="form-group form-md-line-input"> 
       @Html.LabelFor(m => m.Description, new { @class = "col-md-2 control-label" }) 
       <div class="col-md-10"> 
        @Html.TextAreaFor(m => m.Description, new { @class = "form-control", @placeholder = "Description" }) 
        <div class="form-control-focus"> </div> 
        @Html.ValidationMessageFor(m => m.Description, "", new { @class = "help-block" }) 
       </div> 
      </div> 
      <div class="form-group form-md-line-input"> 
       @Html.LabelFor(m => m.DocumentDate, new { @class = "col-md-2 control-label" }) 

<!-- this block is for document date--> 
       <div class="col-md-10"> 
        @Html.TextBoxFor(m => m.DocumentDate, new { @class = "form-control date-mask", @placeholder = "Document Date" }) 
        <div class="form-control-focus"> </div> 
        @Html.ValidationMessageFor(m => m.DocumentDate, "", new { @class = "help-block" }) 
       </div> 
      </div> 
     </div> 
<!-- my form continues --> 

這是我的行動:

[Route("Insert")] 
    [HttpPost] 
    public async Task<ActionResult> InsertAsync(AccountingDocument model, FormCollection collection) 
    { 
     try 
     { 

      // much code here 
      await _service.EntInsertAsync(model); 
      if (await _service.CommitAsync()) 
       await SetResultMessageAsync(""); 
     } 
     catch 
     { 

     } 
     return RedirectToAction("RenderTop"); 
    } 

我的Global.asax類:

protected void Application_BeginRequest() 
    { 

     var persianCulture = new PersianCulture(); 
     Thread.CurrentThread.CurrentCulture = persianCulture; 
     Thread.CurrentThread.CurrentUICulture = persianCulture; 

    } 

,最後我persianCulture類:

public class PersianCulture : CultureInfo 
{ 
    private readonly Calendar cal; 
    private readonly Calendar[] optionals; 


    public PersianCulture() 
     : this("fa-IR", true) 
    { 
    } 

    public PersianCulture(string cultureName, bool useUserOverride) 
     : base(cultureName, useUserOverride) 
    { 
     //Temporary Value for cal. 
     cal = base.OptionalCalendars[0]; 

     //populating new list of optional calendars. 
     var optionalCalendars = new List<Calendar>(); 
     optionalCalendars.AddRange(base.OptionalCalendars); 
     optionalCalendars.Insert(0, new PersianCalendar()); 


     Type formatType = typeof(DateTimeFormatInfo); 
     Type calendarType = typeof(Calendar); 


     PropertyInfo idProperty = calendarType.GetProperty("ID", BindingFlags.Instance | BindingFlags.NonPublic); 
     FieldInfo optionalCalendarfield = formatType.GetField("optionalCalendars", 
                   BindingFlags.Instance | BindingFlags.NonPublic); 

     //populating new list of optional calendar ids 
     var newOptionalCalendarIDs = new Int32[optionalCalendars.Count]; 
     for (int i = 0; i < newOptionalCalendarIDs.Length; i++) 
      newOptionalCalendarIDs[i] = (Int32)idProperty.GetValue(optionalCalendars[i], null); 

     optionalCalendarfield.SetValue(DateTimeFormat, newOptionalCalendarIDs); 

     optionals = optionalCalendars.ToArray(); 
     cal = optionals[0]; 
     DateTimeFormat.Calendar = optionals[0]; 

     DateTimeFormat.MonthNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" }; 
     DateTimeFormat.MonthGenitiveNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" }; 
     DateTimeFormat.AbbreviatedMonthNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" }; 
     DateTimeFormat.AbbreviatedMonthGenitiveNames = new[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" }; 


     DateTimeFormat.AbbreviatedDayNames = new string[] { "ی", "د", "س", "چ", "پ", "ج", "ش" }; 
     DateTimeFormat.ShortestDayNames = new string[] { "ی", "د", "س", "چ", "پ", "ج", "ش" }; 
     DateTimeFormat.DayNames = new string[] { "یکشنبه", "دوشنبه", "ﺳﻪشنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه" }; 

     DateTimeFormat.AMDesignator = "ق.ظ"; 
     DateTimeFormat.PMDesignator = "ب.ظ"; 
    } 

    public override Calendar Calendar 
    { 
     get { return cal; } 
    } 

    public override Calendar[] OptionalCalendars 
    { 
     get { return optionals; } 
    } 
} 
+0

我想「正確的」方法是將你的波斯日期轉換爲格利高利(也許使用NodaTime)並存儲它。顯示之前,請翻回來。 –

+0

我正在這樣做,就像翻譯日期時間,當我想向用戶展示時,但是當我開始使用Devexpress組件時,爲了更改devexpress語言,我必須更改文化。 –

回答

0

我假設用戶輸入伊斯蘭時代的年份(當前年份爲1438年)。

然後錯誤The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value發生在數據庫上,因爲您的日期時間列使用datetime類型而不是datetime2

datetime T-SQL數據類型僅支持1753-01-01至9999-12-31範圍內的日期。

將數據庫上的數據類型更改爲支持日期0001-01-01 00:00:00.0000000至9999-12-31 23:59:59.9999999的datetime2

+0

伊斯蘭日曆有12個月與公曆的日期相同嗎?換句話說:根據sql server,是否有可能獲得「非法」的月份編號或日期編號? –

+0

嗨,沒有用戶輸入shamsi dateTime的年份,現在它的1396 ,不幸的是它沒有與datetime2相同的天數,所以我必須將其轉換,我的程序自動將DateTime.now中的值轉換爲1396/01/01格式,但是對於用戶輸入我得到這個錯誤 –

+0

C#'DateTime'支持從01-01-0001到31-12-9999的日期,所以它可能在C#端(在調試器中)工作,但不在數據庫上? –

0

由於用戶可能在Hijri日曆中輸入日期,因此可能它的年份值小於SQL datetime支持(1753-01-01)。請注意,默認情況下,格雷戈裏系統均用於數據類型爲datetime,&,datetime2數據類型,而不管文化是否設置。

有一些可能的解決方案:映射列DocumentDate到DATETIME2在數據庫,它支持的DateTime.MinValue最小值

  1. 變化數據類型。

  2. 如果您使用SqlCommand與參數化查詢,你可以定義SqlDbType.DateTime2如在任何Parameters.AddParameters.AddWithValue DB數據類型。

  3. 如果您將EF與EDMX結合使用,則可以通過將相應的列映射更新爲DateTime2來定義屬性DocumentDate

+0

shamsi日期已經是第二個月的31天了,所以我不能直接保存日期時間。 –

+1

個人而言,我更喜歡將日期存儲在數據庫中作爲'datetime2'(公曆日期),其中轉換爲波斯語出現在表示層(存儲和檢索值)。或者,您可以使用UDT(請參閱https://docs.microsoft.com/zh-cn/sql/t-sql/statements/create-type-transact-sql),但我仍然找不到波斯語的UDT使用示例日曆格式。 –