十一、常用API——时间类

一、Date类

java.util.Date类 表示特定的瞬间,精确到毫秒。

继续查阅Date类的描述,发现Date拥有多个构造函数,只是部分已经过时,我们重点看以下两个构造函数

  • public Date():从运行程序的此时此刻到时间原点经历的毫秒值,转换成Date对象,分配Date对象并初始化此对象,以表示分配它的时间(精确到毫秒)。
  • public Date(long date):将指定参数的毫秒值date,转换成Date对象,分配Date对象并初始化此对象,以表示自从标准基准时间(称为“历元(epoch)”,即1970年1月1日00:00:00 GMT)以来的指定毫秒数。

tips: 由于中国处于东八区(GMT+08:00)是比世界协调时间/格林尼治时间(GMT)快8小时的时区,当格林尼治标准时间为0:00时,东八区的标准时间为08:00。

简单来说:使用无参构造,可以自动设置当前系统时间的毫秒时刻;指定long类型的构造参数,可以自定义毫秒时刻。

public static void main(String[] args) {
        //0.创建对象表示一个时间
        Date d1 = new Date();
        System.out.println(d1); // Sat Jan 20 15:34:59 CST 2024

        //1.创建对象表示一个指定时间
        Date d2 = new Date(0L);
        System.out.println(d2); // Thu Jan 01 08:00:00 CST 197

        //2.setTime 修改时间
        //1000毫秒 = 1秒
        d2.setTime(1000L);
        System.out.println(d2); // Thu Jan 01 08:00:01 CST 1970

        //3.getTime 获取当前时间的毫秒值
        long time = d2.getTime(); // 1000
        System.out.println(time);
    }

public static void main(String[] args) {
        /*时间计算
         *   需求1:打印时间远点开始一年之后的时间
         *   需求2:定义任意两个Date对象,比较以下哪个时间在前,哪个时间在后*/

        //需求1:打印时间远点开始一年之后的时间
        demand1();
        //需求2:定义任意两个Date对象,比较以下哪个时间在前,哪个时间在后
        demand2();
    }

    private static void demand2() {
        //需求2:定义任意两个Date对象,比较以下哪个时间在前,哪个时间在后
        Random r = new Random();
        Date d1 = new Date(Math.abs(r.nextInt()));
        Date d2 = new Date(Math.abs(r.nextInt()));

        System.out.println(d1);
        System.out.println(d2);

        long time1 = d1.getTime();
        long time2 = d2.getTime();

        if (time1>time2){
            System.out.println("第一个时间在后面,第二个时间在前面");
        } else if (time1<time2) {
            System.out.println("第二个时间在后面,第一个时间在前面");
        }else {
            System.out.println("两个时间相等");
        }
    }

    private static void demand1() {
        //需求1:打印时间原点开始一年之后的时间
        //0.创建一个对象,表示时间原点
        Date d1 = new Date(0L);

        //1.获取d1时间的毫秒值
        long time = d1.getTime();

        //2.在这个基础上加一年的毫米值即可
        time = time + 1000L * 60 * 60 * 24 * 365;

        //3.把计算之后的时间毫秒值,在设置回d1当中
        d1.setTime(time);
        System.out.println(d1); // Fri Jan 01 08:00:00 CST 1971
    }

二、SimpleDateFormat类

java.text.SimpleDateFormat 是日期/时间格式化类,我们通过这个类可以帮我们完成日期和文本之间的转换,也就是可以在Date对象与String对象之间进行来回转换。

  • 格式化:按照指定的格式,把Date对象转换为String对象。

在这里插入图片描述

  • 解析:按照指定的格式,把String对象转换为Date对象。

在这里插入图片描述
在这里插入图片描述

格式规则:

标识字母(区分大小写)含义
y
M
d
H
m
s

备注:更详细的格式规则,可以参考SimpleDateFormat类的API文档。

在这里插入图片描述

