Java 在两个日期之间从Sqllite数据库检索数据

Java 在两个日期之间从Sqllite数据库检索数据,java,android,sqlite,Java,Android,Sqlite,我检索两个日期之间的数据—一些是如何得到正确结果的,一些是如何在我选择月份日期时输出空列表视图—它工作正常,但当我选择多个月份之间的日期时,它输出空列表视图—下面是我的代码 这里我在DB类中声明变量 public static final String EX_RowID = "_id"; public static final String EX_Cattype = "Ecattype"; public static final String EX_Date = "Ecdate"; public

我检索两个日期之间的数据—一些是如何得到正确结果的,一些是如何在我选择月份日期时输出空列表视图—它工作正常,但当我选择多个月份之间的日期时,它输出空列表视图—下面是我的代码

这里我在DB类中声明变量

public static final String EX_RowID = "_id";
public static final String EX_Cattype = "Ecattype";
public static final String EX_Date = "Ecdate";
public static final String EX_Price = "Ecprice";
public static final String EX_Type = "itype";
创建表语句

    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        db.execSQL("CREATE TABLE " + Food_TABLE +"(" +
                EX_RowID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                EX_Cattype + " TEXT NOT NULL, " +
                EX_Date + " TEXT NOT NULL," +
                EX_Price + " INTEGER NOT NULL," +
                EX_Type + " TEXT NOT NULL UNIQUE );"
                );

    }
输入数据方法

 public long ExEntry(String Ecatgtype, String Edate, String Eprice, String Eitype) {
// TODO Auto-generated method stub

ContentValues cv = new ContentValues();
cv.put(EX_Cattype, Ecatgtype);
cv.put(EX_Date, Edate );
cv.put(EX_Price, Eprice);
cv.put(EX_Type, Eitype);
return ourdatabase.insertOrThrow(Food_TABLE, null, cv);
 }
这里我访问ExEntry方法

ExMgDB Expentry = new ExMgDB(ADD_EX.this);
    Expentry.open();
    Expentry.ExEntry(cate, date, price, itype);
    Expentry.close();
