programing

Android SQLite에서 날짜를 사용하는 가장 좋은 방법입니다.

fastcode 2023. 4. 25. 23:10
반응형

Android SQLite에서 날짜를 사용하는 가장 좋은 방법입니다.

SQLite를 사용하는 Android 애플리케이션에서 날짜 작업에 문제가 있습니다.몇 가지 질문이 있습니다.

  1. SQLite(텍스트, 정수 등)에 날짜를 저장하려면 어떤 유형을 사용해야 합니까?
  2. 날짜를 저장하는 가장 좋은 방법이 주어진 경우 ContentValues를 사용하여 날짜를 올바르게 저장하는 방법은 무엇입니까?
  3. SQLite 데이터베이스에서 날짜를 검색하는 가장 좋은 방법은 무엇입니까?
  4. SQLite에서 SQL을 선택하고 결과를 날짜별로 정렬하려면 어떻게 해야 합니까?

가장 좋은 방법은 달력 명령을 사용하여 수신한 날짜를 숫자로 저장하는 것입니다.

//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()); 

왜 이런 짓을 하죠?먼저, 날짜 범위에서 값을 쉽게 얻을 수 있습니다.날짜를 밀리초로 변환한 다음 적절하게 쿼리하십시오.날짜별로 정렬하는 것도 마찬가지로 쉽습니다.여러 형식 간에 변환하는 호출도 마찬가지로 쉽습니다.요컨대 이 방법을 사용하면 필요한 모든 작업을 문제 없이 수행할 수 있습니다.원시 값을 읽는 것은 약간 어렵지만, 기계 판독이 쉽고 사용이 용이하다는 단점만 보완할 수는 없습니다.그리고 실제로 읽기 쉽도록 자동으로 시간 태그를 최신 상태로 변환하는 판독기를 만드는 것은 비교적 쉽습니다.

여기서 나오는 값은 int가 아니라 길어야 합니다.sqlite의 정수는 1~8바이트의 여러 가지 의미를 가질 수 있지만, 거의 모든 날짜에서 64비트 또는 긴 값이 작동합니다.

편집 댓글에 지적된 것처럼 집:: the서서서 the the the, the the the음음음음음이다를 사용해야 합니다.cursor.getLong()이렇게 하면 타임스탬프를 제대로 얻을 수 있습니다.

텍스트 필드를 하여 날짜를 저장할 수 있습니다.SQLite요.

UTC 형식으로 저장, UTC를 사용할 경우 기본값입니다.datetime('now') (yyyy-MM-dd HH:mm:ss)이겁니다.

날짜를 문자열로 검색하는 중입니다.SQLite그런 달력을 사용하거나 지역별 형식으로 필요에 따라 변환할 수 있습니다.android.text.format.DateUtils.formatDateTime네, 그렇습니다.

다음은 제가 사용하는 지역별 포메터 방법입니다.

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;
}
  1. 이 댓글에서 추정되듯이, 저는 항상 정수를 사용해서 날짜를 저장합니다.
  2. 저장에는 유틸리티 방법을 사용할 수 있습니다.

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

    이렇게요:

    ContentValues values = new ContentValues();
    values.put(COLUMN_NAME, persistDate(entity.getDate()));
    long id = db.insertOrThrow(TABLE_NAME, null, values);
    
  3. 다른 유틸리티 방법이 로드를 처리합니다.

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

    다음과 같이 사용할 수 있습니다.

    entity.setDate(loadDate(cursor, INDEX));
    
  4. 날짜별로 정렬하는 것은 간단한 SQL ORDER 절입니다(숫자 열이 있으므로).다음은 내림차순입니다(최신 날짜가 먼저 표시됨).

    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
        }
    

항상 UTC/GMT 시간을 저장하십시오(특히 작업 시).java.util.Calendar그리고요.java.text.SimpleDateFormat기본(즉, 장치의 표준 시간대)을 사용합니다. java.util.Date.Date()UTC입니다.

SQLite는 텍스트, 실제 또는 정수 데이터 유형을 사용하여 날짜를 저장할 수 있습니다.또한 쿼리를 수행할 때마다 결과가 형식을 사용하여 표시됩니다.%Y-%m-%d %H:%M:%S요.

이제 SQLite 날짜/시간 함수를 사용하여 날짜/시간 값을 삽입/업데이트하면 실제로 밀리초도 저장할 수 있습니다.이 경우 결과는 형식을 사용하여 표시됩니다.%Y-%m-%d %H:%M:%f이겁니다.

sqlite> create table test_table(col1 text, col2 real, col3 integer);
sqlite> insert into test_table values (
            strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.123'),
            strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.123'),
            strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.123')
        );
sqlite> insert into test_table values (
            strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.126'),
            strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.126'),
            strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.126')
        );
sqlite> select * from test_table;
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
2014-03-01 13:01:01.126|2014-03-01 13:01:01.126|2014-03-01 13:01:01.126

이제 실제로 시간을 비교할 수 있는지 확인하기 위해 몇 가지 쿼리를 수행합니다.

sqlite> select * from test_table /* using col1 */
           where col1 between 
               strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.121') and
               strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.125');
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123

