LocalDateLocalTimeLocalDateTimeInstant不可变对象,修改这些对象对象会返回一个副本

Date

我们在 Java 中使用时间格式,第一个想到的肯定是 Date了,Date在格式化之前是这样的:Tue Sep 10 09:34:04 CST 2019

最终我们会用 SimpleDateFormat对时间进行格式化,但是,SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为static,必须加锁,或者使用DateUtils工具类。

如果是JDK8的应用,可以使用instant代替DateLocalDateTime代替CalendarDateTimeFormatter代替SimpleDateFormat

深究:SimpleDateFormatformat方法里会调用calendar.setTime(date);,此变量是共享变量并没有做线程安全控制,当多个线程同时使用时,会导致返回的格式化时间可能是错误的。另外,parse方法也是线程不安全的。如果要保证线程安全,每个线程都得创建一个SimpleDateFormat对象,对性能开销较大。

且,Date对具体时间、年月日星期的获取并不方便,而在JDK8中,提供了全新的日期和时间 API,也就是LocalDateTime

LocalDate

常见 API:

// 创建对象
LocalDate localDate = LocalDate.now();
LocalDate localDate = LocalDate.of(2020, 11, 11);

// 获取方法
int year = localDate.getYear();
// int year = localDate.get(ChronoField.YEAR);
Month month = localDate.getMonth();
int day = localDate.getDayOfMonth();
DayOfWeek dayOfWeek = localDate.getDayOfWeek();

LocalTime

常见 API:

//创建对象
LocalDate localDate = LocalDate.now();
LocalDate localDate = LocalDate.of(2020, 11, 11);

// 获取方法
// 小时
int hour = localTime.getHour();
// int hour1 = localTime.get(ChronoField.HOUR_OF_DAY);
// 分
int minute = localTime.getMinute();
// int minute1 = localTime.get(ChronoField.MINUTE_OF_HOUR);
// 秒
int second = localTime.getSecond();
// int second1 = localTime.get(ChronoField.SECOND_OF_MINUTE);

LocalDateTime

常用 API:

// 创建对象
LocalDateTime localDateTime = LocalDateTime.now();
LocalDateTime localDateTime1 = LocalDateTime.of(2020, Month.SEPTEMBER, 10, 14, 46, 56);
LocalDateTime localDateTime2 = LocalDateTime.of(localDate, localTime);
LocalDateTime localDateTime3 = localDate.atTime(localTime);
LocalDateTime localDateTime4 = localTime.atDate(localDate);

// 转换
LocalDate localDate2 = localDateTime.toLocalDate();
LocalTime localTime2 = localDateTime.toLocalTime();

// 获取方法同上

修改的 API

//修改年为2019
localDateTime = localDateTime.withYear(2020);
//修改为2022
localDateTime = localDateTime.with(ChronoField.YEAR, 2022);

//增加一年
localDateTime = localDateTime.plusYears(1);
localDateTime = localDateTime.plus(1, ChronoUnit.YEARS);
//减少一个月
localDateTime = localDateTime.minusMonths(1);
localDateTime = localDateTime.minus(1, ChronoUnit.MONTHS);  

格式化与解析的 API

// 格式化
String s1 = localDate.format(DateTimeFormatter.BASIC_ISO_DATE);
String s2 = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
// 自定义格式化
DateTimeFormatter dateTimeFormatter =   DateTimeFormatter.ofPattern("dd/MM/yyyy");
String s3 = localDate.format(dateTimeFormatter);

// 解析
LocalDate localDate1 = LocalDate.parse("20201111", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate localDate2 = LocalDate.parse("2020-11-11", DateTimeFormatter.ISO_LOCAL_DATE);
SimpleDateFormat相比,DateTimeFormatter是线程安全的

扩展

配置全局转换器以时间戳的格式返回给前端:

/**
 * 返回数据,时间格式化成时间戳
 */
@Configuration
public class WebConfig {
    @Bean
    public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
        //支持JAVA8时间格式
        ObjectMapper objectMapper = new ObjectMapper()
                .registerModule(new ParameterNamesModule())
                .registerModule(new Jdk8Module())
                .registerModule(new JavaTimeModule());
        objectMapper.configure(FAIL_ON_UNKNOWN_PROPERTIES,false);
        objectMapper.configure(WRITE_DATES_AS_TIMESTAMPS,false);
        //Long类型传输前端时转换为String,防止精度丢失
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
        //设置中文编码格式
        List<MediaType> list = new ArrayList<MediaType>();
        list.add(MediaType.APPLICATION_JSON_UTF8);
        mappingJackson2HttpMessageConverter.setSupportedMediaTypes(list);
        return mappingJackson2HttpMessageConverter;
    }
}

相关注解知识:

// 将LocalDateTime字段以指定格式化日期的方式返回给前端
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
// 对前端传入的日期进行格式化
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")

参考