支持语言和不同日期格式的日期控件






4.14/5 (10投票s)
2005年5月13日
4分钟阅读

99576

713
使用 .NET 的 System.Globalization 类来检索外国语言的月份名称,以及 DateTimeFormatInfo 来确保您的日期格式正确。
引言
互联网上有很多日期控件,包括 CodeProject 上的许多。然而,很少有控件能够利用 .NET 的 System.Globalization
类来检索外语月份的名称。从南非荷兰语到越南语的月份名称,无需了解所说的语言即可实现。此外,我还增加了处理任何我选择的日期格式的可能性。此控件可以很好地处理美国或欧洲的日期格式。该控件还支持 Visual Studio 设计器。
背景
System.Globalization
命名空间包含定义与区域设置相关信息的类,包括语言、国家/地区、使用的日历以及日期、货币和数字的格式模式。
我使用了 CodeProject 上的 David Truxall 的控件 作为该控件的模板,并添加了以下功能:
属性
属性 | 默认值 | 描述 |
YearsForward |
0 | (可选)一个整数,用于设置控件从当前年份开始显示的未来年份数。 |
YearsBack |
0 | (可选)一个整数,用于设置控件从当前年份开始显示的过去年份数。 |
文化 |
(可选)一个 string ,与 Culture Name 相同,用于显示月份名称。例如,en-gb es-ES。有关完整列表,请参阅 MSDN。如果未设置,则使用服务器的区域代码。- 这不会影响控件的值。 | |
MonthFormat |
MMMM | (可选)一个 string ,用于设置控件中的月份文本。例如 MMM、MMMM、MM。 - 这不会影响控件的值。 |
DateFormat |
默认使用服务器上的格式 | 一个 string ,用于设置输出日期值格式。例如,dd/MM/yyyy MM-dd-yyyy yyyyMMdd |
值 |
一个用于设置 date 的值。* 请注意,如果您使用 dd/MM/yyyy,请确保值设置为双位数,例如 02/04/2005 是有效的,而 2/4/2005 是无效的。 | |
SelectCurrentDate |
true |
一个布尔值,用于在未指定值时将值设置为当前日期。 |
使用示例
<%@ Register TagPrefix="cc1"
Namespace="i386.UI" Assembly="i386.UI" %>
德语,显示短月份文本,未来 10 年,比当前年份早 2 年
<cc1:dropdowndatetime id="DropDownDateTime1" runat="server" YearsForward="2"
YearsBack="10" Culture="de-DE" SelectCurrentDate="False" MonthFormat="MMM">
</cc1:dropdowndatetime>
使用 date
进行美国日期格式化
<cc1:dropdowndatetime id="Dropdowndatetime4" runat="server"
dateFormat="MM/dd/yyyy" Value="11/02/2005">
</cc1:dropdowndatetime>
YearsForward
和 YearsBack
属性可以为负值,这会控制范围和顺序。
YearsForward | YearsBack | 显示的年份 |
-11 | 20 | 1985 ... 1994 |
11 | -20 | 1994 ... 1985 |
11 | 20 | 1985 ... 2016 |
控件的工作原理
首先,DateFormat
默认设置为服务器当前使用的格式,除非设置了 DateFormat
属性。
private string _DateFormat=
System.Threading.Thread.CurrentThread.
CurrentCulture.DateTimeFormat.ShortDatePattern;
public string Value
{
get
{
string s = (string)ViewState["Value"];
if(s == null) return String.Empty;
else return s;
}
set
{
this.SetSelected(value);
ViewState["Value"] = value;
}
}
private void SetSelected(string StoredValue)
{
DateTimeFormatInfo formatInfo =
new DateTimeFormatInfo();
formatInfo.FullDateTimePattern = DateFormat;
DateTime dt = DateTime.ParseExact(StoredValue,
DateFormat,formatInfo);
SelectedDay = dt.Day;
SelectedMonth = dt.Month;
SelectedYear = dt.Year;
}
该控件实现 IPostBackDataHandler
来管理控件值在 PostBack 时发生更改时的重置。这与 David Truxall 的相同,不同之处在于构建 postCollection
的 Value
属性。
bool IPostBackDataHandler.LoadPostData(string postDataKey,
System.Collections.Specialized.NameValueCollection postCollection)
{
....
....
if(this.SelectedDay == -1 && this.SelectedMonth == -1 &&
this.SelectedYear == -1)
this.Value = "";
else
{
// Build a DateTime string based on the DateFormat
DateTimeFormatInfo formatInfo = new DateTimeFormatInfo();
formatInfo.FullDateTimePattern = DateFormat;
DateTime dt = new DateTime(this.SelectedYear,
this.SelectedMonth, this.SelectedDay);
this.Value = dt.ToString(DateFormat,formatInfo);
}
}
构建子控件
当 SelectCurrentDate
设置为 true
(默认)并且控件的 Value
为空时,我们将控件设置为当前日期。我们使用 DateTimeFormatInfo
和 DateFormat
将日期正确格式化为 string
以用于 Value
属性。如果 SelectCurrentDate
设置为 false
,则控件设置为年份下拉框中列出的第一年的 1 月 1 日。我们使用 JavaScript 来限制闰年的天数,并保持 Value
输入框的更新。Value
由客户端和服务器值保持最新。
protected override void CreateChildControls()
{
DateTime dt = DateTime.Today;
// Use CurrentDate if Value is empty and
// SelectCurrentDate is true.
if (SelectCurrentDate && this.Value=="")
{
// Use Current Date
SelectedDay = dt.Day;
SelectedMonth = dt.Month;
SelectedYear = dt.Year;
DateTimeFormatInfo formatInfo =
new DateTimeFormatInfo();
formatInfo.FullDateTimePattern = DateFormat;
this.Value = dt.ToString(DateFormat,formatInfo);
}
// Days
DropDownList ddlboxDay = new DropDownList();
ddlboxDay.ID ="Day";
ddlboxDay.Attributes.Add("onchange",
"ChangeOptionDays('" + this.ClientID +"',
'" + DateFormat + "');");
for (int nDay = 1; nDay<32; nDay++)
ddlboxDay.Items.Add(nDay.ToString());
// So we can restore the Culture later
CultureInfo ExistingCulture =
System.Threading.Thread.CurrentThread.CurrentCulture;
// Culture - changes language of months
if (Culture!=null)
System.Threading.Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo(Culture);
// Months
DropDownList ddlboxMonth = new DropDownList();
ddlboxMonth.ID ="Month";
ddlboxMonth.Attributes.Add("onchange",
"ChangeOptionDays('" + this.ClientID +"',
'" + DateFormat + "');");
for ( int nMonth=1; nMonth<=12; nMonth++)
{
DateTime MonthDate = new DateTime(2000,nMonth,1);
ddlboxMonth.Items.Add(new
ListItem(MonthDate.ToString(this.MonthFormat),
nMonth.ToString()));
}
// Restore
System.Threading.Thread.CurrentThread.CurrentCulture =
ExistingCulture;
// Years (Forward and Back properties)
DropDownList ddlboxYear = new DropDownList();
ddlboxYear.ID ="Year";
ddlboxYear.Attributes.Add("onchange",
"ChangeOptionDays('" + this.ClientID +"',
'" + DateFormat + "');");
ddlboxYear.ID ="Year";
if (YearsBack>=0)
{
for (int nYear = -YearsBack; nYear<=YearsForward; nYear++)
{
int ddlYear =dt.Year+nYear;
ddlboxYear.Items.Add(ddlYear.ToString());
}
}
else
{
for (int nYear = YearsForward; nYear<=-YearsBack; nYear++)
{
int ddlYear =dt.Year-nYear;
ddlboxYear.Items.Add(ddlYear.ToString());
}
}
// Select the DropDownList for the year
if (SelectedYear>0)
{
// See if the year is in the list.
if (ddlboxYear.Items.FindByValue(SelectedYear.ToString())!=null)
{
ddlboxYear.Items.FindByValue(SelectedYear.ToString()).Selected =
true;
}
}
if (SelectedMonth>0)
ddlboxMonth.Items.FindByValue(SelectedMonth.ToString()).Selected = true;
if (SelectedDay>0)
ddlboxDay.Items.FindByValue(SelectedDay.ToString()).Selected = true;
// Add Child Control
Controls.Add(ddlboxDay);
Controls.Add(ddlboxMonth);
Controls.Add(ddlboxYear);
调试模式
用于检查控件的运行情况。DebugMode
输出 Value
、ViewStates
、CultureInfo
和 DateFormat
。要启用 DebugMode
,请使用 DebugMode="true"
。
<cc1:dropdowndatetime DebugMode=true id="DropDownDateTime1" runat="server">
</cc1:dropdowndatetime>
浏览器兼容性
这只是我测试过的浏览器列表中的一小部分。我的电脑上没有安装 Netscape。
浏览器 | 操作系统下 | |
Safari 1.0.3 |
Mac System 9+ | 完全支持 |
Netscape 4.77 | Mac System 10.2.8 | 否 |
Opera 6.0.3 | Mac System 10.2.8 | 完全支持 |
Internet Explorer 5.1, 5.2 | Mac System 9+ | 完全支持 |
Firefox 1.x | Windows XP | 完全支持 |
Internet Explorer 4.0+ | Windows XP | 完全支持 |
Netscape ?? | Windows | ?? |
Internet Explorer 3.0 需要使用服务器验证。如果某个浏览器无法正常工作,请告知我。
JavaScript 支持
从调试模式中,您可能会注意到隐藏的输入框。此输入框可以在 PostBack 到服务器之前在 JavaScript 中使用。
更新、版本和错误修复
- 2005 年 5 月 18 日,版本 0.2
- 添加并修复了
YearsForward
和YearsBack
属性的负值。 - 支持旧版 JavaScript 浏览器。
- 添加并修复了
未来增强功能
- 支持和测试使用服务器验证的旧版、无 JavaScript 或禁用 JavaScript 的浏览器。
EnableSetDate
属性尚未完成。此功能通过复选框启用/禁用日期框,并允许空白日期。- 日期和闰年的服务器验证。源代码中包含一个
DateTimeValidator
。 - 另一个功能是支持
Value
的年份超出YearsForward
和YearsBack
属性范围。 - 时间支持。
欢迎评论或自行添加功能。如果您对该页面的评分较低,请在下方的论坛中留言。