똑같이 확인하실 수 있습니다.SELECT용 using를 사용해서.col2그리고요.col3이겁니다.보시다시피 두 번째 행(126밀리초)은 반환되지 않습니다.

주의하세요.BETWEEN아, 그래요?

sqlite> select * from test_table 
            where col1 between 
                 /* Note that we are using 123 milliseconds down _here_ */
                strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.123') and
                strftime('%Y-%m-%d %H:%M:%f', '2014-03-01 13:01:01.125');

...는 동일한 세트를 반환합니다.

다른 날짜/시간 범위로 재생해 보십시오. 그러면 모든 것이 예상대로 작동합니다.

없으면 어떨까요?strftime동합?????

sqlite> select * from test_table /* using col1 */
           where col1 between 
               '2014-03-01 13:01:01.121' and
               '2014-03-01 13:01:01.125';
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123

없으면 어떨까요?strftime기능을 수행하는데 밀리초가 필요합니까?

sqlite> select * from test_table /* using col1 */
           where col1 between 
               '2014-03-01 13:01:01' and
               '2014-03-01 13:01:02';
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
2014-03-01 13:01:01.126|2014-03-01 13:01:01.126|2014-03-01 13:01:01.126

때어는요?ORDER BY무슨 일입니까

sqlite> select * from test_table order by 1 desc;
2014-03-01 13:01:01.126|2014-03-01 13:01:01.126|2014-03-01 13:01:01.126
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
sqlite> select * from test_table order by 1 asc;
2014-03-01 13:01:01.123|2014-03-01 13:01:01.123|2014-03-01 13:01:01.123
2014-03-01 13:01:01.126|2014-03-01 13:01:01.126|2014-03-01 13:01:01.126

잘 먹히네요.

마지막으로, 프로그램 내에서 실제 작업을 처리할 때(sqlite 실행 파일을 사용하지 않고...)입니다.

BTW: JDBC를 사용하고 있습니다(다른 언어는 잘 모르겠습니다).xerial의 sqlite-jdbc 드라이버 v3.7.2 - 새 개정판으로 아래 설명된 동작이 변경될 수 있습니다.안드로이드를 개발한다면 jdbc 드라이버가 필요 없습니다.모든 SQL 작업은 다음을 사용하여 제출할 수 있습니다.SQLiteOpenHelper요.

JDBC에는 데이터베이스에서 실제 날짜/시간 값을 가져오는 여러 가지 방법이 있습니다. java.sql.Date, , 입니다.java.sql.Time , 그리고 ,면 됩니다.java.sql.Timestamp요.

그럼 에 나와 있는 관련 방법들은요.java.sql.ResultSet이(가) 있습니다.getDate(..), , 입니다.getTime(..) , 그리고 ,면 됩니다.getTimestamp()이겁니다.

예를 들어 다음과 같습니다.

Statement stmt = ... // Get statement from connection
ResultSet rs = stmt.executeQuery("SELECT * FROM TEST_TABLE");
while (rs.next()) {
    System.out.println("COL1 : "+rs.getDate("COL1"));
    System.out.println("COL1 : "+rs.getTime("COL1"));
    System.out.println("COL1 : "+rs.getTimestamp("COL1"));
    System.out.println("COL2 : "+rs.getDate("COL2"));
    System.out.println("COL2 : "+rs.getTime("COL2"));
    System.out.println("COL2 : "+rs.getTimestamp("COL2"));
    System.out.println("COL3 : "+rs.getDate("COL3"));
    System.out.println("COL3 : "+rs.getTime("COL3"));
    System.out.println("COL3 : "+rs.getTimestamp("COL3"));
}
// close rs and stmt.

SQLite에는 실제 DATE/TIME/TIMESTamp 데이터 유형이 없으므로 다음 세 가지 메서드는 모두 개체가 0으로 초기화된 것처럼 값을 반환합니다.

new java.sql.Date(0)
new java.sql.Time(0)
new java.sql.Timestamp(0)

그렇다면 실제로 Date/Time/Timestamp 개체를 선택, 삽입 또는 업데이트하려면 어떻게 해야 합니까?쉬운 답은 없어요.여러 가지 조합을 시도할 수 있지만 SQLite 함수를 모든 SQL 문에 포함하도록 강제합니다.Java 프로그램 내에서 텍스트를 날짜 개체로 변환하는 유틸리티 클래스를 훨씬 쉽게 정의할 수 있습니다.그러나 SQLite는 모든 날짜 값을 UTC+0000으로 변환합니다.

요약하자면, 항상 올바른 데이터 유형이나 Unix 시간(Epoch 이후 밀리초)을 나타내는 정수까지 사용해야 하는 일반적인 규칙에도 불구하고 기본 SQLite 형식을 사용하는 것이 훨씬 쉽습니다.'%Y-%m-%d %H:%M:%f'또는 Java입니다.'yyyy-MM-dd HH:mm:ss.SSS'대신 SQLite 함수로 모든 SQL 문을 복잡하게 만듭니다.이전 접근 방식은 유지하기가 훨씬 쉽습니다.

