ฉันจะได้รับความแตกต่างระหว่างวันที่ 2 วันใน SQLite ได้อย่างไร ฉันได้ลองสิ่งนี้แล้ว:
SELECT Date('now') - DateCreated FROM Payment
มันจะคืนค่า 0 ทุกครั้ง
ฉันจะได้รับความแตกต่างระหว่างวันที่ 2 วันใน SQLite ได้อย่างไร ฉันได้ลองสิ่งนี้แล้ว:
SELECT Date('now') - DateCreated FROM Payment
มันจะคืนค่า 0 ทุกครั้ง
คำตอบ:
SELECT julianday('now') - julianday(DateCreated) FROM Payment;
DateCreated
อยู่ใน UTC หากเป็นเวลาท้องถิ่นคุณต้องแปลงjulianday('now')
เป็นเวลาท้องถิ่นแทน ฉันไม่พบที่ใดที่มีข้อมูลนี้ หากคุณทำjulianday('now') - julianday(DateCreated)
เช่นเดียวกับที่โพสต์นี้แนะนำด้วยวันที่ที่จัดเก็บในเวลาท้องถิ่นคำตอบของคุณจะไม่ถูกต้องตามการชดเชยจาก GMT และจะไม่ถูกต้อง แม้ว่าอาจจะไม่ใช่แนวทางปฏิบัติที่ดีที่สุดในการจัดเก็บวันที่ในเวลาท้องถิ่น แต่ก็ยังสามารถเกิดขึ้นได้ในแอปที่เขตเวลาไม่สำคัญ (ยกเว้นเมื่อเครื่องมือที่คุณกำลังทำงานบังคับใช้กับคุณเช่นที่นี่)
julianday('now') - julianday(DateCreated, 'utc')
เพื่อให้ทั้งสอง UTC julianday('now', 'localtime') - julianday(DateCreated)
ก็ไม่ได้ทำงานแบบเดียวกับที่ทำ เดิมไม่มีบัญชีสำหรับวัน DST และจะเพิ่มชั่วโมงพิเศษในวันที่สร้างในเดือน มี.ค. - พ.ย. หลังทำบัญชีได้จริง stackoverflow.com/questions/41007455/…
ความแตกต่างในแต่ละวัน
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) As Integer)
ความแตกต่างในชั่วโมง
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 As Integer)
ความแตกต่างในนาที
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 As Integer)
ความแตกต่างในไม่กี่วินาที
Select Cast ((
JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 * 60 As Integer)
คำตอบทั้งสองให้คำตอบที่ซับซ้อนขึ้นเล็กน้อยอย่างที่ควรจะเป็น January 6, 2013
กล่าวว่าการชำระเงินที่ถูกสร้างขึ้นบน และเราต้องการทราบความแตกต่างระหว่างวันที่นี้กับวันนี้
sqlite> SELECT julianday() - julianday('2013-01-06');
34.7978485878557
ความแตกต่างคือ 34 วัน เราสามารถใช้julianday('now')
เพื่อความชัดเจนที่ดีขึ้น กล่าวอีกนัยหนึ่งเราไม่จำเป็นต้องใส่
date()
หรือdatetime()
ทำหน้าที่เป็นพารามิเตอร์ในการjulianday()
ทำงาน
เอกสาร SQLite เป็นข้อมูลอ้างอิงที่ดีและหน้าDateAndTimeFunctionsเป็นสิ่งที่ดีในการบุ๊กมาร์ก
นอกจากนี้ยังมีประโยชน์ที่จะต้องจำไว้ว่ามันค่อนข้างง่ายที่จะเล่นกับแบบสอบถามด้วยยูทิลิตี้บรรทัดคำสั่ง sqlite:
sqlite> select julianday(datetime('now'));
2454788.09219907
sqlite> select datetime(julianday(datetime('now')));
2008-11-17 14:13:55
คำตอบนี้ยืดยาวเล็กน้อยและเอกสารจะไม่บอกคุณในเรื่องนี้ (เพราะถือว่าคุณจัดเก็บวันที่ของคุณเป็นวันที่ UTC ในฐานข้อมูล) แต่คำตอบสำหรับคำถามนี้ส่วนใหญ่ขึ้นอยู่กับเขตเวลาที่จัดเก็บวันที่ของคุณ นอกจากนี้คุณยังไม่ได้ใช้Date('now')
แต่ใช้julianday()
ฟังก์ชันเพื่อคำนวณวันที่ทั้งสองย้อนหลังเทียบกับวันที่ทั่วไปจากนั้นลบความแตกต่างของผลลัพธ์เหล่านั้นออกจากกัน
หากวันที่ของคุณถูกเก็บไว้ใน UTC:
SELECT julianday('now') - julianday(DateCreated) FROM Payment;
นี่คือสิ่งที่คำตอบอันดับต้น ๆ มีและอยู่ในเอกสารด้วย มันเป็นเพียงส่วนหนึ่งของภาพและเป็นคำตอบที่ง่ายมากถ้าคุณถามฉัน
หากวันที่ที่คุณจะถูกเก็บไว้ในเวลาท้องถิ่นโดยใช้โค้ดข้างต้นจะทำให้คำตอบของคุณผิดจากจำนวนชั่วโมงค่าชดเชย GMT คือ ถ้าคุณอยู่ในสหรัฐอเมริกาฝั่งตะวันออกเหมือนฉันซึ่งก็คือ GMT -5 ผลลัพธ์ของคุณจะมีเวลาเพิ่มอีก 5 ชั่วโมง และหากคุณพยายามทำให้DateCreated
สอดคล้องกับ UTC เนื่องจากjulianday('now')
ขัดกับวันที่ GMT:
SELECT julianday('now') - julianday(DateCreated, 'utc') FROM Payment;
สิ่งนี้มีข้อบกพร่องที่จะเพิ่มชั่วโมงสำหรับเวลาDateCreated
ที่อยู่ในช่วงเวลาออมแสง (มีนาคม - พฤศจิกายน) สมมติว่า "ตอนนี้" เป็นเวลาเที่ยงของวันที่ไม่ใช่ DST และคุณได้สร้างบางสิ่งกลับมาในเดือนมิถุนายน (ในช่วง DST) ตอนเที่ยงผลลัพธ์ของคุณจะให้เวลาห่างกัน 1 ชั่วโมงแทนที่จะเป็น 0 ชั่วโมงสำหรับส่วนของชั่วโมง คุณต้องเขียนฟังก์ชันในโค้ดของแอปพลิเคชันของคุณที่แสดงผลลัพธ์เพื่อแก้ไขผลลัพธ์และลบหนึ่งชั่วโมงจากวันที่ DST ฉันทำอย่างนั้นจนกระทั่งฉันรู้ว่ามีวิธีแก้ปัญหาที่ดีกว่าสำหรับปัญหานั้น: SQLite กับ Oracle - การคำนวณความแตกต่างของวันที่ - ชั่วโมง
ตามที่ได้ชี้ให้ฉันทราบสำหรับวันที่ที่จัดเก็บในเวลาท้องถิ่นให้ทั้งคู่ตรงกับเวลาท้องถิ่น:
SELECT julianday('now', 'localtime') - julianday(DateCreated) FROM Payment;
หรือต่อท้าย'Z'
เวลาท้องถิ่น:
julianday(datetime('now', 'localtime')||'Z') - julianday(CREATED_DATE||'Z')
ทั้งสองอย่างนี้ดูเหมือนจะชดเชยและไม่เพิ่มชั่วโมงพิเศษสำหรับวันที่ DST และทำการลบแบบตรง - ดังนั้นรายการที่สร้างขึ้นตอนเที่ยงของวัน DST เมื่อตรวจสอบตอนเที่ยงของวันที่ไม่ใช่ DST จะไม่ได้รับชั่วโมงพิเศษเมื่อ ทำการคำนวณ
และในขณะที่ฉันรับรู้ส่วนใหญ่จะบอกว่าอย่าจัดเก็บวันที่ในเวลาท้องถิ่นในฐานข้อมูลของคุณและเก็บไว้ใน UTC ดังนั้นคุณจะไม่พบปัญหานี้ไม่ใช่ว่าทุกแอปพลิเคชันจะมีผู้ชมทั่วโลกและไม่ใช่โปรแกรมเมอร์ทุกคนที่ต้องการ เพื่อดำเนินการแปลงทุกวันที่ในระบบเป็น UTC และกลับมาอีกครั้งทุกครั้งที่ทำ GET หรือ SET ในฐานข้อมูลและจัดการกับการหาว่ามีบางอย่างอยู่ในท้องถิ่นหรือใน UTC
เพียงบันทึกสำหรับการเขียนฟังก์ชันจับเวลา สำหรับผู้ที่กำลังมองหาชั่วโมงทำงานการเปลี่ยนแปลงที่ง่ายมากทำให้ชั่วโมงบวกนาทีแสดงเป็นเปอร์เซ็นต์ 60 ตามที่ บริษัท รับเงินเดือนส่วนใหญ่ต้องการ
CAST ((julianday(clockOUT) - julianday(clockIN)) * 24 AS REAL) AS HoursWorked
Clock In Clock Out HoursWorked
2016-08-07 11:56 2016-08-07 18:46 6.83333332836628
หากคุณต้องการเวลาในรูปแบบ 00:00: ฉันแก้ไขแบบนั้น:
select strftime('%H:%M',CAST ((julianday(FinishTime) - julianday(StartTime)) AS REAL),'12:00') from something
ระบุว่ารูปแบบวันที่ของคุณเป็นดังนี้: "YYYY-MM-DD HH: MM: SS" หากคุณต้องการค้นหาความแตกต่างระหว่างวันที่สองวันในจำนวนเดือน:
(strftime('%m', date1) + 12*strftime('%Y', date1)) -
(strftime('%m', date2) + 12*strftime('%Y', date2))
ประการแรกไม่ชัดเจนว่ารูปแบบวันที่ของคุณคืออะไร มีคำตอบที่เกี่ยวข้องstrftime("%s")
อยู่แล้ว
ฉันต้องการขยายคำตอบนั้น
SQLite มีเฉพาะคลาสหน่วยเก็บข้อมูลต่อไปนี้: NULL, INTEGER, REAL, TEXT หรือ BLOB เพื่อให้ง่ายขึ้นฉันจะถือว่าวันที่เป็นจริงประกอบด้วยวินาทีตั้งแต่ 1970-01-01 นี่คือตัวอย่างสคีมาที่ฉันจะใส่ในข้อมูลตัวอย่างของ "1 ธันวาคม 2018":
CREATE TABLE Payment (DateCreated REAL);
INSERT INTO Payment VALUES (strftime("%s", "2018-12-01"));
ตอนนี้เรามาดูความแตกต่างของวันที่ระหว่าง "1 ธันวาคม 2018" กับตอนนี้ (ตามที่ผมเขียนไว้คือเที่ยงวันที่ 12 ธันวาคม 2018):
วันที่ต่างกันเป็นวัน:
SELECT (strftime("%s", "now") - DateCreated) / 86400.0 FROM Payment;
-- Output: 11.066875
วันที่ต่างกันเป็นชั่วโมง:
SELECT (strftime("%s", "now") - DateCreated) / 3600.0 FROM Payment;
-- Output: 265.606388888889
ความแตกต่างของวันที่เป็นนาที:
SELECT (strftime("%s", "now") - DateCreated) / 60.0 FROM Payment;
-- Output: 15936.4833333333
ความแตกต่างของวันที่เป็นวินาที:
SELECT (strftime("%s", "now") - DateCreated) FROM Payment;
-- Output: 956195.0
หากคุณต้องการความแตกต่างในไม่กี่วินาที
SELECT strftime('%s', '2019-12-02 12:32:53') - strftime('%s', '2019-12-02 11:32:53')
หากคุณต้องการบันทึกระหว่างวัน
select count(col_Name) from dataset where cast(julianday("now")- julianday(_Last_updated) as int)<=0;
ในกรณีของฉันฉันต้องคำนวณความแตกต่างเป็นนาทีและjulianday()
ไม่ได้ให้ค่าที่ถูกต้อง ฉันใช้strftime()
:
SELECT (strftime('%s', [UserEnd]) - strftime('%s', [UserStart])) / 60
วันที่ทั้งสองจะถูกแปลงเป็น unixtime (วินาที) จากนั้นลบออกเพื่อให้ได้ค่าเป็นวินาทีระหว่างวันที่ทั้งสอง ถัดไปหารด้วย 60