Java8之日期和时间(四)

Java 8新增了LocalDateLocalTime接口,为什么要搞一套全新的处理日期和时间的API。因为旧的java.util.Date实在是太难用了。

java.util.Date月份从0开始,一月是0,十二月是11,变态吧!java.time.LocalDate月份和星期都改成了enum,就不可能再用错了。

java.util.DateSimpleDateFormatter都不是线程安全的,而LocalDateLocalTime和最基本的String一样,是不变类型,不但线程安全,而且不能修改。

java.util.Date是一个“万能接口”,它包含日期、时间,还有毫秒数,如果你只想用java.util.Date存储日期,或者只存储时间,那么,只有你知道哪些部分的数据是有用的,哪些部分的数据是不能用的。在新的Java 8中,日期和时间被明确划分为LocalDateLocalTimeLocalDate无法包含时间,LocalTime无法包含日期。当然,LocalDateTime才能同时包含日期和时间。

新接口更好用的原因是考虑到了日期时间的操作,经常发生往前推或往后推几天的情况。用java.util.Date配合Calendar要写好多代码,而且一般的开发人员还不一定能写对。

 

LocalDate、 LocalTime、LocalDateTime 类的实例是别表示使用ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。

1. LocalDate

getYear()    int    获取当前日期的年份

getMonth()    Month    获取当前日期的月份对象

getMonthValue()    int    获取当前日期是第几月

getDayOfWeek()    DayOfWeek    表示该对象表示的日期是星期几

getDayOfMonth()    int    表示该对象表示的日期是这个月第几天

getDayOfYear()    int    表示该对象表示的日期是今年第几天

withYear(int year)    LocalDate    修改当前对象的年份

withMonth(int month)    LocalDate    修改当前对象的月份

withDayOfMonth(int dayOfMonth)    LocalDate    修改当前对象在当月的日期

isLeapYear()    boolean    是否是闰年

lengthOfMonth()    int    这个月有多少天

lengthOfYear()    int    该对象表示的年份有多少天(365或者366)

plusYears(long yearsToAdd)    LocalDate    当前对象增加指定的年份数

plusMonths(long monthsToAdd)    LocalDate    当前对象增加指定的月份数

plusWeeks(long weeksToAdd)    LocalDate    当前对象增加指定的周数

plusDays(long daysToAdd)    LocalDate    当前对象增加指定的天数

minusYears(long yearsToSubtract)    LocalDate    当前对象减去指定的年数

minusMonths(long monthsToSubtract)    LocalDate    当前对象减去注定的月数

minusWeeks(long weeksToSubtract)    LocalDate    当前对象减去指定的周数

minusDays(long daysToSubtract)    LocalDate    当前对象减去指定的天数

compareTo(ChronoLocalDate other)    int    比较当前对象和other对象在时间上的大小,返回值如果为正,则当前对象时间较晚,

isBefore(ChronoLocalDate other)    boolean    比较当前对象日期是否在other对象日期之前 <

isAfter(ChronoLocalDate other)    boolean    比较当前对象日期是否在other对象日期之后 >

isEqual(ChronoLocalDate other)    boolean    比较两个日期对象是否相等

// 取当前日期:
LocalDate today = LocalDate.now(); // -> 2014-12-24
// 根据年月日取日期,12月就是12:
LocalDate crischristmas = LocalDate.of(2014, 12, 25); // -> 2014-12-25
// 根据字符串取:
LocalDate endOfFeb = LocalDate.parse("2014-02-28"); // 严格按照ISO yyyy-MM-dd验证,02写成2都不行,当然也有一个重载方法允许自己定义格式
LocalDate.parse("2014-02-29"); // 无效日期无法通过:DateTimeParseException: Invalid date

日期转换经常遇到,比如:

// 取本月第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

2. LocalTime

LocalTime只包含时间,以前用java.util.Date怎么才能只表示时间呢?答案是,假装忽略日期。

LocalTime包含毫秒:

LocalTime now = LocalTime.now(); // 11:09:09.240

你可能想清除毫秒数:

LocalTime now = LocalTime.now().withNano(0)); // 11:09:09

构造时间也很简单:

LocalTime zero = LocalTime.of(0, 0, 0); // 00:00:00
LocalTime mid = LocalTime.parse("12:00:00"); // 12:00:00

时间也是按照ISO格式识别,但可以识别以下3种格式:

  • 12:00
  • 12:01:02
  • 12:01:02.345

 

JDBC

最新JDBC映射将把数据库的日期类型和Java 8的新类型关联起来:

SQL -> Java
--------------------------
date -> LocalDate
time -> LocalTime
timestamp -> LocalDateTime

再也不会出现映射到java.util.Date其中日期或时间某些部分为0的情况了。

 

3.LocalDateTime

LocalDateTime类是Java 8中日期时间功能里,用于表示当地的日期与时间的类,它的值是无时区属性的。你可以将其视为Java 8中LocalDate与LocalTime两个类的结合。LocalDateTime类的值是不可变的,所以其计算方法会返回一个新的LocalDateTime实例。

 

