SQLite 数据库结果中的 LocalDate 格式错误

问题描述 投票:0回答:1

我的数据库使用 SQLite,但 date_logged 的结果显示了一个意外的值,例如 1731279600000,而不是我输入的日期(例如 2024-11-12)。我以前使用 H2 作为我的数据库,它在那里工作得很好,但它在 SQLite 中工作不正常。我该如何解决这个问题?

@Column(nullable = false)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate dateLogged;

这是我的日志实体中的代码

@PostMapping("/logs")
public Log createLog(@RequestBody Map<String, Object> logData) {
    return logService.createLogEntry(
            (String) logData.get("username"),
            (String) logData.get("project_name"),
            Double.valueOf(logData.get("hours_logged").toString()),
            LocalDate.parse((String) logData.get("date_logged"))
    );
}

日志控制器

public Log createLogEntry(String username, String projectName, Double hoursLogged, LocalDate dateLogged) {
    User user = userRepository.findByUsername(username);
    if (user == null) throw new RuntimeException("User not found");
    Log log = new Log();
    log.setUser(user);
    log.setProjectName(projectName);
    log.setHoursLogged(hoursLogged);
    log.setDateLogged(dateLogged);
    return logRepository.save(log);
}

日志服务

java spring-boot sqlite maven localdate
1个回答
0
投票

1731279600000 是 unix 时间戳。看一下:https://www.unixtimestamp.com。所以这是存储您提供的日期(2024-11-10)的方法之一。

谈谈sqlite,与其他数据库不同,它没有日期类型。相反,它可以是以下之一:

SQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:

TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.

完整文档:https://www.sqlite.org/datatype3.html

在您的场景中,您可以创建自定义设置器。

因此,当您设置它(dateLogged)时:它将数据库中的值保存为unix时间戳并设置您想要的值 因此,当 spring 设置它(dateLoggedUnix)时:它设置了值并且已经设置了您想要在 locadate 中设置的值。

示例:

@Entity
class Log {
    private String projectName;
    private Double hoursLogged;
    @Transient // jpa one to make database ignore this field
    private LocalDate dateLogged;
    private long dateLoggedUnix;

    public void setDateLoggedUnix(int dateLoggedUnix) {
        this.dateLoggedUnix = dateLoggedUnix;
        this.dateLogged = Instant.ofEpochSecond(dateLoggedUnix)
                .atZone(ZoneId.systemDefault())
                .toLocalDate();
    }

    public void setDateLogged(LocalDate dateLogged) {
        this.dateLogged = dateLogged;
        this.dateLoggedUnix = dateLogged
                .atStartOfDay(ZoneId.systemDefault())
                .toEpochSecond();
    }
    // other noraml gettters and setter
}

记住,@JsonFormat(shape = JsonFormat.Shape.STRING,pattern =“yyyy-MM-dd”)仅适用于jackson库,不适用于JPA。

另外,您可能会发现这个答案很有趣https://stackoverflow.com/a/77771796/10880357

© www.soinside.com 2019 - 2024. All rights reserved.