Java中常见时间类的使用

模拟场景

针对于常用的操作API,比如流操作(字符流、字节流),时间操作等,仅仅了解概念性的定义终究是无法了解该类的用途和使用方式;这种情况在使用的时候便一脸茫然,脑海中映射不到对应的知识点。
本篇博客将通过一个简单的应用场景来体会这两个类的使用。

项目开发阶段,有一个关于下单发货的需求:
如果今天下午三点前进行下单,那么发货时间是明天
如果今天下午三点后机型下单,那么发货时间是后天
如果被确定的发货时间是周日的话,那么在此时间上再加一天为最终发货时间

牛刀小试( java 原始)

整体逻辑:主函数创建下单时间,调用函数进行逻辑判断,返回最终的发货时间。
整理代码如下(主函数不在列举):

	private static Date sendDateTime(String orderTime) throws ParseException {
		/**
		 * 1:
		 * 1.1:实例化一个date为今天下午三点
		 * 2:判断date是否大于今天下午三点,定义一个发货时间
		 * 2.1:如果不大于的话,则发货时间是明天
		 * 2.2:如果大于的话,则发货时间是后天
		 * 3:判断发货时间是否是周日,
		 * 3.1:如果不大于的话,则发货时间不变
		 * 3.2:如果大于的话,则发货时间再加一天
		 *
		 */
		// 获取订单时间
		DateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date orderDateTime = format.parse(orderTime);
		
		// 获取今天下午三点,这里计算有问题
		Calendar equalInstance = Calendar.getInstance();
		equalInstance.set(Calendar.HOUR_OF_DAY,15);
		equalInstance.set(Calendar.MINUTE, 0);
		equalInstance.set(Calendar.SECOND, 0);
		Date orderEqualTime = equalInstance.getTime();
		
		// 创建预下单时间
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(orderDateTime);

		// 判断订单时间是否大于今天下午三点
		boolean isMoreThan = orderDateTime.after(orderEqualTime);
		if(isMoreThan){
		//	发货时间是后天(订单时间加两天)
			calendar.add(Calendar.DATE,2);
		}else{
		//	发货时间是明天(订单时间加一天)
			calendar.add(Calendar.DATE,1);
		}
		Date preShipTime = calendar.getTime();
		return skipTime(preShipTime);
	}
	private static Date skipTime(Date date){
		Calendar instance = Calendar.getInstance();
		instance.setTime(date);
		// 外国的习俗是周末是一周的第一天,在java8以及JodaTime中已经恢复成正常的周末顺序
		int preWeekDay = instance.get(Calendar.DAY_OF_WEEK);
		// 因为是今天,所以我拿周二来判断,而不是周日
		if(preWeekDay==Calendar.SUNDAY){
			instance.add(Calendar.DATE,1);
		}
		return instance.getTime();
	}

第三方库使用(Joda-Time)

	private static DateTime calculateTime(String orderTime) {
		// 获取当前订单时间
		DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
		DateTime orderDateTime = dateTimeFormatter.parseDateTime(orderTime);
		// 创建今天下午三点的时间
		DateTime orderEqualTime = orderDateTime.withHourOfDay(15).withMinuteOfHour(0).withSecondOfMinute(0);
		// DateTime orderEqualTime = new DateTime(2019, 11, 10, 15, 0, 0, 0);

		// 创建预发货时间
		DateTime preSkipDateTime=orderEqualTime.isAfter(orderDateTime)?orderDateTime.plusDays(1):orderDateTime.plusDays(2);

		return isTuesday(preSkipDateTime);
	}

	private static DateTime isTuesday(DateTime preSkipDateTime) {
		// 获取预发货时间位于星期几
		int dayOfWeek = preSkipDateTime.getDayOfWeek();
		return (dayOfWeek != DateTimeConstants.SUNDAY) ? preSkipDateTime : preSkipDateTime.plusDays(1);
	}

版本升级(java 8)

	private static LocalDateTime calculateTime(String orderTime){
		/**
		 * 1:将字符串转变为date
		 * 1.1:实例化一个date为今天下午三点
		 * 2:判断date是否大于今天下午三点,定义一个发货时间
		 * 2.1:如果不大于的话,则发货时间是明天
		 * 2.2:如果大于的话,则发货时间是后天
		 * 3:判断发货时间是否是周日,
		 * 3.1:如果不大于的话,则发货时间不变
		 * 3.2:如果大于的话,则发货时间再加一天
		 *
		 */
		// 获取订单时间
		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime orderDateTime = LocalDateTime.parse(orderTime, dateTimeFormatter);

		// 设置今天下午三点
		LocalDateTime orderEqualTime= orderDateTime.withHour(15).withMinute(0).withSecond(0);
		// LocalDateTime orderEqualTime = LocalDateTime.of(LocalDate.now(), LocalTime.of(15, 0, 0));

		// 判断订单时间是否在下午三点之前,如果是的话,设定发货时间是明天,否则的话是后天
		// 定义一个预发货时间
		LocalDateTime preSkipDateTime=orderEqualTime.isAfter(orderDateTime)?orderDateTime.plusDays(1):orderDateTime.plusDays(2);
		return isSunday(preSkipDateTime);
	}

	/**
	 * 判断预下单时间是否周末
	 * @param preSendDateTime
	 * @return
	 */
	private static LocalDateTime isSunday(LocalDateTime preSendDateTime){
		// 获取预下单时间是星期几
		DayOfWeek dayOfWeek = preSendDateTime.getDayOfWeek();
		// 定义发货时间
		return (dayOfWeek!=DayOfWeek.SUNDAY)?preSendDateTime:preSendDateTime.plusDays(1);
	}

心得体会

想必通过这三次代码的迭代和重构,大家已经看到的哪些时间类API功能强大;当然他们之中的区别绝不是表面使用方便那么简单,第一种利用Data和Calendar的方式目前不推荐使用,因为SimpleDateFormat作为一个非线程安全的类,被当做了共享变量在多个线程中进行使用,这就出现了线程安全问题。推荐大家使用第二个或者是第三种,第二种是在Java8出现之间一直作为Java时间类的替代品所使用的,通过代码即表明功能依旧很强大。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值