一、核心方法概览

方法 推荐度 适用版本 特点
new Date() ⚠️ 一般 所有版本 简单但已过时
Calendar.getInstance() ⚠️ 一般 Java 1.1+ 灵活但复杂
LocalDateTime.now() ✅ 强烈推荐 Java 8+ 现代、简洁、线程安全
ZonedDateTime.now() ✅ 推荐 Java 8+ 包含时区信息

二、详细操作步骤

方法 1:使用 java.util.Date(传统方式)

import java.util.Date;

public class GetCurrentTime {
    public static void main(String[] args) {
        // 获取当前时间
        Date now = new Date();
        
        System.out.println("当前日期时间: " + now);
        // 输出示例: Sat Aug 16 07:15:30 CST 2025
        
        // 格式化输出
        java.text.SimpleDateFormat sdf = 
            new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("格式化时间: " + sdf.format(now));
    }
}

⚠️ 注意Date 已标记为过时,不推荐在新项目中使用。


方法 2:使用 Calendar(传统方式)

import java.util.Calendar;
import java.util.Date;

public class CalendarExample {
    public static void main(String[] args) {
        // 获取当前时间
        Calendar calendar = Calendar.getInstance();
        Date now = calendar.getTime();
        
        System.out.println("当前时间: " + now);
        
        // 获取具体字段
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1; // 月份从0开始
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        
        System.out.printf("当前日期: %d-%02d-%02d %02d:%02d:%02d%n", 
                         year, month, day, hour, minute, second);
    }
}

⚠️ 缺点:代码冗长,月份从0开始,易出错。


方法 3:使用 java.time API(Java 8+ 推荐)

✅ 3.1 使用 LocalDateTime.now()

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

public class ModernTimeExample {
    public static void main(String[] args) {
        // 获取当前日期时间(不带时区)
        LocalDateTime now = LocalDateTime.now();
        
        System.out.println("当前时间: " + now);
        // 输出: 2025-08-16T07:15:30.123
        
        // 格式化输出
        DateTimeFormatter formatter = 
            DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formatted = now.format(formatter);
        System.out.println("格式化时间: " + formatted);
    }
}

✅ 3.2 使用 ZonedDateTime.now()

import java.time.ZonedDateTime;
import java.time.ZoneId;

public class ZonedExample {
    public static void main(String[] args) {
        // 获取当前时间(带时区)
        ZonedDateTime now = ZonedDateTime.now();
        System.out.println("带时区时间: " + now);
        // 输出: 2025-08-16T07:15:30.123+08:00[Asia/Shanghai]
        
        // 指定时区
        ZonedDateTime nyTime = ZonedDateTime.now(ZoneId.of("America/New_York"));
        System.out.println("纽约时间: " + nyTime);
    }
}

✅ 3.3 使用 Instant.now()(UTC 时间)

import java.time.Instant;

public class InstantExample {
    public static void main(String[] args) {
        // 获取 UTC 时间戳
        Instant now = Instant.now();
        System.out.println("UTC时间: " + now);
        // 输出: 2025-08-15T23:15:30.123Z
    }
}

三、常见错误

❌ 错误 1:使用 Date() 构造函数而不格式化

// 输出可读性差
System.out.println(new Date()); // Sat Aug 16 07:15:30 CST 2025

❌ 错误 2:Calendar 月份处理错误

// 错误:忘记 +1
int month = calendar.get(Calendar.MONTH); // 0-11
// 正确:
int month = calendar.get(Calendar.MONTH) + 1; // 1-12

❌ 错误 3:SimpleDateFormat 线程不安全

// 危险!多线程环境下可能出错
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

// 正确做法:使用 ThreadLocal 或 DateTimeFormatter

四、注意事项

  1. 线程安全

    • DateSimpleDateFormat 不是线程安全的
    • java.time 包中的类(LocalDateTime, Instant 等)是线程安全的
  2. 时区问题

    • LocalDateTime 不包含时区信息
    • 跨时区系统建议使用 ZonedDateTimeInstant
  3. 性能考虑

    • java.time API 性能优于传统方式
    • 频繁格式化时,缓存 DateTimeFormatter
  4. null 安全

    • LocalDateTime.now() 永不返回 null
    • new Date() 也永不返回 null

五、使用技巧

✅ 技巧 1:封装常用格式

public class TimeUtils {
    private static final DateTimeFormatter DEFAULT_FORMATTER = 
        DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    
    public static String now() {
        return LocalDateTime.now().format(DEFAULT_FORMATTER);
    }
}

✅ 技巧 2:获取特定部分

LocalDateTime now = LocalDateTime.now();
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
int hour = now.getHour();

✅ 技巧 3:仅获取日期或时间

LocalDate dateOnly = LocalDate.now();      // 2025-08-16
LocalTime timeOnly = LocalTime.now();      // 07:15:30

六、最佳实践与性能优化

✅ 最佳实践 1:新项目使用 java.time API

// 推荐 ✅
LocalDateTime now = LocalDateTime.now();

// 不推荐 ❌
Date now = new Date();

✅ 最佳实践 2:缓存格式化器

// 好做法
private static final DateTimeFormatter FORMATTER = 
    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

✅ 最佳实践 3:明确时区需求

// 需要时区信息
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));

// 不需要时区
LocalDateTime now = LocalDateTime.now();

✅ 性能优化

  • LocalDateTime.now()new Date() 略快
  • 避免在循环中创建 DateTimeFormatter
  • 高并发场景下,java.time 更安全高效

七、总结

推荐方案(Java 8+)

// 1. 获取当前日期时间(推荐)
LocalDateTime now = LocalDateTime.now();

// 2. 格式化输出
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = now.format(formatter);

// 3. 打印
System.out.println("当前时间: " + formatted);

选择建议

需求 推荐类型
通用场景 LocalDateTime.now()
需要时区 ZonedDateTime.now()
存储时间戳 Instant.now()
仅日期 LocalDate.now()
仅时间 LocalTime.now()