LocalDate
,LocalDateTime
,LocalTime
开发中基本用法package java.time;
LocalDate
ISO-8601
日历系统中没有时区的日期,例如 2023-08-19。LocalDate
。LocalTime
ISO-8601
日历系统中表示的时间是没有时区的,例如10:15:30LocalTime
是一个不可变的日期时间对象,它表示时间,常被视为小时-分-秒,时间以纳秒精度表示。LocalTime
。LocalDateTime
ISO-8601
日历系统中表示的时间是没有时区的 ,例如 2007-12-03T10:15:30。LocalDateTime
是一个不可变的日期时间对象,它表示日期时间,常被视为年-月-日-时-分-秒。其他日期和时间字段,如年月日、星期、星期等,亦可查阅,时间以纳秒精度表示。LocalDateTime
。LocalDate
默认使用yyyy-MM-dd
格式,源码说明
public static final DateTimeFormatter ISO_LOCAL_DATE;
static {
ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
.appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH, 2)
.toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
}
LocalDate now = LocalDate.now();
log.info("获取当前日期 now : [{}]" , now);
// 获取当前日期 now : [2023-08-18]
LocalDate appointDate = LocalDate.of(2023, 8, 18);
log.info("创建指定日期 appointDate : [{}]" , appointDate);
// 创建指定日期 appointDate : [2023-08-18]
// 默认就是格式yyyy-MM-dd
LocalDate parse = LocalDate.parse("2023-08-18");
log.info("字符串转换日期 parse : [{}]" , parse);
String dateStr = String.valueOf(parse);
log.info("日期转换字符串 dateStr : [{}]" , dateStr);
15:11:53.399 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - 获取当前日期 now : [2023-08-18]
15:11:53.405 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - 创建指定日期 appointDate : [2023-08-18]
15:11:53.435 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - 字符串转换日期 parse : [2023-08-18]
15:11:53.435 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - 日期转换字符串 dateStr : [2023-08-18]
LocalTime
默认时间格式hh:mm:ss
,源码说明
public static final DateTimeFormatter ISO_LOCAL_TIME;
static {
ISO_LOCAL_TIME = new DateTimeFormatterBuilder()
.appendValue(HOUR_OF_DAY, 2)
.appendLiteral(':')
.appendValue(MINUTE_OF_HOUR, 2)
.optionalStart()
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE, 2)
.optionalStart()
.appendFraction(NANO_OF_SECOND, 0, 9, true)
.toFormatter(ResolverStyle.STRICT, null);
}
案例说明
LocalTime now = LocalTime.now();
log.info("当前时间 now : [{}]" , now);
// 当前时间 now : [15:15:53.546]
LocalTime appointTime = LocalTime.of(15, 14, 39);
log.info("创建指定时间 appointTime : [{}]" , appointTime);
// 创建指定时间 appointTime : [15:14:39]
String timeStr = String.valueOf(appointTime);
log.info("时间转换字符串 timeStr : [{}]" , timeStr);
// 时间转换字符串 timeStr : [15:14:39]
LocalTime parse = LocalTime.parse(timeStr);
log.info("字符串转换时间 parse : [{}]" , parse);
// 字符串转换时间 parse : [15:14:39]
15:17:30.158 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - 当前时间 now : [15:17:30.152]
15:17:30.168 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - 创建指定时间 appointTime : [15:14:39]
15:17:30.168 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - 时间转换字符串 timeStr : [15:14:39]
15:17:30.196 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - 字符串转换时间 parse : [15:14:39]
LocalDateTime
默认日期时间格式为yyyy-MM-ddTHH:mm:ss
public static final DateTimeFormatter ISO_LOCAL_DATE;
static {
ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
.appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
.appendLiteral('-')
.appendValue(MONTH_OF_YEAR, 2)
.appendLiteral('-')
.appendValue(DAY_OF_MONTH, 2)
.toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
}
public static final DateTimeFormatter ISO_LOCAL_TIME;
static {
ISO_LOCAL_TIME = new DateTimeFormatterBuilder()
.appendValue(HOUR_OF_DAY, 2)
.appendLiteral(':')
.appendValue(MINUTE_OF_HOUR, 2)
.optionalStart()
.appendLiteral(':')
.appendValue(SECOND_OF_MINUTE, 2)
.optionalStart()
.appendFraction(NANO_OF_SECOND, 0, 9, true)
.toFormatter(ResolverStyle.STRICT, null);
}
public static final DateTimeFormatter ISO_LOCAL_DATE_TIME;
static {
ISO_LOCAL_DATE_TIME = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(ISO_LOCAL_DATE)
.appendLiteral('T')
.append(ISO_LOCAL_TIME)
.toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
}
案例说明
LocalDateTime now = LocalDateTime.now();
log.info("当前日期时间 now : [{}]" , now);
LocalDateTime appointDateTime = LocalDateTime.of(2023, 8, 18, 15, 21, 33);
log.info("创建指定日期时间 appointDateTime : [{}]" , appointDateTime);
LocalDateTime parse = LocalDateTime.parse("2023-08-18T15:22:33");
log.info("字符串转换日期 parse : [{}]" , parse);
// 日期与时间加上T java.time.format.DateTimeParseException: Text '2023-08-18 15:22:33' could not be parsed at index 10
String dateStr = String.valueOf(parse);
log.info("日期转换字符串 dateStr : [{}]" , dateStr);
15:25:19.136 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - 当前日期时间 now : [2023-08-18T15:25:19.131]
15:25:19.145 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - 创建指定日期时间 appointDateTime : [2023-08-18T15:21:33]
15:25:19.180 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - 字符串转换日期 parse : [2023-08-18T15:22:33]
15:25:19.180 [main] INFO com.geekmice.springbootselfexercise.NoDaoTest - 日期转换字符串 dateStr : [2023-08-18T15:22:33]
入参
private LocalDateTime insertTime;
@Data
public class UserLocalDateParam {
@DateTimeFormat(pattern = DateUtils.DATE_FORMAT_19)
private LocalDateTime insertTime;
private String userName;
}
出参
private LocalDateTime insertTime;
package com.geekmice.springbootselfexercise.domain;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelIgnore;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* (User)实体类
*
* @author pingmingbo
* @since 2023-08-06 09:51:28
*/
@Data
@ApiModel
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "user")
public class UserDomain implements Serializable {
private static final long serialVersionUID = 723356122339609354L;
/**
* 编号
*/
@ApiModelProperty(value = "编号")
@ExcelIgnore
@TableId(type = IdType.AUTO)
private Long id;
/**
* 用户名
*/
@ApiModelProperty(value = "用户名")
@Excel(name = "用户名")
@TableField(value = "user_name")
private String userName;
/**
* 生日
*/
@ApiModelProperty(value = "生日")
@Excel(name="生日",format = "yyyy-MM-dd")
@TableField(value = "birthday")
@JSONField(format = DateUtils.DATE_FORMAT_10)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime birthday;
/**
* 性别
*/
@Excel(name = "性别")
@ApiModelProperty(value = "性别")
@TableField(value = "sex")
private String sex;
/**
* 地址
*/
@ApiModelProperty(value = "地址")
@Excel(name = "地址")
@TableField(value = "address")
private String address;
/**
* 插入时间
*/
@ApiModelProperty(value = "插入时间")
@TableField(value = "insert_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime insertTime;
/**
* 更新时间
*/
@ApiModelProperty(value = "更新时间")
@TableField(value = "update_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
}
数据库字段说明
<resultMap type="com.geekmice.springbootselfexercise.domain.UserDomain" id="UserMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="userName" column="user_name" jdbcType="VARCHAR"/>
<result property="birthday" column="birthday" jdbcType="DATE"/>
<result property="sex" column="sex" jdbcType="VARCHAR"/>
<result property="address" column="address" jdbcType="VARCHAR"/>
<result property="insertTime" column="insert_time" jdbcType="TIMESTAMP"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
resultMap>
业务代码
@MethodExporter
@GetMapping(value = "validLocalDate")
public AjaxResult validLocalDate(@Valid UserLocalDateParam userLocalDateParam){
List<UserDomain> result = userService.validLocalDate(userLocalDateParam);
log.info("result : [{}]" , result);
return AjaxResult.success(result);
}
@Override
public List<UserDomain> validLocalDate(UserLocalDateParam userLocalDateParam) {
LambdaQueryWrapper<UserDomain> lambda = new QueryWrapper<UserDomain>().lambda();
LocalDateTime insertTime = userLocalDateParam.getInsertTime();
String insertTimeStr = insertTime.toString();
log.info("insertTimeStr : [{}]" , insertTimeStr);
// LocalDateTime转换为LocalDate
LocalDate userLocalDate = LocalDate.of(insertTime.getYear(), insertTime.getMonthValue(), insertTime.getDayOfMonth());
log.info("userLocalDate : [{}]" , userLocalDate);
// LocalDateTime 转换为 LocalTime
LocalTime userLocalTime = LocalTime.of(insertTime.getHour(), insertTime.getMinute(), insertTime.getSecond());
log.info("userLocalTime : [{}]" , userLocalTime);
String userName = userLocalDateParam.getUserName();
lambda.eq(UserDomain::getInsertTime,insertTime)
.eq(UserDomain::getUserName,userName);
List<UserDomain> result = userDao.selectList(lambda);
return result;
}
返回结果
{
"msg": "操作成功",
"code": 200,
"data": [
{
"id": 1,
"userName": "张1",
"birthday": "2023-08-10 00:00:00",
"sex": "男",
"address": "[email protected]",
"insertTime": "2023-08-17 02:00:00",
"updateTime": "2023-08-17 22:19:43"
}
]
}
java.time.format.DateTimeParseException: Text ‘2023-08-1815:22:33’ could not be parsed at index 10
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
at java.time.LocalDateTime.parse(LocalDateTime.java:477)
at com.geekmice.springbootselfexercise.NoDaoTest.testTransferDate(NoDaoTest.java:593)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner 2. e v a l u a t e ( P a r e n t R u n n e r . j a v a : 268 ) a t o r g . j u n i t . r u n n e r s . P a r e n t R u n n e r . r u n ( P a r e n t R u n n e r . j a v a : 363 ) a t o r g . j u n i t . r u n n e r . J U n i t C o r e . r u n ( J U n i t C o r e . j a v a : 137 ) a t c o m . i n t e l l i j . j u n i t 4. J U n i t 4 I d e a T e s t R u n n e r . s t a r t R u n n e r W i t h A r g s ( J U n i t 4 I d e a T e s t R u n n e r . j a v a : 68 ) a t c o m . i n t e l l i j . r t . j u n i t . I d e a T e s t R u n n e r 2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.junit.IdeaTestRunner 2.evaluate(ParentRunner.java:268)atorg.junit.runners.ParentRunner.run(ParentRunner.java:363)atorg.junit.runner.JUnitCore.run(JUnitCore.java:137)atcom.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)atcom.intellij.rt.junit.IdeaTestRunnerRepeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
LocalDateTime parse = LocalDateTime.parse("2023-08-18 15:22:33");
log.info("字符串转换日期 parse : [{}]" , parse);
解决方案
// 加上T
LocalDateTime parse = LocalDateTime.parse("2023-08-18T15:22:33");
log.info("字符串转换日期 parse : [{}]" , parse);
// 指定格式
LocalDateTime parse = LocalDateTime.parse("2023-08-18 15:22:33", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
log.info("字符串转换日期 parse : [{}]" , parse);
@JsonFormat
和@DateTimeFormat(pattern = DateUtils.DATE_FORMAT_19)
格式化问题@DateTimeFormat(pattern = DateUtils.DATE_FORMAT_19) 入参需要
@JsonFormat出参需要格式化
否则错误提示
{
“msg”: “Failed to convert property value of type ‘java.lang.String’ to required type ‘java.time.LocalDateTime’ for property ‘insertTime’; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDateTime] for value ‘2023-08-17 02:00:00’; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2023-08-17 02:00:00];”,
“code”: 500
}