Java基础10——日期和时间
Date
java.util.Date
表示特定的时间(某一个瞬间),用来表示时间和日期,提供一系列操作
public class Dateimplements java.io.Serializable,Cloneable,Comparable<Date>
- 获取的是系统的时间和日期
- 1天=24 * 60 * 60=86400秒
- 计算机标准是根据格林威治标准时间(GMT),由于中国属于东八区,所以比GMT时间早8小时。
类的所欲方法Date
接受或返回年、月、日、小时、分钟、和秒值,以下描述中使用:
Y
年代表整数y-1900
。- 一个月由0到11的整数表示;可以理解为数组的索引,0是1月,11是十二月。
- 日期(月的一天)以通常的方式从0-31的整数表示。
- 一小时由0~23之间的整数表示。因此,从午夜到凌晨一点的时间是小时0,从中午到下午1点的小时是十二小时。
- 一般以0~59的整数表示
minute
- 秒由0到61的整数表示; 值60和61仅发生在闰秒上,甚至仅在实际上正确跟踪闰秒的 Java实现中发生。 由于目前引入闰秒的方式,在同一分钟内不会发生两个闰秒,但是 本规范遵循ISO C的日期和时间约定。
成员变量
private transient long fastTime;
构造方法
目前还有两个未被弃用的构造方法:
Constructor | Description |
---|---|
Date() | 分配一个Date对象并初始化它,当前系统时间 |
Date(long date) | 分配一个Date对象,date毫秒。即1970年1月1日00:00:00GMT以来的毫秒数 |
System.currentTimeMillis()
也是获取自1970年1月1日以来,以此日期为准的00:00:00 GMT的毫秒数。
public Date(long millis){fastTime = millis;
}public Date(){this(System.currentTimeMillis()); // 将System.currentTimeMillis()保存到fastTime
}
public static void main(String[] args){Date date = new Date();System.out.println(date);Date date1 = new Date(1000L);System.out.println(date1);
}
成员方法
Date
中大部分方法都已经被弃用,仅存在以下成员方法:
Method | Type | Description |
---|---|---|
after(Date when) | boolean | 测试此日期是否在指定日期之后 |
before(Date when) | boolean | 测试此日期是否在指定日期之前 |
equals(Object obj) | boolean | 比较两个日期相等 |
getTime() | long | 1970年1月1日以来,以此日期为准的00:00:00 GMT的 毫秒数 |
setTime(long time) | void | 设置此 Date对象以表示1970年1月1日00:00:00 GMT后的 time毫秒的时间点 |
toString() | String | 将此 Date对象转换为 String的形式 |
其中toString()
的格式是:dow mon dd hh:mm:ss zzz yyyy
dow(day of week)
是星期几(Sun,Mon,Tue,Wed,Thu,Fri,Sat
).mon
是月(Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
)。dd
是一个月的某天(01~31),作为两位十进制数字。hh
是一天的小时( 00 到 23 ),作为两位十进制数字。mm
是一小时内的分钟( 00 至 59 ),为两位十进制数字。ss
是分钟内的秒( 00 到 61 ),作为两位十进制数字。zzz
是时区。 标准时区缩写包括通过方法parse识别的缩写
。 如果时区信息不可用, 那么zzz
是空的 - 也就是说,它根本没有字符。年份
为yyyy
,为四位十进制数字
比较Date对象
Date
对象的比较可以通过uquals
、after
、before
方法实现。
public static void main(String[] args) {long mills = System.currentTimeMillis(); //获取当前时间的毫秒值Date first = new Date(mills);System.out.println(first);Date second = new Date(mills);System.out.println(second);// == 比较System.out.println(first == second);//false//equals比较,Date重写了从Object继承的equals方法//内部实现是 obj instanceof Date && getTime() == ((Date) obj).getTime()System.out.println(first.equals(second));//trueDate now = new Date();System.out.println(now.after(first));//trueSystem.out.println(now.after(second));//trueSystem.out.println(first.before(now));//trueSystem.out.println(second.before(now));//true
}
Date实例是可变的
Date
实例创建后,内部的毫秒值fastTime
是可以改变的
public static void main(String[] args){long ms = 1000L * 60 * 60 * 24 * 365 * 25 ;//1995final Date birthdate = new Date(ms);System.out.println(birthdate);//Sat Dec 25 08:00:00 CST 1999birthdate.setTime(1000);//改变Date对象System.out.println(birthdate);//Thu Jan 01 08:00:01 CST 1970
}
java.util.Calendar
是一个抽象类。可以为在某一特定时刻和日历字段之间的转换的方法,以及用于操纵该日历的字段提供了方法,时间上的瞬间可以用毫秒值表示,该值是从1970年1月1日00:00 00:00.000 GMT
public abstract class Calendar implements Serializable, Cloneable,
Comparable<Calendar>// 这是jdk源码
由于该类是抽象类,所以不能直接实例化,在类中提供了一个方法Calendar.getInstance();
这个方法返回了一个Calendar
对象,其日历字段已使用当前日期和进行初始化。
类变量
Calendar.ERA
对应纪元 比如罗马儒略历中的 AD 或 BC ( 中文表示为 公元 或 公元前 )Calendar.YEAR
对应年份Calendar.MONTH
对应月份 月份从 0 开始计数,0 表示 January (一月),1 表示 February ( 二月 )Calendar.DATE
对应月份中的日期 日期从 1 开始计数,有效范围为 1 ~ 31 。Calendar.HOUR_OF_DAY
对应一天当中的小时 小时从 0 开始计数,有效范围为 0 ~ 23 。Calendar.MINUTE
对应分钟 分钟从 0 开始计数,有效范围为 0 ~ 59 。Calendar.SECOND
对应秒 秒数从 0 开始计数,有效范围为 0 ~ 60 。(要注意闰秒)Calendar.MILLISECOND
对应毫秒 毫秒数从 0 开始计数,有效范围为 0 ~ 999 。 `Calendar.DAY_OF_MONTH
对应月份中的日期 日期从 1 开始计数,有效范围为 1 ~ 31。Calendar.HOUR
对应上午或下午的小时 小时从 0 开始计数,有效范围为 0 ~ 11 。Calendar.DAY_OF_WEEK
对应星期 用于指示一个星期中的某天。 该字段可取的值可以是 SUNDAY 、 MONDAY 、 TUESDAY 、 WEDNESDAY 、 THURSDAY 、 FRIDAY 和 SATURDAY 。Calendar.DAY_OF_YEAR
对应年份中的天数 指示当前年中的天数。 一年中第一天的值为 1,最大值为 366 。Calendar.AM
表示一天午夜到中午之前的时间,即上午Calendar.PM
表示从中午到午夜之前的一天中的一段时间,即下午
获取Calendar对象
通过子类获取
java.util.GregorianCalendar
是 Calendar
类的子类,并提供了世界上大多数国家使用的 标准日历系统。通过 GregorianCalendar
对象即可使用 Calendar
中的方法
Calendar calendar = new GregorianCalendar();
System.out.println(calendar);
通过Calendar的static方法获取
Calendar
类中提供了大量的 static
方法用于获取 Calendar
对象
Calendar c = Calendar.getInstance(); //使用默认时区和区域设置获取日历
Calendar c1 = Calendar.getInstance(Locale.CHINA);//使用默认时区和指定的区域设置获取日历
Calendar.getInstance(TimeZone.getDefault());//使用指定的时区和默认语言环境获取日历
Calendar.getInstance(TimeZone.getDefault(), Locale.CHINA);//获取具有指定时区和区域设置的日历
成员方法
获取时间
-
获取
Calendar
对象所表示的某个特定瞬间所对应的毫秒值public long getTImeInMillis();
-
获取
Calendar
对象所表示的某个特定瞬间的指定字段
所对应的值public int get(int field);//field是前面提到的Calendar的类变量
package com.itlaobing.note;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class CalendarTest {public static void main(String[] args) {// 父类引用 指向 子类对象Calendar c = new GregorianCalendar();System.out.println( c );// 从 c 对应的 Calendar 实例中获取 日历字段 ERA 对应的值int era = c.get( Calendar.ERA ) ;System.out.println( era );//1int year = c.get( Calendar.YEAR );System.out.println( year );//2019// 在西方国家,月份的索引从 零 开始,0 表示 1月 , 11 表示12月int month = c.get( Calendar.MONTH );System.out.println( month ); //9//对应月份中的日期int date = c.get( Calendar.DATE );System.out.println( date );//24//一天中的小时 24时制int hourOfDay = c.get( Calendar.HOUR_OF_DAY );System.out.println( hourOfDay );//20//分钟int minute = c.get( Calendar.MINUTE );System.out.println( minute );//0//秒int second = c.get( Calendar.SECOND );System.out.println( second );//13// 仅仅获取 MILLISECOND 字段对应的值,取值范围为 [ 0 , 1000 )int millis = c.get( Calendar.MILLISECOND );System.out.println( millis );//48System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );// 获取 当前的 Calendar 实例所表示的瞬间 对应的毫秒值(距离历元的偏移量)long ms = c.getTimeInMillis();System.out.println( ms );//1571918413048
}
设置/清除Calendar对象值
Calendar
类中提供了一下方法用于设置 日历字段
的值
public void set(int field, int value)
同时也提供了一下方法来批量设置 日历字段
值
public final void set(int year, int month, int date);
public final void set(int year, int month, int date, int hourOfDay, int minute);
public final void set(int year, int month, int date, int hourOfDay, int minute, int second)
另外, Calendar
类中提供了清空指定 日历字段
值的方法
public final void clear(int field);
Calendar 类中还提供了清空所有 日历字段 值的方法
public final void clear();
eg:
package com.itlaobing.note;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class CalendarTest2 {public static void main(String[] args) {// 父类引用 指向 子类对象Calendar c = new GregorianCalendar();System.out.println(c);c.set(Calendar.YEAR, 1995); // 公元1995年c.set(Calendar.MONTH, 0); // 月份的索引从 0 开始,0表示1月c.set(Calendar.DATE, 10);c.set(Calendar.HOUR_OF_DAY, 11);c.set(Calendar.MINUTE, 45);c.set(Calendar.SECOND, 0);c.set(Calendar.MILLISECOND, 0);System.out.println(c);System.out.println(c.getTimeInMillis());System.out.println(c);System.out.println("==============================");c.clear(); // 清除所有日历字段的值System.out.println(c);// YEAR 、MONTH 、HOUR_OF_DAY 、MINUTE、SECONDc.set(0, 0, 10, 11, 45, 30);c.set(Calendar.MILLISECOND, 100);System.out.println(c.getTimeInMillis());//-62166600869900System.out.println(c);}
}
Calendar对象和Date对象互相转换
Calendar
类中提供了将 Calendar
对象所表示的某一特定瞬间转换成 Date
对象的方法
public final Date getTime();
Calendar
类中提供了将 Date
对象转换成 Calendar
对象所表示的某一特定瞬间的方法
public final void setTime(Date date);
eg:
package com.itlaobing.note;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class CalendarTest3 {public static void main(String[] args) {Calendar calendar = new GregorianCalendar();// java.util.Date 类中的 getTime() 方法可以返回一个毫秒值// java.util.Calendar 类中的 getTime() 用于返回相应的 Date 实例Date d = calendar.getTime();System.out.println(d);Date date = new Date();Calendar c = Calendar.getInstance();c.clear(); //清空所有字段值c.setTime(date); //设置时间System.out.println(c);}
}
LocalDate
java.time.LocalDate
是一个不可变( final
修饰)的日期时间对象,是线程安全的,表示日 期,通常被表示为年月日。也可以访问其他日期字段,例如日期,星期几和星期字段
public final class LocalDateimplements Temporal, TemporalAdjuster, ChronoLocalDate, Serializable {
LocalDate
中声明了三个字段来存储年、月、日
/*** The year.*/
private final int year;/*** The month-of-year.*/
private final short month;/*** The day-of-month.*/
private final short day;
因为它们都是 fina
l 修饰的,因此一旦创建 LocalDate
实例,其 年份、月份、日期 的 值再也不能被更改。
常用实例方法
LocalDate
类中定义了大量的实例方法,其中比较常用的是:
public int getYear()
用于获取年份public int getMonthValue()
用于获取月份 ( 取值范围是 1 ~ 12 )public int getDayOfMonth()
用于获取日期 ( 取值范围是 1 ~ 31 )public DayOfWeek getDayOfWeek()
用于获取星期 ( 返回类型为DayOfWeek
)public boolean isLeapYear()
用于判断LocalDate
实例对应的年份是否是闰年public int lengthOfYear()
用于获取LocalDate
实例对应的年份的总天数public int lengthOfMonth()
用于获取LocalDate
实例对应的月份的总天数
LocalTime
java.time.LocalTime
是一个不可变( final
)的日期时间对象,代表一个时间。 时间表示 为纳秒精度。它不存储或表示日期或时区。
public final class LocalTime
implements Temporal, TemporalAdjuster, Comparable<LocalTime>, Serializable
在 java.time.LocalTime
类中声明了四个字段用来存储 小时、分钟、秒、纳秒
/*** The hour.*/
private final byte hour;/*** The minute.*/
private final byte minute;/*** The second.*/
private final byte second;/*** The nanosecond.*/
private final int nano;
因为它们都是 final 修饰的,因此一旦创建 LocalTime 实例,其中各个字段的值再也不 能被更改
常用的成员方法
LocalTime
类中定义了大量的实例方法,其中比较常用的是:
public int getHour()
用于获取小时 (取值范围为 0 ~ 23 )public int getMinute()
用于获取分钟 (取值范围为 0 ~ 59 )public int getSecond()
用于获取秒 (取值范围为 0 ~ 59 )public int getNano()
用于获取纳秒 (取值范围为 0 ~ 999999999 )
LocalDateTime
java.time.LocalDateTime
是一个不可变的日期时间对象,代表日期时间。
public final class LocalDateTime
implements Temporal, TemporalAdjuster, ChronoLocalDateTime<LocalDate>,
Serializable {
在 java.time.LocalDateTime
类中声明了两个实例字段用来存储 日期 和 时间 :
/**
* The date part.
*/
private final LocalDate date;
/**
* The time part.
*/
private final LocalTime time;
可以看出其实 LocalDateTime
底层就是一个 LocalDate
+ LocalTime
。
这里需要注意,不仅仅 date 和 time 字段是 final 修饰的, LocalDate
、 LocalTime
类中的实例字段也是 final 修饰的,因此 LocalDateTime
的实例一经创建,其内部的各 项取值都是不可更改的。
转换
LocalDate转LocalDateTime
LocalDate
atStartOfDay()
将时间初始化为 00:00atTime(int hours, int minutes[, int seconds[, int nanoOfSecond]])
将时间初始 化为指定的值atTime(LocalTime time)
以指定的时间
LocalDateTime
of(LocalDate date, LocalTime time)
package com.itlaobing.note;
import java.time.LocalDate;
import java.time.LocalDateTime;
public class LocalDateTest4 {public static void main(String[] args) {LocalDate n = LocalDate.now();System.out.println(n);// LocalDate ---> LocalDateTimeLocalDateTime datetime = n.atStartOfDay();//一天的开始System.out.println(datetime);LocalDateTime first = n.atTime(10, 20);//在某个时间点System.out.println(first);LocalDateTime second = n.atTime(10, 20, 30);System.out.println(second);LocalDateTime third = n.atTime(10, 20, 30, 100200300);System.out.println(third);}
}
LocalTime转LocalDateTime
package com.itlaobing.note;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class LocalTimeTest4 {public static void main(String[] args) {LocalTime time = LocalTime.now();System.out.println(time); //22:03:07.970// LocalTime ---> LocalDateTimeLocalDate date = LocalDate.of(2019, 10, 24);LocalDateTime dateTime = time.atDate(date);// 在某一天System.out.println(dateTime);}
}
LocalDateTime 转 LocalDate 或 LocalTime
package com.itlaobing.note;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class LocalDateTimeTest4 {
public static void main(String[] args) {LocalDateTime datetime = LocalDateTime.now();System.out.println(datetime);// LocalDateTime ---> LocalDateLocalDate date = datetime.toLocalDate();System.out.println(date);// LocalDateTime ---> LocalTimeLocalTime time = datetime.toLocalTime();System.out.println(time);}
}
Date转LocalDateTime
package com.itlaobing.note;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
public class DateTest2 {
public static void main(String[] args) {/*** 将Date对象转换成LocalDate/LocalTime/LocalDateTime* 1. 将java.util.Date对象所表示的瞬间转换成java.time.Instant* 2. 通过java.time.Instant获取具有时区的日期时间java.time.ZonedDateTime* 3. 将java.time.ZonedDateTime转换成相应类型*/final long ms = 1000L * 60 * 60 * 24 * 365 * 26;Date date = new Date(ms);System.out.println(date);//Tue Dec 26 08:00:00 CST 1995System.out.println("===============");//Instant指在时间线上的瞬间点Instant instant = date.toInstant(); // Date ==> java.time.Instant//ZoneId指一个时区IDZoneId zone = ZoneId.of("Asia/Shanghai");//时区设置成亚洲/上海时间//ZonedDateTime指具有时区的日期时间ZonedDateTime zonedDateTime = instant.atZone(zone);LocalDateTime datetime = zonedDateTime.toLocalDateTime();System.out.println(datetime);//1995-12-26T08:00LocalDate d = zonedDateTime.toLocalDate();System.out.println(d);//1995-12-26LocalTime t = zonedDateTime.toLocalTime();System.out.println(t);//08:00}
}
LocalDateTime转Date
package com.itlaobing.note;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
public class LocalDateTimeTest5 {
public static void main(String[] args) {
/**
* 将LocalDateTime对象转换成Date对象
* 1. 获取带时区的java.time.ZonedDateTime对象
* 2. 将java.time.ZonedDateTime对象转换成表示某一瞬间的java.time.Instant对象
* 3. 通过Date.from方法,将java.time.Instant对象转换成Date对象
*/LocalDateTime datetime = LocalDateTime.of(1999, 11, 22, 6, 30, 7);ZoneId zone = ZoneId.systemDefault();//获取系统默认时区ZonedDateTime zonedDateTime = ZonedDateTime.of(datetime, zone);Instant instant = Instant.from(zonedDateTime);Date date = Date.from(instant);System.out.println(date);//Mon Nov 22 06:30:07 CST 1999}
}