javaSE基础-日期时间

日期时间类

日期时间主要类

日期时间

jdk8之前常用的日期时间API

System静态方法

//System类中的currentTimeMillis()
@Test
public void test1(){

    //返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差(俗称时间戳)
    long time = System.currentTimeMillis();
    System.out.println(time);//1661945707478
}

Date类

java.util.Date类
1、两个构造器的使用
构造器一:Date():创建一个对应当前时间的Date对象
构造器二:创建指定毫秒数的Date对象
2、两个方法的使用:
toString():显示当前时间的年月日时分秒
getTime():获取当前Date对象对应的毫秒数(时间戳)
java.sql.Date类

示例:构造器使用

@Test
public void test2(){
    //构造器一
    Date date1 = new Date();
    System.out.println(date1.toString());//Mon Aug 22 16:34:19 CST 2022

    long time = date1.getTime();
    System.out.println(time);//1661157259360
    //构造器二
    Date date2 = new Date(3465436457L);
    System.out.println(date2.toString());

    //sql中Date的构造器
    java.sql.Date date3 = new java.sql.Date(1661157259360L);
    System.out.println(date3.toString());//2022-08-22
}

如何将java.util.Date对象转换为 java.sql.Date对象

@Test
public void test2(){
    //java.util.Date对象转换为java.sql.Date,使用getTime()时间毫秒数转换
    //情况一:
    Date date5 = new java.sql.Date(3465436457L);
    java.sql.Date date6 = (java.sql.Date) date5;
    System.out.println(date6.toString()); //1970-02-10

    //情况二:date1.getTime()为java.util.Date的时间戳
    java.sql.Date date4 = new java.sql.Date(date1.getTime());
    System.out.println(date4.toString());//2022-08-22
}

Calendar类

Calendar日历类(abstract)的使用
获取实例的方式:
1、使用Canlendar.getInstance()方法
2、调用它的子类GregorianCalendar的构造器

@Test
public void test3(){
    //实例化
    GregorianCalendar gc = new GregorianCalendar();
    System.out.println(gc.getClass());//class java.util.GregorianCalendar

    Calendar calendar = Calendar.getInstance();
    System.out.println(calendar.getClass());//class java.util.GregorianCalendar

    //常用方法
    //get()
    int days = calendar.get(Calendar.DAY_OF_YEAR);//这一年的第几天
    System.out.println(days);

    System.out.println(calendar.get(Calendar.DAY_OF_MONTH));//这一月的第几天
    System.out.println(calendar.get(Calendar.DAY_OF_WEEK));//从周日开始算一周的第一天,这一周的第几天

    //set()
    //calendar可变性
    calendar.set(Calendar.DAY_OF_MONTH, 26);//设置当前Date日期为 26日
    System.out.println(calendar.get(Calendar.DAY_OF_MONTH));

    //add()
    calendar.add(Calendar.DAY_OF_MONTH, 2);//当前日期下 +2,注:减三天则值为-3
    System.out.println(calendar.get(Calendar.DAY_OF_MONTH));

    //getTime(): Calendar日历类 --> Date
    Date date = calendar.getTime();
    System.out.println(date);

    //setTime()
    Date date1 = new Date();
    calendar.setTime(date1);//重置当前Date日期时间
    System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
}

注:
获取月份时:一月是 0,二月是1

获取星期时:周日是1,周一是2

SimpleDateFormat类

SimpleDateFormat的使用:SimpleDateFormat对日期Date类的格式化和解析
1、格式化:日期 -->字符串
xxx.format()

2、解析:字符串 --> 日期
xxx.parse()

@Test
public void test1() throws ParseException {
    //SimpleDateFormat()无参构造的方式
    SimpleDateFormat sdf = new SimpleDateFormat();
    Date date1 = new Date();
    System.out.println(date1);//Wed Aug 24 15:14:51 CST 2022

    //格式化
    String str1 = sdf.format(date1);
    System.out.println(str1);//22-8-24 下午3:14

    //解析
    Date parseDate = sdf.parse("22-10-24 下午3:14");
    System.out.println(parseDate);//Mon Oct 24 15:14:00 CST 2022

    System.out.println("***********************");
    //有参构造,自定义格式话标准
    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String str2 = sdf2.format(date1);
    System.out.println(str2);//2022-08-24 15:25:40

    Date date4 = sdf2.parse("2022-10-11 13:25:09");
    System.out.println(date4);//Tue Oct 11 13:25:09 CST 2022

}

