Я пытаюсь восстановить некоторые данные из базы данных SQLite, у которой дата меньше сегодняшней. Достал день из календаря, желаемого результата не дает:

Calendar cal = Calendar.getInstance(); 
    int dayofmonth = cal.get(Calendar.DAY_OF_MONTH);
String sql = "SELECT SUM(filed1) FROM Table1 WHERE "+Table1.DATE+"<= '%"+dayofmonth+"'";
1
user2847219 10 Апр 2014 в 02:33

2 ответа

Лучший ответ

Поскольку формат ваших данных - YYYY-MM-DD, т.е. компоненты даты упорядочены от наиболее значимого до наименее значимого и дополнены нулями, вы можете использовать здесь обычные сравнения строк.

Сначала создайте строку в том же формате, что и сегодня, например.

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String today = sdf.format(new Date());

Затем используйте эту строку в своем SQL, например.

String sql = ... " WHERE " + Table1.DATE + " < ?";
String[] bindArgs = new String[] { today };
Cursor c = db.rawQuery(sql, bindArgs);
4
laalto 10 Апр 2014 в 07:24

ТЛ ; др

String sql =                                                  // Create the text of your SQL statement to be executed.
    "SELECT SUM( number_col ) FROM tbl WHERE date_col <= '"   // Include the name of the date column to be compared. Should be part of your string literal.
    + LocalDate.now( ZoneId.of( "Pacific/Auckland" ) )        // Capture the current date per the wall-clock time used by the people of a particular region (a time zone). 
        .toString()                                           // Generate a string in standard ISO 8601 to represent the value of this `LocalDate` value.
    + "' ;"                                                   // A proper SQL statement is terminated with a semicolon. Omitted from the Question’s example code.
;

Java.time

Современный подход использует классы java.time , которые вытеснили проблемные устаревшие классы Date, Calendar и SimpleDateFormat.

В вашем комментарии говорится, что вы храните только даты в SQLite в виде текста в стандартном формате ISO 8601: YYYY. -ММ-ДД.

Для значения только даты в Java используйте класс LocalDate. Класс LocalDate представляет значение только для даты без времени суток и без часового пояса.

Часовой пояс имеет решающее значение при определении даты. В любой момент времени дата меняется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париже Франция новый день, пока еще " вчера "в Монреаль-Квебек.

Если часовой пояс не указан, JVM неявно применяет свой текущий часовой пояс по умолчанию. Это значение по умолчанию может измениться в любой момент, поэтому ваши результаты могут отличаться. Лучше явно указать желаемый / ожидаемый часовой пояс в качестве аргумента.

Укажите правильное имя часового пояса в формате continent/region, например America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 3-4-буквенное сокращение, такое как EST или IST, поскольку они являются не истинными часовыми поясами, не стандартизированы и даже не уникальны (!).

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

Если вы хотите использовать текущий часовой пояс JVM по умолчанию, попросите его и передайте в качестве аргумента. Если опущено, текущее значение по умолчанию JVM применяется неявно. Лучше быть явным, поскольку значение по умолчанию может быть изменено в любой момент во время выполнения любым кодом в любом потоке любого приложения в JVM.

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

Или укажите дату. Вы можете установить месяц по номеру, с нормальным номером 1-12 для января-декабря.

LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ;  // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.

Или, лучше, используйте Month < / a> объекты перечисления предопределены, по одному на каждый месяц года. Совет: используйте эти объекты Month во всей кодовой базе, а не просто целое число, чтобы сделать ваш код более самодокументированным, обеспечить допустимые значения и предоставить типобезопасность.

LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;

Сгенерируйте строку в стандартном формате, просто вызвав toString.

String dateText = LocalDate.now( z ).toString() ;

Добавьте в свою строку SQL. Ваша строка SQL была неправильной в том смысле, что имя столбца должно быть частью текста SQL. Он должен быть частью вашего строкового литерала, но вы исключили его, что не имеет смысла в контексте Java.

String sql = "SELECT SUM( number_col ) FROM tbl WHERE date_col <= '" + dateText + "' ;" ;

Это отображает строку, например:

SELECT SUM( number_col ) FROM tbl WHERE when_col <= '2018-01-23' ;

О java.time

java.time фреймворк встроен в Java 8 и новее. Эти классы заменяют неудобные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time , теперь в режим обслуживания, советует перейти на java.time.

Чтобы узнать больше, см. Руководство по Oracle . И поиск переполнения стека для многих примеров и объяснений. Спецификация - JSR 310.

Вы можете обмениваться объектами java.time непосредственно с вашей базой данных. Используйте драйвер JDBC, совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?

  • Java SE 8 , Java SE 9 , и позже
      < Li> Встроенный .
    • Часть стандартного Java API с связанной реализацией.
    • Java 9 добавляет некоторые мелкие функции и исправления.
  • Java SE 6 а также Java SE 7
    • Большая часть функций java.time перенесена на Java 6 и 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии реализаций пакетов Android для классов java.time.
    • Для более ранних версий Android (<26) ThreeTenABP адаптирует проект ThreeTen-Backport (упомянутый выше). См. Как использовать ThreeTenABP… .
0
Basil Bourque 27 Мар 2018 в 01:24