1
votes

Toutes les dates d'horodatage sont réduites de 2 heures, Java 1.7 et MS SQL Server

J'ai développé une API Rest basée sur Spring, retournant une liste de DTO. Dans mon DTO, j'ai certains champs ayant TimeStamp comme DataType. Pendant que j'essaie de déboguer, l'API renvoie bien les valeurs, le seul problème est que toutes les valeurs d'horodatage sont réduites de 2 heures. Par exemple: il doit renvoyer

04/09/2019 00: 00: 00.000,

mais il renvoie

2019-09-03T22: 00: 00Z

J'ai déjà essayé de changer la date et l'heure de mon PC pour voir s'il y a un effet, mais aucune aide

actionDescription: "action description 1",
startDate: "2019-09-04 00:00:00.000",
dueDate: "2019-09-04 00:00:00.000",
assigneeResponse: "",
actionStatus: "Action-Assigned-New",
isDeleted: false
}

classe publique ActionCustomDto { p>

actionDescription: "action description 1",
startDate: "2019-09-03T22:00:00Z",
dueDate: "2019-09-03T22:00:00Z",
assigneeResponse: "",
actionStatus: "Action-Assigned-New",
isDeleted: false
}

}

Résultat réel:

private String actionDescription;

private Timestamp startDate;

private Timestamp dueDate;

private String assigneeResponse;

private String actionStatus;

private Boolean isDeleted;

public String getActionDescription() {
    return this.actionDescription;
}

public void setActionDescription(String actionDescription) {
    this.actionDescription = actionDescription;
}

public Timestamp getStartDate() {
    return this.startDate;
}

public void setStartDate(Timestamp startDate) {
    this.startDate = startDate;
}

public Timestamp getDueDate() {
    return this.dueDate;
}

public void setDueDate(Timestamp dueDate) {
    this.dueDate = dueDate;
}

public String getAssigneeResponse() {
    return this.assigneeResponse;
}

public void setAssigneeResponse(String assigneeResponse) {
    this.assigneeResponse = assigneeResponse;
}

public String getActionStatus() {
    return this.actionStatus;
}

public void setActionStatus(String actionStatus) {
    this.actionStatus = actionStatus;
}


public List<String> getSerialNumbers() {
    return this.serialNumbers;
}

public void setSerialNumbers(List<String> serialNumbers) {
    this.serialNumbers = serialNumbers;
}

public Boolean getIsDeleted() {
    return this.isDeleted;
}

public void setIsDeleted(Boolean isDeleted) {
    this.isDeleted = isDeleted;
}

Résultat attendu:

@GetMapping("/")
public ResponseEntity<List<ActionCustomDto>> getAllActions(HttpServletRequest request, @RequestParam(value = "ncId", required = true) List<String> ncIdList, @RequestParam(value = "actionPlan", required = true) List<String> actionPlanList) {
    LOGGER.info("Fetching Action List with the following params : ncIdList = " + ncIdList + ", actionPlanList = " + actionPlanList);
    // String user = request.getHeader("X-User-Login");
    // LOGGER.info("Retrieved user ad login : " + user);

    List<String> exactActionPlans = this.populateExactActionPlans(actionPlanList);
    List<ActionCustomDto> result = new ArrayList<>();

    for (final String ncId : ncIdList) {

        List<ActionPlanDto> actionPlans = this.actionPlanService.findRequiredActionPlans(ncId, exactActionPlans);

        for (ActionPlanDto actionPlan : actionPlans) {
            List<ActionDto> actions = this.actionService.findRequiredActions(actionPlan.getActionPlanId());
            for (ActionDto action : actions) {
                ActionCustomDto actionCustomDto = new ActionCustomDto();
                this.populateActionCustomDto(actionCustomDto, action, ncId);
                result.add(actionCustomDto);
            }
        }
    }

    return ResponseEntity.ok().body(result);
}