/**
 * 字符串“2020-12-01” 转换为 java.sql.Date类的日期
 */
@Test
public void test2() throws ParseException {
    String info = "2020-12-01";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    Date date = sdf.parse(info);
    System.out.println(date);//Tue Dec 01 00:00:00 CST 2020

    java.sql.Date date1 = new java.sql.Date(date.getTime());//将date调用getTime()转为时间戳
    System.out.println(date1);//2020-12-01
}

jdk8中新的日期时间API

Java8汲取Joda-Time第三方jar包的日期时间API,开发出全新的java.time的API

LocalDate、LocalTime、LocalDateTime类是主要的使用类,它们的实例对象是不可变的对象,分别表示使用ISO-8601日历系统的日期、时间、日期和时间。

LocalDateTimeL较其它两个使用频率更高

注:ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法,也就是公历。

LocalDate \ LocalTime \ LocalDateTime类

常用方法

日期时间常用方法-1

示例

click me
@Test
public void test2(){
	//实例化localDateTime
	//1、now():获取当前的日期+时间
	LocalDateTime localDateTime = LocalDateTime.now();
	LocalDate localDate = LocalDate.now();
	LocalTime localTime = LocalTime.now();
	System.out.println(localDateTime);
	System.out.println(localDate);
	System.out.println(localTime);

	//2、of():设置指定具体的年、月、日、时、分、秒,没有偏移量设置
	LocalDateTime localDateTime2 = LocalDateTime.of(2022, 8, 26, 13, 38, 10);
	System.out.println(localDateTime2);

	//获取具体字段时间的方法:xxx.get()
	//获取年份
	int year = localDateTime.getYear();
	System.out.println(year);//2022
	//获取月份,enum形式
	Month month = localDateTime.getMonth();
	System.out.println(month);//AUGUST
	//获取月份,数字形式
	int monthValue = localDateTime.getMonthValue();
	System.out.println(monthValue);//8
	//获取月份的第几天,相当于当前几号
	int day = localDateTime.getDayOfMonth();
	System.out.println(day);//26
	//获取一周的第几天,相当于周几
	DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
	System.out.println(dayOfWeek);//FRIDAY
	//获取一年的第几天
	int dayOfYear = localDateTime.getDayOfYear();
	System.out.println(dayOfYear);//238


	//设置时间
	LocalDateTime localDateTime3 = localDateTime.withDayOfMonth(28);//设置当前为28日
	System.out.println(localDateTime);//2022-08-26T13:56:28.256,原来的时间不可变
	System.out.println(localDateTime3);//2022-08-28T13:56:28.256

	//指定时间增加操作
	LocalDateTime localDateTime4 = localDateTime.plusDays(3);//当前时间+3
	System.out.println(localDateTime);//2022-08-26T14:00:27.193
	System.out.println(localDateTime4);//2022-08-29T14:00:27.193

	//指定时间减小操作
	LocalDateTime localDateTime5 = localDateTime.minusDays(5);
	System.out.println(localDateTime);//2022-08-26T14:02:34.666
	System.out.println(localDateTime5);//2022-08-21T14:02:34.666

}

Instant类

时间上的一个瞬时点。概念上,只是简单的表示自1970年1月1日0时0分0秒(UTC开始的秒数)

常用方法

Instant常用方法

示例