public static void main(String[] args) throws ParseException {
//        method();

        //0.定义一个字符串表示时间
        String str = "2024-01-20 16:50:30";
        //1.利用空参构造创建SimpleDateFormat对象
        //细节:
        //创建对象的格式要跟字符串的格式完全一致
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = sdf.parse(str);

        System.out.println(date); // Sat Jan 20 16:50:30 CST 2024
    }

    private static void method() {
        //0.利用空参构造创建SimpleDateFormat对象,默认格式
        SimpleDateFormat sdf = new SimpleDateFormat();
        Date d = new Date(0L);
        String str = sdf.format(d);
        System.out.println(str); // 1970/1/1 上午8:00

        //1.利用带参构造创建SimpleDateFormat对象,指定格式
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        String str2 = sdf2.format(d);
        System.out.println(str2); //1970年01月01日 08:00:00

        //2.yyyy年年MM月dd日 时:分:秒 星期
        SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss EE");
        String str3 = sdf3.format(d);
        System.out.println(str3); // 1970年01月01日 08:00:00 周四
    }

    public static void main(String[] args) throws ParseException {
        /*练习:
        * 假设,你初恋的出生年月日为:2002-04-11
        * 请用字符串表示这个数据,并将其转换为:2002年04月11日
        * */

        //0.可以通过给定的对象进行解析,解析成一个Date对象
        String str = "2002-04-11";
        //1.解析
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdf.parse(str);
        //2.格式化
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日");
        String str2 = sdf2.format(date);
        System.out.println(str2);
    }


public static void main(String[] args) throws ParseException {
        /*需求:
         秒杀活动开始时间:2023年11月11日 0:0:0(毫秒值)
         秒杀活动结束时间:2023年11月11日 0:10:0(毫秒值)
            小贾下单并付款的时间为:2023年11月11日0:01:00
            小皮下单并付款的时间为:2023年11月11日 0:11:0
         用代码说明这两位同学有没有参加上秒杀活动?*/

        //0.定义字符串表示四个时间
        String startstr = "2023年11月11日 0:0:0";
        String ednstr = "2023年11月11日 0:10:0";
        String jiaOrderStr = "2023年11月11日 0:01:00";
        String piOrderStr = "2023年11月11日 0:11:00";

        //1.解析上面的字符串,获得Date对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        Date startDate = sdf.parse(startstr);
        Date endDate = sdf.parse(ednstr);
        Date jiaOrderDate = sdf.parse(jiaOrderStr);
        Date piOrderDate = sdf.parse(piOrderStr);

        //2.获得四个时间的毫秒值
        long starttime = startDate.getTime();
        long endtime = endDate.getTime();
        long jiaOrdertime = jiaOrderDate.getTime();
        long piOrdertime = piOrderDate.getTime();

        //3.比较
        isSuccess(starttime, endtime, jiaOrdertime,"小贾");
        isSuccess(starttime, endtime, piOrdertime,"小皮");
    }

    private static void isSuccess(long starttime, long endtime, long Ordertime, String name) {
        if (Ordertime >= starttime && Ordertime <= endtime) {
            System.out.println(name + "同学参加秒杀活动成功!");
        } else {
            System.out.println(name + "同学参加秒杀活动失败!");
        }
    }

三、Calendar类

Calendar代表了系统当前时间的日历对象,可以单独修改、获取时间中的年,月,日
细节:Calendar是一个抽象类,不能直接创建对象。
获取Calendar日历类对象的方法

常用方法

方法名说明
public static Calendar getInstance()获取一个它的子类GregorianCalendar对象。
public int get(int field)获取某个字段的值。field参数表示获取哪个字段的值,
可以使用Calender中定义的常量来表示:
Calendar.YEAR : 年
Calendar.MONTH :月
Calendar.DAY_OF_MONTH:月中的日期
Calendar.HOUR:小时
Calendar.MINUTE:分钟
Calendar.SECOND:秒
Calendar.DAY_OF_WEEK:星期
public void set(int field,int value)设置某个字段的值
public void add(int field,int amount)为某个字段增加/减少指定的值

