วิธีที่ดีที่สุดในการทำงานกับวันที่ใน Android SQLite [ปิด]


237

ฉันมีปัญหาในการทำงานกับวันที่ในแอปพลิเคชัน Android ที่ใช้ SQLite ฉันมีคำถามสองสามข้อ:

  1. ฉันควรใช้ประเภทใดในการจัดเก็บวันที่ใน SQLite (ข้อความ, จำนวนเต็ม, ... )
  2. ได้รับวิธีที่ดีที่สุดในการจัดเก็บวันที่ฉันจะจัดเก็บอย่างถูกต้องโดยใช้ ContentValues ​​ได้อย่างไร
  3. วิธีที่ดีที่สุดในการดึงข้อมูลวันที่จากฐานข้อมูล SQLite คืออะไร
  4. วิธีการเลือก sql บน SQLite เรียงลำดับผลลัพธ์ตามวันที่?

2
เพียงใช้คลาสปฏิทินและเวลาสมาชิก (ซึ่งแทนจำนวนมิลลิวินาทีที่ผ่านไปตั้งแต่ 1/1/1970) มีฟังก์ชันสมาชิกสำหรับแปลงค่าเวลาเป็นสตริงที่ผู้ใช้อ่านได้
slayton

คำตอบ:


43

SQLiteคุณสามารถใช้ช่องข้อความให้เป็นวันที่ร้านค้าภายใน

การจัดเก็บวันที่ในรูปแบบ 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;
}

63
คุณจะจัดการกับช่วงวันสอบถามได้อย่างไร
Joe

51
"การปฏิบัติที่แนะนำ"? เสียงไม่ถูกต้อง
ชิม

135
ในปีที่ผ่านมาฉันใช้ SQL ฉันไม่เคยเห็นใครมาก่อนเลยแนะนำให้เก็บวันที่เป็นสตริง หากคุณไม่มีประเภทคอลัมน์วันที่ระบุให้ใช้จำนวนเต็มและเก็บในเวลา Unix (วินาทีนับตั้งแต่ยุค) มันสามารถจัดเรียงและใช้งานได้ในช่วงและแปลงได้อย่างง่ายดาย
mikebabcock

20
การจัดเก็บวันที่เป็นสตริงนั้นใช้ได้ถ้าคุณต้องการเก็บไว้เป็น "ข้อมูล" สิ่งที่คุณดึงและแสดง แต่ถ้าคุณต้องการจัดเก็บวันที่เป็น "ข้อมูล" สิ่งที่จะใช้ได้คุณควรพิจารณาจัดเก็บเป็นจำนวนเต็มตั้งแต่กาลเวลา สิ่งนี้จะช่วยให้คุณสามารถสืบค้นช่วงวันที่ซึ่งเป็นมาตรฐานดังนั้นคุณไม่ต้องกังวลกับการแปลง ฯลฯ การจัดเก็บวันที่เนื่องจากสตริงมี จำกัด มากและฉันอยากจะรู้ว่าใครแนะนำวิธีปฏิบัตินี้เป็นกฎทั่วไป
Krystian

8
เอกสาร SQLiteรายการการจัดเก็บเป็นข้อความ (ISO 8601) เป็นโซลูชั่นที่ทำงานได้สำหรับการจัดเก็บวัน อันที่จริงมันเป็นรายการแรก
anderspitman

211

วิธีที่ดีที่สุดคือการเก็บวันที่เป็นตัวเลขที่ได้รับโดยใช้คำสั่งปฏิทิน

//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 บิตหรือนานกว่านั้นคืออะไร

แก้ไข: ตามที่ได้รับการชี้ให้เห็นในความคิดเห็นที่คุณต้องใช้cursor.getLong()เพื่อให้ได้รับการประทับเวลาอย่างถูกต้องหากคุณทำเช่นนี้


17
ขอบคุณครับ ฮ่า ๆ ฉันคิดถึงการพิมพ์ผิด แต่ฉันหามันไม่เจอ มันต้องถูกค้นคืนโดย cursor.getLong () ไม่ใช่โดย cursor.getInt () ฮ่า ๆ ไม่สามารถหยุดหัวเราะกับตัวเองได้ ขอบคุณอีกครั้ง.
Son Huy TRAN

37
  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 แบบง่าย(เพราะเรามีคอลัมน์ที่เป็นตัวเลข) คำสั่งต่อไปนี้จะเรียงจากมากไปน้อย (ซึ่งเป็นวันที่ใหม่ที่สุดจะไปก่อน):

    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


9

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ใช้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 executable ... )

BTW: ฉันใช้ JDBC (ไม่แน่ใจเกี่ยวกับภาษาอื่น ๆ ) ... ไดรเวอร์ sqlite-jdbc v3.7.2 จากxerial - อาจมีการแก้ไขที่ใหม่กว่าเปลี่ยนพฤติกรรมที่อธิบายไว้ด้านล่าง ... หากคุณกำลังพัฒนาใน Android คุณไม่ ต้องการไดรเวอร์ jdbc การดำเนินงาน SQL SQLiteOpenHelperทั้งหมดสามารถส่งโดยใช้

