0

0

如何在Java中使用SimpleDateFormat格式化日期

P粉602998670

P粉602998670

发布时间:2025-09-22 08:11:01

|

909人浏览过

|

来源于php中文网

原创

使用SimpleDateFormat格式化日期需创建实例并调用format()方法,但其非线程安全,推荐用ThreadLocal或Java 8的DateTimeFormatter替代。

如何在java中使用simpledateformat格式化日期

在Java中,使用

SimpleDateFormat
格式化日期,核心就是将一个
Date
对象转换成我们人类能读懂的、特定格式的字符串。它通过定义一个模式字符串(pattern string)来指导日期时间的显示方式,让原本无序的日期数据变得井井有条。

使用

SimpleDateFormat
格式化日期,通常分两步走:首先,你需要根据想要的日期时间格式,创建一个
SimpleDateFormat
实例;接着,调用这个实例的
format()
方法,传入你的
Date
对象,就能得到格式化后的字符串了。

import java.text.SimpleDateFormat;
import java.util.Date;

public class DateFormatterExample {
    public static void main(String[] args) {
        // 1. 获取当前日期时间
        Date now = new Date();

        // 2. 定义你想要的日期时间格式
        // 例如:"yyyy-MM-dd HH:mm:ss" 会显示像 "2023-10-27 15:30:00" 这样的格式
        // "yyyy年MM月dd日 E HH时mm分ss秒" 会显示像 "2023年10月27日 星期五 15时30分00秒"
        String pattern = "yyyy-MM-dd HH:mm:ss"; // 我个人最常用的一种,简洁明了

        // 3. 创建 SimpleDateFormat 实例
        SimpleDateFormat formatter = new SimpleDateFormat(pattern);

        // 4. 使用 format() 方法将 Date 对象格式化为字符串
        String formattedDate = formatter.format(now);

        System.out.println("原始日期: " + now);
        System.out.println("格式化后的日期: " + formattedDate);

        // 反过来,如果你有一个日期字符串,想把它解析成 Date 对象,也可以用 parse() 方法
        String dateString = "2024-01-01 08:00:00";
        SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date parsedDate = parser.parse(dateString);
            System.out.println("解析后的日期: " + parsedDate);
        } catch (java.text.ParseException e) {
            System.err.println("日期字符串解析失败: " + e.getMessage());
        }
    }
}

这里面的模式字符串(pattern string)是关键。

y
代表年份,
M
代表月份,
d
代表日期,
H
代表24小时制的小时,
H
代表12小时制的小时,
M
代表分钟,
s
代表秒,
s
代表毫秒,
E
代表星期几。字符的数量会影响输出的格式,比如
MM
会输出两位数的月份(01-12),
MMM
会输出缩写(Jan, Feb),
MMMM
会输出完整名称(January, February)。我通常会根据需求去查阅一下Java官方文档,确保模式字符的正确使用,因为有时候一些细微的差别会导致意想不到的输出。

SimpleDateFormat的线程安全问题:那些隐藏的坑

说实话,

SimpleDateFormat
用起来确实方便,但它有一个非常大的“坑”,那就是它不是线程安全的。我第一次遇到这个问题时,是在一个多线程环境中,偶尔会发现日期格式化结果是错乱的,甚至直接抛出异常,当时真是把我搞得一头雾水。

立即学习Java免费学习笔记(深入)”;

简单来说,

SimpleDateFormat
format()
parse()
方法内部使用了共享的成员变量,当多个线程同时访问这些方法时,这些共享变量的状态就可能被意外修改,导致结果不一致。这就好比多个厨师共用一个案板,但每个人都在上面切菜,没有加锁,最后案板上的东西就乱套了。

为了解决这个问题,通常有几种做法:

BGremover
BGremover

VanceAI推出的图片背景移除工具

