TOC
Java 8 新增日期类基本使用介绍
Java 8 – Date and Time Operation
介绍
Java 8 新增许多日期操作类来替换原来的Date,Calendar,timestamp,SimpleDateFormat(线程不安全)。
新增类大致如下:
- 日期类
- Instant: 瞬时实例;
- LocalDate: 本地日期,不包含具体时间 例如:2014-01-14 可以用来记录生日、纪念日、加盟日等;
- LocalTime: 本地时间,不包含日期;
- LocalDateTime: 组合了日期和时间,但不包含时差和时区信息;
- ZonedDateTime: 最完整的日期时间,包含时区和相对UTC或格林威治的时差;
- 持续时间类
- Duration: 表示两个Instant间的一段时间;具有:纳秒值(小于一秒的部分),秒钟值(一共有几秒)
- Period: 表示两个LocalDate间的一段时间;内部使用三个int值分表表示年、月、
- 格式化和解析类
- DateTimeFormatter
日期类
LocalDate
public static void init() {
log.debug("LocalDate.MAX: "+LocalDate.MAX); //LocalDate.MAX: +999999999-12-31
log.debug("LocalDate.MIN: "+LocalDate.MIN); //LocalDate.MIN: -999999999-01-01
log.debug("LocalDate.of(2015, Month.SEPTEMBER,12): "+LocalDate.of(2015, Month.SEPTEMBER,12)); //LocalDate.of(2015, Month.SEPTEMBER,12): 2015-09-12
log.debug("LocalDate.now(): "+LocalDate.now()); //LocalDate.now(): 2018-09-09
}
public static void apiBaseUse() {
LocalDate localDate = LocalDate.of(2015,11,12);
log.debug("toString: "+localDate.toString()); //toString: 2015-11-12
log.debug("getYear: "+localDate.getYear()); //getYear: 2015
log.debug("getMonth: "+localDate.getMonth()); //getMonth: NOVEMBER
log.debug("getMonthValue: "+localDate.getMonthValue()); //getMonthValue: 11
log.debug("getDayOfWeek: "+localDate.getDayOfWeek()); //getDayOfWeek: THURSDAY
log.debug("getDayOfMonth: "+localDate.getDayOfMonth()); //getDayOfMonth: 12
log.debug("getDayOfYear: "+localDate.getDayOfYear()); //getDayOfYear: 316
log.debug("isLeapYear: "+localDate.isLeapYear()); //isLeapYear: false
log.debug("lengthOfMonth: "+localDate.lengthOfMonth()); //lengthOfMonth: 30
log.debug("lengthOfYear: "+localDate.lengthOfYear()); //lengthOfYear: 365
}
## 求两个日期的天数
public static long getBetweenDays(LocalDate d1,LocalDate d2) {
return Math.abs(d1.toEpochDay() - d2.toEpochDay());
}
方法 | 描述 |
---|---|
now,of | 根据当前时间或指定年月日来创建LocalDate对象 |
plusDays,plusWeeks,plusMonths,plusYears | 向当前对象添加天、周、月、年 |
minusDays,minusWeeks,minusMonths,plusYears | 向当前对象减去天、周、月、年 |
plus,minus | 添加或减少一个Duration或者Perid |
WithDayOfMonth,WithDayOfYear,withMonth,withYear | 将月份天数、年份天数、年份修改为指定的值,并返回一个新的LocalDate对象 |
getDayOfMonth | 获得月份天数(1~31) |
getDayOfYear | 获得年份天数(1~366) |
getDayOfWeek | 获得星期几 |
getMonth,getMonthValue | 获得月份,或者Month枚举值,或者1-12数字 |
getYear | 获得年份 |
isBefore,isAfter | 比较日期 |
isleapYear | 是否为闰年 |
LocalTime
public static void init() {
log.debug("LocalTime.MAX: "+ LocalTime.MAX); //LocalTime.MAX: 23:59:59.999999999
log.debug("LocalTime.MIDNIGHT: "+ LocalTime.MIDNIGHT); //LocalTime.MIDNIGHT: 00:00
log.debug("LocalTime.MIN: "+ LocalTime.MIN); //LocalTime.MIN: 00:00
log.debug("LocalTime.NOON: "+ LocalTime.NOON); //LocalTime.NOON: 12:00
}
public static void apiBasicUse() {
LocalTime time = LocalTime.of(7,20,10,110000000);
log.debug("time.getHour(): "+time.getHour()); //time.getHour(): 7
log.debug("time.getMinute(): "+time.getMinute()); //time.getMinute(): 20
log.debug("time.getSecond(): "+time.getSecond()); //time.getSecond(): 10
log.debug("time.getLong(ChronoField.MICRO_OF_DAY): "+ time.getLong(ChronoField.MICRO_OF_DAY)); //time.getLong(ChronoField.MICRO_OF_DAY): 26410110000
log.debug("time.getNano(): "+time.getNano()); //time.getNano(): 110000000
log.debug("time.plusHours(17): "+ time.plusHours(17)); //time.plusHours(17): 00:20:10.110
log.debug("time.plus(Duration.ofHours(17)): "+time.plus(Duration.ofHours(17))); //time.plus(Duration.ofHours(17)): 00:20:10.110
}
方法 | 描述 |
---|---|
now,of | 根据当前时间或指定年月日来创建LocalTime对象 |
plusHours,plusMinutes,plusSeconds,plusNanos | 向当前对象添加时、分秒、微秒 |
minusHours,minusMinutes,minusSeconds,minusNanos | 向当前对象减去时、分秒、微秒 |
plus,minus | 添加或减少一个Duration |
WithHour,WithMinute,withSecond,withNano | 将时、分、秒、微秒修改为指定的值,并返回一个新的LocalTime对象 |
getHour,getMinute,getSecond,getNano | 获取事件对象的时、分、秒、微秒 |
isBefore,isAfter | 比较时间 |
持续时间类
Duration
Duration表示秒、纳秒,分钟,小时和天数的持续时间
public static long getLivedDays() {
LocalDateTime birthday = LocalDateTime.of(
LocalDate.of(1990, Month.JANUARY, 1),
LocalTime.of(10, 10));
LocalDateTime deathDay = LocalDateTime.of(
LocalDate.of(2090, Month.JANUARY, 1),
LocalTime.of(10, 10));
return Duration.between(birthday, deathDay).toDays(); //36525
}
Period
Period表示年,月,日的时间差值。
public static Period getLivedDays() {
LocalDate birthday = LocalDate.of(1990, Month.JANUARY, 1);
LocalDate deathDay = LocalDate.of(2090, Month.JANUARY, 1);
return Period.between(birthday,deathDay); //36525
}
## 测试
@Test
public void getLivedDays() {
assertThat(PeriodDemo.getLivedDays().getYears()).isEqualTo(100);
assertThat(PeriodDemo.getLivedDays().getMonths()).isEqualTo(0);
assertThat(PeriodDemo.getLivedDays().getDays()).isEqualTo(0);
}
基本操作
Convert between LocalDate and LocalDateTime to java.util.Date
public static Date asDate(LocalDate localDate) {
return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
}
public static Date asDate(LocalDateTime localDateTime) {
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
public static LocalDate asLocalDate(Date date) {
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
}
public static LocalDateTime asLocalDateTime(Date date) {
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
}
Convert between LocalDate to java.sql.Date
public static java.sql.Date asDate(LocalDate localDate) {
return java.sql.Date.valueOf( localDate );
}
public static LocalDate asLocalDate(java.sql.Date date) {
return date.toLocalDate();
}
Convert between String to LocalDate
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
String dateString = "14/07/2018";
LocalDate localDateObj = LocalDate.parse(dateString, dateTimeFormatter); //String to LocalDate
String dateStr = localDateObj.format(dateTimeFormatter); //LocalDate to String
LocalDate localDate = LocalDate.parse( dateString ); ##defaul pattern yyyy-MM-dd
Java Convert Date or Timestamp Between Timezones
Convert ZonedDateTime between timezones
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
private static final String DATE_FORMAT = "dd-M-yyyy hh:mm:ss a z";
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
public static void main(String[] args) {
ZoneId fromTimeZone = ZoneId.of("Asia/Kolkata"); //Source timezone
ZoneId toTimeZone = ZoneId.of("America/New_York"); //Target timezone
LocalDateTime today = LocalDateTime.now(); //Current time
ZonedDateTime currentISTime = today.atZone(fromTimeZone); //Zoned date time at source timezone
ZonedDateTime currentETime = currentISTime.withZoneSameInstant(toTimeZone);//Zoned date time at target timezone
//Format date time - optional
System.out.println(formatter.format(currentISTime));
System.out.println(formatter.format(currentETime));
}
}
//Output:
14-7-2018 11:57:46 PM IST
14-7-2018 02:27:46 PM EDT
Convert Date between timezones
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Main {
static SimpleDateFormat FORMATTER = new SimpleDateFormat("MM/dd/yyyy 'at' hh:mma z");
public static void main(String[] args) {
TimeZone etTimeZone = TimeZone.getTimeZone("America/New_York"); //Target timezone
Date currentDate = new Date();
System.out.println(FORMATTER.format(currentDate)); //Date in current timezone
FORMATTER.setTimeZone(etTimeZone);
System.out.println(FORMATTER.format(currentDate)); //Date in target timezone
}
}
//Output:
07/15/2018 at 12:13AM IST
07/14/2018 at 02:43PM EDT
Convert Calendar between timezones
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
public class Main {
static SimpleDateFormat FORMATTER = new SimpleDateFormat("MM/dd/yyyy 'at' hh:mma z");
public static void main(String[] args) {
TimeZone istTimeZone = TimeZone.getTimeZone("Asia/Kolkata"); //Source timezone
TimeZone etTimeZone = TimeZone.getTimeZone("America/New_York"); //Target timezone
Calendar today = Calendar.getInstance(istTimeZone);
System.out.println(FORMATTER.format(today.getTime())); //07/15/2018 at 12:35AM IST
//Change timezone in formatter
FORMATTER.setTimeZone(etTimeZone);
System.out.println(FORMATTER.format(today.getTime())); //07/14/2018 at 03:05PM EDT
//OR calendar static methods
System.out.println(today.get(Calendar.HOUR)); //0
System.out.println(today.get(Calendar.MINUTE)); //37
System.out.println(today.get(Calendar.SECOND)); //9
//Change calendar timezone
today.setTimeZone(etTimeZone);
System.out.println(today.get(Calendar.HOUR)); //3
System.out.println(today.get(Calendar.MINUTE)); //7
System.out.println(today.get(Calendar.SECOND)); //9
}
}
Data Compare
Class: - java.time.LocalDate - java.time.LocalTime - java.time.LocalDateTime.
Method: - date1.isAfter( date2 ) – It returns true is date1 comes after date2; else false. - date1.isBefore( date2 ) – It returns true is date1 comes before date2; else false. - date1.compareTo( date2 ) – It returns ‘positive number’ is date1 comes after date2; else ‘negative number’. A value ‘0’ means both dates are equal.
public static void compareLocalDates() {
LocalDate todayLocalDate = LocalDate.now();
LocalDate pastLocalDate = LocalDate.of(2018, 10, 01);
DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String date1 = sdf.format(todayLocalDate);
String date2 = sdf.format(pastLocalDate);
//isAfter() Method
System.out.println(date1 + " is after " + date2 + " :: " + todayLocalDate.isAfter(pastLocalDate)); //true
//isBefore() Method
System.out.println(date2 + " is before " + date2 + " :: " + pastLocalDate.isBefore(todayLocalDate)); //true
//compareTo()
int dateDifference = todayLocalDate.compareTo(pastLocalDate);
System.out.println("Date diff : " + dateDifference);
if (dateDifference > 0)
System.out.println(date1 + " > " + date2); //prints
else if (dateDifference < 0)
System.out.println(date1 + " < " + date2); //does not print
else
System.out.println(date1 + " = " + date2); //does not print
}
## 结果
2018-10-18 is after 2018-10-01 :: true
2018-10-01 is before 2018-10-01 :: true
Date diff : 17
2018-10-18 > 2018-10-01
Writing custom TemporalAdjuster
public static void nextWorkDate() {
LocalDate today = LocalDate.now();
TemporalAdjuster nextWorkingDayAdjuster = TemporalAdjusters.ofDateAdjuster(localDate -> {
DayOfWeek dayOfWeek = localDate.getDayOfWeek();
if (dayOfWeek == DayOfWeek.FRIDAY) {
return localDate.plusDays(3);
} else if (dayOfWeek == DayOfWeek.SATURDAY) {
return localDate.plusDays(2);
}
return localDate.plusDays(1);
});
System.out.println(today.with(nextWorkingDayAdjuster));
}