关于时间日期的几个练习

从Java 8开始,java.time包提供了新的日期和时间API,主要涉及的类型有三个重要的处理时间日期的类:

  • LocalDateTime 通过日期时间来创建
  • DateTimeFormatter 日期时间格式化工具
  • Instant:通过时间戳来创建

下面来通过几个例子来看看这几个类的用法:

日期时间戳互相转换

首先看给定一个日期,获取时间戳的操作。

import java.time.*;
import java.time.format.*;

public class Demo1 {

    public static void main(String[] args) {
        var format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        var dateTime1 = LocalDateTime.parse("2020-01-01 00:00:00", format);
        var dateTime2 = LocalDateTime.now();
        var dateTime3 = LocalDateTime.of(2020,1,1,12,11,23);

        var zoneDt1 = dateTime1.atZone(ZoneId.systemDefault());
        var zoneDt2 = dateTime2.atZone(ZoneId.systemDefault());
        var zoneDt3 = dateTime3.atZone(ZoneId.systemDefault());

        var ins1 = zoneDt1.toInstant();
        var ins2 = zoneDt2.toInstant();
        var ins3 = zoneDt3.toInstant();

        System.out.println(ins1.getEpochSecond());
        System.out.println(ins1.toEpochMilli());
        System.out.println(ins2.getEpochSecond());
        System.out.println(ins3.getEpochSecond());
    }
}

给定一个时间戳,获取格式化的日期。

import java.time.*;
import java.time.format.*;

public class T10 {
    public static void main (String[] args) {
        var fmt = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        var ins = Instant.ofEpochSecond(1509558252);
        var ldt = LocalDateTime.ofInstant(ins, ZoneId.systemDefault()); 

        System.out.println(ldt.format(fmt)); // 2017/11/02 01:44:12
    }
}

倒计时

计算倒计时,需要给定一个目标日期。获取目标日期的时间戳以及当前日期时间戳。再获取两个时间戳的差值,将差值进行计算。

import java.time.*;
import java.time.format.*;

public class Demo2 {

    public static void main (String[] args) {
        var fmt = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        var dt = LocalDateTime.parse("2021/02/03 00:00:00", fmt);

        var zoneDt = dt.atZone(ZoneId.systemDefault());
        var zoneNow = ZonedDateTime.now();

        if (zoneNow.isBefore(zoneDt)) {
            long second = zoneDt.toInstant().getEpochSecond() - zoneNow.toInstant().getEpochSecond();
            System.out.println(second);
        }
    }
}

计算自己还有多久过生日

这里有点需要注意,首先需要判断今年的生日是否已经过了。

import java.time.*;

public class Demo2 {

    public static void main (String[] args) {
        var now = LocalDateTime.now();
        int year = now.getYear();

        var birth = LocalDateTime.of(year, 2, 3, 0, 0);

        if (now.isAfter(birth)) {
            birth = LocalDateTime.of(year + 1, 2, 3, 0, 0);
        }

        var insNow = now.atZone(ZoneId.systemDefault()).toInstant();
        var insBir =  birth.atZone(ZoneId.systemDefault()).toInstant();
        long times = insBir.getEpochSecond() - insNow.getEpochSecond();

        int days = (int) (times / 86400);
        int hours = (int) (times % 86400 / 3600);

        System.out.println(days + "days " + hours + "hours");
    }

}

日历

想要写出一个日历程序的话,需要获取几个重要的信息

  • 该月份有多少天
  • 该月份第一天是周几
  • 今天的时间
import java.time.*;
import java.time.temporal.*;

public class Demo2 {

    public static void main (String[] args) {
        var now = LocalDate.now();
        var first = now.withDayOfMonth(1);
        var last = now.with(TemporalAdjusters.lastDayOfMonth());

        int days = last.getDayOfMonth();
        int week = first.getDayOfWeek().getValue();

        System.out.printf("%-8s%-8s%-8s%-8s%-8s%-8s%-8s\n", "Sun", "Mon", "Tus", "Wed", "Thu", "Fri", "Sat");

        for (int i =0, j = 1; i < days + week % 7; i ++) {
            if (i < week % 7) {
                System.out.print("        ");
            } else {
                System.out.printf("%-8s", j++);
            }

            if ( (i+1)%7 == 0) {
                System.out.println();
            }
        }
    }

}

效果如下:

Sun     Mon     Tus     Wed     Thu     Fri     Sat
                                        1       2
3       4       5       6       7       8       9
10      11      12      13      14      15      16
17      18      19      20      21      22      23
24      25      26      27      28      29      30
31