在这里,我面临着这两个日期变量之间的问题

 public Cursor CstmRpot(String fd, String td) {
// TODO Auto-generated method stub
String[] columns = new String[] {EX_RowID,EX_Cattype, EX_Date, EX_Price, EX_Type };
Cursor c= ourdatabase.query(Food_TABLE, columns, EX_Date  + " BETWEEN '" + fd + "'  
 AND '" + td + "'" , null, null, null, null);
if (c != null) {

       c.moveToFirst();

      }
return c;

}
我像下面那样访问它

 CustemRpt dbcs = new CustemRpt();    
Cursor cursor = CstDB.CstmRpot(frmdate,tondate);

尝试
从“您的表”中选择*,其中日期介于“起始日期”和“截止日期”之间

您需要存储yyyy mm dd的日期通知,然后使用此方法只需调用getWeekData(开始日期、结束日期)


有两个主要的解决方案。所有解决方案都有一个共同点,即包含日期的列必须以某种方式排序。如果此订单被销毁,您的数据将损坏,您的查询将无法返回预期结果

1。在数据库中将日期另存为
INTEGER
,并使用一种方法将日期映射到一个数字:

一种可能的方法是使用
Date.getTime()
将日期映射到数字,但还有许多其他方法。重要的是

  • 相同的日期得到相同的数字和时间
  • 在另一个日期之后的日期会得到一个更大的数字
  • 这样订购肯定是正确的。 要使用'Java.util.Date.getTime()实现这一点,如果只想存储日期,只需将时间设置为0:00:00:000

    例如:

    "CREATE TABLE " + Food_TABLE +"(" +
        EX_RowID + "INTEGER PRIMARY KEY AUTOINCREMENT, " +
        EX_Cattype + " TEXT NOT NULL, " +
        EX_Date + " INTEGER NOT NULL," +
        EX_Price + " INTEGER NOT NULL," +
        EX_Type + " TEXT NOT NULL UNIQUE );"
    
    private static String dateOnly(java.util.Date d) {
        Calendar cal = Calendar.getInstance(); // locale-specific
        cal.setTime(d);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return Long.toString(cal.getTimeInMillis());
    }
    
    public Cursor CstmRpot(java.util.Date fd, java.util.Date td) {
        // TODO Auto-generated method stub
        String[] columns = new String[]{EX_RowID,EX_Cattype, EX_Date, EX_Price, EX_Type };
        Cursor c= ourdatabase.query(Food_TABLE, columns, EX_Date + " > " + dateOnly (fd) + " AND " + EX_Date + " < " + dateOnly(td), null, null, null, null);
        if (c != null) {
            c.moveToFirst();
        }
        return c;
    }
    
    “创建表格”+食品表格+”(“+
    EX_RowID+“整数主键自动递增,”+
    EX_Cattype+“文本不为空,”+
    EX_日期+“整数不为空,”+
    出厂价+整数不为空+
    EX_Type+“文本不为NULL唯一);”
    专用静态字符串dateOnly(java.util.Date d){
    Calendar cal=Calendar.getInstance();//特定于语言环境
    校准设定时间(d);
    校准设置(日历小时/天,0);
    校准设置(日历分钟,0);
    校准设置(日历秒,0);
    校准设置(日历毫秒,0);
    返回Long.toString(cal.getTimeInMillis());
    }
    公共游标CstmRpot(java.util.Date fd,java.util.Date td){
    //TODO自动生成的方法存根
    String[]columns=新字符串[]{EX_RowID,EX_Cattype,EX_Date,EX_Price,EX_Type};
    游标c=ourdatabase.query(食物表、列、EX_Date+“>”+dateOnly(fd)+”和“+EX_Date+”<”+dateOnly(td)、null、null、null、null);
    如果(c!=null){
    c、 moveToFirst();
    }
    返回c;
    }
    
    如果不使用不同的时区,则可以优化
    dateOnly(java.util.dated)
    。 当然,你也可以利用乔达的时间

    2。将日期另存为
    文本

    如果选择此方法,则比较日期列的查询将稍微慢一点,但数据库中的条目是人类可读的,而方法1则没有这种情况。
    TEXT
    -默认情况下,列按顺序排列,这意味着
    memcmp()
    用于比较值并确定哪个值更大或值是否相等。(记住a和b之间的
    x
    表示
    x=b
    ) 您可以使用此函数检查
    memcmp()
    的工作

    为了确保获得正确的结果,您必须确保以下几点:

  • 数据库中的所有日期值必须具有相同的文本长度
  • 数据库中的所有日期值必须采用相同的格式。较大的日期部分(年)必须早于较小的日期部分(月)
  • 查询中日期值的所有参数也必须遵循这些规则
  • 可能的日期格式如下:
    yyyy-MM-dd
    (例如
    2014-02-04
    2000-12-24

    建议

    • 使用而不是
      Edittext
      获取日期作为输入
    • 不要在查询中直接使用从用户输入中获得的任何文本,但要事先验证它们(请参阅)
    • 阅读一些关于如何比较字符串的文章

      • 对于这个问题,我们有两种解决方案

        一是我们需要将日期和时间转换为毫秒,并输入长数据类型

        Sqllite数据库和保存值(转换的日期和时间)。编写查询,如“选择

        数据,开始日期,结束日期,从表名开始日期>结束日期”

        第二种方法是您需要以字符串格式保存开始和结束日期+时间(yyy-MM-dd HH:MM:ss)

        在Sqllite数据库中,您需要这样查询

        从tablename中选择datetime\u start,datetime\u end,其中((datetime(atetime\u start)>=

        DATETIME(“+””+“条目”\u开始”\u时间+“““+””+”和DATETIME(DATETIME\u结束)
        (“+””“+输入\结束\时间+”“+”)).

        如何在Ecdate字段中存储日期值?如果使用字符串字段存储日期,请确保按字符串排序对于相应的日期也是有效的。要实现这一点,当我更改格式时,您应该将日期存储为yyyymmddso,那么您认为正确的结果是什么对于两个日期之间的数据,数据库引擎需要获得一个有序列表,不是吗?我使用了你的方法,但问题仍然存在。我应用了与你相同的方法,但我也获得了超出范围的数据。我喜欢你的代码,先生,但你的dateOnly()方法我无法理解它结合了三个函数:1.从
        java.util.Date
        截断时间,使其仅为日期2.将其转换为1970年1月1日以来的毫秒。3.将其转换为
        String
        ,这是创建语句所需的内容。这只是如何在sqlite中存储日期的一个示例。另一个示例回答了排序字符串也是正确的,根据您的具体需要,我会使用一种或另一种解决方案,或者只是将日期表示为数字的另一种形式,
        "CREATE TABLE " + Food_TABLE +"(" +
            EX_RowID + "INTEGER PRIMARY KEY AUTOINCREMENT, " +
            EX_Cattype + " TEXT NOT NULL, " +
            EX_Date + " INTEGER NOT NULL," +
            EX_Price + " INTEGER NOT NULL," +
            EX_Type + " TEXT NOT NULL UNIQUE );"
        
        private static String dateOnly(java.util.Date d) {
            Calendar cal = Calendar.getInstance(); // locale-specific
            cal.setTime(d);
            cal.set(Calendar.HOUR_OF_DAY, 0);
            cal.set(Calendar.MINUTE, 0);
            cal.set(Calendar.SECOND, 0);
            cal.set(Calendar.MILLISECOND, 0);
            return Long.toString(cal.getTimeInMillis());
        }
        
        public Cursor CstmRpot(java.util.Date fd, java.util.Date td) {
            // TODO Auto-generated method stub
            String[] columns = new String[]{EX_RowID,EX_Cattype, EX_Date, EX_Price, EX_Type };
            Cursor c= ourdatabase.query(Food_TABLE, columns, EX_Date + " > " + dateOnly (fd) + " AND " + EX_Date + " < " + dateOnly(td), null, null, null, null);
            if (c != null) {
                c.moveToFirst();
            }
            return c;
        }