private void populateActionCustomDto(ActionCustomDto actionCustomDto, ActionDto action, String ncId) {

    actionCustomDto.setActionDescription(action.getActionDescription());
    actionCustomDto.setStartDate(action.getStartDate());
    actionCustomDto.setDueDate(action.getDueDate());
    actionCustomDto.setAssigneeResponse(action.getActionResponse());
    actionCustomDto.setActionStatus(action.getActionStatus());
    actionCustomDto.setIsDeleted(action.getIsDeleted());
}


6 commentaires

D'où proviennent vos horodatages? Peut-être qu'il y a un décalage de fuseau horaire entre une base de données et votre application?


quelle base de données utilisez-vous?


Comment convertissez-vous l'horodatage en une chaîne? Semble un problème de fuseau horaire. Peut-être la différence entre UTC et votre fuseau horaire local


Étant donné le décalage du fuseau horaire de 2 heures, il s'agit très probablement d'un problème de fuseau horaire. Une partie attend un décalage de 0 fuseau horaire. Une partie compense pour mettre les choses en UTC.


Je vois que votre heure locale a le fuseau +02: 00. Le résultat réel est probablement exprimé en UTC


La base de données est MS SQL Server et la version Java est 1.7


4 Réponses :


0
votes

Modifiez l'horodatage de ZonedDateTime, et je vous donnerai la date réelle, avec l'heure zonée.


1 commentaires

Java 7 est utilisé



0
votes

J'ai eu le même problème ... Est-ce MySQL? Essayez de spécifier à la fois le serveur et le fuseau horaire local sur votre chaîne de connexion. Mon serveur MySQL, fonctionnant sur Docker, ne détecte pas correctement son fuseau horaire. Cela a résolu le problème pour moi:

jdbc: mysql: // serveur: 3306 / database? useSSL = false & useUnicode = true & characterEncoding = utf-8 & serverTimezone = America / Sao_Paulo & sessionVariables = time_zone = 'America / Sao_Paulo'


0 commentaires

0
votes

Le fuseau horaire de configuration de votre base de données doit être UTC +0 . Ainsi, lorsque vous insérez une date , elle passera automatiquement à UTC +0 .

Pour cette raison, lorsque vous obtenez ces données, vous voyez la date 2 heures de moins, car votre heure locale est UTC +2 .

De plus, vous ne pouvez pas définir une valeur dans un fuseau horaire particulier avec Timestamp .

Pour résoudre ce problème, vous devez soit déclarer un SimpleDateFormat pour réajuster vos Dates soit changer la configuration du fuseau horaire de votre base de données.


1 commentaires

Oui correct! Je viens de le résoudre en changeant le getter @JsonGetter ("dueDate") public String getDueDate () {if (this.dueDate! = Null) {return new SimpleDateFormat ("yyyy-MM-dd'T'H: mm: ss. SSS'Z '"). Format (this.‌ dueDate); } else {return null; }}



1
votes

Tout d'abord, gardez à l'esprit que le Z à la fin de la date signifie UTC (ou décalage zéro par rapport à UTC ).

Dans mon DTO, j'ai des champs ayant Timestamp comme type de données.

Depuis Java 8, Date et leurs amis tels que Heure , Timestamp , Calendrier et SimpleDateFormat sont des anciennes classes . Ils ne sont pas (encore) obsolètes, mais vous devriez les éviter. Dans votre situation, vous pouvez soit utiliser Instant ou OffsetDateTime .

Pour Java 7 et les versions antérieures, vous voudrez peut-être envisager le Projet ThreeTen Backport : id apporte un backport des classes de date et d'heure Java 8 vers Java 6 et 7, vous pouvez donc utiliser Instant ou OffsetDateTime . p >

Si l'utilisation du backport, pour une raison quelconque, n'est pas une option, alors vous pouvez envisager de définir un fuseau horaire pour Jackson:

spring.jackson.time-zone: UTC


3 commentaires

En utilisant Java 7, c'est le problème


@MohdSalim Ensuite, vous pouvez examiner le projet ThreeTen Backport .


@MohdSalim Essayez également de définir le fuseau horaire pour Jackson: spring.jackson.time-zone: .