类型转换器日期时间格式问题
本文关键字:格式 问题 时间 日期 类型转换 转换器 类型 | 更新日期: 2023-09-27 18:20:55
我正在使用4.0,我试图通过开发一些用于类型转换的辅助方法来简化我的生活。以下方法工作正常。它将从任何字符串转换为其他数据类型。
System.ComponentModel;
public static T Convert<T>(string s)
{
var typeConverter = TypeDescriptor.GetConverter(typeof(T));
if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string)))
{
return (T)typeConverter.ConvertFrom(s);
}
return default(T);
}
//calling this method...
var dateTime = MyConverter.Convert<DateTime>("13/07/2013"); // Date format "DD/mm/yyyy"
// Working as expected... Taking "13" as Day, "07" as month
现在,以下方法也属于同一类MyConverter,但它不能很好地与DateTime配合使用:
public static bool CanConvertTo<T>(string s)
{
var typeConverter = TypeDescriptor.GetConverter(typeof(T));
if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string)))
{
return typeConverter.IsValid(s);
}
else
return false;
}
这种方法的问题是,它只接受日期格式:"MM/dd/yyyy">
// This will give exception. It is taking "13" as month, "07" as Day
bool canConvert = MyConverter.CanConvertTo<DateTime>("13/07/2013");
编辑按照KeyboardP的建议,我将方法更改为:
public static bool CanConvertTo<T>(string s)
{
TypeConverter typeConverter;
if (typeof(T) == typeof(DateTime))
{
typeConverter = new DateTimeConverter();
}
else
{
typeConverter = TypeDescriptor.GetConverter(typeof(T));
}
if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string)))
{
return typeConverter.IsValid(s);
}
else
return false;
}
并经过测试。测试结果是:
var date = MyConverter.Convert<DateTime>("13/07/2013"); //return perfect date
var canConvert = MyConverter.CanConvertTo<DateTime>("13/07/2013"); // returned false...
所以没有成功DateTimeConverter
由于DateTime
可以有许多不同的格式样式,我只使用 DateTimeConverter,而不是尝试在通用方法中重新创建它。
编辑
我做了一些ILsping,这就是我的结论(很高兴在任何一点上得到纠正(。
GetCoverter(typeof(DateTime))
将返回一个DateTimeConverter
所以调用CanConvertFrom
实际上是在调用DateTimeConverter.CanConvertFrom
。 CanConvertFrom
调用base.CanConvertFrom
(base
是父类型转换器类(。
基地。CanConvertFrom 方法看起来像这样
public virtual bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(InstanceDescriptor);
}
自 DateTime.GetType() != typeof(InstanceDescriptor)
以来,返回值为 false
。 CanConvertFrom
由 IsValid
方法调用,由于我们刚刚确定返回值为 false
,IsValid
返回false
。
那么,即使调用了相同的CanConvertFrom
方法,Convert
方法为什么会起作用呢?
好吧,您传递的参数是类型 string
,而不是 DateTime
.
typeConverter.CanConvertFrom(typeof(string))
在上面的第一个代码片段中,CanConvertFrom
方法适用于TypeConverter
基类。如果我们看一下DateTimeConverter.CanConvertFrom
覆盖,它看起来像这样
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
由于我们将String
作为类型传递,因此此方法返回 true(与IsValid
调用不同(。因为这返回 true,所以代码继续调用
return (T)typeConverter.ConvertFrom(s);
(其中 T 是DateTime
(
DateTimeConverter
只是称DateTime.Parse
,忽视文化。我不确定这是设计使然还是错误,但我不会依赖DateTime.Parse
,除非您知道字符串始终具有相同的格式(或者在调用方法之前正确格式化(。
DateTimeConverter.IsValid 不使用当前区域性。这是我解决这个问题的方法
public class FixedDateTimeConverter : DateTimeConverter
{
public override bool IsValid(ITypeDescriptorContext context, object value)
{
DateTime d;
return DateTime.TryParse(value.ToString(), out d);
}
}
。
var converter = TypeDescriptor.GetConverter(typeof (T));
if (typeof (T) == typeof (DateTime))
converter = new FixedDateTimeConverter();
return converter.IsValid(null,r);