在这里插入图片描述

public static void main(String[] args) {
        //0.获取日历对象
        /*细节1:
         * Calendar是一个抽象类,不能直接new,而是通过一个静态方法获取到子类对象
         * 底层原理:
         * 会根据系统的不同时区来获取不同的日历对象,默认表示当前时间。
         * 把会把时间中的纪元、年、月、日、时、分、秒、星期,等等的都放到一个数组当中
         * 0 : 纪元
         * 1 : 年
         * 2 : 月
         * 3 : 一年中的第几周
         * 4 : 一个月中的第几周
         * 5:一个月中的第几天(日期)
         * ……
         * 细节2:
         * 月份:范围0~11,如果获取出来的是0,那么实际上是1月
         * 星期:在老外的眼里,星期日是一周中的第一天
         *       1(星期日)   2(星期一)   3(星期二)   4(星期三)   5(星期四)   6(星期五)   7(星期六)*/
        Calendar c = Calendar.getInstance();
        System.out.println(c);

        //1.修改一下日历代表的时间
        Date d = new Date(0L);
        c.setTime(d);
        System.out.println(c);

        //2.获取日期中的某个字段信息
        int year = c.get(1);
        int month = c.get(2);
        int day = c.get(5);
        System.out.println(year + ", " + month + ", " + day); // 1970, 0, 1

        int year2 = c.get(Calendar.YEAR);
        int month2 = c.get(Calendar.MONTH);
        int day2 = c.get(Calendar.DAY_OF_MONTH);
        int week = c.get(Calendar.DAY_OF_WEEK);
        System.out.println(year2 + ", " + month2 + ", " + day2 + ", " + week); // 1970, 0, 1, 5
        System.out.println(year2 + ", " + month2 + ", " + day2 + ", " + getWeek(week)); // 1970, 0, 1, 星期四

        //3.修改日历的某个字段信息
        c.set(Calendar.YEAR, 2024);

        year2 = c.get(Calendar.YEAR);
        month2 = c.get(Calendar.MONTH)+1;
        day2 = c.get(Calendar.DAY_OF_MONTH);
        week = c.get(Calendar.DAY_OF_WEEK);
        System.out.println(year2 + ", " + month2 + ", " + day2 + ", " + getWeek(week)); // 2024, 1, 1, 星期一

        //4.为某个字段增加/减少指定的值
        c.set(Calendar.DAY_OF_MONTH, 10);
        c.add(Calendar.MONTH, 2);

        year2 = c.get(Calendar.YEAR);
        month2 = c.get(Calendar.MONTH)+1;
        day2 = c.get(Calendar.DAY_OF_MONTH);
        week = c.get(Calendar.DAY_OF_WEEK);
        System.out.println(year2 + ", " + month2 + ", " + day2 + ", " + getWeek(week)); // 2024, 3, 10, 星期日
    }

    /*查表法:
    表:容器
    让数据跟索引产生对应的关系*/
    //传入对应的数字:1~7
    //返回对应的星期
    private static String getWeek(int index) {
        //定义一个数组,让汉字星期几,跟1~7产生对应关系
        String[] arr = {"","星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
        //根据索引返回对应的星期
        return arr[index];
    }



以上属于JDK7以前时间相关类
以下属于JDK8新增时间相关类




在这里插入图片描述

在这里插入图片描述

JDK8 新增时间相关类
ZoneId:时区
Instant:时间戳
ZoneDateTime:时区的时间
DateTimeFormatter:用于时间的格式化和解析
LocalDate:年、月、日
LocalTime:时、分、秒
LocalDateTime:年、月、日、时、分、秒
Duration:时间间隔(秒,纳秒)
Period:时间间隔(年,月,日)
ChronoUnit:时间间隔(所有单位)


在这里插入图片描述

3.1 ZoneId 时区

在这里插入图片描述
在这里插入图片描述

public static void main(String[] args) {
        //0.获取Java支持的所有时区名称
        Set<String> zoneIds = ZoneId.getAvailableZoneIds();
        System.out.println(zoneIds.size()); //603个时区
        System.out.println(zoneIds);

        //1.获取当前系统的默认时区
        ZoneId zoneId = ZoneId.systemDefault();
        System.out.println(zoneId); //Asia/Shanghai

        //2.获取指定的时区
        ZoneId zoneId1 = ZoneId.of("Pacific/Kwajalein");
        System.out.println(zoneId1); // Pacific/Kwajalein
    }

3.2 Instant:时间戳

在这里插入图片描述

public static void main(String[] args) {
        //0.获取当前时间的Instant对象(标准时间)
        Instant now = Instant.now();
        System.out.println(now); //2024-01-23T08:07:05.751238400Z

        //1.根据(秒/毫秒/纳秒)获取Instant对象
        Instant instant1 = Instant.ofEpochMilli(0L);
        System.out.println(instant1); // 1970-01-01T00:00:00Z

        Instant instant2 = Instant.ofEpochSecond(1L);
        System.out.println(instant2); // 1970-01-01T00:00:01Z

        Instant instant3 = Instant.ofEpochSecond(1L, 1000000000L);
        System.out.println(instant3); // 1970-01-01T00:00:02Z

        //2.指定时区
        ZonedDateTime time = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));
        System.out.println(time); // 2024-01-23T16:15:58.467774300+08:00[Asia/Shanghai]

        //3.isXxx判断
        Instant instant4 = Instant.ofEpochMilli(0L);
        Instant instant5 = Instant.ofEpochMilli(1000L);

        //isBefore:判断调用者代表的时间是否在参数表示时间的前面
        boolean result1 = instant4.isBefore(instant5);
        System.out.println(result1); // true

        //isAfter:判断调用者代表的时间是否在参数表示时间的后面
        boolean result2 = instant4.isAfter(instant5);
        System.out.println(result2); // false

        //4.minusXxx 减少时间
        Instant instant6 = Instant.ofEpochMilli(1000L);
        System.out.println(instant6); //1970-01-01T00:00:01Z

        Instant instant7 = instant6.minusSeconds(1);
        System.out.println(instant7); // 1970-01-01T00:00:01Z

        //5.plusXxx 增加时间
        Instant instant8 = instant7.plusSeconds(2);
        System.out.println(instant8); // 1970-01-01T00:00:02Z

    }