JDBC มีวิธีการที่แตกต่างกันที่จะได้รับค่าวันที่ / เวลาที่เกิดขึ้นจริงจากฐานข้อมูล: java.sql.Date, และjava.sql.Timejava.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 ที่แท้จริงให้ทั้ง 3 วิธีนี้จึงส่งคืนค่าราวกับว่าวัตถุนั้นเริ่มต้นด้วย 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 (มิลลิวินาทีนับตั้งแต่ยุค) ฉันพบว่าการใช้รูปแบบ SQLite เริ่มต้นง่ายขึ้น ( '%Y-%m-%d %H:%M:%f'หรือใน Java 'yyyy-MM-dd HH:mm:ss.SSS') ค่อนข้างซับซ้อน ฟังก์ชัน SQLite วิธีการแบบเดิมนั้นง่ายกว่ามากในการรักษา

สิ่งที่ต้องทำ: ฉันจะตรวจสอบผลลัพธ์เมื่อใช้ getDate / getTime / getTimestamp ใน Android (API15 หรือดีกว่า) ... บางทีไดรเวอร์ภายในอาจแตกต่างจาก sqlite-jdbc ...


1
ด้วยเอนจินการจัดเก็บข้อมูลภายในของ SQLite ฉันไม่เชื่อว่าตัวอย่างของคุณมีผลกระทบกับคุณ: ดูเหมือนว่าเอ็นจิ้น "อนุญาตให้จัดเก็บค่าประเภทการจัดเก็บในคอลัมน์ใด ๆ โดยไม่คำนึงถึงประเภท SQL ที่ประกาศ" ( books.google.co.th de / … ) ฟังดูแล้วว่าในตัวอย่าง Real vs. Integer vs. Text ของคุณสิ่งที่เกิดขึ้นคือ: SQLite เก็บข้อความเป็นข้อความในคอลัมน์ต้นไม้ทั้งหมด ดังนั้นผลลัพธ์ที่ได้โดยธรรมชาติก็ดีการจัดเก็บก็ยังคงสิ้นเปลือง หากใช้เพียง Integer คุณควรหลวมมิลลิวินาที แค่พูดว่า ...
marco

ในความเป็นจริงคุณสามารถยืนยันสิ่งที่ฉันพูดด้วยการเลือกวันที่และเวลา (col3, 'unixepoch') จาก test_table สิ่งนี้จะแสดงแถวที่ว่างเปล่าสำหรับตัวอย่างของคุณ ... เว้นแต่คุณจะใส่จำนวนเต็มจริง ตัวอย่างเช่นหากคุณต้องการเพิ่มแถวที่มีค่า col3 37 คำสั่ง SELECT ด้านบนจะแสดง: 1970-01-01 00:00:37 ดังนั้นเว้นแต่ว่าคุณจะสบายดีกับการจัดเก็บวันที่ทั้งหมดของคุณแทนที่จะเป็นสตริงข้อความอย่าทำตามที่คุณแนะนำ
marco

เป็นเวลานานแล้วที่ฉันโพสต์คำตอบนี้ ... อาจมีการอัพเดต SQLite สิ่งเดียวที่ฉันคิดได้ก็คือใช้คำสั่ง SQL อีกครั้งกับข้อเสนอแนะของคุณ
miguelt

3

โดยปกติ (เหมือนกับที่ฉันทำใน mysql / postgres) ฉันเก็บวันที่ใน int (mysql / โพสต์) หรือข้อความ (sqlite) เพื่อเก็บไว้ในรูปแบบเวลาประทับ

จากนั้นฉันจะแปลงเป็นวัตถุวันที่และดำเนินการตามผู้ใช้ TimeZone


3

วิธีที่ดีที่สุดในการจัดเก็บdateในSQLite DBDateTimeMillisecondsคือการจัดเก็บในปัจจุบัน ด้านล่างนี้เป็นข้อมูลโค้ดที่ต้องทำ

  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. แทรกข้อมูลในฐานข้อมูลของคุณ
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 .

ขั้นตอนต่อไปคือเมื่อคุณต้องการดึงข้อมูลจากฐานข้อมูลคุณจำเป็นต้องแปลงมิลลิวินาทีเวลาตามลำดับเป็นวันที่ที่เกี่ยวข้อง ด้านล่างนี้เป็นตัวอย่างข้อมูลโค้ดเพื่อทำแบบเดียวกัน _

  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;

}

หวังว่านี่จะช่วยทุกคน! :)


SQLite ไม่รองรับประเภทข้อมูลที่มีความยาว แก้ไข: ความผิดพลาดของฉัน INTEGER ยาว 8 ไบต์ดังนั้นจึงควรสนับสนุนประเภทข้อมูลนี้
Antonio Vlasic


1

ฉันชอบสิ่งนี้ นี่ไม่ใช่วิธีที่ดีที่สุด แต่เป็นวิธีแก้ปัญหาที่รวดเร็ว

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.