将由BeanUtils的getProperty方法返回的Date对象的字符串表示还原为对象

现象描述:

打算将由BeanUtils的getProperty方法返回的Date类型的字符串表示重新通过SimpleDateFormat转换成Date类型的对象老是失败,抛ParseException异常.

分析:

调用commons项目里的BeanUtils对象里的getProperty方法返回某个对象中的Date类型的成员变量.BeanUtil中对getProperty方法的描述如下:

Return the value of the specified property of the specified bean, no matter which property reference format is used, as a String.

也就是说,无论这个成员变量的类型是什么,经由getProperty方法返回的值都将是一个字符串.

如果这个成员变量的类型是java.util.Date,那么BeanUtils会调用一个专门为Date类型准备的converter来对这个Date进行转换,其实最终是调用了Date的toString方法.

在某些特殊的时候,我们需要将这个字符串表示的Date还原成真正的Date类,以备后用.

如果抛出异常,则肯定是由于转换格式的不匹配造成的.

解决过程及成果:

查阅JDK的manual,找到Date类的toString方法,其中描述说所有的Date类都将被转换成形如"dow mon dd hh:mm:ss zzz yyyy"的形式,"dow,mon"是什么?从表面上看,似乎是"E"和"MMM",由debug的跟踪结果来看,确实像是"E MMM dd hh:mm:ss zzz yyyy".

但是,以上述的格式对字符串进行转换,照样出错.没办法,直接冲入JDK源码,查看Date类的toString方法:

public String toString() {
 // "EEE MMM dd HH:mm:ss zzz yyyy";
 BaseCalendar.Date date = normalize();
 StringBuilder sb = new StringBuilder(28);
 int index = date.getDayOfWeek();
 if (index == gcal.SUNDAY) {
     index = 8;
 }
 convertToAbbr(sb, wtb[index]).append(' ');     // EEE
 convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
 CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd

 CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');   // HH
 CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
 CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
 TimeZone zi = date.getZone();
 if (zi != null) {
     sb.append(zi.getDisplayName(date.isDaylightTime(), zi.SHORT, Locale.US)); // zzz
 } else {
     sb.append("GMT");
 }
 sb.append(' ').append(date.getYear());  // yyyy
 return sb.toString();
    }

这一眼就看出它的日期格式确实是用的"EEE MMM dd HH:mm:ss zzz yyyy"(都不用读代码,人家注释里直接告诉你了),这么说我最初判断它的格式字符串并没有错,确实是"E MMM dd hh:mm:ss zzz yyyy"(E的个数在1-3之间是没有区别的),那么到底问题在哪呢?

没办法,那么干脆照着"E MMM dd hh:mm:ss zzz yyyy"的格式,亲手把一个Date对象转换一下,看看出来是什么样子:

public static void main(String args[]) {
  Calendar c = Calendar.getInstance();
  SimpleDateFormat format = new SimpleDateFormat("E MMM dd hh:mm:ss z yyyy");
  System.out.println(format.format(c.getTime()));
 }

输出结果:"星期日 十一月 04 05:03:52 CST 2007"

好了,至此,可以恍然大悟了.原来是因为我们是中国人,身在中国,Java库的开发人员十分体贴我们,充满人性关怀地将SimpleDateFormat类使用的Locale默认成了我们所在位置的Locale,输出了符合我们中国人习惯的日期表示方式.然而,却没有在Date的toString方法里做同样的人性化设定,toString方法一律输出美国的时间字符串格式"Sun Nov 04 17:10:26 CST 2007".无奈中美语言不通,这样你来我往转换一个回合,不出错才叫怪了.

解决方法很简单,就是在构造SimpleDateFormat对象时使用两个参数的构造函数,将Locale指定为US,就可以了:

SimpleDateFormat format = new SimpleDateFormat("E MMM dd hh:mm:ss z yyyy", Locale.US);

完结.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值