string转DateTime(时间格式转换)

1、不知道为什么时间在数据库用varchar(8)来保存,例如"19900505",但是这样的保存格式在处理时间的时候是非常不方便的。

但是转换不能用Convert.ToDateTime(string s),详细可以参考

 1  //
 2         // 摘要: 
 3         //     将日期和时间的指定字符串表示形式转换为等效的日期和时间值。
 4         //
 5         // 参数: 
 6         //   value:
 7         //     日期和时间的字符串表示形式。
 8         //
 9         // 返回结果: 
10         //     value 的值的日期和时间等效项,如果 value 为 null,则为 System.DateTime.MinValue 的日期和时间等效项。
11         //
12         // 异常: 
13         //   System.FormatException:
14         //     value 不是格式正确的日期和时间字符串。
15  public static DateTime ToDateTime(string value);
Convert.ToDateTime


也不能用DateTime.Parse(string s),详细参考

 1 //
 2         // 摘要: 
 3         //     将日期和时间的指定字符串表示形式转换为其等效的 System.DateTime。
 4         //
 5         // 参数: 
 6         //   s:
 7         //     包含要转换的日期和时间的字符串。
 8         //
 9         // 返回结果: 
10         //     一个对象,它等效于 s 中包含的日期和时间。
11         //
12         // 异常: 
13         //   System.ArgumentNullException:
14         //     s 为 null。
15         //
16         //   System.FormatException:
17         //     s 中不包含有效的日期和时间的字符串表示形式。
18         public static DateTime Parse(string s);
DateTime.Parse


之所以不能用这两个内置的方法是因为s的格式不能被识别,能识别的格式为"yyyy-MM-dd",类似这样的格式才能被识别。

所以,纠结到最后还是自己写了个方法,如下:

 1  /// <summary>
 2         /// 获取年龄
 3         /// </summary>
 4         /// <param name="birthday"></param>
 5         /// <returns></returns>
 6         public string GetAge(string birthday)
 7         {
 8             DateTime sNow = DateTime.Now;
 9             DateTime.Parse(birthday);
10             Convert.ToDateTime(birthday);
11             int year = Convert.ToInt32(birthday.Substring(0, 4));
12             int month = Convert.ToInt32(birthday.Substring(4, 2));
13             int iAge = (sNow.Year * 12 + sNow.Month - year * 12 - month)/12;
14             return iAge.ToString();
15         }

顺便对Convert类和Parse做了一些了解。

