1. Date类 1.1 对象创建 可以通过Date的两个构造函数来实现
Date( ) 获取当前日期和时间的Date对象 Date(long millisec) 其中的参数是从1970年1月1日起的毫秒数 代码示例:
1 2 3 4 5 6 7 8 9 10 11 import java.util.Date; public class DateDemo { public static void main (String args[]) { Date date = new Date(); System.out.println(date.toString()); } }
1.2 常用API boolean after(Date date);
若当调用此方法的Date对象在指定日期之后返回true,否则返回false。
boolean before(Date date)
若当调用此方法的Date对象在指定日期之前返回true,否则返回false。
int compareTo(Date date)
比较当调用此方法的Date对象和指定日期。两者相等时候返回0。调用对象在指定日期之前则返回负数。调用对象在指定日期之后则返回正数。
boolean equals(Object date)
当调用此方法的Date对象和指定日期相等时候返回true,否则返回false。
long getTime( )
返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数。
void setTime(long time)
用自1970年1月1日00:00:00 GMT以后time毫秒数设置时间和日期。
String toString( )
把此 Date 对象转换为以下形式的 String: dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue, Wed, Thu, Fri, Sat)。
1.3 日期比较 Java使用以下三种方法来比较两个日期:
使用 getTime() 方法获取两个日期(自1970年1月1日经历的毫秒数值),然后比较这两个值。 使用方法 before(),after() 和 equals()。 使用 compareTo() 方法,它是由 Comparable 接口定义的,Date 类实现了这个接口。 代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package time;import java.util.Date;public class DateDemo { public static void main (String[] args) throws InterruptedException { Date d1 = new Date(); Thread.sleep(20 ); Date d2 = new Date(); boolean flag = (d2.getTime() - d1.getTime())>0 ? true :false ; System.out.println("d2比d1大吗?" + flag); System.out.println("d2比d1大吗?" + d2.after(d1)); boolean cFlag = d2.compareTo(d1) > 0 ? true : false ; System.out.println("d2比d1大吗?" + cFlag); } }
1.4 格式化日期 代码示例:
1 2 3 4 Date date = new Date(); DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL); String dateStr = dateFormat.format(date); System.out.println(dateStr);
使用该类来格式化日期都是JDK自带的日期格式,DateFormat.FULL为其中一种格式化风格,其他风格可以查看API。
SimpleDateFormat是DateFormat的子类,可以自定义 日期的格式化风格
代码示例:
1 2 3 4 5 6 private static void simpleDateFormatDemo () { Date dNow = new Date( ); SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss" ); System.out.println("当前时间为: " + ft.format(dNow)); }
其中 yyyy 是完整的公元年,MM 是月份,dd 是日期,HH:mm:ss 是时、分、秒。 注意:有的格式大写,有的格式小写,例如 MM 是月份,mm 是分;HH 是 24 小时制,而 hh 是 12 小时制。
具体的日期和时间的格式化编码如下示:
1.4.3 使用parse方法解析字符串为时间 SimpleDateFormat 类有一些附加的方法,特别是parse(),它试图按照给定的SimpleDateFormat 对象的格式化存储来解析字符串。
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 private static void strToDate () { try { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd" ); String strDate = "2019-01-11" ; Date date = simpleDateFormat.parse(strDate); DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL); String newStrDate = dateFormat.format(date); System.out.println(newStrDate); } catch (ParseException e) { System.out.println("时间转换错误!" ); } }
2. Calendar类 Date有许多弊端和不足之处,无法满足特定需求。相比于Date,Calendar则强大得多。我们可以使用Calendar类设置和获取日期数据的特定部分,比如说小时,日,或者分钟。
2.1 Calendar实例获取 可以使用getInstance方法。
1 2 3 4 Calendar calendar = Calendar.getInstance(); String strDate = calendar.getTime().toString(); System.out.println(strDate);
2.2 Calendar类对象字段类型
特别注意:MONTH月份是从0开始计算的,也就是说0代表一月份,1代表二月份,以此类推;DAY_OF_WEEK规定了一个星期是从星期日开始的,1代表星期日,2代表星期一,以此类推。
2.2.1 Calendar对象特定部分的获取 下面是Calendar对象的特定部分进行获取的代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Calendar c1 = Calendar.getInstance(); int year = c1.get(Calendar.YEAR);System.out.println("year:" + year); int month = c1.get(Calendar.MONTH) + 1 ;System.out.println("month:" + month); int date = c1.get(Calendar.DATE);System.out.println("date:" + date); int hour = c1.get(Calendar.HOUR_OF_DAY);System.out.println("hour:" + hour); int minute = c1.get(Calendar.MINUTE);System.out.println("minute:" + minute); int second = c1.get(Calendar.SECOND);System.out.println("second:" + second); int day = c1.get(Calendar.DAY_OF_WEEK);System.out.println("day:" + day);
输出结果:
1 2 3 4 5 6 7 year:2019 month:1 date:10 hour:11 minute:9 second:7 day:5
2.2.2 Calendar类对象信息的设置 set设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public void setCalendarTime () { Calendar c1 = Calendar.getInstance(); c1.set(2019 , 5 , 25 ); myPrintln(c1); c1.set(Calendar.YEAR, 2018 ); myPrintln(c1); c1.set(Calendar.MONTH, 10 ); myPrintln(c1); c1.set(Calendar.DATE, 31 ); myPrintln(c1); } public void myPrintln (Calendar c1) { Date time = c1.getTime(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss" ); System.out.println(format.format(time)); }
set方法有两种,一种是直接设置日期时间,另一种则是设置日期时间的某一特定部分。 注意:在设置月份的时候,如果设置的月份为负数或者大于12,则会对应的更改当前年份。日期和具体时间同理。
add设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public void addCalendarTime () { Calendar c1 = Calendar.getInstance(); myPrintln(c1); c1.add(Calendar.MONTH, 13 ); myPrintln(c1); c1.add(Calendar.DATE, 23 ); myPrintln(c1); } public void myPrintln (Calendar c1) { Date time = c1.getTime(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss" ); System.out.println(format.format(time)); }
其他字段属性的add的意义以此类推。
3. GregorianCalendar类 Calendar类实现了公历日历,GregorianCalendar是Calendar类的一个具体实现。
3.1 GregorianCalendar对象的创建
3.2 GregorianCalendar常用方法 GregorianCalendar类的常用方法主要是使用其父类Calendar的方法。
下面讲一下其比较特殊常用的方法:
boolean isLeapYear(int year);
确定给定的年份是否为闰年。如果给定的年份是闰年,则返回 true。如果要指定 BC 年份,必须给定 1 - 年份。例如,指定 -3 为 BC 4 年
Calendar的功能还不够给力,它的实现是易便的,并且它没有处理诸如闰秒这样的缺。所以Java SE 8中引入的java.time API,它修正了过去的缺陷。
下面开始讲述关于Java SE 8的一些关于时间日期的新特性,包括java.time.*;包里的Instant,LocalDate,LocalTime 和 LocalDateTime等类。
4. Instant类 所谓的 Instant 类代表的是时间线上的某个时间点(有点像 java.util.Date),它是精确到纳秒(而不是像旧版本的Date精确到毫秒),是计算机相关的时间。 起点是格林威治时间(GMT)1970-01-01:00:00(实际上Instant 取代原有的 Date 类)。 时间从起点开始向前移动,每天为86,400秒。
4.1 对象创建 1 2 3 4 5 Instant instant = Instant.now(); Instant instant = Instant.ofEpochSecond(1547102726 ); Instant instant = Instant.ofEpochMilli(1564564121354544 );
注意:Instant表示的时间是UTC时区的时间,即世界标准时间(比中国时差为-8个小时)
4.2 获取时间 Instant 对象中包含两个内部属性用于表示当前的时间:即距离初始时间的秒钟数+在当前一秒内的第几纳秒,他们的组合表达了当前时间点。
1 2 3 Instant instant = Instant.now(); long second = instant.getEpochSecond();int nano = instant.getNano();
4.3 Instant的操作 Instant类与许多用于时间的算术运算方法,比如plusNanos,plusMillis等等。下面仅仅演示plusMillis(long millisToAdd)方法。其他方法可以查看API文档。
1 2 3 4 5 6 7 8 Instant startInstant = Instant.now(); Thread.sleep(200 ); Instant endInstant = Instant.now(); Instant plusMillis = startInstant.plusMillis(200 ); System.out.println(plusMillis); System.out.println(endInstant);
输出结果:
1 2 2019-01-10T07:09:00.763Z 2019-01-10T07:09:00.764Z
5. Duration类 Duration类用来计算两个时刻之间的时间量
5.1 常用方法 static Duration between(Temporal startInclusive,Temporal endExclusive);
计算两个时间的间隔,默认的单位是秒
示例:
1 2 3 4 5 6 Instant startInstant = Instant.now(); Thread.sleep(200 ); Instant endInstant = Instant.now(); Duration duration = Duration.between(startInstant, endInstant); System.out.println(duration.toMillis());
其他常用方法基本与Instant类一样。
注意:Instant和Duration类都是不可修改类 ,所以诸如multipliedBy和munus这样的方法都会返回一个新的实例。
6. LocalDate类 LocalDate类指的是本地时间,它包含年、月、日的日期,也就是说它不包含时间,只是单纯的年月日。
6.1 对象的创建 主要使用now方法和of方法
1 2 3 4 5 6 7 8 9 10 11 12 LocalDate today = LocalDate.now(); LocalDate crischristmas = LocalDate.of(2017 , 12 , 25 ); LocalDate endOfFeb = LocalDate.parse("2014-02-28" );
6.2 常用日期操作 6.2.1 加法运算 plusDays,plusWeeks,plusMonths,plusYears,plus等方法 即在当前的LocalDate上加上一定量的天、星期、月或年等。
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public void dateCalculate () { LocalDate programmingDay = LocalDate.of(2014 , 1 , 1 ).plusDays(255 ); System.out.println(programmingDay); LocalDate newYearDay = programmingDay.plusYears(5 ); System.out.println(newYearDay); LocalDate newMonthDay = newYearDay.plusMonths(6 ); System.out.println(newMonthDay); }
我们知道在两个Insatnt之间的时长是Duration,而用于本地时期的等价物是Period,它表示的是流逝的年、月或日的数量。plus方法涉及到该类,下面以代码的方式说明。
1 2 3 4 LocalDate birthday = LocalDate.of(1997 , 4 , 19 ); LocalDate nextYearBirthday = birthday.plus(Period.ofYears(1 )); System.out.println(nextYearBirthday);
日期的减法运算 和加法运算基本运算,不过多说明。
6.2.2 util方法 代码示例:
1 2 3 4 5 6 7 8 LocalDate today = LocalDate.now(); LocalDate birthday = LocalDate.of(1997 , 4 , 19 ); System.out.println("距离出生日期的日期时长为:" + birthday.until(today)); System.out.println("距离出生日期的天数为:" + birthday.until(today, ChronoUnit.DAYS));
运行结果:
1 2 距离出生日期的日期时长为:P21Y8M23D 距离出生日期的天数为:7937
6.2.3 其他方法 注意:DayOfWeek.MONDAY的枚举值为1,而DayOfWeek.SUNDAY的枚举值为7。这与Calendar类周日为1,周一为2有所不同。
代码示例:
1 2 3 4 5 6 7 8 9 10 11 private void weekDayDemo () { LocalDate today = LocalDate.now(); System.out.println(today); DayOfWeek dayOfWeek = today.getDayOfWeek(); System.out.println(dayOfWeek); System.out.println(dayOfWeek.getValue()); }
其他方法查看API文档。
7. TemporalAdjusters类 该类为日期调整器,提供大量的用于常见调整的静态方法。
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public void temporalAdjustersDemo () { LocalDate today = LocalDate.now(); LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth()); System.out.println(firstDayOfThisMonth); LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth()); System.out.println(lastDayOfThisMonth); LocalDate firstMondayOf2017 = LocalDate.parse("2017-01-01" ).with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); System.out.println(firstMondayOf2017); LocalDate nextMonday = today.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); System.out.println(nextMonday); LocalDate theThirdMonday = today.with(TemporalAdjusters.dayOfWeekInMonth(3 , DayOfWeek.MONDAY)); System.out.println(theThirdMonday); }
8. LocalTime类 与LocalDate仅仅包含日期不同是,LocalTime仅包含时间部分。LocalTime表示当前时刻,例如 15:30:21。
8.1 对象的创建 使用now方法创建当前时间的实例1 2 3 4 5 LocalTime rightTime = LocalTime.now(); System.out.println("当前时间为:" + rightTime); LocalTime bedTime = LocalTime.of(23 , 12 , 30 , 4560 << 9 ); System.out.println("睡觉时间为:" + bedTime);
8.2 常见操作 LocalTime的许多时间的操作方法基本与LocalDate相同,这里不再赘述。详细参见API文档。
9. LocalDateTime类 LocalDateTime类相当于LocalDate类与LocalTime的结合,它可以表示日期和时间,适合存储固定时区的时间点。
9.1 对象的创建 1 2 3 4 5 LocalDateTime dateTime = LocalDateTime.now(); System.out.println(dateTime); LocalDateTime myDateTime = LocalDateTime.of(2018 , 9 , 23 , 12 , 45 ); System.out.println(myDateTime);
9.2 常见操作 9.2.1 间隔运算 使用Duration进行 day,hour,minute,second等的计算 使用Period进行Year,Month的计算
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public void tiemCalculate () { LocalDateTime dateTime = LocalDateTime.now(); LocalDateTime birthdateTime = LocalDateTime.of(1997 , 4 , 19 , 4 , 21 ); Duration duration = Duration.between(birthdateTime,dateTime); long days = duration.toDays(); long hours = duration.toHours(); long minutes = duration.toMinutes(); System.out.println("days:" + days + " | hours:" + hours + " | minutes:" + minutes); Period period = Period.between(birthdateTime.toLocalDate(), dateTime.toLocalDate()); int years = period.getYears(); long totalMonths = period.toTotalMonths(); System.out.println("years:" + years + " | totalMonths:" + totalMonths); }
运行结果:
1 2 days:7937 | hours:190495 | minutes:11429737 years:21 | totalMonths:260
9.2.2 其他方法 LocalDateTime与LocalDate和LocalTime的方法有许多相似之处,如时间日期的运算、比较、获取和设置等,在这里不再赘述。
10. 格式化与解析 格式化与解析所涉及到的类主要是DateTimeFormater类,它是用来替代java.util.DateFormat类的。
10.1 格式化 DateTimeFormater类提供了三种用于打印日期/时间的格式器:
预定义的格式器(具体参见API文档) Locale相关的格式器 带有定制模式的格式器 代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 DateTimeFormatter[] formatters = new DateTimeFormatter[]{ DateTimeFormatter.ISO_LOCAL_DATE, DateTimeFormatter.ISO_LOCAL_TIME, DateTimeFormatter.ISO_LOCAL_DATE_TIME, DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM), DateTimeFormatter.ofLocalizedTime(FormatStyle.LONG), DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG), DateTimeFormatter.ofPattern("Gyyyy%%MMM%%dd HH:mm:ss" ) }; LocalDateTime date = LocalDateTime.now(); for (int i = 0 ; i < formatters.length ; i++) { System.out.println(date.format(formatters[i])); System.out.println(formatters[i].format(date)); } }
运行结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 2019-01-11 2019-01-11 11:40:29.895 11:40:29.895 2019-01-11T11:40:29.895 2019-01-11T11:40:29.895 2019年1月11日 星期五 11:40:29 2019年1月11日 星期五 11:40:29 上午11时40分29秒 上午11时40分29秒 2019年1月11日 2019年1月11日 公元2019%%一月%%11 11:40:29 公元2019%%一月%%11 11:40:29
10.2 字符串解析 代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 String str1 = "2014==04==12 01时06分09秒" ; DateTimeFormatter fomatter1 = DateTimeFormatter .ofPattern("yyyy==MM==dd HH时mm分ss秒" ); LocalDateTime dt1 = LocalDateTime.parse(str1, fomatter1); System.out.println(dt1); String str2 = "2014$$$四月$$$13 20小时" ; DateTimeFormatter fomatter2 = DateTimeFormatter .ofPattern("yyy$$$MMM$$$dd HH小时" ); LocalDateTime dt2 = LocalDateTime.parse(str2, fomatter2); System.out.println(dt2);
11. Java 8 日期/时间设计原则 Java 8 日期/时间 API 是 JSR-310 的实现,它的实现目标是克服旧的日期时间实现中所有的缺陷,新的日期/时间API 的一些设计原则是:
不变性:新的日期/时间 API 中,所有的类都是不可变的 ,这对多线程环境有好处。 关注点分离:新的 API 将人可读的日期时间和机器时间(unix timestamp)明确分离,它为日期(Date)、时间(Time)、日期时间(DateTime)、时间戳(unix timestamp)以及时区定义了不同的类。 清晰:在所有的类中,方法都被明确定义用以完成相同的行为。举个例子,要拿到当前实例我们可以使用 now()方法,在所有的类中都定义了 format()和 parse()方法,而不是像以前那样专门有一个独立的类。为了更好的处理问题,所有的类都使用了工厂模式和策略模式,一旦你使用了其中某个类的方法,与其他类协同工作并不困难。 实用操作:所有新的日期/时间 API 类都实现了一系列方法用以完成通用的任务,如:加、减、格式化、解析、从日期/时间中提取单独部分,等等。 可扩展性:新的日期/时间 API 是工作在 ISO-8601 日历系统上的,但我们也可以将其应用在非 ISO 的日历上。 12. 总结 java关于时间日期的内容还有很多,比如不同类之间的转换问题以及相互应用的问题等等。另外,还有关于时区时间的内容等还没有讲到。
这部分内容错综复杂,暂时就总结到这了。应该多在具体的实践中加深这部分内容的理解和应用。
参考文章:https://blog.csdn.net/lamp113/article/details/79049528 http://www.runoob.com/java/java-date-time.html http://www.runoob.com/java/java8-datetime-api.html