TODO: Android에서 getDate/getTime/getTimestamp를 사용할 때 결과를 확인합니다(API15 이상).내부 드라이버가 sqlite-jdbc와 다를 수 있습니다...

일반적으로(mysql/postgres에서와 동일) 날짜를 int(mysql/post) 또는 text(sqlite)로 저장하여 타임스탬프 형식으로 저장합니다.

그런 다음 Date 개체로 변환하고 사용자 TimeZone을 기반으로 작업을 수행합니다.

저장하는 가장 좋은 방법입니다.dateSQLite DB는 현재를 저장하는 것입니다.DateTimeMilliseconds아래는 이를 위한 코드 스니펫입니다.

  1. 구합니다.DateTimeMilliseconds
public static long getTimeMillis(String dateString, String dateFormat) throws ParseException {
    /*Use date format as according to your need! Ex. - yyyy/MM/dd HH:mm:ss */
    String myDate = dateString;//"2017/12/20 18:10:45";
    SimpleDateFormat sdf = new SimpleDateFormat(dateFormat/*"yyyy/MM/dd HH:mm:ss"*/);
    Date date = sdf.parse(myDate);
    long millis = date.getTime();

    return millis;
}
  1. DB에 데이터를 삽입합니다.
public void insert(Context mContext, long dateTimeMillis, String msg) {
    //Your DB Helper
    MyDatabaseHelper dbHelper = new MyDatabaseHelper(mContext);
    database = dbHelper.getWritableDatabase();

    ContentValues contentValue = new ContentValues();
    contentValue.put(MyDatabaseHelper.DATE_MILLIS, dateTimeMillis);
    contentValue.put(MyDatabaseHelper.MESSAGE, msg);

    //insert data in DB
    database.insert("your_table_name", null, contentValue);

   //Close the DB connection.
   dbHelper.close(); 

}

Now, your data (date is in currentTimeMilliseconds) is get inserted in DB .

다음 단계에서는 DB에서 데이터를 검색하려면 해당 날짜 시간(밀리초)을 해당 날짜로 변환해야 합니다.다음은 동일한 작업을 수행하기 위한 샘플 코드 조각입니다.

  1. 날짜(밀리초)를 날짜 문자열로 변환합니다.
public static String getDate(long milliSeconds, String dateFormat)
{
    // Create a DateFormatter object for displaying date in specified format.
    SimpleDateFormat formatter = new SimpleDateFormat(dateFormat/*"yyyy/MM/dd HH:mm:ss"*/);

    // Create a calendar object that will convert the date and time value in milliseconds to date.
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(milliSeconds);
    return formatter.format(calendar.getTime());
}
  1. 자, 마지막으로 데이터를 가져와 작동 상태를 확인합니다.
public ArrayList<String> fetchData() {

    ArrayList<String> listOfAllDates = new ArrayList<String>();
    String cDate = null;

    MyDatabaseHelper dbHelper = new MyDatabaseHelper("your_app_context");
    database = dbHelper.getWritableDatabase();

    String[] columns = new String[] {MyDatabaseHelper.DATE_MILLIS, MyDatabaseHelper.MESSAGE};
    Cursor cursor = database.query("your_table_name", columns, null, null, null, null, null);

    if (cursor != null) {

        if (cursor.moveToFirst()){
            do{
                //iterate the cursor to get data.
                cDate = getDate(cursor.getLong(cursor.getColumnIndex(MyDatabaseHelper.DATE_MILLIS)), "yyyy/MM/dd HH:mm:ss");

                listOfAllDates.add(cDate);

            }while(cursor.moveToNext());
        }
        cursor.close();

    //Close the DB connection.
    dbHelper.close(); 

    return listOfAllDates;

}

이것이 모두에게 도움이 되기를 바랍니다! :)

1 - SterMi가 말한 그대로입니다.

2 - 다음 문서를 읽어보십시오. http://www.vogella.de/articles/AndroidSQLite/article.html

3 -

Cursor cursor = db.query(TABLE_NAME, new String[] {"_id", "title", "title_raw", "timestamp"}, 
                "//** YOUR REQUEST**//", null, null, "timestamp", null);

여기를 참조하십시오.

SQLiteDatabase에 Query()가 있습니다.

4 - 정답 3을 참조하십시오.

저는 이게 더 좋아요.이것이 최선의 방법이 아니라 빠른 해결책입니다.

//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_CREATION_DATE+" DATE)");

//Inserting the data includes this:
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
values.put(COLUMN_CREATION_DATE,dateFormat.format(reactionGame.getCreationDate())); 

// Fetching the data includes this:
try {
   java.util.Date creationDate = dateFormat.parse(cursor.getString(0);
   YourObject.setCreationDate(creationDate));
} catch (Exception e) {
   YourObject.setCreationDate(null);
}
"SELECT  "+_ID+" ,  "+_DESCRIPTION +","+_CREATED_DATE +","+_DATE_TIME+" FROM "+TBL_NOTIFICATION+" ORDER BY "+"strftime(%s,"+_DATE_TIME+") DESC";

언급URL : https://stackoverflow.com/questions/7363112/best-way-to-work-with-dates-in-android-sqlite 입니다.

반응형