简体   繁体   English

SQL消耗日期与前一天

[英]Sql consume date with day before

So I'm writing some REST API and one of my entity has a java.util.Date type; 因此,我正在编写一些REST API,我的一个实体具有java.util.Date类型。 My POST endpoint consumes JSON type, something like this: 我的POST端点使用JSON类型,如下所示:

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

Also I override jackson deserialize method to handle invalid date format and everything that involves this: 我也重写了杰克逊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;
    }
}

In my DTO model I use exactly this deserializer for this parameter: 在我的DTO模型中,我将此参数完全使用此反序列化器:

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

During life of all my intermediate objects (models and DTOs) this value everywhere looks like in input JSON - 1987-10-25 . 在我所有中间对象(模型和DTO)的生命周期中,这个值到处都看起来像输入JSON- 1987-10-25

Controller: 控制器:

@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);
}

Service method: 服务方式:

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);
}

All objects - postAuthor (parsed by Jackson in Controller), toPost , response and returned value from service - contains Date value like in input JSON - 1987-10-25 . 所有对象postAuthor (由Controller中的Jackson解析), toPostresponse和服务返回的值均包含Date值,例如输入JSON- 1987-10-25

But in SQL and in returned value from controller date appear with the day before: 1987-10-24 ... 但是在SQL中以及从控制器日期返回的值中出现的日期与前一天: 1987-10-24 ...

How to fix this?? 如何解决这个问题?

Oh... After day of fighting with this I won! 噢...经过一天的战斗,我赢了!

Problem was in next: when I post my json with date 1987-10-25 it parsed to my DTO as it needed. 接下来是问题:当我发布日期为1987-10-25 json时,它会根据需要解析为我的DTO。 But date must also has hours, munites and seconds. 但是日期还必须有小时,毫秒和秒。 So, that's why Java automatically set here six zeros: 00:00:00 . 因此,这就是Java在此处自动设置六个零的原因: 00:00:00 : 00:00:00 : 00:00:00 So, my Date look like this: 1987-10-25 00:00:00 . 因此,我的Date看起来像这样: 1987-10-25 00:00:00

As I wrote during life of all my intermediate objects (models and DTOs) this value everywhere looks like this date: 1987-10-25 00:00:00 . 正如我在所有中间对象(模型和DTO)的使用期间所写的那样,到处都是这个值: 1987-10-25 00:00:00 But as soon as this object leave my application it set here my time zone: -2. 但是,一旦该对象离开我的应用程序,它就会在此处设置我的时区:-2。 So, to SQL and in response JSON my date be like this: 1987-10-24 22:00:00 . 因此,对于SQL和响应JSON,我的日期是这样的: 1987-10-24 22:00:00

To solve it - set timezone to 0 in deserialize method: 解决方法-在反序列化方法中将时区设置为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;
}

Now it works good for me. 现在对我有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM