存储日期时间与自定义文化
我有一个页面在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; }
}
}
我假设用户输入伊斯兰时代的年份(当前年份为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
。
伊斯兰日历有12个月与公历的日期相同吗?换句话说:根据sql server,是否有可能获得“非法”的月份编号或日期编号? –
嗨,没有用户输入shamsi dateTime的年份,现在它的1396 ,不幸的是它没有与datetime2相同的天数,所以我必须将其转换,我的程序自动将DateTime.now中的值转换为1396/01/01格式,但是对于用户输入我得到这个错误 –
C#'DateTime'支持从01-01-0001到31-12-9999的日期,所以它可能在C#端(在调试器中)工作,但不在数据库上? –
由于用户可能在Hijri日历中输入日期,因此可能它的年份值小于SQL datetime
支持(1753-01-01)。请注意,默认情况下,格雷戈里系统均用于数据类型为datetime
,&,datetime2
数据类型,而不管文化是否设置。
有一些可能的解决方案:映射列DocumentDate
到DATETIME2在数据库,它支持的DateTime.MinValue
最小值
变化数据类型。
如果您使用
SqlCommand
与参数化查询,你可以定义SqlDbType.DateTime2
如在任何Parameters.Add
或Parameters.AddWithValue
DB数据类型。如果您将EF与EDMX结合使用,则可以通过将相应的列映射更新为
DateTime2
来定义属性DocumentDate
。
shamsi日期已经是第二个月的31天了,所以我不能直接保存日期时间。 –
个人而言,我更喜欢将日期存储在数据库中作为'datetime2'(公历日期),其中转换为波斯语出现在表示层(存储和检索值)。或者,您可以使用UDT(请参阅https://docs.microsoft.com/zh-cn/sql/t-sql/statements/create-type-transact-sql),但我仍然找不到波斯语的UDT使用示例日历格式。 –
我想“正确的”方法是将你的波斯日期转换为格利高利(也许使用NodaTime)并存储它。显示之前,请翻回来。 –
我正在这样做,就像翻译日期时间,当我想向用户展示时,但是当我开始使用Devexpress组件时,为了更改devexpress语言,我必须更改文化。 –