DateFormat、NumberFormat、MessageFormat

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


java.text.Format体系

在日常开发中,我们经常会有格式化的需求,如日期格式化、数字格式化、钱币格式化等等。

在这里插入图片描述

格式化器的作用似乎跟转换器的作用类似,但是它们的关注点却不一样:

  • 转换器:将类型S转换为类型T,关注的是类型而非格式
  • 格式化器: String <-> Java类型。这么一看它似乎和PropertyEditor类似,但是它的关注点是字符串的格式

在这里插入图片描述
Java里从来都缺少不了字符串拼接的活,JDK也提供了多种“工具”供我们使用,如:StringBuffer、StringBuilder以及最直接的+号,相信这些大家都有用过。但这都不是本文的内容,本文将讲解格式化器,给你提供一个新的思路来拼接字符串,并且是推荐方案。

JDK内置有格式化器,便是java.text.Format体系。它是个抽象类,提供了两个抽象方法:

public abstract class Format implements Serializable, Cloneable {
    public abstract StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos);	
	public abstract Object parseObject (String source, ParsePosition pos);
}

  • format:将Object格式化为String,并将此String放到toAppendTo里面
  • parseObject:讲String转换为Object,是format方法的逆向操作

在这里插入图片描述

1.DateFormat:日期时间格式化

抽象类。用于用于格式化日期/时间类型java.util.Date。虽然是抽象类,但它提供了几个静态方法用于获取它的实例:

// 格式化日期 + 时间
public final static DateFormat getInstance() {
    return getDateTimeInstance(SHORT, SHORT);
}
public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale){
    return get(timeStyle, dateStyle, 3, aLocale);
}

// 格式化日期
public final static DateFormat getDateInstance(int style, Locale aLocale) {
    return get(0, style, 2, aLocale);
}
// 格式化时间
public final static DateFormat getTimeInstance(int style, Locale aLocale){
    return get(style, 0, 1, aLocale);
}

在这里插入图片描述
有了这些静态方法,你可在不必关心具体实现的情况下直接使用:

    @Test
    public void test1() {
        Date curr = new Date();

        // 格式化日期 + 时间
        System.out.println(DateFormat.getInstance().getClass() + "-->" + DateFormat.getInstance().format(curr));
        System.out.println(DateFormat.getDateTimeInstance().getClass() + "-->" + DateFormat.getDateTimeInstance().format(curr));

        // 格式化日期
        System.out.println(DateFormat.getDateInstance().getClass() + "-->" + DateFormat.getDateInstance().format(curr));

        // 格式化时间
        System.out.println(DateFormat.getTimeInstance().getClass() + "-->" + DateFormat.getTimeInstance().format(curr));
    }

在这里插入图片描述

SimpleDateFormat

一般来说,我们会直接使用SimpleDateFormat来对Date进行格式化,它可以自己指定Pattern,个性化十足。如:
在这里插入图片描述

2.NumberFormat:数字格式化

抽象类。用于格式化数字,它可以对数字进行任意格式化,如小数、百分数、十进制数等等。它有两个实现类:

在这里插入图片描述

    @Test
    public void test41() {
        double myNum = 1220.0455;

        System.out.println(NumberFormat.getInstance().getClass() + "-->" + NumberFormat.getInstance().format(myNum));
        System.out.println(NumberFormat.getCurrencyInstance().getClass() + "-->" + NumberFormat.getCurrencyInstance().format(myNum));
        System.out.println(NumberFormat.getIntegerInstance().getClass() + "-->" + NumberFormat.getIntegerInstance().format(myNum));
        System.out.println(NumberFormat.getNumberInstance().getClass() + "-->" + NumberFormat.getNumberInstance().format(myNum));
        System.out.println(NumberFormat.getPercentInstance().getClass() + "-->" + NumberFormat.getPercentInstance().format(myNum));
    }

在这里插入图片描述

DecimalFormat

Decimal:小数,小数的,十进位的。

