Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ResultSet.getDate()返回错误的日期_Java_Mysql_Date_Jodatime - Fatal编程技术网

Java ResultSet.getDate()返回错误的日期

Java ResultSet.getDate()返回错误的日期,java,mysql,date,jodatime,Java,Mysql,Date,Jodatime,我在使用ResultSet.getDate方法时遇到问题。我在MySQL中有一个日期字段,当我尝试获取该值时,获取的日期是今天的日期,而不是指定表中的日期。我不知道是什么导致了这个错误,我搜索了其他帖子,但是getDate的其他错误是不同的,比如解析错误、数据不匹配错误或者其他类型的错误。由于时区的原因,这可能是一个错误,因为日期的值来自昨天,但有一行的日期是两天前,它也返回今天的日期 代码如下: package dao; import java.sql.Connection; import

我在使用ResultSet.getDate方法时遇到问题。我在MySQL中有一个日期字段,当我尝试获取该值时,获取的日期是今天的日期,而不是指定表中的日期。我不知道是什么导致了这个错误,我搜索了其他帖子,但是getDate的其他错误是不同的,比如解析错误、数据不匹配错误或者其他类型的错误。由于时区的原因,这可能是一个错误,因为日期的值来自昨天,但有一行的日期是两天前,它也返回今天的日期

代码如下:

package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.joda.time.LocalDate;

import model.Paciente;
import teste.ConnectionFactory;

public class PacienteDao {


    // a conexão com o banco de dados
    private Connection connection;

    public PacienteDao() {
        this.connection = new ConnectionFactory().getConnection();
    }

