杰瑞科技汇

java calendar毫秒

Calendar 类本身并不直接存储“毫秒”作为一个独立的字段,但它有一个核心概念叫做 “时间”,这个时间在 Java 中通常以 从 1970 年 1 月 1 日 00:00:00 UTC(纪元)开始的毫秒数 来表示。

java calendar毫秒-图1
(图片来源网络,侵删)

理解这一点是关键。


核心方法:getTimeInMillis()setTimeInMillis()

这是 Calendar 类中与毫秒数交互最主要、最直接的两个方法。

getTimeInMillis()

这个方法返回 Calendar 对象所表示的时间点,对应的毫秒数(long 类型)。

示例代码:

java calendar毫秒-图2
(图片来源网络,侵删)
import java.util.Calendar;
public class CalendarMillisecondExample {
    public static void main(String[] args) {
        // 1. 创建一个 Calendar 实例,默认设置为当前时间
        Calendar calendar = Calendar.getInstance();
        // 2. 获取当前时间对应的毫秒数
        long currentTimeInMillis = calendar.getTimeInMillis();
        System.out.println("当前时间的毫秒数: " + currentTimeInMillis);
        // 3. 设置一个特定的日期和时间,2000-01-01 00:00:00
        Calendar specificDate = Calendar.getInstance();
        specificDate.set(2000, Calendar.JANUARY, 1, 0, 0, 0);
        // 注意:月份是从0开始的,Calendar.JANUARY 是 0
        long specificTimeInMillis = specificDate.getTimeInMillis();
        System.out.println("2000-01-01 的毫秒数: " + specificTimeInMillis);
    }
}

输出结果会类似这样(因为“当前时间”是动态的):

当前时间的毫秒数: 1678886400000  // 这是一个示例值,每次运行都会不同
2000-01-01 的毫秒数: 946684800000

setTimeInMillis(long millis)

这个方法使用一个给定的毫秒数来设置 Calendar 对象的日期和时间。

示例代码:

import java.util.Calendar;
public class SetTimeInMillisExample {
    public static void main(String[] args) {
        // 创建一个 Calendar 实例
        Calendar calendar = Calendar.getInstance();
        // 定义一个毫秒数,代表某个时间点
        long someTimeInMillis = 946684800000L; // 2000-01-01 00:00:00 UTC
        // 使用这个毫秒数来设置 Calendar
        calendar.setTimeInMillis(someTimeInMillis);
        // calendar 对象就代表了 2000-01-01 这个时间点
        // 我们可以从中提取年、月、日等信息
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH) + 1; // +1 因为月份从0开始
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println("毫秒数 " + someTimeInMillis + " 对应的日期是:");
        System.out.println("年份: " + year);
        System.out.println("月份: " + month);
        System.out.println("日期: " + day);
    }
}

输出:

毫秒数 946684800000 对应的日期是:
年份: 2000
月份: 1
日期: 1

CalendarDate 类的关系

CalendarDate 是 Java 早期处理日期和时间的重要类,它们之间通过毫秒数紧密相连。

  • Date 对象本质上就是一个封装了 long 类型毫秒数 的容器。
  • CalendargetTime() 方法可以将其内部的时间(毫秒数)转换为一个 Date 对象。
  • CalendarsetTime(Date date) 方法可以将一个 Date 对象代表的毫秒数设置到 Calendar 实例中。

示例代码:

import java.util.Calendar;
import java.util.Date;
public class CalendarAndDateExample {
    public static void main(String[] args) {
        // 1. 从 Calendar 获取 Date
        Calendar calendar = Calendar.getInstance();
        Date dateFromCalendar = calendar.getTime(); // 内部调用 getTimeInMillis() 转换
        System.out.println("Calendar 转换后的 Date 对象: " + dateFromCalendar);
        System.out.println("Date 对象内部存储的毫秒数: " + dateFromCalendar.getTime());
        System.out.println("--------------------");
        // 2. 从 Date 设置 Calendar
        Date someDate = new Date(); // 当前时间的 Date 对象
        System.out.println("原始 Date 对象: " + someDate);
        Calendar calendarFromDate = Calendar.getInstance();
        calendarFromDate.setTime(someDate); // 将 Date 的毫秒数设置给 Calendar
        System.out.println("用 Date 设置后的 Calendar 年份: " + calendarFromDate.get(Calendar.YEAR));
    }
}

输出:

Calendar 转换后的 Date 对象: Sat Mar 18 10:30:00 CST 2025
Date 对象内部存储的毫秒数: 1679106600000  // 示例值
--------------------
原始 Date 对象: Sat Mar 18 10:30:00 CST 2025
用 Date 设置后的 Calendar 年份: 2025