click me
@Test
public void test3(){
	//实例化:now():获取本初子午线对应的标准时间
	Instant instant = Instant.now();
	System.out.println(instant);

	//添加时间偏移量
	OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.UTC);
	System.out.println(offsetDateTime);//2022-08-26T07:29:14.259Z

	//获取自1970年1月1日0时0分0秒的 毫秒数
	long milli = instant.toEpochMilli();
	System.out.println(milli);//1661499089722

	//将指定的毫秒数 转换为 Instant的实例对象
	Instant instant1 = Instant.ofEpochMilli(1661499089722L);
	System.out.println(instant1);//2022-08-26T07:31:29.722Z
}

DateTimeFormatter类

DateTimeFormatter类:格式化、解析日期时间常用方法

三种格式化方式

  • 预定义的标准格式:ISO_LOCAL_DATE_TIME、ISO_LOCAL_DATE、ISO_LOCAL_TIME
  • 本地化的格式:ofLocalizedDateTime() 、ofLocalizedDate()、ofLocalizedTime()
  • 自定义格式:ofPattern("yyyy-MM-dd hh:mm:ss E")

常用方法

DateTimeFormatter类

示例

click me
@Test
public void test4(){
	//方式一:预定义标准格式:ISO_LOCAL_DATE_TIME、ISO_LOCAL_DATE、ISO_LOCAL_TIME
	DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;

	//格式化: 日期 --> 字符串
	LocalDateTime localDateTime = LocalDateTime.now();
	String str = dateTimeFormatter.format(localDateTime);
	System.out.println(str);//2022-08-26T15:59:49.101

	//解析: 字符串--> 日期
	TemporalAccessor dateTime = dateTimeFormatter.parse("2022-08-26T15:59:49.101");
	System.out.println(dateTime);//{},ISO resolved to 2022-08-26T15:59:49.101

	//方式二:本地化
	//①ofLocalizedDateTime(): 参数有FormatStyle.LONG \ FormatStyle.MEDIUM \ FormatStyle.SHORT,用于格式化LocalDateTime类的时间形式
	DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
	String str2 = formatter.format(LocalDateTime.now());
	System.out.println(str2);//2022年8月26日 下午04时16分23秒

	//②ofLocalizedDate():参数有 FormatStyle.FULL \ FormatStyle.LONG \ FormatStyle.MEDIUM \ FormatStyle.SHORT,用于格式化LocalDateTime类的时间形式
	DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
	String str3 = formatter2.format(LocalDateTime.now());
	System.out.println(str3);//2022年8月26日 星期五

	//③ofLocalizedTime(): 参数有FormatStyle.LONG \ FormatStyle.MEDIUM \ FormatStyle.SHORT,用于格式化LocalDateTime类的时间形式
	DateTimeFormatter formatter3 = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
	String str4 = formatter3.format(LocalDateTime.now());
	System.out.println(str4);//下午4:21

	//方式三: 自定义的格式(常用的)如 ofPattern("yyyy-MM-dd hh:mm:ss E")
	DateTimeFormatter formatter4 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss E");
	//格式化
	String str5 = formatter4.format(LocalDateTime.now());
	System.out.println(str5);//2022-08-26 04:26:37 星期五

	//解析
	TemporalAccessor dateTime2 = formatter4.parse("2022-08-26 04:26:37 星期五");
	System.out.println(dateTime2);//{MinuteOfHour=26, HourOfAmPm=4, NanoOfSecond=0, MilliOfSecond=0, SecondOfMinute=37, MicroOfSecond=0},ISO resolved to 2022-08-26

	}

总结

日期时间API迭代

第一代:jdk1.0 Date类API

第二代:jdk1.1 Calendar日历类API

第三代:jdk1.8 LocalDateTime类等全新的API

jdk1.8中日期时间API包含的包:

java.time 日期、时间、时刻主要的API,和持续时间。
java.time.chrono 除了默认的标准以外的日历系统的通用的。
java.time.format 提供打印和解析日期和时间的类。
java.time.temporal 访问日期和时间的应用领域和单位,时间和日期的调节。
java.time.zone 支持时区及其规则。

前两代日期时间存在的问题:

可变性:日期时间这样的类本该不可改变的,但如Calendar类的set()方法,可以修改当前对象的时间

