小熊奶糖(BearCandy)
小熊奶糖(BearCandy)
发布于 2025-10-11 / 0 阅读
0
0

Java时间戳与日期类详解

Java时间戳与日期类详解

1. 时间戳 (Timestamp)

什么是时间戳

时间戳是指从1970年1月1日00:00:00 GMT开始到现在的总毫秒数,也称为Unix时间戳。

获取时间戳的方法

// 方法1: System.currentTimeMillis() - 最常用
long timestamp1 = System.currentTimeMillis();
System.out.println("当前时间戳: " + timestamp1);

// 方法2: java.util.Date
long timestamp2 = new Date().getTime();
System.out.println("Date获取时间戳: " + timestamp2);

// 方法3: java.util.Calendar
Calendar calendar = Calendar.getInstance();
long timestamp3 = calendar.getTimeInMillis();
System.out.println("Calendar获取时间戳: " + timestamp3);

// 方法4: java.time.Instant (Java 8+)
Instant instant = Instant.now();
long timestamp4 = instant.toEpochMilli();
System.out.println("Instant获取时间戳: " + timestamp4);

时间戳与日期转换

// 时间戳转日期
long timestamp = 1698765432100L;

// 转换为java.util.Date
Date dateFromTimestamp = new Date(timestamp);

// 转换为java.time.LocalDateTime (Java 8+)
LocalDateTime localDateTime = Instant.ofEpochMilli(timestamp)
        .atZone(ZoneId.systemDefault())
        .toLocalDateTime();

// 日期转时间戳
Date date = new Date();
long timestampFromDate = date.getTime();

2. 传统日期类 (Java 8之前)

java.util.Date

import java.util.Date;

// 创建Date对象
Date now = new Date(); // 当前时间
Date specificDate = new Date(1698765432100L); // 指定时间戳

// 常用方法
System.out.println("当前时间: " + now);
System.out.println("时间戳: " + now.getTime());
System.out.println("比较时间: " + now.after(specificDate)); // 是否在指定时间之后
System.out.println("比较时间: " + now.before(specificDate)); // 是否在指定时间之前

// 设置时间
now.setTime(1698765432100L);

java.util.Calendar

import java.util.Calendar;

// 获取Calendar实例
Calendar calendar = Calendar.getInstance();

// 常用字段常量
System.out.println("年: " + calendar.get(Calendar.YEAR));
System.out.println("月: " + (calendar.get(Calendar.MONTH) + 1)); // 月份从0开始
System.out.println("日: " + calendar.get(Calendar.DAY_OF_MONTH));
System.out.println("时: " + calendar.get(Calendar.HOUR_OF_DAY));
System.out.println("分: " + calendar.get(Calendar.MINUTE));
System.out.println("秒: " + calendar.get(Calendar.SECOND));

// 设置日期时间
calendar.set(2023, Calendar.NOVEMBER, 1, 10, 30, 0); // 2023年11月1日 10:30:00

// 日期计算
calendar.add(Calendar.DAY_OF_MONTH, 5); // 加5天
calendar.add(Calendar.MONTH, -1); // 减1个月

// 获取Date对象
Date dateFromCalendar = calendar.getTime();

SimpleDateFormat - 日期格式化

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

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

// 日期转字符串
String dateString = sdf.format(new Date());
System.out.println("格式化日期: " + dateString);

// 字符串转日期
try {
    String dateStr = "2023-11-01 10:30:00";
    Date parsedDate = sdf.parse(dateStr);
    System.out.println("解析后的日期: " + parsedDate);
} catch (Exception e) {
    e.printStackTrace();
}

// 常用格式模式
SimpleDateFormat[] formats = {
    new SimpleDateFormat("yyyy-MM-dd"),           // 2023-11-01
    new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"),  // 2023/11/01 10:30:00
    new SimpleDateFormat("yyyy年MM月dd日"),        // 2023年11月01日
    new SimpleDateFormat("EEE, MMM d, ''yy")      // 周三, 11月 1, '23
};

3. Java 8日期时间API (java.time包)

