La mejor manera de trabajar con fechas en Android SQLite [cerrado]

Resuelto Filipe asked hace 54 años • 9 respuestas

Tengo problemas para trabajar con fechas en mi aplicación de Android que usa SQLite. Tengo un par de preguntas:

  1. ¿Qué tipo debo usar para almacenar fechas en SQLite (texto, entero,...)?
  2. Dada la mejor manera de almacenar fechas, ¿cómo las almaceno correctamente usando ContentValues?
  3. ¿Cuál es la mejor manera de recuperar la fecha de la base de datos SQLite?
  4. ¿Cómo hacer un sql select en SQLite, ordenando los resultados por fecha?
Filipe avatar Jan 01 '70 08:01 Filipe
Aceptado

La mejor manera es almacenar las fechas como un número, recibido usando el comando Calendario.

//Building the table includes:
StringBuilder query=new StringBuilder();
query.append("CREATE TABLE "+TABLE_NAME+ " (");
query.append(COLUMN_ID+"int primary key autoincrement,");
query.append(COLUMN_DATETIME+" int)");

//And inserting the data includes this:
values.put(COLUMN_DATETIME, System.currentTimeMillis()); 

¿Por qué hacer esto? En primer lugar, obtener valores de un rango de fechas es fácil. Simplemente convierta su fecha en milisegundos y luego realice la consulta adecuada. Ordenar por fecha es igualmente fácil. Las llamadas para convertir entre varios formatos también son sencillas, como incluí. La conclusión es que, con este método, puedes hacer todo lo que necesites sin problemas. Será un poco difícil leer un valor bruto, pero compensa con creces esa ligera desventaja al ser fácilmente legible y utilizable por máquina. Y, de hecho, es relativamente fácil crear un lector (y sé que hay algunos) que convertirá automáticamente la etiqueta de tiempo a la fecha como tal para facilitar la lectura.

Cabe mencionar que los valores que salgan de esto deben ser long, no int. Un número entero en sqlite puede significar muchas cosas, desde 1 a 8 bytes, pero para casi todas las fechas lo que funciona es 64 bits, o un valor largo.

EDITAR: Como se señaló en los comentarios, debe usar cursor.getLong()para obtener correctamente la marca de tiempo si hace esto.

PearsonArtPhoto avatar Dec 04 '2012 01:12 PearsonArtPhoto

Puede utilizar un campo de texto para almacenar fechas dentro de SQLite.

Almacenar fechas en formato UTC; el valor predeterminado, si lo usa, datetime('now') (yyyy-MM-dd HH:mm:ss)permitirá ordenar por la columna de fecha.

Al recuperar fechas como cadenas, SQLitepuede formatearlas/convertirlas según sea necesario a formatos regionalizados locales utilizando el Calendario o el android.text.format.DateUtils.formatDateTimemétodo.

Aquí hay un método de formateo regionalizado que utilizo;

public static String formatDateTime(Context context, String timeToFormat) {

    String finalDateTime = "";          

    SimpleDateFormat iso8601Format = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    Date date = null;
    if (timeToFormat != null) {
        try {
            date = iso8601Format.parse(timeToFormat);
        } catch (ParseException e) {
            date = null;
        }

        if (date != null) {
            long when = date.getTime();
            int flags = 0;
            flags |= android.text.format.DateUtils.FORMAT_SHOW_TIME;
            flags |= android.text.format.DateUtils.FORMAT_SHOW_DATE;
            flags |= android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
            flags |= android.text.format.DateUtils.FORMAT_SHOW_YEAR;

            finalDateTime = android.text.format.DateUtils.formatDateTime(context,
            when + TimeZone.getDefault().getOffset(when), flags);               
        }
    }
    return finalDateTime;
}
CodeChimp avatar Sep 09 '2011 14:09 CodeChimp
  1. Como se supone en este comentario , siempre uso números enteros para almacenar fechas.
  2. Para almacenar, puede utilizar un método de utilidad.

    public static Long persistDate(Date date) {
        if (date != null) {
            return date.getTime();
        }
        return null;
    }
    

    al igual que:

    ContentValues values = new ContentValues();
    values.put(COLUMN_NAME, persistDate(entity.getDate()));
    long id = db.insertOrThrow(TABLE_NAME, null, values);
    
  3. Otro método de utilidad se encarga de la carga.

    public static Date loadDate(Cursor cursor, int index) {
        if (cursor.isNull(index)) {
            return null;
        }
        return new Date(cursor.getLong(index));
    }
    

    se puede utilizar así:

    entity.setDate(loadDate(cursor, INDEX));
    
  4. Ordenar por fecha es una simple cláusula ORDER de SQL (porque tenemos una columna numérica). Lo siguiente se ordenará de forma descendente (es decir, la fecha más reciente va primero):

    public static final String QUERY = "SELECT table._id, table.dateCol FROM table ORDER BY table.dateCol DESC";
    
    //...
    
        Cursor cursor = rawQuery(QUERY, null);
        cursor.moveToFirst();
    
        while (!cursor.isAfterLast()) {
            // Process results
        }
    

Asegúrese siempre de almacenar la hora UTC/GMT , especialmente cuando trabaje con java.util.Calendarla java.text.SimpleDateFormatzona horaria predeterminada (es decir, la de su dispositivo) y la use. java.util.Date.Date()es seguro de usar ya que crea un valor UTC.

schnatterer avatar Jul 26 '2013 21:07 schnatterer