获取和设置毫秒级的精度(MILLISECOND 字段)

Calendar 确实有一个字段叫做 Calendar.MILLISECOND,但它通常不被推荐使用,原因如下:

  • 默认行为:当你通过 Calendar.getInstance() 创建一个实例时,MILLISECOND 字段的值通常是 0
  • 作用范围MILLISECOND 字段只影响 一秒内的毫秒部分,它的取值范围是 0 到 999。
  • 主要用途:当你需要对一个已经存在的 Calendar 对象进行微调,增加或减少几毫秒时,可以使用它。

示例代码:

import java.util.Calendar;
public class CalendarMillisecondFieldExample {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        System.out.println("初始毫秒字段: " + calendar.get(Calendar.MILLISECOND)); // 很可能是 0
        // 设置毫秒为 500
        calendar.set(Calendar.MILLISECOND, 500);
        System.out.println("设置后的毫秒字段: " + calendar.get(Calendar.MILLISECOND));
        // 验证 getTimeInMillis() 的变化
        long time1 = calendar.getTimeInMillis();
        System.out.println("设置 500ms 后的总毫秒数: " + time1);
        // 再增加 100 毫秒
        calendar.add(Calendar.MILLISECOND, 100);
        long time2 = calendar.getTimeInMillis();
        System.out.println("再增加 100ms 后的总毫秒数: " + time2);
        System.out.println("毫秒差值: " + (time2 - time1)); // 应该输出 100
    }
}

输出:

初始毫秒字段: 0
设置后的毫秒字段: 500
设置 500ms 后的总毫秒数: 1678886400500  // 示例值
再增加 100ms 后的总毫秒数: 1678886400600  // 示例值
毫秒差值: 100

重要提醒:Calendar 已被废弃

自 Java 8 以来,java.util.Calendarjava.util.Date 类都已被标记为 @Deprecated (已废弃),官方文档强烈建议使用新的 java.time 包来处理日期和时间。

java.time 包中的类(如 Instant, LocalDateTime, ZonedDateTime)提供了更强大、更直观、更不容易出错的 API。

java.time 中的毫秒处理:

  • Instant: 代表时间线上的一个精确点,其内部就是存储了从纪元开始的纳秒数,可以轻松获取毫秒。
  • LocalDateTime: 代表一个不带时区的日期和时间,可以处理纳秒精度。

示例(对比 Calendarjava.time):

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
public class ModernJavaTimeExample {
    public static void main(String[] args) {
        // --- 旧方式 (Calendar) ---
        Calendar calendar = Calendar.getInstance();
        long calendarMillis = calendar.getTimeInMillis();
        System.out.println("[Calendar] 当前时间的毫秒数: " + calendarMillis);
        // --- 新方式 (java.time) ---
        // 1. 获取当前时间的毫秒数 (推荐)
        Instant instant = Instant.now();
        long instantMillis = instant.toEpochMilli(); // 直接获取毫秒
        System.out.println("[Instant] 当前时间的毫秒数: " + instantMillis);
        // 2. 使用毫秒数创建一个时间点
        long someMillis = 946684800000L;
        Instant instantFromMillis = Instant.ofEpochMilli(someMillis);
        System.out.println("[Instant] 从毫秒创建的时间点: " + instantFromMillis);
        // 3. 转换为本地日期时间
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instantFromMillis, ZoneId.systemDefault());
        System.out.println("[LocalDateTime] 对应的本地日期时间: " + localDateTime);
    }
}

输出:

[Calendar] 当前时间的毫秒数: 1678886400000  // 示例值
[Instant] 当前时间的毫秒数: 1678886400000  // 示例值
[Instant] 从毫秒创建的时间点: 2000-01-01T00:00:00Z
[LocalDateTime] 对应的本地日期时间: 2000-01-01T08:00:00  // 假设系统时区是 CST (UTC+8)
特性 java.util.Calendar java.time.Instant / LocalDateTime
核心概念 内部存储一个从纪元开始的 毫秒数 Instant 直接存储从纪元开始的 纳秒数
获取毫秒数 getTimeInMillis() toEpochMilli()
设置毫秒数 setTimeInMillis(long) ofEpochMilli(long)
精度 毫秒 纳秒(更高精度)
状态 已废弃 (@Deprecated) 推荐使用
线程安全 非线程安全 大部分核心类是不可变的,因此是线程安全的
  • 如果你正在维护旧的 Java 代码(Java 8 之前),你需要使用 Calendar,记住它与毫秒数交互的核心是 getTimeInMillis()setTimeInMillis()
  • 对于所有新的项目,请务必使用 java.time 包,它更现代、更安全、更易用,是处理日期和时间的标准方式。
分享:
扫描分享到社交APP
上一篇
下一篇