创建一个LocatDateTime实例
可以通过LocalDateTime的静态工厂方法来创建LocalDateTime实例。以下举例使用now()方法创建:
LocalDateTime localDateTime = LocalDateTime.now();
另一种方式是使用指定的年月日、时分秒、纳秒来新建对象:
LocalDateTime localDateTime2 = LocalDateTime.of(2015, 11, 26, 13, 55, 36, 123);

 

 

 

示例:

@Test
public void test1(){
		LocalDateTime ldt = LocalDateTime.now();
		System.out.println(ldt);
		LocalDateTime ld2 = LocalDateTime.of(2016, 11, 21, 10, 10, 10);
		System.out.println(ld2);
		LocalDateTime ldt3 = ld2.plusYears(20);
		System.out.println(ldt3);
		LocalDateTime ldt4 = ld2.minusMonths(2);
		System.out.println(ldt4);
		System.out.println(ldt.getYear());
		System.out.println(ldt.getMonthValue());
		System.out.println(ldt.getDayOfMonth());
		System.out.println(ldt.getHour());
		System.out.println(ldt.getMinute());
		System.out.println(ldt.getSecond());
}

 

 

 

4.Instant : 时间戳

用于“时间戳”的运算。它是以Unix元年(传统的设定为UTC时区1970年1月1日午夜时分)开始所经历的描述进行运算

@Test
public void test2(){
		Instant ins = Instant.now();  //默认使用 UTC 时区
		System.out.println(ins);
		
		OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8));
		System.out.println(odt);
		
		System.out.println(ins.getNano());
		
		Instant ins2 = Instant.ofEpochSecond(5);
		System.out.println(ins2);
}

 

 

 

5.Duration 和 Period

Duration:用于计算两个“时间”间隔
Period:用于计算两个“日期”间隔

     //Duration : 用于计算两个“时间”间隔
	//Period : 用于计算两个“日期”间隔
	@Test
	public void test3(){
		Instant ins1 = Instant.now();
		System.out.println("--------------------");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
		}
		Instant ins2 = Instant.now();
		Duration	duration=Duration.between(ins1, ins2);
		System.out.println( duration);
		System.out.println(  duration.getNano());
		System.out.println( duration.getSeconds());
		System.out.println( duration.getUnits());
		System.out.println("----------------------------------");
		LocalDate ld1 = LocalDate.now();
		LocalDate ld2 = LocalDate.of(2011, 1, 1);
		
		Period pe = Period.between(ld2, ld1);
		System.out.println(pe.getYears());
		System.out.println(pe.getMonths());
		System.out.println(pe.getDays());
	}

 

 

 

 

 

6.日期的操纵

TemporalAdjuster :时间校正器。有时我们可能需要获取例如:将日期调整到“下个周日”等操作。

TemporalAdjusters: 该类通过静态方法提供了大量的常用TemporalAdjuster 的实现

 TemporalAdjuster : 时间校正器
	@Test
	public void test4(){
	LocalDateTime ldt = LocalDateTime.now();
		System.out.println(ldt);
		LocalDateTime ldt2 = ldt.withDayOfMonth(10);
		System.out.println(ldt2);
		LocalDateTime ldt3 = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
		System.out.println(ldt3);
		//自定义:下一个工作日
		LocalDateTime ldt5 = ldt.with((l) -> {
			LocalDateTime ldt4 = (LocalDateTime) l;
			DayOfWeek dow = ldt4.getDayOfWeek();
			if(dow.equals(DayOfWeek.FRIDAY)){
				return ldt4.plusDays(3);
			}else if(dow.equals(DayOfWeek.SATURDAY)){
				return ldt4.plusDays(2);
			}else{
				return ldt4.plusDays(1);
			}
		});
		System.out.println(ldt5);
	}

 

 

 

7.解析与格式化

java.time.format.DateTimeFormatter 类:该类提供了三种

格式化方法:

 预定义的标准格式

 语言环境相关的格式

 自定义的格式

	@Test
	public void test5(){
		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E");
		LocalDateTime ldt = LocalDateTime.now();
		String strDate = ldt.format(dtf);
		System.out.println(strDate);
		LocalDateTime newLdt = ldt.parse(strDate, dtf);
		System.out.println(newLdt);
	}

 

8.时区的处理

 

Java8 中加入了对时区的支持,带时区的时间为分别为:ZonedDate、 ZonedTime、 ZonedDateTime
其中每个时区都对应着 ID,地区ID都为 “{区域}/{城市}”的格式
例如 : Asia/Shanghai 等
ZoneId:该类中包含了所有的时区信息
getAvailableZoneIds() : 可以获取所有时区时区信息
of(id) : 用指定的时区信息获取 ZoneId 对象 

@Test
public void test7(){
		LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
		System.out.println(ldt);
		
		ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("US/Pacific"));
		System.out.println(zdt);
}

 

Date与LocalDateTime、LocalDate、LocalTime互转

https://www.cnblogs.com/exmyth/p/6425878.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值