20145312 《Java程序设计》第七周学习总结 20145312 《Java程序设计》第七周学习总结

学习笔记

Chapter 13时间与日期

13.1 认识时间与日期

13.1.1 时间的度量

  1. 格林威治标准时间
  2. 世界时:观测远方星体跨过子午线而得。
  3. 国际原子时:铯原子辐射振动。
  4. 世界协调时间:地球自转越来越慢,提出具有折衷修正版本的世界协调时间。
  5. Unix 时间:定义为UTC时间1970年(Unix 元年)1月1日00:00:00为起点而经过的秒数。
  6. epoch:某个特定的时代开始,时间轴上的某一瞬间。

13.1.2 年历简介

  1. 儒略历:现今公历的前身,用来取代罗马历。
  2. 格里高利历:由宗教Pope Gregory XIII于1528年颁行。
  3. ISO 8601 标准:时间日期表示方法的标准。

13.1.3 认识时区

  1. 从地理上来说,由于地球是圆的,基本上一边白天另一边就是夜晚,因而设置了UTC偏移。
  2. 有些高纬度国家,夏季、冬季日照时间差异很大,为了节省能源会尽量利用夏季日照,因而实施日光节约时间,也称为夏季时间。

13.2 认识Date与Calendar

13.2.1 时间轴上瞬间的Date

  1. 使用System.currentTimeMillis()是取得系统时间的方法之一。
代码如下:
package DateCalendar;

import java.util.*;
import static java.lang.System.*;
public class DateDemo {
    public static void main(String[] args){
        Date date1=new Date(currentTimeMillis());
        Date date2=new Date();
        out.println(date1.getTime());
        out.println(date2.getTime());
    }
}
结果截图:

20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

13.2.2格式化时间日期的DateFormat

  1. 有关字符串时间格式的处理用java.text.DateFormat,DateFormat是个抽象类,其操作类是java.text.Simple.DateFormat。
代码如下:
package DateCalendar;

import java.util.*;
import static java.lang.System.out;
import static java.text.DateFormat.*;
public class DateFormatDemo {
    public static void main(String[] args){
        Date date=new Date();
        dateInstanceDemo(date);
        timeInstanceDemo(date);
        dateTimeInstanceDemo(date);
    }
    static void dateInstanceDemo(Date date){
        out.println("getDateInstance() demo");
        out.printf("	SHORT:%s%n",getDateInstance(LONG).format(date));
        out.printf("	SHORT:%s%n",getDateInstance(SHORT).format(date));
    }
    static void timeInstanceDemo(Date date){
        out.println("getTimeInstance() demo");
        out.printf("	LONG:%s%n",getTimeInstance(LONG).format(date));
        out.printf("	MEDIUM:%s%n",getTimeInstance(MEDIUM).format(date));
        out.printf("	SHORT:%s%n",getTimeInstance(SHORT).format(date));
    }
    static void dateTimeInstanceDemo(Date date) {
        out.println("getDateTimeInstance() demo");
        out.printf("	LONG:%s%n", getDateTimeInstance(LONG, LONG).format(date));
        out.printf("	MEDIUM:%s%n", getDateTimeInstance(SHORT, MEDIUM).format(date));
        out.printf("	SHORT:%s%n", getDateTimeInstance(SHORT, SHORT).format(date));
    }
}
结果截图:

20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

直接构建SimpleDateFormat的好处是,可使用模式字符串自定义格式。

代码如下:
package DateCalendar;

import java.text.*;
import java.util.*;
public class SimpleDateFormatDemo {
    public static void main(String[] args){
        DateFormat dateFormat=new SimpleDateFormat(
                args.length==0?"EE-MM-dd-yyyy":args[0]
        );
        System.out.println(dateFormat.format(new Date()));
    }
}
结果截图:

20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

SimpleDateFormat还有parse()方法,可以按构建SimpleDateFormat时指定的格式,将指定的字符串剖析为Date实例。
代码如下:

package DateCalendar;

import java.text.*;
import java.util.*;
public class HowOld {
    public static void main(String[] args) throws Exception {
        System.out.print("输入出生年月(yyyy-mm-dd):");
        DateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
        Date birthDate = dateFormat.parse(new Scanner(System.in).nextLine());
        Date currentDate = new Date();
        long life = currentDate.getTime() - birthDate.getTime();
        System.out.printf("你今年的岁数为:%n" +(life/(365*24*60*60*1000L)));
    }
}
结果截图:

20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

13.2.3 处理时间日期的Calendar

  1. 如果想要取得某个时间日期信息,或者对时间日期进行操作,可以使用Calendar实例。
  2. 取得Calendar实例,可以使用getTime()取得Date实例。
  3. 取得Calendar实例后,可以使用add()方法来改变Calendar时间。
代码如下:
package DateCalendar;

import static java.lang.System.out;
import java.util.Calendar;
public class CalendarUtil {
    public static void main(String[] args){
        Calendar birth=Calendar.getInstance();
        birth.set(1996,Calendar.JANUARY,27);
        Calendar now=Calendar.getInstance();
        out.printf("岁数:%d%n",yearsBetween(birth,now));
        out.printf("天数:%d%n",daysBetween(birth,now));
    }
    public static long yearsBetween(Calendar begin,Calendar end){
        Calendar calendar=(Calendar) begin.clone();
        long years=0;
        while(calendar.before(end)){
            calendar.add(Calendar.YEAR,1);
            years++;
        }
        return years-1;
    }
    public static long daysBetween(Calendar begin,Calendar end){
        Calendar calendar=(Calendar) begin.clone();
        long days=0;
        while(calendar.before(end)){
            calendar.add(Calendar.DATE,1);
            days++;
        }
        return days-1;
    }
}
结果截图:

