You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java21.0.3绘制日期时间时出现非法矩形问题求助

问题描述

时间与am间显示矩形的截图
上图中时间值与“am”之间显示了一个矩形。在Java 21.0.3中,DateTime格式化后的字符串包含**NNBSP(窄不换行空格)**字符,该字符因当前使用的字体不支持,绘制时被渲染为矩形。

复现代码

public class RunningStringPanel extends JPanel implements ActionListener {
    private String text;

    public RunningStringPanel(String text, int delay) {
        this.text = text;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setFont(new Font("MS Gothic", Font.ITALIC, 24));
        System.out.println(text);
        g.drawString(text, 10, 50); // Draw the string up to the current index
        System.out.println();
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        repaint();
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Running String");
        RunningStringPanel panel = new RunningStringPanel(getText(), 200);
        frame.add(panel);
        frame.setSize(400, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static final Long LONG_TIME = 1573430400000L;

    public static String getText() {
        Date created = new Date(LONG_TIME);
        DateFormat format = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
        String value = format.format(created);
        return value;
    }
}

已尝试的解决方法

  • 设置stdout.encoding和stderr.encoding为UTF-8
  • 使用最新的DateFormatter API,问题依旧
  • 将Windows区域设置改为UTF-8

疑问

有没有办法避免字符串中显示这个矩形?


解决方法

出现矩形的核心原因是MS Gothic字体不支持NNBSP(U+202F)字符,可通过以下方式解决:

  1. 替换NNBSP字符
    在格式化后直接将NNBSP替换为字体支持的空格类型,比如普通空格:
public static String getText() {
    Date created = new Date(LONG_TIME);
    DateFormat format = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
    String value = format.format(created);
    // 替换窄不换行空格为普通空格
    return value.replace('\u202F', ' ');
}
  1. 更换支持NNBSP的字体
    把绘制时使用的字体换成支持该字符的字体,比如Segoe UI、微软雅黑等:
@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    // 改用Segoe UI字体
    g.setFont(new Font("Segoe UI", Font.ITALIC, 24));
    System.out.println(text);
    g.drawString(text, 10, 50);
    System.out.println();
}
  1. 自定义日期格式模板
    绕过系统默认的FULL格式,手动指定日期输出模板,从根源避免NNBSP生成:
// 使用旧API的SimpleDateFormat
public static String getText() {
    Date created = new Date(LONG_TIME);
    // 自定义格式,用普通空格分隔
    SimpleDateFormat sdf = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm:ss a", Locale.US);
    return sdf.format(created);
}

// 或者使用Java 8+的新API
public static String getText() {
    LocalDateTime dateTime = Instant.ofEpochMilli(LONG_TIME)
            .atZone(ZoneId.systemDefault())
            .toLocalDateTime();
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(
            "EEEE, MMMM dd, yyyy hh:mm:ss a", 
            Locale.US
    );
    return dateTime.format(formatter);
}

内容的提问来源于Stack Exchange,提问作者Margub Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 16:03:10