将自定义文化的日期时间存储

时间:2017-05-31 12:18:31

标签: c# asp.net-mvc asp.net-mvc-4 datetime cultureinfo

我在asp.net MVC中有一个页面,它以波斯语获取日期时间并将其存储在圣诞节datetime的数据库中。我将我的文化改为波斯语以便用波斯语显示日期和时间,一切正常,我可以使用DateTime.Now在数据库中存储日期时间,但是当我想从文本框中的用户获取日期时间(用户输入带有波斯语日期时间)并存储它时,我得到一个超出范围的错误说

  

将datetime2数据类型转换为日期时间数据类型会导致超出范围的值

我试图从FormCollection对象获取datetime值并将其转换为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; }
    }
}

2 个答案:

答案 0 :(得分:0)

我假设用户进入伊斯兰时代的那一年(当年是1438 AH)。

然后在数据库上发生错误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范围内的日期。

将数据库上的数据类型更改为datetime2,其中包含日期0001-01-01 00:00:00.0000000至9999-12-31 23:59:59.9999999。

答案 1 :(得分:0)

由于用户可能在Hijri日历中输入日期,因此它可能具有小于SQL datetime支持的年份值(1753-01-01)。请注意,默认情况下,格里高利系统用于datetime和{ datetime2数据类型,无论是否设置了文化。

有一些可能的解决方案:

  1. 将数据库中映射列DocumentDate的数据类型更改为datetime2,它支持最小值DateTime.MinValue

  2. 如果您将SqlCommand与参数化查询结合使用,则可以在SqlDbType.DateTime2Parameters.Add中将Parameters.AddWithValue定义为数据库数据类型。

  3. 如果您将EF与EDMX一起使用,则可以通过将相应的列映射更新为DocumentDate来定义属性DateTime2