首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TypeConverter DateTime格式问题

TypeConverter DateTime格式问题
EN

Stack Overflow用户
提问于 2013-07-04 10:36:23
回答 2查看 4K关注 0票数 4

我正在使用4.0,并试图通过开发一些类型转换的助手方法来简化我的生活。下面的方法工作得很好。它将从任何字符串转换为其他数据类型。

代码语言:javascript
复制
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:

代码语言:javascript
复制
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“

代码语言:javascript
复制
// This will give exception. It is taking "13" as month, "07" as Day
bool canConvert = MyConverter.CanConvertTo<DateTime>("13/07/2013");

按照编辑的建议,我将方法更改为:

代码语言:javascript
复制
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;
}

并进行了测试。测试结果如下:

代码语言:javascript
复制
var date = MyConverter.Convert<DateTime>("13/07/2013");    //return perfect date
var canConvert = MyConverter.CanConvertTo<DateTime>("13/07/2013");  // returned false...

所以DateTimeConverter没有成功

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-04 10:42:53

由于DateTime可以有许多不同的格式样式,所以我只使用DateTimeConverter,而不是尝试在泛型方法中重新创建它。

编辑

我做了一些ILspying,这就是我得出的结论(很高兴在任何一点上都能得到纠正)。

GetCoverter(typeof(DateTime))将返回一个DateTimeConverter,因此调用CanConvertFrom实际上是在调用DateTimeConverter.CanConvertFromCanConvertFrom调用base.CanConvertFrom (base是父TypeConverter类)。

base.CanConvertFrom方法如下所示

代码语言:javascript
复制
public virtual bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
    return sourceType == typeof(InstanceDescriptor);
}

因为DateTime.GetType() != typeof(InstanceDescriptor),返回值是falseCanConvertFromIsValid方法调用,因为我们刚刚建立了返回值为falseIsValid返回false

那么,Convert方法是如何工作的,即使调用了相同的CanConvertFrom方法?

您要传递的参数是string类型,而不是DateTime类型。

代码语言:javascript
复制
typeConverter.CanConvertFrom(typeof(string))

在上面的第一个代码片段中,CanConvertFrom方法用于TypeConverter基类。如果我们看一下DateTimeConverter.CanConvertFrom覆盖,它看起来就像这样

代码语言:javascript
复制
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
    return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}

因为我们作为类型传入一个String,所以这个方法返回true (与IsValid调用不同)。因为这返回true,所以代码继续调用

代码语言:javascript
复制
return (T)typeConverter.ConvertFrom(s);

(其中T是DateTime)

DateTimeConverter简单地调用DateTime.Parse并忽略区域性。我不确定这是由设计还是错误造成的,但是我不会依赖DateTime.Parse,除非您知道字符串总是相同的格式(或者在调用方法之前正确地格式化它)。

票数 3
EN

Stack Overflow用户

发布于 2017-12-01 14:01:08

DateTimeConverter.IsValid不使用当前的文化。我是怎么绕过这件事的

代码语言:javascript
复制
public class FixedDateTimeConverter : DateTimeConverter
{
    public override bool IsValid(ITypeDescriptorContext context, object value)
    {
        DateTime d;
        return DateTime.TryParse(value.ToString(), out d);
    }
}

..。

代码语言:javascript
复制
var converter = TypeDescriptor.GetConverter(typeof (T));

if (typeof (T) == typeof (DateTime))
    converter = new FixedDateTimeConverter(); 

return converter.IsValid(null,r);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17468111

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档