I18N DateFormat, 巧用int干掉if else

DateFormat大家应该都知道,用起来挺麻烦的,要考虑如下问题:

1. I18N
2. 带不带time
3. 如何支持多种不同的Patterns

单单考虑I18N,问题很好好解决,直接调用

public final static DateFormat getDateInstance(int style)


即可获得几个常见的DateFormats。但是怎么添加自己需要的Pattern呢?例如希望英文版的软件支持:“MM/dd/yy”,“MM/dd/yyyy”以及带时间的“MM/dd/yy hh:mm”,“MM/dd/yyyy hh:mm”。直接硬编码当然简单,但是修改起来麻烦,考虑使用Resource Bundles,将日期和时间分开写,各种希望支持的日期Format用分号隔开,例如:


dateformat.date.support = MM/dd/yy;MM/dd/yyyy
dateFormat.time.show = hh:mm


然后在程序里面写循环组合一下。例如:


List<DateFormat> getSupportedFormats(boolean withTime) {
ResourceMap rm = context.getResourceMap(getClass());
String timeFormat = rm.getString("dateFormat.time.show");
List<DateFormat> formats = new ArrayList<DateFormat>();
for (String format : rm.getString("dateformat.date.support").split(";")) {
formats.add(new SimpleDateFormat(format));
formats.add(new SimpleDateFormat(format + " "
+ timeFormat));
}
formats.add(DateFormat.getInstance());
return formats;
}


注意返回的formats中第一个DateFormat会被作为默认的显示Format的使用,这段代码并没用考虑是否显示时间。加上时间判断后,通常使用if else来写:


List<DateFormat> getSupportedFormats(boolean withTime) {
ResourceMap rm = context.getResourceMap(getClass());
String timeFormat = rm.getString("dateFormat.time.show");
List<DateFormat> formats = new ArrayList<DateFormat>();
for (String format : rm.getString("dateformat.date.support").split(";")) {
if (withTime) {
formats.add(new SimpleDateFormat(format + " "
+ timeFormat));
formats.add(new SimpleDateFormat(format));

} else {
formats.add(new SimpleDateFormat(format));
formats.add(new SimpleDateFormat(format + " "
+ timeFormat));
}
}
formats.add(DateFormat.getInstance());
return formats;
}


代码看起来挺痛苦的,有重复,还有我很讨厌的if else,就算是重构一个方法出来也没好到哪里去。考虑用一个int变量踢掉if else,先把resource Bundles里面的dateformat.date.support掉个个,默认显示用的那个Format的放在最后:


dateformat.date.support = MM/dd/yyyy;MM/dd/yy
dateFormat.time.show = hh:mm


代码这么写:


List<DateFormat> getSupportedFormats(boolean withTime) {
ResourceMap rm = context.getResourceMap(getClass());
String timeFormat = rm.getString("dateFormat.time.show");
List<DateFormat> formats = new ArrayList<DateFormat>();
// withTime = true -> date with time format will be added first. Otherwise
// the date format first
int i = withTime ? 1 : 0;
formats.add(DateFormat.getInstance());
for (String format : rm.getString("dateformat.date.support").split(";")) {
formats.add(i % 2 , new SimpleDateFormat(format));
formats.add((i + 1) % 2, new SimpleDateFormat(format + " "
+ timeFormat));
}
return formats;
}


这里利用了对int i 取余以及List集合的add()方法会将老的对象全部向右推的功能,这样处理就可以解决所有问题。根据withTime这个开关,期望的DateFormat会被设定为默认显示的Format。

至此,这个方法:

1. 支持I18N
2. 支持自定义多种Patterns,需要支持新的patterns时,直接在resource bundles里面添加,代码不用改动
3. 支持切换是否显示时间

测试代码如下:


public class FormattedTextFieldFactoryTest {

private static DateFormatHelper helper;

@BeforeClass
public static void init() {
Locale.setDefault(Locale.US);
helper = new DateFormatHelper();
}

public void addSupportedFormats() {
List<DateFormat> list = helper.getSupportedFormats(false);
assertEquals(list.size(), 5);
assertEquals(list.get(0).format(createDate(2008, 10, 16)),
"10/16/08");

list = helper.getSupportedFormats(true);
assertEquals(list.size(), 5);
assertEquals(list.get(0).format(createDate(2008, 10, 16)),
"10/16/08 12:00");
}

private Date createDate(int year, int month, int date) {
GregorianCalendar cal = new GregorianCalendar();
cal.clear();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month - 1);
cal.set(Calendar.DATE, date);
return cal.getTime();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值