用于格式化十进制数字。它具有各种特性,可以解析和格式化数字,包括:西方数字、阿拉伯数字和印度数字。它还支持不同种类的数字,包括:整数(123)、小数(123.4)、科学记数法(1.23E4)、百分数(12%)和货币金额($123)。所有这些都可以进行本地化。
在这里插入图片描述
在这里插入图片描述
说明:Number和Digit的区别:

  • Number是个抽象概念,其表达形式可以是数字、手势、声音等等。如1024就是个number
  • Digit是用来表达的单独符号。如0-9这是个digit就可以用来表示number,如1024就是由1、0、2、4这四个digit组成的
  @Test
    public void test4() {
        double myNum = 1220.0455;

        System.out.println("===============0的使用===============");
        System.out.println("只保留整数部分:" + new DecimalFormat("0").format(myNum));
        System.out.println("保留3位小数:" + new DecimalFormat("0.000").format(myNum));
        System.out.println("整数部分、小数部分都5位。不够的都用0补位(整数高位部,小数低位补):" + new DecimalFormat("00000.00000").format(myNum));

        System.out.println("===============#的使用===============");
        System.out.println("只保留整数部分:" + new DecimalFormat("#").format(myNum));
        System.out.println("保留2为小数并以百分比输出:" + new DecimalFormat("#.##%").format(myNum));

        // 非标准数字(不建议这么用)
        System.out.println("===============非标准数字的使用===============");
        System.out.println(new DecimalFormat("666").format(myNum));
        System.out.println(new DecimalFormat(".6666").format(myNum));
    }

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.MessageFormat:字符串格式化

MessageFormat提供了一种与语言无关(不管你在中国还是其它国家,效果一样)的方式生成拼接消息/拼接字符串的方法。使用它来构造显示给最终用户的消息。MessageFormat接受一组对象,对它们进行格式化,然后在模式的适当位置插入格式化的字符串。

简单案例

先来个最简单的使用示例体验一把:

    @Test
    public void test9() {
        String sourceStrPattern = "Hello {0},my name is {1}";
        Object[] args = new Object[]{"girl", "YourBatman"};

        String formatedStr = MessageFormat.format(sourceStrPattern, args);
        System.out.println(formatedStr);
    }

在这里插入图片描述

    @Test
    public void test9() {
        String pattern = "当前执行到:{0}{1},下一个执行第{2}{3}";
        for (int i = 0; i < 10; i++) {
            System.out.println(MessageFormat.format(pattern, new Object[]{i, "次", i + 1, "次"}));
        }
    }

在这里插入图片描述

2.参数模式

在这里插入图片描述
说明:FormatType和FormatStyle只有在传入值为日期时间、数字、百分比等类型时才有可能需要设置,使用得并不多。毕竟:我在外部格式化好后再放进去不香吗?

@Test
public void test10() {
    MessageFormat messageFormat = new MessageFormat("Hello, my name is {0}. I’am {1,number,#.##} years old. Today is {2,date,yyyy-MM-dd HH:mm:ss}");
    // 亦可通过编程式 显示指定某个位置要使用的格式化器
    // messageFormat.setFormatByArgumentIndex(1, new DecimalFormat("#.###"));

    System.out.println(messageFormat.format(new Object[]{"YourBatman", 24.123456, new Date()}));
}

在这里插入图片描述

3.注意事项

下面基于此示例,对MessageFormat的使用注意事项作出几点强调。