@Test
public void test3(){
    //实例化
    Calendar calendar = Calendar.getInstance();
    System.out.println(calendar.getClass());//class java.util.GregorianCalendar

    //set():返回值位void,覆盖了原来对象的值
    calendar.set(Calendar.DAY_OF_MONTH, 26);//设置当前Date日期为 26日
    System.out.println(calendar.get(Calendar.DAY_OF_MONTH));
}

偏移性:Date中的年份是从1900开始计算,月份是从0开始的

@Test
public void test1(){
    Date date = new Date(2022,9,10,12,1,31);
    System.out.println(date);//Tue Oct 10 12:01:31 CST 3922

    //偏移量问题
    Date date2 = new Date(2022-1900,9-1,10,12,1,31);
    System.out.println(date2);//Sat Sep 10 12:01:31 CST 2022
}

格式化:格式化只针对Date用,Calendar类不行

@Test
public void test1() throws ParseException {
    //SimpleDateFormat()无参构造的方式:日期时间 --> 字符串
    SimpleDateFormat sdf = new SimpleDateFormat();
    Date date1 = new Date();
    System.out.println(date1);//Wed Aug 24 15:14:51 CST 2022

    //格式化
    String str1 = sdf.format(date1);
    System.out.println(str1);//22-8-24 下午3:14
}

其它拓展

案例:三天打渔,两天晒网。终端输入一个日期(如2023-5-3),计算从某个固定日期(如1990-01-01)开始轮回打渔晒网操作,计算此时5月3日当天打渔还是晒网?

分析

日期时间-2

示例

click me
public class FishTest2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入年份:");
        int year = sc.nextInt();
        System.out.println("请输入月份:");
        int month = sc.nextInt();
        System.out.println("请输入日期:");
        int day = sc.nextInt();

        String nowDate = year + "-" + month + "-" + day;

        try {
            //从1990-01-01开始到输入当年相差的天数
            int thisDays = getDays(year, month, day);
            //输入当年日期在这一年的第几天的天数
            int dateNum = getDays2(year);
            printInfo(thisDays, dateNum, nowDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    //获取输入日期为当年的第几天
    public static int getDays(int year, int month, int day) throws ParseException {
        String str = year + "-" + month + "-" + day;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdf.parse(str);
        Calendar calendar = Calendar.getInstance();
        //将Calendar日历类设置为某个日期
        calendar.setTime(date);
        //求该日期为这一年的第几天
        int secondPart = calendar.get(Calendar.DAY_OF_YEAR) - 1;

        return secondPart;
    }

    //判断这一年是否为闰年
    public static boolean isRunNian(int year) {
        if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
            return true;
        }
        return false;
    }

    //计算1990-01-01起到指定日期的当年相差天数
    @Test
    public static int getDays2(int year) throws ParseException {

        String str = "1990-01-01";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date startDate = sdf.parse(str);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(startDate);
        int startDay = calendar.get(Calendar.DAY_OF_YEAR);
        int startYear = calendar.get(Calendar.YEAR);
        int firstPartDay = 0;
        if (isRunNian(startYear)) {
            firstPartDay = 366 - startDay;
        } else {
            firstPartDay = 365 - startDay;
        }

        int dateNum = 0;
        for (int i = startYear + 1; i < year; i++) {
            if (isRunNian(year)) {
                dateNum += 366;
            } else {
                dateNum += 365;
            }
        }

        int firstPart = dateNum + firstPartDay;

        return firstPart;
    }

    //输出打印 打渔还是晒网:总天数 % 5 ==1,2,3 为打渔;总天数 % 5 ==0,4 为晒网
    static void printInfo(int thisDate, int dateNum, String nowDate) {
        int sumDate = thisDate + dateNum;
        if (sumDate % 5 == 1 || sumDate % 5 == 2 || sumDate % 5 == 3) {
            System.out.println(nowDate + ",这一天在打渔!");
        } else {
            System.out.println(nowDate + ",这一天在晒网!");
        }
    }
}
posted @ 2022-11-01 21:05  Bingeone  阅读(72)  评论(0编辑  收藏  举报