Android SQLite에서 날짜를 사용하는 가장 좋은 방법입니다.
SQLite를 사용하는 Android 애플리케이션에서 날짜 작업에 문제가 있습니다.몇 가지 질문이 있습니다.
- SQLite(텍스트, 정수 등)에 날짜를 저장하려면 어떤 유형을 사용해야 합니까?
- 날짜를 저장하는 가장 좋은 방법이 주어진 경우 ContentValues를 사용하여 날짜를 올바르게 저장하는 방법은 무엇입니까?
- SQLite 데이터베이스에서 날짜를 검색하는 가장 좋은 방법은 무엇입니까?
- 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;
}
- 이 댓글에서 추정되듯이, 저는 항상 정수를 사용해서 날짜를 저장합니다.
저장에는 유틸리티 방법을 사용할 수 있습니다.
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);다른 유틸리티 방법이 로드를 처리합니다.
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));날짜별로 정렬하는 것은 간단한 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아래는 이를 위한 코드 스니펫입니다.
- 구합니다.
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;
}
- 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에서 데이터를 검색하려면 해당 날짜 시간(밀리초)을 해당 날짜로 변환해야 합니다.다음은 동일한 작업을 수행하기 위한 샘플 코드 조각입니다.
- 날짜(밀리초)를 날짜 문자열로 변환합니다.
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());
}
- 자, 마지막으로 데이터를 가져와 작동 상태를 확인합니다.
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 입니다.
'programing' 카테고리의 다른 글
| Base64 문자열을 디코딩하려면 어떻게 해야 합니까? (0) | 2023.04.25 |
|---|---|
| HTML 표를 Excel에 붙여넣습니다. 줄 바꿈을 셀에 유지하는 방법 (0) | 2023.04.25 |
| Azure 서비스 버스 에뮬레이터입니다. (0) | 2023.04.25 |
| Windows 폼과 비교합니다.WPF입니다. (0) | 2023.04.25 |
| PowerShell의 콘솔에 환경 변수를 인쇄하는 방법은 무엇입니까? (0) | 2023.04.25 |