四、ZonedDateTime 带时区的时间

在这里插入图片描述

public static void main(String[] args) {
        /*
         * static ZonedDateTime now()            获取当前时间的ZonedDateTime对象
         * static ZonedDateTime ofXxx(...)       获取指定时间的ZonedDateTime对象
         * ZonedDateTime withXxx(时间)            修改时间系列的方法
         * ZonedDateTime minusXxx(时间)           减少时间系列的方法
         * ZonedDateTime plusXxx(时间)            增减时间系列的方法*/

        //0.获取当前时间对象(带时区)
        ZonedDateTime now = ZonedDateTime.now();
        System.out.println(now); //2024-01-27T15:03:02.934394300+08:00[Asia/Shanghai]

        //1.获取指定的时间对象(带时区)
        //年月日时分秒纳秒方式指定
        ZonedDateTime time1 = ZonedDateTime.of(2024, 1, 28, 15, 7, 55, 0, ZoneId.of("Asia/Shanghai"));
        System.out.println(time1); // 2024-01-28T15:07:55+08:00[Asia/Shanghai]

        //通过Instant + 时区的方式指定获取时间对象
        Instant instant = Instant.ofEpochMilli(0L);
        ZoneId zoneId = ZoneId.of("Asia/Shanghai");
        ZonedDateTime time2 = ZonedDateTime.ofInstant(instant, zoneId);
        System.out.println(time2); // 1970-01-01T08:00+08:00[Asia/Shanghai]

        //2.withXxx 修改时间系列的方法
        ZonedDateTime time3 = time2.withYear(2023);
        System.out.println(time3); // 2023-01-01T08:00+08:00[Asia/Shanghai]

        //3.减少时间
        ZonedDateTime time4 = time3.minusYears(1);
        System.out.println(time4); // 2022-01-01T08:00+08:00[Asia/Shanghai]

        //4.增加时间
        ZonedDateTime time5 = time3.plusYears(1);
        System.out.println(time5); // 2024-01-01T08:00+08:00[Asia/Shanghai]


    }