@Test
public void test11() {
    System.out.println(MessageFormat.format("{1} - {1}", new Object[]{1})); // {1} - {1}
    System.out.println(MessageFormat.format("{0} - {1}", new Object[]{1})); // 输出:1 - {1}
    System.out.println(MessageFormat.format("{0} - {1}", new Object[]{1, 2, 3})); // 输出:1 - 2

    System.out.println("---------------------------------");

    System.out.println(MessageFormat.format("'{0} - {1}", new Object[]{1, 2})); // 输出:{0} - {1}
    System.out.println(MessageFormat.format("''{0} - {1}", new Object[]{1, 2})); // 输出:'1 - 2
    System.out.println(MessageFormat.format("'{0}' - {1}", new Object[]{1, 2})); // {0} - 2
    // 若你数据库值两边都需要''包起来,请你这么写
    System.out.println(MessageFormat.format("''{0}'' - {1}", new Object[]{1, 2})); // '1' - 2

    System.out.println("---------------------------------");
    System.out.println(MessageFormat.format("0} - {1}", new Object[]{1, 2})); // 0} - 2
    System.out.println(MessageFormat.format("{0 - {1}", new Object[]{1, 2})); // java.lang.IllegalArgumentException: Unmatched braces in the pattern.
}

在这里插入图片描述

在这里插入图片描述

4.经典使用场景

这个就很多啦,最常见的有:HTML拼接、SQL拼接、异常信息拼接等等。

StringBuilder sb =new StringBuilder();
sb.append("insert into user (");
sb.append("		name,");
sb.append("		accountId,");
sb.append("		zhName,");
sb.append("		enname,");
sb.append("		status");
sb.append(") values (");
sb.append("		''{0}'',");
sb.append("		{1},");
sb.append("		''{2}'',");
sb.append("		''{3}'',");
sb.append("		{4},");
sb.append(")");

Object[] args = {name, accountId, zhName, enname, status};

// 最终SQL
String sql = MessageFormat.format(sb.toString(), args);

5.特殊使用

  1. MessageFormat可对时间、日期、数字进行更加特殊格式转化
  2. 一般使用MessageFormat只会简单的{0},如 str = “test:{0}”,但其实MessageFormat支持的不仅仅是{0},{0}只是其中一个模板写法,其全称模板如下: { ArgumentIndex , FormatType , FormatStyle }
  3. ArgumentIndex:数字0,1,2
  4. FormatType:格式化类型,支持:
    在这里插入图片描述
  5. FormatStyle:格式化风格,支持
    在这里插入图片描述

数字

   @Test
    public void test1() {
        // 数字
        String str = "test:{0,number,currency}";
        // 结果:test:¥1.20
        System.out.println(MessageFormat.format(str, 1.2));
        
        

        String str2 = "test:{0,number,percent}";
        // 结果:test:120%
        System.out.println(MessageFormat.format(str2, 1.2));
        
        

        String str3 = "test:{0,number,integer}";
        // 结果:test:1
        System.out.println(MessageFormat.format(str3, 1.2));

    }

在这里插入图片描述

日期

    @Test
    public void test1() {
        // 日期
        String str4 = "test:{0,date,short}";
        // 结果:22-12-17
        System.out.println(MessageFormat.format(str4, new Date()));


        String str5 = "test:{0,date,medium}";
        // 结果:2022-12-17
        System.out.println(MessageFormat.format(str5, new Date()));


        String str6 = "test:{0,date,long}";
        // 结果:2022年12月17日
        System.out.println(MessageFormat.format(str6, new Date()));


        String str7 = "test:{0,date,full}";
        // 结果:2022年12月17日 星期六
        System.out.println(MessageFormat.format(str7, new Date()));

    }

在这里插入图片描述

时间

   public void test1() {
        // 时间
        String str4 = "test:{0,time,short}";
        // 结果:下午2:41
        System.out.println(MessageFormat.format(str4, new Date()));


        String str5 = "test:{0,time,medium}";
        // 结果:14:41:52
        System.out.println(MessageFormat.format(str5, new Date()));


        String str6 = "test:{0,time,long}";
        // 结果:下午02时41分52秒
        System.out.println(MessageFormat.format(str6, new Date()));


        String str7 = "test:{0,time,full}";
        // 结果:下午02时41分52秒 CST
        System.out.println(MessageFormat.format(str7, new Date()));

    }

在这里插入图片描述

在结论上补充其他更加特殊情况

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值