20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

13.2.4 设定TimeZone

  1. 可以使用java.util.TimeZone的getDefault()来取得默认时区信息。
代码如下:
package DateCalendar;

import static java.lang.System.out;
import java.util.TimeZone;
public class TimeZoneDemo {
    public static void main(String[] args){
        TimeZone timeZone=TimeZone.getDefault();
        out.println(timeZone.getDisplayName());
        out.println("	时区ID:"+timeZone.getID());
        out.println("	日光节约时数:"+timeZone.getDSTSavings());
        out.println("	UTC偏移毫秒数:"+timeZone.getRawOffset());
    }
}
结果截图:

20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

可用的ID可以使用TimeZone.getAvailableIDs()来取得,它会返回String[]。

代码如下:
package DateCalendar;

import static java.lang.System.out;
import java.util.*;
public class TimeZoneDemo2 {
    public static void main(String[] args){
        TimeZone shanghaiTz=TimeZone.getTimeZone("Asia/Shanghai");
        Calendar calendar=Calendar.getInstance(shanghaiTz);
        showTime(calendar);

        TimeZone copenhagenTz=TimeZone.getTimeZone("Europe/Copenhagen");
        calendar.setTimeZone(copenhagenTz);
        showTime(calendar);

        TimeZone washingtonTz=TimeZone.getTimeZone("American/Washington");
        calendar.setTimeZone(washingtonTz);
        showTime(calendar);
    }
    static void showTime(Calendar calendar){
        out.print(calendar.getTimeZone().getDisplayName());;
        out.printf("%d:%d%n",
                calendar.get(Calendar.HOUR),
                calendar.get(Calendar.MINUTE));
    }
}
结果截图:

20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

13.3 JDK8新时间日期API

13.3.1 机器时间观点的API

  1. Date名称是机器的时间观念,JDK8新时间日期处理API时,主要套件命名为java.time。
  2. 对于机器相关的时间观念,设计了Instant类。
  3. 可以使用now()方法取得Instant实例。
    4,取得Date实例后,想改用Instant,可以调用from()方法。

13.3.2 人类时间观念的API

  1. LocalDateTime、LocalDate和LocalTime
    1)对于片段的日期时间,JDK8新时间与新日期API有LocalDateTime(包括日期与时间)、LocalDate(只有日期)、LocalTime(只有时间)等类来定义。
  2. ZoneDateTime和OffsetDateTime
代码如下:
package DateCalendar;

import static java.lang.System.out;
import java.time.*;
public class ZonedDateTimeDemo {
    public static void main(String[] args){
        LocalTime localTime=LocalTime.of(0,0,0);
        LocalDate localDate=LocalDate.of(1996,1,27);
        ZonedDateTime zonedDateTime=ZonedDateTime.of(
                localDate,localTime,ZoneId.of("Asia/Shanghai")
        );
        out.println(zonedDateTime);
        out.println(zonedDateTime.toEpochSecond());
        out.println(zonedDateTime.toInstant().toEpochMilli());
    }
}
结果截图:

20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

Year、YearMonth、Month和MonthDay

代码如下:
package DateCalendar;

import static java.lang.System.out;
import java.time.Month;
public class MonthDemo {
    public static void main(String[] args){
        for(Month month:Month.values()){
            out.printf("original:%d	value:%d	%s%n",
                    month.ordinal(),month.getValue(),month);
        }
    }
}
结果截图:

20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

13.3.3 对时间的运算
1.TemporalAmount
1)JDK8新日期时间处理实现了流畅API的概念,其中,ofPattern()其实是java.time.format.DateTimeFormatter的静态方法,可以查看API文件了解格式化的方式。
2)TemporalAmount的操作类就是Period与Duration。

代码如下:
package DateCalendar;

import java.time.*;
import java.util.Scanner;
import static java.lang.System.out;
public class HowOld2 {
    public static void main(String[] args){
        out.print("输入出生年月日(yyy-mm-dd):");
        LocalDate birth=LocalDate.parse(new Scanner(System.in).nextLine());
        LocalDate now=LocalDate.now();
        Period period=Period.between(birth,now);
        out.printf("你活了%d年%d月%d日%n",
                period.getYears(),period.getMonths(),period.getDays());
    }
}
结果截图:

20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

代码调试中的问题和解决过程

问题:

教材p436页TimeZoneDemo.java代码运行结果:
20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

所显示的时区ID是Asia/Shanghai,为什么不是Asia/Beijing呢?

解决过程:

通过查阅相关资料,发现Java所支持的所有时区ID里面并没有Asia/Beijing,所以对于*时区的而言,显示的应该都是Asia/Shanghai

其他(感悟、思考等,可选)

本周学习内容相对简单,学习任务适中,使我能够有结余的时间来复习前面没弄懂的地方。本章###时间与日期从最基础的时间度量开始讲起,主要教给我们输出时间,设置时间,查找时间和运算时间,讲解详细,形成了较为完整的知识架构易于我们的学习。

代码托管截图:

20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

学习进度条

20145312 《Java程序设计》第七周学习总结
20145312 《Java程序设计》第七周学习总结

参考资料