java.util.Date
是一个“万能接口”,它包含日期、时间,还有毫秒数,若是你只想用java.util.Date
存储日期,或者只存储时间,那么,只有你知道哪些部分的数据是有用的,哪些部分的数据是不能用的。java
1.1 Date的构造方法安全
Date 是咱们使用的最多的一个日期类,Date提供的构造方法在官方API中有一下几种:ui
Date 类提供了多种构造方法,可是目前有不少方法都已经不建议使用this
public Date() { this(System.currentTimeMillis()); } public Date(long date) { fastTime = date; } @Deprecated public Date(int year, int month, int date) { this(year, month, date, 0, 0, 0); } @Deprecated public Date(int year, int month, int date, int hrs, int min) { this(year, month, date, hrs, min, 0); } @Deprecated public Date(int year, int month, int date, int hrs, int min, int sec) @Deprecated public Date(String s) { this(parse(s)); }
目前咱们能够经过使用:spa
Date date0 = new Date(); Date date1 = new Date(time);
这两种方法建立对象的不一样主要是经过指定的时间戳不一样,经过设置Date 中的 fastTime 进行设置Date 对象的时间。
线程
除了使用构造方法获取实例,Date 还能够经过 Instant 来建立一个Date 实例:code
Instant instant = Instant.now();
Date date = Date.from(instant);
Instant 是Java 8 提供的新特性:orm
1.2 Date的经常使用方法对象
Date 类中,提供了经常使用的获取:年,月,日,时,分,秒等方法:blog
Date date = new Date(); int dates = date.getDate(); int year = date.getYear(); int month = date.getMonth(); int day = date.getDay(); int hours = date.getHours(); int min = date.getMinutes(); int second = date.getSeconds(); long time = date.getTime(); int times = date.getTimezoneOffset();
输出结果:
dates: 14 year: 116 month: 11 day: 3 hours: 15 min: 8 second: 29 time: 1481699309422 times: -480
读者可能会发现,这里的年份并非咱们想要的,这里主要是由于代码方法实现:
咱们能够看到,这里的getYear 并非获取当前年份,而是获取到和1900年的差值,这里主要是由于JDK老版本遗留下来的问题,对于Date 中获取年月日的方法,如今已经不建议使用了。
Date类中也提供了一些设置日期的方法:
与上面的get方法是一一对应的,可是如今也一样不建议使用了。
1.3 Date的总结
通过咱们上述的分析,咱们发现,Date 类现在不少方法已经没有什么用处了,确实,现在时间的处理并不直接在Date 类中进行,而是经过Calendar,或者LocalDate 来进行,咱们再平常使用中,更多的是要来作一个记录日期的实例。
介绍一下Date 与 Calendar 的区别
Date用于记录某一个含日期的、精确到毫秒的时间。重点在表明一刹那的时间自己。
Calendar用于将某一日期放到历法中的互动——时间和年、月、日、星期、上午、下午、夏令时等这些历法规定互相做用关系和互动。Calendar自己表明公历的一个简化缩水版,姑且叫“计算机历”。
完整的公历是格里高利历,Java SE中以GregorianCalendar类来提供相关的历法功能。
2.1 Calendar 的构造方法
咱们能够看到,Calendar 中的构造方法被封装在包中,咱们没法直接经过构造方法来建立一个新的实例对象,咱们只能经过调用 Calendar中的静态方法 Calendar.getInstance()方法获取一个实例对象。
咱们看一下官方API 中提供了哪些方法获取Calendar 对象:
这是官方文档给出的获取去对象实例的方法,咱们能够看到,咱们能够经过指定TimeZone 和 Locale 来获取特定的 Calendar 对象,这也却分了每一个地区的时间日历,方便开发者使用
除了经过getInstance() 方法获取实例之外,Java 1.8 提供了一个内部类:
咱们能够经过建立一个Builder 的实体,而后经过调用Build 方法获取一个 Calendar 实例。
在Builder 中,Builder 类提供了设置年月日的方法,能够经过设置时间,来获取特定的Calendar 对象。
Calendar.Builder builder =new Calendar.Builder(); Calendar calendar1 = builder.build(); Date date = calendar.getTime();
这里总结一下:
Calendar 提供的获取实例的方法主要有两种途径:
一、调用Calendar.getInstance()方法
二、建立内部类Builder 的实例,经过调用其 build()方法建立 Calendar 实例
对于第一种方法,只能先获取当前时间的Calendar,而后再经过调用相应的set 方法设置年月日等,而若是使用内部类Builder 方法,能够经过setInstant 方法设置咱们所指望的时间。
2.2 Calendar 的经常使用方法
咱们最经常使用的方法有:
Calendar calendar = Calendar.getInstance();
Date date = calendar.getTime();
经过Calendar 方法获取一个Date 的实例。
Calendar 方法获取年月日的方法:
int year =calendar.get(Calendar.YEAR); int month=calendar.get(Calendar.MONTH)+1; int day =calendar.get(Calendar.DAY_OF_MONTH); int hour =calendar.get(Calendar.HOUR_OF_DAY); int minute =calendar.get(Calendar.MINUTE); int seconds =calendar.get(Calendar.SECOND);
咱们能够看到Calendar 里面获取年月日不像上面 Date 类中的经过访问各个方法来获取。
Calendar 在初始化的时候,就已经将年月日划分好,而且存入fields 变量中。咱们只须要传入每一个位置编号,就能够获取咱们须要的信息
除了获取之外,Calendar 也提供了相应的set 方法:
经过从新传入参数,设置Calendar 的时间
Calendar 获取当前月份,当前星期的最大\小天数
System.out.println(calendar.getActualMaximum(Calendar.DAY_OF_WEEK));
System.out.println(calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
System.out.println(calendar.getActualMinimum(Calendar.DAY_OF_WEEK));
System.out.println(calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
提供了Before 和After 两个方法,用于判断当前时间与对比时间前后:
提供了add 方法进行日期的加减
calendar.add(10,10);
2.3 Calendar 的总结
从上面的分析咱们能够看到,Calendar 类 主要是用于做为日历的对象,能够铜鼓哦设置地区时间,区分每一个地区的日期,Calendar 提供的方法也没有不少对时间进行的一些操做。
Java 8新增了LocalDate
和LocalTime
接口,为何要搞一套全新的处理日期和时间的API?由于旧的java.util.Date
实在是太难用了。
java.util.Date
月份从0
开始,一月是0
,十二月是11
,变态吧!java.time.LocalDate
月份和星期都改为了enum
,就不可能再用错了。
java.util.Date
和SimpleDateFormatter
都不是线程安全的,而LocalDate
和LocalTime
和最基本的String
同样,是不变类型,不但线程安全,并且不能修改。
3.1 LocalDate/LocalTime 的构造方法
3.1.1 LocalDate 的构造方法:
LocalDate 并无提供公开的构造方法,只提供了一个封装的构造方法供内部使用。
private LocalDate(int year, int month, int dayOfMonth) { this.year = year; this.month = (short) month; this.day = (short) dayOfMonth; }
LocalDate 提供了三种建立实例的方法:
//获取当前时间的LocalDate LocalDate localDate = LocalDate.now(); //获取指定年、月、日 的 LocalDate LocalDate ofDate = LocalDate.of(2016,12,31); //经过解析字符串获取 LocalDate,若是格式不对会抛出 DateTimeParseException LocalDate parseDate = LocalDate.parse("2016-12-31-");
3.1.2 LocalTime 的构造方法:
LocalTime 与LcoalDate 同样,提供了一个封装的构造方法:
private LocalTime(int hour, int minute, int second, int nanoOfSecond) { this.hour = (byte) hour; this.minute = (byte) minute; this.second = (byte) second; this.nano = nanoOfSecond; }
LocalTime 提供了三种建立方法:
LocalTime localTime = LocalTime.now().withNano(0); LocalTime ofTime = LocalTime.of(16,30,25); LocalTime parseTime = LocalTime.parse("12:00:01");
3.2 LocalDate/LocalTime 的经常使用方法
获取当天的起始时间:atStartOfDay()
LocalDate localDate = LocalDate.now(); LocalDateTime date = localDate.atStartOfDay(); 输出: 2016-12-14T00:00
设置当前日期的时间:atTime()
LocalDate localDate = LocalDate.now(); LocalDateTime date = localDate.atTime(16,25,30); 输出: 2016-12-14T16:25:30
格式转换:format()
经常使用的获取年、月、日 等方法
int year = localDate.getYear(); int month = localDate.getMonthValue(); int day = localDate.getDayOfMonth();
获取改变月份的LocalDate :withMonth()
LocalDate localDate = LocalDate.now();
LocalDate d = localDate.withMonth(10);
其余经常使用的日期转换:
// 取本月第1天: LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth()); // 2014-12-01 // 取本月第2天: LocalDate secondDayOfThisMonth = today.withDayOfMonth(2); // 2014-12-02 // 取本月最后一天,不再用计算是28,29,30仍是31: LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth()); // 2014-12-31 // 取下一天: LocalDate firstDayOf2015 = lastDayOfThisMonth.plusDays(1); // 变成了2015-01-01 // 取2015年1月第一个周一,这个计算用Calendar要死掉不少脑细胞: LocalDate firstMondayOf2015 = LocalDate.parse("2015-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); // 2015-01-05
3.3 LocalDate/LocalTime 的总结
在新的Java 8中,日期和时间被明确划分为LocalDate
和LocalTime
,LocalDate
没法包含时间,LocalTime
没法包含日期。固然,LocalDateTime
才能同时包含日期和时间。
新接口更好用的缘由是考虑到了日期时间的操做,常常发生往前推或日后推几天的状况。用java.util.Date
配合Calendar
要写好多代码,并且通常的开发人员还不必定能写对。