2017-05-31 61 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使用示例日历格式。 –