LocalDate - 日期

import java.time.LocalDate;
import java.time.DayOfWeek;
import java.time.Month;

// 创建LocalDate
LocalDate today = LocalDate.now();
LocalDate specificDate = LocalDate.of(2023, 11, 1);
LocalDate parsedDate = LocalDate.parse("2023-11-01");

// 常用方法
System.out.println("当前日期: " + today);
System.out.println("年: " + today.getYear());
System.out.println("月: " + today.getMonth() + " (" + today.getMonthValue() + ")");
System.out.println("日: " + today.getDayOfMonth());
System.out.println("星期: " + today.getDayOfWeek());
System.out.println("是否闰年: " + today.isLeapYear());
System.out.println("当月天数: " + today.lengthOfMonth());
System.out.println("当年天数: " + today.lengthOfYear());

// 日期计算
LocalDate tomorrow = today.plusDays(1);
LocalDate nextWeek = today.plusWeeks(1);
LocalDate nextMonth = today.plusMonths(1);
LocalDate nextYear = today.plusYears(1);

LocalDate yesterday = today.minusDays(1);

// 日期比较
System.out.println("是否在今天之后: " + tomorrow.isAfter(today));
System.out.println("是否在今天之前: " + yesterday.isBefore(today));
System.out.println("是否相等: " + today.equals(today));

LocalTime - 时间

import java.time.LocalTime;

// 创建LocalTime
LocalTime now = LocalTime.now();
LocalTime specificTime = LocalTime.of(10, 30, 45); // 10:30:45
LocalTime parsedTime = LocalTime.parse("10:30:45");

// 常用方法
System.out.println("当前时间: " + now);
System.out.println("时: " + now.getHour());
System.out.println("分: " + now.getMinute());
System.out.println("秒: " + now.getSecond());
System.out.println("纳秒: " + now.getNano());

// 时间计算
LocalTime later = now.plusHours(2).plusMinutes(30);
LocalTime earlier = now.minusHours(1);

// 时间比较
System.out.println("是否在现在之后: " + later.isAfter(now));

LocalDateTime - 日期时间

import java.time.LocalDateTime;

// 创建LocalDateTime
LocalDateTime now = LocalDateTime.now();
LocalDateTime specificDateTime = LocalDateTime.of(2023, 11, 1, 10, 30, 45);
LocalDateTime parsedDateTime = LocalDateTime.parse("2023-11-01T10:30:45");

// 常用方法
System.out.println("当前日期时间: " + now);
System.out.println("年: " + now.getYear());
System.out.println("时: " + now.getHour());

// 与LocalDate和LocalTime转换
LocalDate datePart = now.toLocalDate();
LocalTime timePart = now.toLocalTime();

LocalDateTime fromDateAndTime = LocalDateTime.of(today, now);

// 日期时间计算
LocalDateTime future = now.plusDays(1).plusHours(2);
LocalDateTime past = now.minusMonths(1).minusHours(3);

Instant - 时间戳

import java.time.Instant;

// 创建Instant
Instant now = Instant.now();
Instant specificInstant = Instant.ofEpochMilli(1698765432100L);

// 常用方法
System.out.println("当前时刻: " + now);
System.out.println("时间戳(毫秒): " + now.toEpochMilli());
System.out.println("时间戳(秒): " + now.getEpochSecond());

// 时间计算
Instant later = now.plusSeconds(3600); // 加1小时
Instant earlier = now.minusSeconds(1800); // 减30分钟

DateTimeFormatter - 格式化

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

// 预定义格式化器
DateTimeFormatter isoFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
DateTimeFormatter basicFormatter = DateTimeFormatter.BASIC_ISO_DATE;

// 自定义格式化器
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter chineseFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");

// 格式化
LocalDateTime now = LocalDateTime.now();
String formatted = now.format(formatter);
System.out.println("格式化结果: " + formatted);

// 解析
LocalDateTime parsed = LocalDateTime.parse("2023-11-01 10:30:00", formatter);
System.out.println("解析结果: " + parsed);