下载
  1. 每次使用时都创建新实例:这是最直接,也最笨但最安全的方法。每次需要格式化或解析日期时,都

    new SimpleDateFormat()
    一个新对象。这虽然解决了线程安全问题,但频繁创建对象会带来一定的性能开销,尤其是在高并发场景下,我个人会尽量避免这种方式。

    // 每次都创建新实例,确保线程安全
    public String formatThreadSafe(Date date) {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
    }
  2. 使用

    ThreadLocal
    包装:这是我比较推荐的一种方案,它能保证每个线程都拥有自己的
    SimpleDateFormat
    实例,既避免了线程安全问题,又避免了频繁创建对象的开销。

    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class ThreadLocalDateFormat {
        private static final ThreadLocal formatter = ThreadLocal.withInitial(
            () -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    
        public static String format(Date date) {
            return formatter.get().format(date);
        }
    
        public static Date parse(String dateString) throws java.text.ParseException {
            return formatter.get().parse(dateString);
        }
    
        public static void main(String[] args) {
            // 示例:在多个线程中使用
            for (int i = 0; i < 5; i++) {
                new Thread(() -> {
                    try {
                        String formatted = format(new Date());
                        System.out.println(Thread.currentThread().getName() + " formatted: " + formatted);
                        Date parsed = parse("2023-11-11 11:11:11");
                        System.out.println(Thread.currentThread().getName() + " parsed: " + parsed);
                    } catch (java.text.ParseException e) {
                        e.printStackTrace();
                    }
                }, "Thread-" + i).start();
            }
        }
    }

    这种方式在Java 8之前是处理

    SimpleDateFormat
    线程安全问题的标准做法,既保证了正确性,又兼顾了性能。

现代Java日期API:使用DateTimeFormatter的优雅之道

在我看来,Java 8引入的

java.time
包(也称为JSR 310)彻底改变了Java日期时间处理的格局,它提供了一套全新的、更强大、更易用且线程安全的API。如果你正在使用Java 8或更高版本,我强烈建议你放弃
SimpleDateFormat
,转而使用
DateTimeFormatter

DateTimeFormatter
java.time
包中用于格式化和解析日期时间的核心类,它与
LocalDate
LocalTime
LocalDateTime
ZonedDateTime
等类配合使用。它的设计初衷就考虑到了线程安全,因此你无需担心多线程并发问题。

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

public class ModernDateFormatterExample {
    public static void main(String[] args) {
        // 1. 获取当前日期时间
        LocalDateTime now = LocalDateTime.now();

        // 2. 定义你想要的日期时间格式
        // DateTimeFormatter 的模式与 SimpleDateFormat 类似,但更严格和清晰
        String pattern = "yyyy-MM-dd HH:mm:ss";
        // 我个人觉得,对于一些标准格式,直接用预定义的常量更方便,比如 ISO_LOCAL_DATE_TIME
        // DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME; // 2023-10-27T15:30:00

        // 3. 创建 DateTimeFormatter 实例
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);

        // 4. 使用 format() 方法将 LocalDateTime 对象格式化为字符串
        String formattedDateTime = now.format(formatter);

        System.out.println("原始日期时间: " + now);
        System.out.println("格式化后的日期时间: " + formattedDateTime);

        // 反过来,解析字符串到 LocalDateTime
        String dateTimeString = "2024-01-01 09:30:15";
        try {
            LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeString, formatter);
            System.out.println("解析后的日期时间: " + parsedDateTime);
        } catch (DateTimeParseException e) {
            System.err.println("日期时间字符串解析失败: " + e.getMessage());
        }

        // 对于只处理日期或时间的情况,也有对应的类
        // LocalDate today = LocalDate.now();
        // DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        // System.out.println("格式化日期: " + today.format(dateFormatter));
    }
}

DateTimeFormatter
的好处显而易见:它不仅解决了线程安全问题,还提供了更丰富的API,例如链式调用、对时区处理的良好支持等等。它的模式字符串虽然和
SimpleDateFormat
有些相似,但更加直观和一致。在我看来,一旦你开始使用
java.time
包,你就会发现之前的日期时间处理简直是“上古时代”的体验了。从项目的长期维护性和代码的健壮性考虑,我总是推荐优先使用
DateTimeFormatter

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

463

2023.08.02

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

804

2023.07.31

python中的format是什么意思
python中的format是什么意思

python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

435

2024.06.27

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

320

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1502

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

625

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

654

2024.03.22

C++ 设计模式与软件架构
C++ 设计模式与软件架构

本专题深入讲解 C++ 中的常见设计模式与架构优化,包括单例模式、工厂模式、观察者模式、策略模式、命令模式等,结合实际案例展示如何在 C++ 项目中应用这些模式提升代码可维护性与扩展性。通过案例分析,帮助开发者掌握 如何运用设计模式构建高质量的软件架构,提升系统的灵活性与可扩展性。

14

2026.01.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

C# 教程
C# 教程

共94课时 | 8万人学习

Java 教程
Java 教程

共578课时 | 53.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号