SQL消耗日期与前一天

时间:2019-04-16 13:15:58

标签: java sql spring date jackson

因此,我正在编写一些REST API,我的一个实体具有java.util.Date类型。 我的POST端点使用JSON类型,如下所示:

{
   "authorId": 7845,
   "authorName": {
      "first": "Dan",
      "second": "Brown"
   },
   "birth": {
      "date": "1987-10-25",
      "country": "USA",
      "city": "New York"
   },
   "description": "Very good author!"
}

我还重写了jackson deserialize方法来处理无效的日期格式以及与此有关的所有内容:

public class CustomDateDeserializer extends StdDeserializer<Date> {
    public CustomDateDeserializer() {
        this(null);
    }

    public CustomDateDeserializer(Class t) {
        super(t);
    }

    @Override
    public Date deserialize(JsonParser jp, DeserializationContext dc) throws IOException {
        String date = jp.getValueAsString();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setLenient(false);

        Date parsed;
        try {
            parsed = sdf.parse(date);
        } catch (ParseException e) {
            throw new InvalidDateTypeException(jp.currentName(), jp.getText());
        }
        return parsed;
    }
}

在我的DTO模型中,我将以下反序列化器完全用于此参数:

@JsonFormat(pattern = "yyyy-MM-dd")
@JsonDeserialize(using = CustomDateDeserializer.class)
@PastOrPresent(message = "Value 'date' must be past or present!")
private Date date;

在我所有中间对象(模型和DTO)的生命周期中,这个值无处不在,就像输入JSON-1987-10-25中一样。

控制器:

@PostMapping(value = "/author/new", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> addNewAuthor(@RequestBody @Valid AuthorPostDto postAuthor) {
    AuthorPostDto response = authorService.addNewAuthor(postAuthor);
    return new ResponseEntity<>(response, HttpStatus.CREATED);
}

服务方法:

public AuthorPostDto addNewAuthor(AuthorPostDto author) {
    if (authorRepository.existsByAuthorId(author.getAuthorId())) {
        throw new AuthorAlreadyExistsException();
    }

    Author toPost = toModelMapper.mapAuthorDtoToAuthor(author);
    Author response = authorRepository.save(toPost);
    return toDtoMapper.mapAuthorModelToDto_POST(response);
}

所有对象-postAuthor(由Controller中的Jackson解析),toPostresponse和服务返回的值-像输入JSON中一样包含Date值-{{ 1}}。

但是在SQL中,控制器日期的返回值与前一天一起出现:1987-10-25 ...

如何解决此问题?

1 个答案:

答案 0 :(得分:0)

哦……经过与之抗争的一天,我赢了!

下一个问题是:当我发布日期为1987-10-25的json时,它会根据需要解析为DTO。但是日期还必须有小时,毫秒和秒。因此,这就是Java在此处自动设置六个零的原因:00:00:00。因此,我的日期看起来像这样:1987-10-25 00:00:00

正如我在所有中间对象(模型和DTO)的使用期间所写的那样,各处的值看起来都像这个日期:1987-10-25 00:00:00。但是,一旦该对象离开我的应用程序,它就会在此处设置我的时区:-2。因此,对于SQL和响应JSON,我的日期是这样的:1987-10-24 22:00:00

要解决此问题,请在反序列化方法中将时区设置为0:

public Date deserialize(JsonParser jp, DeserializationContext dc) throws IOException {
    String date = jp.getValueAsString();

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    sdf.setTimeZone(TimeZone.getTimeZone(ZoneOffset.ofHours(0))); //here
    sdf.setLenient(false);

    Date parsed;

    try {
        parsed = sdf.parse(date);
    } catch (ParseException e) {
        throw new InvalidDateTypeException(jp.currentName(), jp.getText());
    }

    return parsed;
}

现在对我有用。