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


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

    教材学习内容总结

    在本周,我们进行了第十二,十三章的学习,本周的学习目标是:

    了解Lambda语法
    了解方法引用
    了解Fucntional与Stream API
    掌握Date与Calendar的应用
    会使用JDK8新的时间API
    因为Lambda语法在前面的第九章里学过一些基本的内容,对Lambda语法也有了初步的了解,所以,在本周的学习重点放在了第十三章:时间与日期上。

    第十三章: 时间和日期

    • 时间与日期简史
      时间是个很复杂的问题,用程序来设计时间也并不是像我们像想的那样简单。在正式学习Java中有关时间处理的API之前,书中先是介绍了一些有关时间的历史问题,这样对我们在后面对于时间类API的应用很有帮助。
      想要度量时间有很多基准,我们最熟悉的应该就是格林尼治时间,它一开始是参照英国皇家格林尼治天文台的标准太阳时间,其标准是正午太阳抵达天空的最高点的时候。然而由于地球的公转轨道为椭圆形而且速度并不唯一,地球本身的自转也有一定的时间误差,所以格林尼治时间(GMT)已经不作为标准时间进行使用了。
      另一个便是“世界时”(UT),它是由观测远方星体跨国子午线而得的。在1935年便建议用更精确的UT来代替GMT,在1972年引进UTC之前,两者其实是相同的。
      后来人们发现,即便是使用UTC还是会受到地球自转的影响而产生误差。所以,在1967年国际原子时将妙偶的国际单位定义为铯原子的辐射振动9192631770周耗费的时间,时间从1958年开始与UT同步。
      再后来还有世界协调时间,UNIX时间,epoch时间等。
      想要学习本章的知识还要求对日历的标准,计算,时区的标准,计算有一定的掌握。这样会更方便本章的学习。书中已经有了详细的介绍,对我们很有帮助。
    • 13.2:Date与Calender:

    时间轴上瞬间的Date:

    我们要是想要取得系统时间,方法之一就是使用System.currentTimeMillis,返回的是long型的整数,代表的是1970年1月1日0时0分0毫秒至今经过的毫秒数,也就是与之前UNIX的时间计量方法相似,估计苹果的时间计量方法也差不多,要不然不会出现时间设置在1970年之前就会变砖的情况。这种方法取得的是机器的时间观点代表着时间轴上的某一个瞬间,我们可以取得Date实例来取得系统时间的描述,虽然Date也是偏向机器的时间观点。Date的代码如下:

    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());
        }
    }
    
    

    程序在IDEA上的运行结果如下:

    程序运行结果显示的数字也就是1970年1月1日至今所经过的毫秒数。

    格式化时间日期的DateFormat:

    有关字符串时间格式的处理,其职责落到了java.text.Dateformat身上。Dateformat是一个抽象类,其操作类是java.text.SimpleDateFormat,下面这个程序向我们展示了如何通过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));
        }
    }
    
    

    程序运行的结果如下所示:


    上面的不同方法是取到了不同详细程度的时间日期。其实,我们也可以直接构建SimpleDateFormat,这样我们就可以使用模式字符串自定义格式。它还有一个prase()方法,可以构建SimpleDateFormat时指定的格式,将指定的字符串剖析为Date实例:

    package DateCalendar;
    
    
            import java.util.*;
            import java.text.*;
    
    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.println("你今年的年龄为:" +
                    (life / (365 * 24 * 60 * 60 * 1000L)));
        }
    }
    
    

    程序运行的结果如下:

    处理时间日期的Calendar:

    在时间的处理中,若是我们想取得某个时间信息或者对时间信息进行操作,我们可以用Caendar实例。它是一个混合类,操作了儒略历与格里高利历的混合历,在书中,若是我们想比较两个Calendar的日期先后,可以使用after和before的方法。在这里使用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.AUGUST, 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;
        }
    }
    
    

    程序运行如下:

    设定TimeZone

    在前面使用Calendar时并没有使用时区信息,在这里,我们可以使用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());
        }
    }
    
    

    程序运行截图如下:

    Calendar在调用getInstance()时,可以指定TimeZone,如果已经取得Calendar实例,也可以通过setTimeZone()方法设定TimeZone,示例如下:

    package DateCalendar;
    
    
    
            import java.util.*;
            import static java.lang.System.out;
    
    public class TimeZoneDemo2 {
        public static void main(String[] args) {
            TimeZone taipeiTz = TimeZone.getTimeZone("Asia/Taipei");
            Calendar calendar = Calendar.getInstance(taipeiTz);
            showTime(calendar);
    
            TimeZone copenhagenTz = TimeZone.getTimeZone("Europe/Copenhagen");
            calendar.setTimeZone(copenhagenTz);
            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));
        }
    }
    
    

    程序运行截图如下:

    • 13.3JDK新时间日期API

    人类时间观点API:

    如果我们的时间需要带有时区,可以基于LocalDateTime,LocalDate,LocalTime来弥补缺少的信息:

    package DateCalendar;
    
    
            import static java.lang.System.out;
            import java.time.*;
    
    public class ZonedDataTimeDemo {
        public static void main(String[] args) {
            LocalTime localTime = LocalTime.of(0, 0, 0);
            LocalDate localDate = LocalDate.of(1975, 4, 1);
            ZonedDateTime zonedDateTime = ZonedDateTime.of(
                    localDate, localTime, ZoneId.of("Asia/Taipei"));
    
            out.println(zonedDateTime);
            out.println(zonedDateTime.toEpochSecond());
            out.println(zonedDateTime.toInstant().toEpochMilli());
        }
    }
    
    
    

    程序运行如下:

    year,month,yearmonth与monthday:

    如果我们只想表示2014年,可以使用year,如果想表示2014/5可以使用yearmonth。如果只想表示五月,可以使用month,如果想表示5/4,可以使用monthday,其中months是emnu型。如果你想去的代表月份的数字,不要使用oridinal()方法从0开始,想要取得代表月份的数要通过getvalue()方法。,书中有程序示例如下:

    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);
            }
        }
    }
    
    

    程序的执行情况如下所示:

    对时间的运算:

    在JDK8中,新日期时间处理实现了流畅API的概念,这是一种计算时间的新的方法,我们在前面曾经写过HowOld.java,在这里我们可以使用新方法进行改进,修改后的程序如下:

    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("输入出生年月日(yyyy-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());
        }
    }
    
    

    程序执行情况如下:

    教材学习中的问题和解决过程

    在本章的代码编译中,一定要注意日期书写的规范,在上面的HowOld2.java程序中我在程序里输入自己的信息,但却编译不出来,后来一看原来是输入的数据不规范,8应该写成08,这样才会有结果,否则就像下面一样:

    本周代码链接:

    本周代码合集

    本周代码托管截图

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 200/200 2/2 20/20
    第二周 100/300 1/3 18/38
    第三周 200/500 1/4 22/60
    第四周 250/750 1/5 30/90
    第五周 450/1200 1/6 20/110
    第六周 400/1600 2/8 30/140
    第七周 150/1750 2/10 30/170

    参考资料

  • 相关阅读:
    猜数字游戏
    Visual Studio Code如何编写运行C、C++
    Git Submodule使用完整教程
    同一客户端多个git账号的配置
    让 Git Bisect 帮助你
    GitHub 风格的 Markdown 语法
    git 命令图解
    图解git中的最常用命令
    Understanding the Bias-Variance Tradeoff
    Seven Techniques for Data Dimensionality Reduction
  • 原文地址:https://www.cnblogs.com/20145107lcd/p/5393508.html
Copyright © 2020-2023  润新知