细节:

  • JDK8 新增的时间对象都是不可变的
  • 如果我们修改了,减少了,增加了时间
  • 那么调用者是不会发生改变的,产生一个新的时间。

五、日期格式化类(DateTimeFormatter)

DateTimeFormatter——用于时间的格式化和解析

方法名说明
static DateTimeFormatter ofPattern (格式)获取格式对象
String format(时间对象)按照指定方式格式化
public static void main(String[] args) {
        //0.获取时间对象
        ZonedDateTime time = Instant.now().atZone(ZoneId.of("Asia/Shanghai"));

        //1.解析/格式化器
        DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss EE a");

        //2.格式化
        System.out.println(dtf1.format(time)); // 2024-01-28 18:55:00 周日 下午
    }

六、日历类:Calendar

LocalDate:年、月、日
LocalTime:时、分、秒
LocalDateTime:年、月、日、时、分、秒

在这里插入图片描述
在这里插入图片描述

public static void main(String[] args) {
        //0.获取单签时间的日历对象(包含 年月日)
        LocalDate nowDate = LocalDate.now();
        System.out.println(nowDate); // 2024-01-29

        //1.获取指定的时间的日历对象
        LocalDate ldDate = LocalDate.of(2025, 1, 29);
        System.out.println(ldDate); //2025-01-29

        //2.get系列方法获取日历中的每一个属性值
        //获取年
        int year = ldDate.getYear();
        System.out.println("Year: " + year); //Year: 2025

        //获取月
        //方式一:
        Month m = ldDate.getMonth();
        System.out.println(m); // JANUARY
        System.out.println(m.getValue()); // 1

        //方式二:
        int month = ldDate.getMonthValue();
        System.out.println(month); // 1

        //获取日
        int dayOfMonth = ldDate.getDayOfMonth();
        System.out.println(dayOfMonth); // 29

        //获取一年的第几天
        int dayOfYear = ldDate.getDayOfYear();
        System.out.println(dayOfYear); // 29

        //获取星期
        DayOfWeek dayOfWeek = ldDate.getDayOfWeek();
        System.out.println(dayOfWeek); // WEDNESDAY
        System.out.println(dayOfWeek.getValue()); // 3

        //is 开头的方法表示判断
        System.out.println(ldDate.isBefore(ldDate)); // false
        System.out.println(ldDate.isAfter(ldDate));  //false

        //with 开头的方法表示修改,只能修改年月日
        LocalDate localDate = ldDate.withYear(2000);
        System.out.println(localDate); // 2000-01-29

        //minus 开头的方法表示减少,只能减少年月日
        LocalDate localDate1 = ldDate.minusYears(1);
        System.out.println(localDate1); // 2024-01-29

        //plus 开头的方法表示增加,只能增加年月日
        LocalDate localDate2 = ldDate.plusDays(1);
        System.out.println(localDate2); // 2025-01-30

        System.out.println("------------------------");

        /*判断今天是否是你的生日*/
        LocalDate birDate = LocalDate.of(2002, 4, 11);
        LocalDate nowDate1 = LocalDate.now();

        MonthDay birMd = MonthDay.of(birDate.getMonthValue(), birDate.getDayOfMonth());
        MonthDay nowMd = MonthDay.from(nowDate1);

        System.out.println("今天是你的生日吗?" + birMd.equals(nowMd)); // false

    }

另外的两种方法使用类似


七、工具类

在这里插入图片描述
在这里插入图片描述

