博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

JavaEE - 09常用类2

Posted on 2020-12-07 21:58  Kingdomer  阅读(88)  评论(0编辑  收藏  举报

JavaEE - 09常用类2

(2)JDK8之前的日期时间API

  • java.util.Date  implements java.io.Serializable, Cloneable, Comparable<Date>
    • java.sql.Date / java.sql.Time / java.sql.Timestamp
  • java.util.Timezone implements Serializable, Cloneable
  • java.util.Calendar implements Serializable, Cloneable, Comparable<Calendar>
    • java.util.GregorianCalendar extends Calendar
  • java.text.DateFormat extends Format 
    • java.text.SimpleDateFormat extends DateFormat
  • java.text.NumberFormat extends Format

(2.1)java.lang.System类

System类提供的public static long currentTimeMillis()用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。

计算世界时间的主要标准有:

  • UTC(Coordinated Universal Time)
  • GMT(Greenwich Mean Time)
  • CST(Central Standard Time)
    @Test
    public void test2(){
        Long t1 = System.currentTimeMillis();
        System.out.println(t1);  //1606721150824
    }

(2.2)java.util.Date类

表示特定的瞬间,精确到毫秒。

> 构造器

  • Date(): 使用无参构造器创建的对象可以获取本地当前时间。
  • Date(long date)

> 常用方法

  • getTime():  返回自1970年1月1日00:00:00 GMT以来此Date对象表示的毫秒数。
  • toString(): 把Date对象转换成以下形式的String: dow mon dd hh:mm:ss zzz yyyy。 其中dow指一周中的某天,zzz是时间标准。
  • 其他很多方法都已过时。
    @Test
    public void test1(){
        Date d1 = new Date();   // 构造器一:Date()
        System.out.println(d1.toString());  // Mon Nov 30 15:16:18 CST 2020
        System.out.println(d1.getTime());   // 1606720578367

        Date d2 = new Date(1606720363143L);  // 构造器二
        System.out.println(d2.toString());  // Mon Nov 30 15:12:43 CST 2020
      // java.sql.Date 对应着数据库中的日期类型的变量,继承于 java.util.Date
        java.sql.Date d3 = new java.sql.Date(1606720363143L);
        System.out.println(d3);  // 2020-11-30

        Date d4 = new java.sql.Date(1606720363143L); // 2020-11-30
        java.sql.Date d5 = (java.sql.Date) d4; // 2020-11-30

        Date d6 = new Date();
        java.sql.Date d7 = new java.sql.Date(d6.getTime()); // 2020-11-30
    }

(2.3)java.text.SimpleDateFormat类

  • Date类的API不易于国际化,大部分被废弃,java.text.SimpleDateFormat类是一个与语言环境无关的方式来格式化和解析日期的具体类。
  • 它允许进行  格式化: 日期 -> 文本、解析: 文本 -> 日期

格式化:

  • SimpleDateFormat():  默认的模式和语言环境创建对象
  • public SimpleDateFormat(String pattern): 该构造方法用参数pattern指定的格式创建一个对象
  • public String format(Date date): 该方法格式化时间对象date

解析:

  • public Date parse(String source): 从给定字符串的开始解析文本,以生成一个日期。

将字符串转换为java.util.Date类的对象(默认格式)

    @Test
    public void test1() throws ParseException {
        // 实例化 SimpleDateFormat
        SimpleDateFormat sdf = new SimpleDateFormat();

        // 格式化: 日期 --> 字符串
        Date date = new Date();
        System.out.println(date);  //Mon Nov 30 16:04:46 CST 2020
        String format = sdf.format(date);
        System.out.println(format);   //20-11-30 下午4:04
        // 解析: 字符串 --> 日期
        String str = "20-10-05 下午3:43";
        Date d1 = sdf.parse(str);
        System.out.println(d1);  //M on Oct 05 15:43:00 CST 2020
    }

将字符串转换为java.util.Date类的对象(自定义格式化)

    @Test
    public  void test2() throws ParseException {
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date date = new Date();
        String format1 = sdf1.format(date);
        System.out.println(format1);  // 2020-11-30 04:08:37
        Date d2 = sdf1.parse("2019-11-08 13:33:42");
        System.out.println(d2); // Fri Nov 08 13:33:42 CST 2019

将字符串转换为java.sql.Date类的对象

    @Test
    public  void test3() throws ParseException {
        String birth = "2020-09-09";
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdf1.parse(birth);
        System.out.println(date); // Wed Sep 09 00:00:00 CST 2020
        
        java.sql.Date birthDate = new java.sql.Date(date.getTime());  
        System.out.println(birthDate); //2020-09-09
    }

测试题: 从1990-01-01开始计算,三天打渔两天晒网,某天在干啥?

 

    // 从1990-01-01开始计算,三天打渔两天晒网, 某天是干啥
    @Test
    public void test4() throws ParseException {
        String startDay = "1990-01-01";
        String date = "1990-01-01";

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date d1 = sdf.parse(startDay);
        Date d2 = sdf.parse(date);
        // 括号
        int day = (int) ((d2.getTime() - d1.getTime()) / (1000*60*60*24)) + 1;
        String str = "";
        switch (day % 5){
            case 1:
            case 2:
            case 3:
                str =  "今天打渔";
                break;
            case 4:
            case 0:
                str = "今天晒网";
                break;
        }
        System.out.println(str);
    }

 

(2.4)java.util.Calendar(日历)类

Calendar是一个抽象基类,用于完成日期字段之间相互操作的功能。  Object -> Calendar -> GregorianCalendar -> BuddhistCalendar

> 获取Calendar实例的方法

  • 使用Calendar.getInstance()方法
  • 调用它的子类GregorianCalendar的构造器

> 一个Calendar的实例是系统时间的抽象表示,通过get(int field)方法来获取想要的信息。比如YEAR、MONTH、DAY_OF_WEEK、HOUR_OF_DAY、MINUTE、SECOND。获取月份时,一月是0,二月是1,...,12月是11; 获取星期时,周日是1,周一是2,...,周六是7

  • public void set(int field, int value)
  • public void add(int field, int amount)
  • public final Date getTime()
  • public final void setTime(Date date)
    @Test
    public void test1(){
        Calendar calendar = Calendar.getInstance();
        System.out.println(calendar.getClass());   // class java.util.GregorianCalendar
        int days = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(days); // 30
        int days2 = calendar.get(Calendar.DAY_OF_YEAR);
        System.out.println(days2);  //335
        // set()
        calendar.set(Calendar.DAY_OF_MONTH,22);
        days = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(days);  // 22
        System.out.println(calendar.getTime()); //Sun Nov 22 16:28:50 CST 2020
        // add()
        calendar.add(Calendar.DAY_OF_MONTH,-3);
        days = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(calendar.getTime());  //Thu Nov 19 16:32:49 CST 2020
        System.out.println(days);  //19
        // getTime()
        Date date = calendar.getTime();
        System.out.println(date);  //Thu Nov 19 16:32:49 CST 2020
        // setTime()
        Date date1 = new Date();
        calendar.setTime(date1);
        days = calendar.get(Calendar.DAY_OF_MONTH);
        System.out.println(days);  //30
    }

 

(3)JDK8中新日期时间API

JDK1.0中包含了java.util.Date类,但是它大多数方法在JDK1.1引入Calendar类之后被弃用了。

而Calendar并不比Date好多少。面临的问题有:

  • 可变性: 像日期和时间这样的类应该是不可变的。
  • 偏移性: Date中的年份是从1900开始的,而月份是从0开始。
  • 格式化: 格式化只对Date有用,Calendar则不行。
  • 此外,它们也不是线程安全的;不能处理闰秒等。
    @Test
    public void test3(){
        Date d1 = new Date(2020,9,10);
        System.out.println(d1);  // Sun Oct 10 00:00:00 CST 3920
        Date d2 = new Date(2020 - 1900,9,10);  // year 为偏移量
        System.out.println(d2);  // Sun Oct 10 00:00:00 CST 2020
    }

Java8 吸收了Joda-Time的精华,引入了 java.time API,纠正了过去的缺陷。

java.time中包括了 本地日期(LocalDate)、本地时间(LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime)和持续时间(Duration)的类。

Date类新增了toInstant()方法,用于把Date转换成新的表示形式。

新时间日期API
  • java.time            包含值对象的基础包
  • java.time.chrono     提供对不同的日历系统的访问
  • java.time.format     格式化和解析时间和日期
  • java.time.temporal   包含底层框架和扩展特性
  • java.time.zone       包含时区支持的类

(3.1)LocalDate、LocalTime、LocalDateTime

它们的实例是不可变的对象,分别表示使用ISO-8601日历系统(公历)的日期、时间、日期和时间。

它们提供了简单的本地日期或时间,但并不包含当前的时间信息,也不包含与时区相关的信息。

  • LocalDate代表ISO格式(yyyy-MM-dd)的日期,可以存储生日、纪念日等日期
  • LocalTime代表一个时间,而不是日期。
  • LocalDateTime表示时间和日期的。
方法 描述
now() / now(ZoneId zone) 静态方法,根据当前时间创建对象/指定时区的对象
of() 静态方法,根据指定日期/时间创建对象
getDayOfMonth() / getDayOfYear() 获取月份天数(1-31)/获得年份天数(1-366)
getDayOfWeek() 获取星期几(返回一个DayOfWeek枚举值)
getMonth() 获取月份,返回一个Month枚举值
getMonthValue() / getYear() 获取月份(1-12)/获取年份
getHour()/getMinute()/getSecond() 获得当前对象对应的小时、分钟、秒
withDayOfMonth() / withDayOfYear() / withMonth() / withYear() 将月份天数、年份天数、月份、年份修改为指定的值并返回新的对象
plusDays() / plusWeeks() / plusMonths() / plusYears() / plusHours() 向当前对象添加几天、几周、几个月、几年、几小时
minusDays() / minusWeeks() / minusMonths() / minusYears() / minusHours() 从当前对象减去几天、几周、几个月、几年、几小时

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    @Test
    public void test1(){
        LocalDate localDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDate);  //2020-11-30
        System.out.println(localTime);  //17:06:40.418
        System.out.println(localDateTime); //2020-11-30T17:06:40.418

        LocalDateTime ldt = LocalDateTime.of(2020,12,12,14,23,44);
        System.out.println(ldt);   //2020-12-12T14:23:44
        System.out.println(localDateTime.getDayOfYear());  //335
        System.out.println(localDateTime.getDayOfMonth()); //30
        System.out.println(localDateTime.getDayOfWeek());  //MONDAY
        System.out.println(localDateTime.getMonth());      //NOVEMBER
        System.out.println(localDateTime.getMonthValue()); //11
        System.out.println(localDateTime.getYear());       //2020
        // 体现不可变性
        LocalDate localDate1 = localDate.withDayOfMonth(22);
        System.out.println(localDate);   //2020-11-30
        System.out.println(localDate1);  //2020-11-22

        LocalDateTime ldt3 = localDateTime.plusMonths(3);
        System.out.println(localDateTime); //2020-11-30T17:09:57.045
        System.out.println(ldt3);          //2021-02-28T17:09:57.045

        LocalDateTime ldt4 = localDateTime.minusDays(7);
        System.out.println(localDateTime); //2020-11-30T17:09:57.045
        System.out.println(ldt4);          //2020-11-23T17:09:57.045
    }

(3.2)瞬时: Instant

  • Instant: 时间线上的一个瞬时点。可以被用来记录应用程序中的事件时间戳。
  • 处理时间和日期时,年月日时分秒是面向人类的时间模型,通用模型是面向机器的。在UNIX中,从1970年开始,以秒为单位,Java中以毫秒为单位。
  • java.time包通过值类型Instant提供机器视图。不需要任何上下文信息,如时区。表示从1970年1月1日00:00:00开始的秒数。精度可以达到纳秒级。
  • 1秒 = 1000毫秒  = 10^6毫秒 = 10^9纳秒
方法 描述
now() 静态方法,返回默认UTC时区的Instant类的对象
ofEpochMilli(long epochMilli) 静态方法,返回在1970-01-01 00:00:00 基础上加上指定毫秒数之后的Instant类的对象
atOffSet(ZoneOffset offset) 结合即时的偏移来创建一个 OffsetDateTime
toEpochMilli() 返回1970-01-01 00:00:00 到 当前时间的毫秒数,即为时间戳

 

 

 

 

 

 

 

时间戳是指格林威治时间1970-01-01 00:00:00(北京时间1970-01-01 08:00:00)起至现在的总秒数。

    @Test
    public void  test2(){
        Instant instant = Instant.now();
        System.out.println(instant);  // 2020-11-30T09:26:13.897Z
        System.out.println(System.currentTimeMillis()); //1606728374034
        // 添加时间的偏移量
        OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
        System.out.println(offsetDateTime); //2020-11-30T17:28:50.039+08:00
        // 获取自1970-01-01 00:00:00(UTC)开始的毫秒数
        long milli = instant.toEpochMilli();
        System.out.println(milli); //1606728530039
        // 通过给定的毫秒数,获取Instant对象
        Instant instant1 = Instant.ofEpochMilli(1606728374034L);
        System.out.println(instant1);  // 2020-11-30T09:26:14.034Z
    }

(3.3)格式化与解析日期、时间

java.time.format.DateTimeFormatter类: 提供了三种格式化方法

  • 预定义的标准格式。如:ISO_LOCAL_DATE_TIME; ISO_LOCAL_DATE; ISO_LOCAL_TIME。
  • 本地化相关的格式。如:ofLocalizedDateTime(FormatStyle.LONG/MEDIUM/SHORT)、ofLocalizedDate(FormatStyle.FULL/LONG/MEDIUM/SHORT)
  • 自定义的格式。如:ofPattern("yyyy-MM-dd hh:mm:ss E")
方法 描述
ofPattern(String pattern) 静态方法,返回一个指定字符串格式的DateTimeFormatter
format(TemporalAccessor t) 格式化一个日期、时间,返回字符串
parse(Charequence text) 将指定格式的字符序列解析为一个日期、时间

 

 

 

 

 

 

    @Test
    public void test3(){
        DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;  // 预定义的标准格式。
        LocalDateTime ldt = LocalDateTime.now();
        String str = formatter.format(ldt);  
        System.out.println(ldt);  //2020-11-30T17:39:31.719
        System.out.println(str);  //2020-11-30T17:39:31.719
        // 解析: 字符串 --> 日期
        TemporalAccessor parse = formatter.parse("2020-02-18T17:40:12.897");
        System.out.println(parse);  //{},ISO resolved to 2020-02-18T17:40:12.897
        // 本地化格式 
        DateTimeFormatter formatter2 = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
        String str2 = formatter2.format(LocalDate.now());
        System.out.println(str2);  //2020年11月30日 星期一
        // 自定义格式 ofPattern
        DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String str3 = formatter3.format(LocalDateTime.now());
        System.out.println(str3);  //2020-11-30 17:46:20

        TemporalAccessor accessor = formatter3.parse("2020-09-08 17:09:07");
        System.out.println(accessor); //{},ISO resolved to 2020-09-08T17:09:07
    }

(3.4)其他API

  • ZoneId: 该类中包含了所有的时区信息,一个时区的ID,如Europe/Paris
  • ZonedDateTime: 一个在ISO-8601日历系统时区的日期时间,如 2007-12-12T10:09:08+01:00 Europe/Paris。
    • 其中每个时区都对应着ID,地区ID都为"{区域}/{城市}"的格式,如:Asia/Shanghai等
  • Clock: 使用时区提供对当前即时、日期和时间的访问的时钟。
  • Duration:持续时间,用于计算两个"时间"间隔。
  • Period: 日期间隔,用于计算两个"日期"间隔。
  • TemporalAdjuster: 时间校正器。如:将日期调整到"下一个工作日"等操作。
  • TemporalAdjusters: 该类通过静态方法firstDayOfXxx()/lastDayOfXxx()/nextXxx() 提供了常用TemporalAdjuster的实现。

(3.5)参考:与传统日期处理的转换

To 遗留类 From 遗留类
java.time.Instant 与 java.util.Date Date.from(instant) date.toInstant()
java.time.Instant 与 java.sql.Timestamp Timestamp.from(instant) timestamp.toInstant()
java.time.ZonedDateTime与java.util.GregorianCalendar GregorianCalendar.from(zonedDateTime) cal.toZonedDateTime()
java.time.LocalDate 与 java.sql.Time Date.valueOf(localDate) date.toLocalDate()
java.time.LocalTime 与 java.sql.Time Date.valueOf(localDate) date.toLocalTime()
java.time.LocalDateTime 与 java.sql.Timestamp Timestamp.valueOf(localDateTime) timestamp.toLocalDateTime()
java.time.ZoneId与java.util.TimeZone Timezone.getTimeZone(id) timeZone.toZoneId()
java.time.format.DateTimeFormatter与java.text.DateFormat formatter.toFormat()