以下内容来世msdn(http://technet.microsoft.com/zh-cn/subscriptions/system.convert(v=vs.95).aspx)

Convert类主要的一个作用是将一个基本数据类型转换为另一个基本数据类型。

Convert 类的静态方法用于支持 .NET Framework 中与基数据类型之间的转换。 受支持的基类型是BooleanCharSByteByteInt16Int32Int64UInt16UInt32UInt64SingleDoubleDecimalDateTime  String

与基类型之间的转换

存在将每个基类型转换为每个其他基类型的转换方法。 但是,根据运行时基类型和目标基类型的值,对特定转换方法的实际调用会产生五种结果之一。 这五种结果如下:

1、无转换。 当尝试将一个类型转换为其本身时(如使用 Int32 类型参数调用 Convert.ToInt32(Int32))会发生这种情况。 在这种情况下,此方法只是返回原始类型实例。

2、一个 InvalidCastException。 当不支持特定转换时会发生这种情况。 以下转换会引发 InvalidCastException。

将 Char 转换为 Boolean、Single、Double、Decimal 或 DateTime。

将 Boolean、Single、Double、Decimal 或 DateTime 转换为 Char。

将 DateTime 转换为 String 以外的任何其他类型。

将 String 以外的任何其他类型转换为 DateTime。

3、FormatException 。 当由于字符串格式不正确而导致将字符串值转换为任何其他基类型的尝试失败时,会发生该异常。 以下转换会引发该异常:

要转换为 Boolean 值的字符串不等于 Boolean.TrueString 或 Boolean.FalseString。

要转换为 Char 值的字符串由多个字符组成。

要转换为任何数值类型的字符串没有被识别为有效数字。

要转换为 DateTime 值的字符串没有被识别为有效日期和时间值。

4、转换成功。 对于前面结果中未列出的两个不同基类型之间的转换,所有扩大转换和不会导致数据丢失的收缩转换都将成功,此方法将返回目标基类型的值。

5、OverflowException。 当收缩转换导致数据丢失时会发生这种情况。 例如,尝试将值为 10000 的 Int32 实例转换为 Byte 类型会引发 OverflowException,因为 10000 超出了 Byte 数据类型的范围。

如果数字类型转换导致精度丢失(即某些最低有效位丢失),不引发异常。 但是,如果结果超出了特定转换方法的返回值类型所能表示的范围,则将引发异常。

例如,当将 Double 转换为 Single 时,可能会发生精度丢失,但并不引发异常。 但是,如果 Double 的值太大,无法由 Single 表示,则将引发溢出异常。

从自定义对象转换为基类型

除了支持基类型之间的转换外,Convert 方法还支持将任何自定义类型转换为任何基类型。 为此,自定义类型必须实现 IConvertible 接口,该接口定义用于将实现类型转换为每个基类型的方法。 特定类型不支持的转换会引发 InvalidCastException。

向 ChangeType 方法传递自定义类型作为其第一个参数时,或者在调用 Convert.ToType 方法(如 Convert.ToInt32(Object) 或 Convert.ToDouble(Object, IFormatProvider))并向其传递自定义类型的实例作为其第一个参数时,Convert 方法反过来会调用自定义类型的 IConvertible 实现以执行转换。 有关更多信息,请参见 .NET Framework for Silverlight 中的类型转换。

区域性特定的格式设置信息

所有基类型转换方法和 ChangeType 方法都包括具有类型为 IFormatProvider 的参数的重载。 例如,Convert.ToBoolean 方法具有下面两个重载:

Convert.ToBoolean(Object, IFormatProvider)

Convert.ToBoolean(String, IFormatProvider)

IFormatProvider 参数可以提供区域性特定的格式设置信息以帮助转换过程。 但是,大多数基类型转换方法忽略了该参数。 只有下列基类型转换方法使用该参数:

将值转换为数值类型的方法。 IFormatProvider 参数由具有类型为 String 和 IFormatProvider 的参数的重载使用。 它也由具有类型为 Object 和 IFormatProvider 的参数的重载使用(如果对象的运行时类型为 String)。

将值转换为日期和时间的方法。 IFormatProvider 参数由具有类型为 String 和 IFormatProvider 的参数的重载使用。 它也由具有类型为 Object 和 IFormatProvider 的参数的重载使用(如果对象的运行时类型为 String)。

包含 IFormatProvider 参数并将数字值转换为字符串或将 DateTime 值转换为字符串的 Convert.ToString 重载。

但是,实现 IConvertible 的任何用户定义类型都可以使用 IFormatProvider 参数。

其他转换方法

有一组方法可支持字节数组与 String 或由以 64 为基的数字字符组成的 Unicode 字符数组之间的转换。 表示为以 64 为基的数字的数据可以很容易地通过只能传输 7 位字符的数据信道进行传送。

Parse意为解析方法,顾名思义就是解析字符串的方法,例如DateTime.Parse(string s),就是将s解析成DateTime格式,即将日期和时间的字符串表示形式转换为其等效的DateTime。

但需要注意是因为日期和时间的字符串表示形式必须符合公认的模式,你应该总是调用时使用异常处理解析方法来分析用户的输入。 如果你不想处理异常,你可以调用的DateTime TryParse的方法来分析日期和时间字符串,这个方法返回一个值,指示分析操作是否成功。

 更多细节请参考(http://msdn.microsoft.com/zh-cn/library/System.DateTime.Parse(v=vs.110).aspx

-----------------------------------------------------我是分割线--------------------------------------------------------

感谢@muki的指导,其中还有个比较方便的方法是DateTime.ParseExact(string s, string format, IFormatProvider provider),详细如下

 1  //
 2         // 摘要: 
 3         //     使用指定的格式和区域性特定格式信息,将日期和时间的指定字符串表示形式转换为其等效的 System.DateTime。 字符串表示形式的格式必须与指定的格式完全匹配。
 4         //
 5         // 参数: 
 6         //   s:
 7         //     包含要转换的日期和时间的字符串。
 8         //
 9         //   format:
10         //     用于定义所需的 s 格式的格式说明符。
11         //
12         //   provider:
13         //     一个对象,提供有关 s 的区域性特定格式信息。
14         //
15         // 返回结果: 
16         //     一个对象,它等效于 s 中包含的日期和时间,由 format 和 provider 指定。
17         //
18         // 异常: 
19         //   System.ArgumentNullException:
20         //     s 或 format 为 null。
21         //
22         //   System.FormatException:
23         //     s 或 format 是空字符串。 - 或 - s 不包含与 format 中指定的模式相对应的日期和时间。 - 或 - s 中的小时组成部分和
24         //     AM/PM 指示符不一致。
25         public static DateTime ParseExact(string s, string format, IFormatProvider provider);
DateTime ParseExact

其中需要注意的是虽然这个方法能直接"读懂""yyyyMMdd",但是你必须在format这个参数中指定,而且s的长度必须和format一致,不然同样会报错。另外一个值得注意的地方是provider参数,参数解释为   一个对象,提供有关 s 的区域性特定格式信息,如关联的语言、子语言、国家/地区、日历和区域性约定。

如关联的语言、子语言、国家

/

地区、

日历和区域性约定。

关于Convert.ToDateTime(string s),DateTime.Parse(string s)有什么区别,如果您有更详细的说明和更深入的理解请和我交流,如果有不正确的地方请多多指教。

再次感谢您的阅读,感谢各位大大!

原文地址:https://www.cnblogs.com/bindot/p/GetAge.html