public class PeriodDemo {
    public static void main(String[] args) {
        //当前本地 年月日
        LocalDate today = LocalDate.now();
        System.out.println(today); // 2024-01-29

        //生日的 年月日
        LocalDate birthDate = LocalDate.of(2002, 4, 11);
        System.out.println(birthDate); //2002-04-11

        Period period = Period.between(birthDate, today);
        System.out.println("相差的时间间隔对象"+period); // 相差的时间间隔对象P21Y9M18D
        System.out.println(period.getYears()); // 21
        System.out.println(period.getMonths()); // 9
        System.out.println(period.getDays()); // 18


        System.out.println(period.toTotalMonths()); // 261
    }
}

public class DurationDemo {
    public static void main(String[] args) {
        // 本地日期的对象
        LocalDateTime today = LocalDateTime.now();
        System.out.println(today); //2024-01-29T15:18:11.619626600

        //出生日期时间对象
        LocalDateTime birthDate = LocalDateTime.of(2002, 4, 11, 5, 30, 18);
        System.out.println(birthDate); //2002-04-11T05:30:18

        Duration duration = Duration.between(birthDate, today);
        System.out.println("相差的时间间隔对象:" + duration); //相差的时间间隔对象:PT191121H51M50.2725462S
        System.out.println("-------------------------");
        System.out.println(duration.toDays()); //7963 两个时间相差的天数
        System.out.println(duration.toHours()); // 191121 两个时间差的小时数
        System.out.println(duration.toMinutes()); // 11467314 两个时间差分钟数
        System.out.println(duration.toMillis()); // 688038897589  两个时间差毫秒数
        System.out.println(duration.toNanos()); // 688038931775256200 两个时间差的纳秒数
    }
}

public class ChronoUnitDemo {
    public static void main(String[] args) {
        //当前时间
        LocalDateTime today = LocalDateTime.now();
        System.out.println(today); // 2024-01-29T15:29:59.462302400

        //生日时间
        LocalDateTime birthDate = LocalDateTime.of(2002, 4, 11, 0, 0, 0);
        System.out.println(birthDate); // 2002-04-11T00:00

        System.out.println("相差的年数: " + ChronoUnit.YEARS.between(birthDate, today)); // 相差的年数: 21
        System.out.println("相差的月数: " + ChronoUnit.MONTHS.between(birthDate, today));// 相差的月数: 261
        System.out.println("相差的周数: " + ChronoUnit.WEEKS.between(birthDate, today));// 相差的周数: 1137
        System.out.println("相差的天数: " + ChronoUnit.DAYS.between(birthDate, today));// 相差的天数: 7963
        System.out.println("相差的时数: " + ChronoUnit.HOURS.between(birthDate, today));// 相差的时数: 191127
        System.out.println("相差的分数: " + ChronoUnit.MINUTES.between(birthDate, today));// 相差的分数: 11467655
        System.out.println("相差的秒数: " + ChronoUnit.SECONDS.between(birthDate, today));// 相差的秒数: 688059351
        System.out.println("相差的毫秒数: " + ChronoUnit.MILLIS.between(birthDate, today));// 相差的毫秒数: 688059402339
        System.out.println("相差的微秒数: " + ChronoUnit.MICROS.between(birthDate, today));// 相差的微秒数: 688059433393297
        System.out.println("相差的纳秒数: " + ChronoUnit.NANOS.between(birthDate, today));// 相差的纳秒数: 688059562484599800
        System.out.println("相差的半天数: " + ChronoUnit.HALF_DAYS.between(birthDate, today));// 相差的半天数: 15927
        System.out.println("相差的十年数: " + ChronoUnit.DECADES.between(birthDate, today));// 相差的十年数: 2
        System.out.println("相差的世纪(百年)数: " + ChronoUnit.CENTURIES.between(birthDate, today));// 相差的世纪(百年)数: 0
        System.out.println("相差的千年数: " + ChronoUnit.MILLENNIA.between(birthDate, today));// 相差的千年数: 0
        System.out.println("相差的纪元数: " + ChronoUnit.ERAS.between(birthDate, today));// 相差的纪元数: 0
    }
}

  • 26
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值