JAVA新时间

本文探讨了Java中传统的时间格式化存在的安全问题,并通过实例展示了使用ThreadLocal解决线程安全问题的方法。同时,文章比较了Java新时间API(如LocalDate, LocalDateTime, DateTimeFormatter等)在多线程环境下的优势,强调了新API的高效和安全特性。此外,还介绍了新API中的时间操纵、日期校正器、时间格式化和时区处理等功能,揭示了其在日期和时间操作上的便利性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传统时间格式化的现成安全问题

package 新特性;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import org.junit.Test;

public class DateFormatThreadLocal {

	private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
		@Override
		protected DateFormat initialValue() {
			return new SimpleDateFormat("yyyy-mm-dd");
		}
	};
	
	public static Date convert(String str) throws ParseException {
		return df.get().parse(str);
	}
	/**
	 * 传统解决办法
	 */
	@Test
	public void test() {
		Callable<Date> task = new Callable<Date>() {
			@Override
			public Date call() throws Exception {
				return convert("2016-09-09");
			}
		};
		ExecutorService pool = Executors.newFixedThreadPool(10);
		List<Future<Date>> result = new ArrayList<>();
		for (int i = 0; i < 10; i++) {
			Future<Date> f = pool.submit(task);
			result.add(f);
		}
		result.stream().forEach(f->{
			try {
				System.out.println(f.get());
			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			}
		});
		
		pool.shutdown();
	}
	/**
	 * java全新API
	 */
	@Test
	public void test1() {
		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-mm-dd");
		Callable<LocalDate> task = new Callable<LocalDate>() {
			@Override
			public LocalDate call() throws Exception {
				return LocalDate.parse("2016-09-09",dtf);
			}
		};
		ExecutorService pool = Executors.newFixedThreadPool(10);
		List<Future<LocalDate>> result = new ArrayList<>();
		for (int i = 0; i < 10; i++) {
			Future<LocalDate> f = pool.submit(task);
			result.add(f);
		}
		result.stream().forEach(f->{
			try {
				System.out.println(f.get());
			} catch (InterruptedException | ExecutionException e) {
				e.printStackTrace();
			}
		});
		
		pool.shutdown();
	}
}

JAVA全新时间API

package 新特性;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZoneOffset;

import org.junit.Test;

public class TestLocalDateTime {

	//LocalDate LocalTime LocalDateTime
	@Test
	public void test() {
		LocalDateTime ldt = LocalDateTime.now();
		System.out.println(ldt);
		LocalDate ld = LocalDate.now();
		System.out.println(ld);
		LocalTime lt = LocalTime.now();
		System.out.println(lt);
		
		LocalDateTime ldt1 = LocalDateTime.of(2021,10,1,23,59,59);
		System.out.println(ldt1);
		
		//加一年
		System.out.println(ldt.plusYears(1));
		//减少2月
		System.out.println(ldt.minusMonths(2));
		System.out.println(ldt.getMonth());
		System.out.println(ldt.getMonthValue());
		System.out.println(ldt.getYear());
		System.out.println(ldt.getDayOfMonth());
		System.out.println(ldt.getDayOfYear());
		System.out.println(ldt.getHour());
		System.out.println(ldt.getSecond());
		System.out.println(ldt.getDayOfWeek());
		System.out.println(ldt.getChronology());
		
		//Instant : 时间戳(以UNIX 元年 : 1970年1月1日 00:00:00 到耨个时间的毫秒值)
		Instant inst = Instant.now();//默认获取的是UTC时区  世界协调时间 
		System.out.println(inst); 
		System.out.println(inst.toEpochMilli()); //转毫秒时间 时间戳
		
		Instant ofEpochSecond = Instant.ofEpochSecond(1000);//从1970年1月1日 00:00:00 追加1000s
		System.out.println(ofEpochSecond);
		//带偏移量运算
		OffsetDateTime atOffset = inst.atOffset(ZoneOffset.ofHours(8));
		System.out.println(atOffset);
		
	}
	//Duration:计算2个时间之间的间隔
	@Test
	public void test2() throws InterruptedException {
		Instant now = Instant.now();
		Thread.sleep(1000);
		Instant now2 = Instant.now();
		Duration duration = Duration.between(now, now2);
		System.out.println(duration);//PT0S     IOS显示方法
		System.out.println(duration.toMillis());
		
		System.out.println("-----------------------------");
		
		LocalTime now3 = LocalTime.now();
		Thread.sleep(1000);
		LocalTime now4 = LocalTime.now();
		Duration duration1 = Duration.between(now3, now4);
		System.out.println(duration1.toMillis());
		System.out.println(duration1.toHours());
	}
	
	//Period:计算2个日期之间的间隔
	@Test
	public void test3() throws InterruptedException {
		LocalDate of = LocalDate.of(2015, 9, 14);
		LocalDate now = LocalDate.now();
		Period between = Period.between(of, now);
		System.out.println(between);
		System.out.println(between.getYears());
		System.out.println(between.getMonths());
		System.out.println(between.getDays());
	}
}

日期的操纵-时间校正器

package 新特性;

import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZoneOffset;
import java.time.temporal.TemporalAdjusters;

import org.junit.Test;

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

时间日期格式化

package 新特性;

import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;

import org.junit.Test;

public class TestLocalDateTime {
	
	//DateTimerFormatter 格式化时间/日期
	@Test
	public void test5() {
		DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE;
		LocalDateTime now = LocalDateTime.now();
		String format = now.format(dtf);
		System.out.println(format);
		
		String format2 = dtf.format(now);
		System.out.println(format2);
		
		System.out.println("--------------------");
		dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
		String strdate = dtf.format(now);
		System.out.println(strdate);
		System.out.println(now.format(dtf));
		
		LocalDateTime newDate = now.parse(strdate,dtf);
		System.out.println(newDate);
		
	}
}

时区的处理

package 新特性;

import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Set;

import org.junit.Test;

public class TestLocalDateTime {
	
	//ZoneDate ZoneTime ZoneDateTime
	@Test
	public void test8() {
		LocalDateTime ldt = LocalDateTime.now(ZoneId.of("Africa/Juba"));
		System.out.println(ldt);
		
		LocalDateTime now = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
		ZonedDateTime zdt = now.atZone(ZoneId.of("Asia/Shanghai"));
		System.out.println(zdt);
	}
	//时区的处理
	//ZonedDate、ZonedTime、ZonedDateTime
	@Test
	public void test6() {
		Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
		availableZoneIds.forEach(System.out::println);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值