    public void adiciona(Paciente paciente) {
        String sql = "insert into paciente" +
                " (nome_paciente,cpf_paciente,rg_paciente,data_nasc)" +

                "values (?,?,?,?)";

        try {
            PreparedStatement stmt = connection.prepareStatement(sql);

            stmt.setString(1, paciente.getNome_paciente());
            stmt.setString(2, paciente.getCpf());
            stmt.setString(3, paciente.getRg());

            java.sql.Date data_nasc = new java.sql.Date(paciente.getData_nasc().toDate().getTime());
            stmt.setDate(4, data_nasc);

            stmt.execute();
            stmt.close();

        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public List<Paciente> listaPacientes() {

        List<Paciente> pacientes = new ArrayList<Paciente>();

        try {
            PreparedStatement stmt = this.connection.prepareStatement("select * from paciente");

            ResultSet rs = stmt.executeQuery();

            while (rs.next()) {
                Paciente paciente = new Paciente();
                paciente.setId_paciente(rs.getInt("id_paciente"));
                paciente.setNome_paciente(rs.getString("nome_paciente"));
                paciente.setCpf(rs.getString("cpf_paciente"));
                paciente.setRg(rs.getString("rg_paciente"));

                LocalDate dt = new LocalDate();
                dt.fromDateFields(rs.getDate("data_nasc"));
                paciente.setData_nasc(dt);

                pacientes.add(paciente);
            }

            rs.close();
            stmt.close();

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return pacientes;
    }
以下是应返回的数据:

卢卡斯,11111111 2222222 017-12-19 卢卡斯,11111111 2222222 017-12-20 卢卡斯,11111111 2222222 017-12-20 莱安德罗4号,23212322017-12-20 以下是StackTrace返回的数据:

身份证号码:1 诺姆:卢卡斯 中央公积金:1111 RG:1222222 纳西门托数据:2017-12-21

身份证号码:2 诺姆:卢卡斯 中央公积金:1111 RG:1222222 纳西门托数据:2017-12-21

身份证号码:3 诺姆:卢卡斯 中央公积金:1111 RG:1222222 纳西门托数据:2017-12-21

身份证号码:4 诺姆:莱安德罗 中央公积金:2321 RG:21232 纳西门托数据:2017-12-21

就像我说的,其中一行的日期是两天前,但它也显示了今天的日期,所以我认为这不是时区错误

PS:变量和方法的名称是葡萄牙语的,因为应用程序也是葡萄牙语的。

问题就在这里

LocalDate dt = new LocalDate();
dt.fromDateFields(rs.getDate("data_nasc"));
第一条语句创建一个新的LocalDate集,设置为today。第二条语句是对静态方法fromDateFields的调用,IDE和/或编译器应该将其标记为警告。此方法返回一个新的LocalDate对象,您丢弃了它,并且不修改dt。以上内容应为:

LocalDate dt = LocalDate.fromDateFields(rs.getDate("data_nasc"));
问题就在这里

LocalDate dt = new LocalDate();
dt.fromDateFields(rs.getDate("data_nasc"));
第一条语句创建一个新的LocalDate集,设置为today。第二条语句是对静态方法fromDateFields的调用,IDE和/或编译器应该将其标记为警告。此方法返回一个新的LocalDate对象,您丢弃了它,并且不修改dt。以上内容应为:

LocalDate dt = LocalDate.fromDateFields(rs.getDate("data_nasc"));
答案是正确的。下面看到的更简单、更直观的代码可以防止这种特殊的错误

此外,你是:

在确定日期时忽略了时区这一关键问题。 使用一个项目中的旧库,该项目建议您转到他们的现代替换类。 tl;博士 使用替代Joda time的java.time类

myResultSet().getObject( … , Instant.class )         // Extract a moment on the timeline in UTC, an `Instant` object.
             .atZone( ZoneId.of( "Asia/Kolkata" ) )  // Adjust into a time zone, to determine a date, rendering a `ZonedDateTime` object. 
             .toLocalDate()                          // Extract a date-only object, a `LocalDate` without time-of-day and without a time zone. 
避免遗留类 您不应该使用PreparedStatement::getDate。避免与最早版本的Java捆绑在一起的所有麻烦的旧日期时间类,例如date、Calendar和相关的Java.sql类型。它们完全被java.time类和JDBC4.2驱动程序所取代

同样,Joda Time项目现在处于维护模式。其团队建议迁移到他们在JSR310中启发、定义和实现的java.time

java.time 使用getObject和setObject方法

而且

myPrepatedStatement.setObject( … , ld ) ;
myPreparedStatement.setObject( … , instant ) ;
上面的代码用于标准的SQL日期列,该列是一个仅限日期的值

但听起来好像您存储了一个时刻,可能是MySQL类型的时间戳,它似乎与时区类型的标准SQL时间戳相匹配。在MySQL中,任何提供的偏移量或时区信息用于在提交到数据库时将值调整为UTC,分辨率为微秒

因此,Java中的等效类型是Instant,即UTC时间轴中的某个点,但分辨率更高,为纳秒

Instant instant = myResultSet.getObject( … , Instant.class ) ;
而且

myPrepatedStatement.setObject( … , ld ) ;
myPreparedStatement.setObject( … , instant ) ;
请记住,瞬间始终以UTC为单位。但确定日期需要一个时区。对于任何给定的时刻,日期都因区域而异

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ; 
ZonedDateTime zdt = instant.atZone( z ) ;
从中提取似乎是您目标的仅日期对象

LocalDate ld = zdt.toLocalDate() ;
答案是正确的。下面看到的更简单、更直观的代码可以防止这种特殊的错误

此外,你是:

在确定日期时忽略了时区这一关键问题。 使用一个项目中的旧库,该项目建议您转到他们的现代替换类。 tl;博士 使用替代Joda time的java.time类

myResultSet().getObject( … , Instant.class )         // Extract a moment on the timeline in UTC, an `Instant` object.
             .atZone( ZoneId.of( "Asia/Kolkata" ) )  // Adjust into a time zone, to determine a date, rendering a `ZonedDateTime` object. 
             .toLocalDate()                          // Extract a date-only object, a `LocalDate` without time-of-day and without a time zone. 
避免遗留类 您不应该使用PreparedStatement::getDate。避免与最早版本的Java捆绑在一起的所有麻烦的旧日期时间类,例如date、Calendar和相关的Java.sql类型。它们完全被java.time类和JDBC4.2驱动程序所取代

同样,Joda Time项目现在处于维护模式。其团队建议迁移到他们在JSR310中启发、定义和实现的java.time

java.time 使用getObject和setObject方法

而且

myPrepatedStatement.setObject( … , ld ) ;
myPreparedStatement.setObject( … , instant ) ;
上面的代码用于标准的SQL日期列,该列是一个仅限日期的值

但听起来好像您存储了一个时刻,可能是MySQL类型的时间戳,它似乎与时区类型的标准SQL时间戳相匹配 . 在MySQL中,任何提供的偏移量或时区信息用于在提交到数据库时将值调整为UTC,分辨率为微秒

因此,Java中的等效类型是Instant,即UTC时间轴中的某个点,但分辨率更高,为纳秒

Instant instant = myResultSet.getObject( … , Instant.class ) ;
而且

myPrepatedStatement.setObject( … , ld ) ;
myPreparedStatement.setObject( … , instant ) ;
请记住,瞬间始终以UTC为单位。但确定日期需要一个时区。对于任何给定的时刻,日期都因区域而异

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ; 
ZonedDateTime zdt = instant.atZone( z ) ;
从中提取似乎是您目标的仅日期对象

LocalDate ld = zdt.toLocalDate() ;