Java 8 新特性:日期处理
1. Java 8 日期处理新特性
Java 8基于ISO标准日期系统,提供了java.time包来处理时间日期,且该包下的所有类都是不可变类型而且线程安全。
2. 关键类
- Instant:瞬时实例。
- LocalDate:本地日期,不包含具体时间 例如:2014-01-14 可以用来记录生日、纪念日、加盟日等。
- LocalTime:本地时间,不包含日期。
- LocalDateTime:组合了日期和时间,但不包含时差和时区信息。
- ZonedDateTime:最完整的日期时间,包含时区和相对UTC或格林威治的时差。
新API还引入了 ZoneOffSet 和 ZoneId 类,解决时区问题。
对用于解析和格式化时间的 DateTimeFormatter 类也进行了优化。
3. 示例代码
1 import java.time.Clock; 2 import java.time.Instant; 3 import java.time.LocalDate; 4 import java.time.LocalDateTime; 5 import java.time.LocalTime; 6 import java.time.Month; 7 import java.time.MonthDay; 8 import java.time.OffsetDateTime; 9 import java.time.Period; 10 import java.time.Year; 11 import java.time.YearMonth; 12 import java.time.ZoneId; 13 import java.time.ZoneOffset; 14 import java.time.ZonedDateTime; 15 import java.time.format.DateTimeFormatter; 16 import java.time.temporal.ChronoUnit; 17 import java.util.Date; 18 19 import org.junit.Test; 20 21 /** 22 * Java 8 日期时间单元测试 23 * 24 * @author CL 25 * 26 */ 27 public class TestDateTime { 28 29 /** 30 * 测试当前时间 31 */ 32 @Test 33 public void testCurrentDate() { 34 LocalDate localDate = LocalDate.now(); 35 System.out.printf("当前时间(不包含时间): %s \n", localDate); 36 37 Date date = new Date(); 38 System.out.printf("当前时间(包含时间): %s \n", date); 39 } 40 41 /** 42 * 测试详细日期,获取年、月、日 43 */ 44 @Test 45 public void testDetailsDate() { 46 LocalDate today = LocalDate.now(); 47 int year = today.getYear(); 48 int month = today.getMonthValue(); 49 int day = today.getDayOfMonth(); 50 System.out.printf("今天是:%s 年 %s 月 %s 日", year, month, day); 51 } 52 53 /** 54 * 测试特殊日期 55 */ 56 @Test 57 public void testSpecialDate() { 58 LocalDate specialDate = LocalDate.of(2018, 5, 12); 59 System.out.printf("%s 是个特殊的日子!", specialDate); 60 } 61 62 /** 63 * 测试周期日期 64 */ 65 @Test 66 public void testCalculationDate() { 67 LocalDate today = LocalDate.now(); 68 LocalDate laborDay = LocalDate.of(2020, 5, 1); 69 70 MonthDay currMonthDay = MonthDay.from(today); 71 MonthDay laborMonthDay = MonthDay.of(laborDay.getMonthValue(), laborDay.getDayOfMonth()); 72 73 if (currMonthDay.equals(laborMonthDay)) { 74 System.out.println("今天是劳动节!"); 75 } else { 76 System.out.println("今天不是劳动节!"); 77 } 78 } 79 80 /** 81 * 测试当前时间 82 */ 83 @Test 84 public void testCurrentTime() { 85 LocalTime localTime = LocalTime.now(); 86 System.out.printf("当前时间是:%s", localTime); 87 } 88 89 /** 90 * 测试当前日期时间 91 */ 92 @Test 93 public void testCurrentDateTime() { 94 LocalDateTime localDateTime = LocalDateTime.now(); 95 System.out.printf("当前日期时间是:%s", localDateTime); 96 } 97 98 /** 99 * 测试加减日期时间 100 */ 101 @Test 102 public void testMinusPlusDateTime() { 103 LocalDate localDate = LocalDate.now(); 104 LocalTime localTime = LocalTime.now(); 105 System.out.printf("两小时前的时间是:%s \n", localTime.minusHours(2L)); 106 System.out.printf("两小时后的时间是:%s \n", localTime.plusHours(2L)); 107 System.out.printf("一周前的日期是:%s \n", localDate.minus(1L, ChronoUnit.WEEKS)); 108 System.out.printf("一周后的日期是:%s \n", localDate.plus(1L, ChronoUnit.WEEKS)); 109 System.out.printf("一年前的日期是:%s \n", localDate.minus(1L, ChronoUnit.YEARS)); 110 System.out.printf("一年后的日期是:%s \n", localDate.plus(1L, ChronoUnit.YEARS)); 111 } 112 113 /** 114 * 测试时钟类 115 */ 116 @Test 117 public void testClock() { 118 // 根据系统时间返回当前UTC 119 Clock systemUTC = Clock.systemUTC(); 120 System.out.printf("当前UTC: %s \n", systemUTC); 121 122 // 根据系统时区返回当前时区 123 Clock systemDefaultZone = Clock.systemDefaultZone(); 124 System.out.printf("当前时区: %s \n", systemDefaultZone); 125 } 126 127 /** 128 * 测试判断是否为前后日期 129 */ 130 @Test 131 public void testBeforeOrAfterDate() { 132 LocalDate today = LocalDate.now(); 133 134 LocalDate yesterday = today.minus(1L, ChronoUnit.DAYS); 135 if (yesterday.isBefore(today)) { 136 System.out.printf("%s 是今天之前的日期! \n", yesterday); 137 } 138 139 LocalDate tomorrow = today.plus(1L, ChronoUnit.DAYS); 140 if (tomorrow.isAfter(today)) { 141 System.out.printf("%s 是今天之后的日期! \n", tomorrow); 142 } 143 } 144 145 /** 146 * 测试指定时区日期时间 147 */ 148 @Test 149 public void testZoneTime() { 150 LocalDateTime localDateTime = LocalDateTime.now(); 151 152 ZoneId america = ZoneId.of("America/New_York"); 153 ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, america); 154 System.out.printf("当前日期时间在指定时区的日期时间为: %s", zonedDateTime); 155 } 156 157 /** 158 * 测试具体时区时间 159 */ 160 @Test 161 public void testZoneOffset() { 162 LocalDateTime localDateTime = LocalDateTime.of(Year.now().getValue(), Month.FEBRUARY, 1, 12, 30); 163 ZoneOffset zoneOffset = ZoneOffset.of("+08:00"); 164 165 OffsetDateTime offsetDateTime = OffsetDateTime.of(localDateTime, zoneOffset); 166 System.out.printf("与当前时区指定时间相差8小时的时区时间为:%s", offsetDateTime); 167 } 168 169 /** 170 * 测试天数 171 */ 172 @Test 173 public void testLengDays() { 174 YearMonth yearMonth = YearMonth.now(); 175 System.out.printf("今天是 %s 年 %s 月,本年共有 %s 天,本月共有 %s 天", yearMonth.getYear(), yearMonth.getMonthValue(), 176 yearMonth.lengthOfYear(), yearMonth.lengthOfMonth()); 177 } 178 179 /** 180 * 测试闰年 181 */ 182 @Test 183 public void testLeapYear() { 184 LocalDate today = LocalDate.now(); 185 if (today.isLeapYear()) { 186 System.out.printf("%s 年是闰年!", today.getYear()); 187 } else { 188 System.out.printf("%s 年不是闰年!", today.getYear()); 189 } 190 } 191 192 /** 193 * 测试计算时间间隔天数 194 */ 195 @Test 196 public void testCalcDays() { 197 LocalDate today = LocalDate.now(); 198 LocalDate nextWeek = today.plus(1L, ChronoUnit.WEEKS); 199 LocalDate nextMonth = today.plus(1L, ChronoUnit.MONTHS); 200 LocalDate nextYear = today.plus(1L, ChronoUnit.YEARS); 201 LocalDate anyDate = LocalDate.of(2022, 8, 8); 202 203 Period periodOfNextWeek = Period.between(today, nextWeek); 204 System.out.printf("%s 和 %s 之间距离 %s 年 %s 月 %s 天 \n", today, nextWeek, periodOfNextWeek.getYears(), 205 periodOfNextWeek.getMonths(), periodOfNextWeek.getDays()); 206 207 Period periodOfNextMonth = Period.between(today, nextMonth); 208 System.out.printf("%s 和 %s 之间距离 %s 年 %s 月 %s 天 \n", today, nextWeek, periodOfNextMonth.getYears(), 209 periodOfNextMonth.getMonths(), periodOfNextMonth.getDays()); 210 211 Period periodOfNextYear = Period.between(today, nextYear); 212 System.out.printf("%s 和 %s 之间距离 %s 年 %s 月 %s 天 \n", today, nextWeek, periodOfNextYear.getYears(), 213 periodOfNextYear.getMonths(), periodOfNextYear.getDays()); 214 215 Period periodOfAnyDate = Period.between(today, anyDate); 216 System.out.printf("%s 和 %s 之间距离 %s 年 %s 月 %s 天 \n", today, anyDate, periodOfAnyDate.getYears(), 217 periodOfAnyDate.getMonths(), periodOfAnyDate.getDays()); 218 } 219 220 /** 221 * 测试当前时间戳 222 */ 223 @Test 224 public void testTimestamp() { 225 Instant timestamp = Instant.now(); 226 System.out.printf("当前时间戳是:%s", timestamp); 227 } 228 229 /** 230 * 测试格式化日期时间 231 */ 232 @Test 233 public void testFormatDateTime() { 234 String date = "20080808"; 235 LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.BASIC_ISO_DATE); 236 System.out.printf("%s 格式化后为: %s \n", date, localDate); 237 238 String dateTime = "2020-01-01T12:30"; 239 LocalDateTime localDateTime = LocalDateTime.parse(dateTime, DateTimeFormatter.BASIC_ISO_DATE); 240 System.out.printf("%s 格式化后为: %s \n", dateTime, localDateTime); 241 } 242 }