4. 常用工具方法

日期比较和计算

import java.time.temporal.ChronoUnit;

LocalDate date1 = LocalDate.of(2023, 1, 1);
LocalDate date2 = LocalDate.of(2023, 12, 31);

// 计算日期差
long daysBetween = ChronoUnit.DAYS.between(date1, date2);
long monthsBetween = ChronoUnit.MONTHS.between(date1, date2);
long yearsBetween = ChronoUnit.YEARS.between(date1, date2);

System.out.println("相差天数: " + daysBetween);
System.out.println("相差月数: " + monthsBetween);
System.out.println("相差年数: " + yearsBetween);

时区处理

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

// 时区日期时间
ZonedDateTime beijingTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
ZonedDateTime newYorkTime = ZonedDateTime.now(ZoneId.of("America/New_York"));

System.out.println("北京时间: " + beijingTime);
System.out.println("纽约时间: " + newYorkTime);

// 时区转换
ZonedDateTime convertedTime = beijingTime.withZoneSameInstant(ZoneId.of("UTC"));
System.out.println("UTC时间: " + convertedTime);

5. 最佳实践

  1. 推荐使用Java 8的日期时间API,它更清晰、线程安全且功能更强大
  2. 避免使用已过时的构造方法,如 Date的年份从1900开始计算
  3. 注意时区问题,明确业务需求的时区
  4. 使用不可变对象,Java 8的日期时间类都是不可变的,更安全
  5. 合理选择日期类
    • 只需要日期:LocalDate
    • 只需要时间:LocalTime
    • 需要日期时间:LocalDateTime
    • 需要时间戳:Instant
    • 需要时区:ZonedDateTime

这些类和方法覆盖了Java中处理日期时间的常见需求,根据具体场景选择合适的类和方法即可。

日历类 - Calendar

基本使用

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

public class CalendarExample {
    public static void main(String[] args) {
        // 获取Calendar实例
        Calendar calendar = Calendar.getInstance();
      
        // 获取各个字段的值
        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年%d月%d日 %d时%d分%d秒\n", 
                         year, month, day, hour, minute, second);
      
        // 设置特定时间
        calendar.set(2024, Calendar.JANUARY, 15, 14, 30, 0);
        Date specificDate = calendar.getTime();
        System.out.println("设置的特定时间: " + specificDate);
      
        // 日期计算
        calendar.add(Calendar.DAY_OF_MONTH, 7); // 加7天
        System.out.println("7天后: " + calendar.getTime());
      
        calendar.add(Calendar.MONTH, -1); // 减1个月
        System.out.println("1个月前: " + calendar.getTime());
    }
}

日历操作示例

import java.util.Calendar;

public class CalendarOperations {
    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();
      
        // 获取月份的第一天和最后一天
        cal.set(Calendar.DAY_OF_MONTH, 1);
        System.out.println("本月第一天: " + cal.getTime());
      
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        System.out.println("本月最后一天: " + cal.getTime());
      
        // 获取星期几
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayOfWeek < 0) dayOfWeek = 0;
        System.out.println("今天是: " + weekDays[dayOfWeek]);
      
        // 计算两个日期之间的天数差
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal2.add(Calendar.DAY_OF_MONTH, 10);
      
        long diff = cal2.getTimeInMillis() - cal1.getTimeInMillis();
        long days = diff / (1000 * 60 * 60 * 24);
        System.out.println("相差天数: " + days);
    }
}

3. 新的时间API (Java 8+)

Instant - 时间戳

import java.time.Instant;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;

public class InstantExample {
    public static void main(String[] args) {
        // 获取当前时间戳
        Instant instant = Instant.now();
        System.out.println("当前时间戳: " + instant);
        System.out.println("时间戳(毫秒): " + instant.toEpochMilli());
        System.out.println("时间戳(秒): " + instant.getEpochSecond());
      
        // 从时间戳创建
        Instant specificInstant = Instant.ofEpochMilli(1705296000000L);
        System.out.println("特定时间戳: " + specificInstant);
      
        // 时间计算
        Instant later = instant.plus(Duration.ofHours(2));
        System.out.println("2小时后: " + later);
      
        // 与LocalDateTime转换
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        System.out.println("转换为LocalDateTime: " + localDateTime);
    }
}

LocalDateTime 和 ZonedDateTime

import java.time.LocalDateTime;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;

public class NewDateTimeAPI {
    public static void main(String[] args) {
        // LocalDate, LocalTime, LocalDateTime
        LocalDate date = LocalDate.now();
        LocalTime time = LocalTime.now();
        LocalDateTime dateTime = LocalDateTime.now();
      
        System.out.println("当前日期: " + date);
        System.out.println("当前时间: " + time);
        System.out.println("当前日期时间: " + dateTime);
      
        // 创建特定时间
        LocalDateTime specificDateTime = LocalDateTime.of(2024, 1, 15, 14, 30, 0);
        System.out.println("特定时间: " + specificDateTime);
      
        // 时区时间
        ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        System.out.println("上海时区时间: " + zonedDateTime);
      
        // 格式化
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formatted = dateTime.format(formatter);
        System.out.println("格式化时间: " + formatted);
      
        // 解析
        LocalDateTime parsed = LocalDateTime.parse("2024-01-15 14:30:00", formatter);
        System.out.println("解析的时间: " + parsed);
    }
}

日期计算和比较

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.time.Period;
import java.time.Duration;

public class DateTimeCalculations {
    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        LocalDate tomorrow = today.plusDays(1);
        LocalDate nextWeek = today.plusWeeks(1);
        LocalDate nextMonth = today.plusMonths(1);
      
        System.out.println("今天: " + today);
        System.out.println("明天: " + tomorrow);
        System.out.println("下周: " + nextWeek);
        System.out.println("下月: " + nextMonth);
      
        // 日期比较
        System.out.println("今天在明天之前: " + today.isBefore(tomorrow));
        System.out.println("今天是闰年: " + today.isLeapYear());
      
        // 计算日期间隔
        long daysBetween = ChronoUnit.DAYS.between(today, nextWeek);
        System.out.println("今天到下周的天数差: " + daysBetween);
      
        Period period = Period.between(today, nextMonth);
        System.out.printf("时间间隔: %d年%d个月%d天\n", 
                         period.getYears(), period.getMonths(), period.getDays());
      
        // 时间间隔计算
        LocalDateTime start = LocalDateTime.now();
        LocalDateTime end = start.plusHours(2).plusMinutes(30);
        Duration duration = Duration.between(start, end);
        System.out.println("时间间隔(小时): " + duration.toHours());
        System.out.println("时间间隔(分钟): " + duration.toMinutes());
    }
}

4. 新旧API转换

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Calendar;

public class APIConversion {
    public static void main(String[] args) {
        // Date 转 Instant
        Date date = new Date();
        Instant instant = date.toInstant();
        System.out.println("Date -> Instant: " + instant);
      
        // Instant 转 Date
        Date fromInstant = Date.from(instant);
        System.out.println("Instant -> Date: " + fromInstant);
      
        // Calendar 转 Instant
        Calendar calendar = Calendar.getInstance();
        Instant fromCalendar = calendar.toInstant();
        System.out.println("Calendar -> Instant: " + fromCalendar);
      
        // LocalDateTime 转 Date
        LocalDateTime localDateTime = LocalDateTime.now();
        Instant localToInstant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
        Date fromLocal = Date.from(localToInstant);
        System.out.println("LocalDateTime -> Date: " + fromLocal);
      
        // Date 转 LocalDateTime
        LocalDateTime fromDate = LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
        System.out.println("Date -> LocalDateTime: " + fromDate);
    }
}

总结

  1. 传统API (Date, Calendar):

    • 存在于 java.util
    • 线程不安全
    • API设计不够友好
  2. 新时间API (Java 8+):

    • 存在于 java.time
    • 线程安全
    • API设计更直观易用
    • 推荐在新项目中使用

评论