วิธีการเปรียบเทียบเฉพาะวันที่ไม่มีเวลาในประเภท DateTime ใน Linq กับ SQL ด้วย Entity Framework


303

มีวิธีเปรียบเทียบDateTimeตัวแปรสองตัวLinq2Sqlแต่ไม่สนใจส่วนของเวลาหรือไม่

แอพจัดเก็บรายการต่าง ๆ ในฐานข้อมูลและเพิ่มวันที่เผยแพร่ ฉันต้องการรักษาเวลาที่แน่นอน แต่ก็ยังสามารถดึงตามวันที่ได้

ฉันต้องการเปรียบเทียบ12/3/89 12:43:34และ12/3/89 11:22:12ไม่สนใจเวลาจริงของวันดังนั้นทั้งสองอย่างนี้จึงถือว่าเหมือนกัน

ฉันเดาว่าฉันสามารถตั้งค่าเวลาทั้งหมดของวันเป็น00:00:00ก่อนที่ฉันจะเปรียบเทียบ แต่จริง ๆ แล้วฉันต้องการทราบเวลาของวันที่ฉันแค่ต้องการเปรียบเทียบตามวันที่เท่านั้น

ฉันพบรหัสบางอย่างที่มีปัญหาเดียวกันและพวกเขาเปรียบเทียบปีเดือนและวันแยกจากกัน มีวิธีที่ดีกว่าในการทำเช่นนี้?

คำตอบ:


534

ลองใช้DateคุณสมบัติบนDateTimeวัตถุ ...

if(dtOne.Date == dtTwo.Date)
    ....

25
หากคุณลงเอยที่นี่หลังจากช่วงต้นปี 2017 กำลังมองหาวิธีเปรียบเทียบวันที่ในสภาพแวดล้อม Entity Framework เช่นฉันลองดูคำตอบด้านล่างโดย Alejandro และความคิดเห็นโดย wasatchWizard
Mike Devenney

8
หากคุณลงเอยที่นี่หลังจากกลางปี ​​2018 มองหาวิธีอ่านความคิดเห็นที่เป็นประโยชน์อย่างยิ่งเช่นที่กล่าวมาข้างต้นแสดงว่าคุณไม่มีโชค
nardnob

4
หากคุณสิ้นสุดที่นี่ในช่วงต้นปี 2562 มองหาการ์ตูนโล่งอกคุณจะพบว่า
Phil Ringsmuth

1
นี่ไม่ใช่คำตอบที่ถูกต้องอย่างแน่นอน OP ระบุว่า Linq เป็น SQL และ datetime.date ไม่ได้รับอนุญาตในการแสดงออกของ linq
ฟิลิปจอห์น

2
หากคุณลงเอยที่นี่หลังจากช่วงต้นปี 2563 ฉันหวังว่าคุณจะดูแลตัวเองและอยู่บ้านในช่วงวิกฤตการระบาดของโรคคอโรนาไวรัส กลับไปที่นี่ในปี 2021!
นายอ็อต

61

สำหรับการเปรียบเทียบที่แท้จริงคุณสามารถใช้:

dateTime1.Date.CompareTo(dateTime2.Date);

18
คุณหมายถึงอะไรโดย "การเปรียบเทียบที่แท้จริง"
Randolpho

6
Randolpho: การใช้ == จะให้ความเสมอภาคกับคุณดังนั้นไม่ว่าวันที่สองวันจะเท่ากันหรือแตกต่างกัน CompareTo จะ ~ เปรียบเทียบ ~ พวกเขาเช่น: ให้วิธีการในหนึ่งรอบเพื่อบอกว่า date1> date2, date1 <date2 หรือ date1 == date2
Reed Copsey

6
@ReedCopsey คุณไม่สามารถใช้ (dateTime1.Date <dateTime1.Date) ใช่หรือไม่
David

14
แต่ผู้ที่ต้องการ-1, 0และ1จริงๆ? พวกเขาเป็นเพียงตัวเลขมหัศจรรย์ที่แสดงถึง "น้อยลง", "เท่ากัน" และ "ยิ่งใหญ่" และคุณจะต้อง "เปรียบเทียบ" จำนวนเต็มผลกับบางสิ่งหลังจากนั้นเพราะมีค่าที่เป็นไปได้สามค่า ผมต้องเห็นด้วยกับ @ David ว่ามันเป็นธรรมชาติมากขึ้นกับการใช้งานdateTime1.Date < dateTime1.Dateและเช่นเดียวกันกับ<=, >และ>=ในการใช้งานมากที่สุด
Jeppe Stig Nielsen

8
@JeppeStigNielsen หากคุณกำลังใช้สิ่งนี้ในการเรียงลำดับหรือรับ comaprison คุณก็ต้องการมัน - ไม่เช่นนั้นโดยทั่วไปคุณแค่ต้องการโอเปอเรเตอร์
รี้ Copsey

45

นี่คือวิธีที่ฉันทำเพื่อทำงานกับ LINQ

DateTime date_time_to_compare = DateTime.Now;
//Compare only date parts
context.YourObject.FirstOrDefault(r =>
                EntityFunctions.TruncateTime(r.date) == EntityFunctions.TruncateTime(date_to_compare));

ถ้าคุณใช้dtOne.Date == dtTwo.Dateมันจะไม่ทำงานกับ LINQ (ข้อผิดพลาด: สมาชิกประเภทที่ระบุ 'วันที่' ไม่ได้รับการสนับสนุนใน LINQ ไปยังเอนทิตี)


22
วิธีนี้ใช้งานได้ดีกับ LINQ ไปยังเอนทิตี อย่างไรก็ตามEntityFunctionsได้เลิกใช้แล้วใน. NET 4.5.2 ใช้สิ่งนี้แทน: DbFunctions.TruncateTime. ดูเหมือนว่าจะเป็นวิธีที่เหมือนกันเพิ่งย้าย ..
wasatchwizard

25

หากคุณใช้ Entity Framework <v6.0 ให้ใช้EntityFunctions.TruncateTime ถ้าคุณใช้ Entity Framework> = v6.0 จากนั้นใช้DbFunctions.TruncateTime

ใช้อย่างใดอย่างหนึ่ง (ขึ้นอยู่กับรุ่น EF ของคุณ) รอบ ๆDateTimeคลาสของคุณสมบัติที่คุณต้องการใช้ภายในเคียวรี Linq ของคุณ

ตัวอย่าง

var list = db.Cars.Where(c=> DbFunctions.TruncateTime(c.CreatedDate) 
                                       >= DbFunctions.TruncateTime(DateTime.UtcNow));

เพียงเตือนความทรงจำที่นี่: ตราบใดที่มันเป็น Linq เพื่อกิจการ
อยากรู้อยากเห็นบอย

นี่ควรเป็นคำตอบที่ถูกต้อง (ณ ปี 2562) EntityFunctions ถูกคิดค่าเสื่อมราคาและคุณไม่ได้รับอนุญาตให้ใช้ datetime.date ในรูปแบบแลมบ์ดา (ไม่ว่าด้วยเหตุผลใด - ฉันหมายถึงอย่างจริงจัง ... ทำไมพวกเขาถึงไม่แก้ไขปัญหานี้!
Philip Vaughn

12
DateTime dt1 = DateTime.Now.Date;
DateTime dt2 = Convert.ToDateTime(TextBox4.Text.Trim()).Date;
if (dt1 >= dt2)
{
    MessageBox.Show("Valid Date");
}
else
{
    MessageBox.Show("Invalid Date... Please Give Correct Date....");
}

9
DateTime? NextChoiceDate = new DateTime();
DateTIme? NextSwitchDate = new DateTime();
if(NextChoiceDate.Value.Date == NextSwitchDate.Value.Date)
{
Console.WriteLine("Equal");
}

คุณสามารถใช้สิ่งนี้หากคุณใช้ DateFields เป็นโมฆะ


3
DateTime dt1=DateTime.ParseExact(date1,"dd-MM-yyyy",null);
DateTime dt2=DateTime.ParseExact(date2,"dd-MM-yyyy",null);

int cmp=dt1.CompareTo(dt2);

   if(cmp>0) {
       // date1 is greater means date1 is comes after date2
   } else if(cmp<0) {
       // date2 is greater means date1 is comes after date1
   } else {
       // date1 is same as date2
   }

2
DateTime econvertedDate = Convert.ToDateTime(end_date);
DateTime sconvertedDate = Convert.ToDateTime(start_date);

TimeSpan age = econvertedDate.Subtract(sconvertedDate);
Int32 diff = Convert.ToInt32(age.TotalDays);

ค่า diff แสดงจำนวนวันสำหรับอายุ หากค่าเป็นลบวันที่เริ่มต้นจะอยู่หลังวันที่สิ้นสุด นี่เป็นการตรวจสอบที่ดี


1

คุณสามารถใช้เท่ากับหรือCompareTo

เท่ากับ : ส่งคืนค่าที่ระบุว่าอินสแตนซ์DateTimeสองรายการมีค่าวันที่และเวลาเหมือนกันหรือไม่

CompareTo ค่าส่งคืน :

  1. น้อยกว่าศูนย์ : หากอินสแตนซ์นี้เก่ากว่าค่า
  2. ศูนย์ : หากอินสแตนซ์นี้เหมือนกับค่า
  3. มากกว่าศูนย์ : หากอินสแตนซ์นี้ช้ากว่าค่า

DateTime เป็นโมฆะ:

DateTime? first = new DateTime(1992,02,02,20,50,1);
DateTime? second = new DateTime(1992, 02, 02, 20, 50, 2);

if (first.Value.Date.Equals(second.Value.Date))
{
    Console.WriteLine("Equal");
}

หรือ

DateTime? first = new DateTime(1992,02,02,20,50,1);
DateTime? second = new DateTime(1992, 02, 02, 20, 50, 2);


var compare = first.Value.Date.CompareTo(second.Value.Date);

switch (compare)
{
    case 1:
        Console.WriteLine("this instance is later than value.");
        break;
    case 0:
        Console.WriteLine("this instance is the same as value.");
        break;
    default:
        Console.WriteLine("this instance is earlier than value.");
        break;
}

DateTime ไม่เป็นโมฆะ:

DateTime first = new DateTime(1992,02,02,20,50,1);
DateTime second = new DateTime(1992, 02, 02, 20, 50, 2);

if (first.Date.Equals(second.Date))
{
    Console.WriteLine("Equal");
}

หรือ

DateTime first = new DateTime(1992,02,02,20,50,1);
DateTime second = new DateTime(1992, 02, 02, 20, 50, 2);


var compare = first.Date.CompareTo(second.Date);

switch (compare)
{
    case 1:
        Console.WriteLine("this instance is later than value.");
        break;
    case 0:
        Console.WriteLine("this instance is the same as value.");
        break;
    default:
        Console.WriteLine("this instance is earlier than value.");
        break;
}

0

ในการเข้าร่วมของคุณหรือข้อใดให้ใช้Dateคุณสมบัติของคอลัมน์ เบื้องหลังการดำเนินCONVERT(DATE, <expression>)การนี้ สิ่งนี้จะช่วยให้คุณสามารถเปรียบเทียบวันที่โดยไม่มีเวลา



-16
        int o1 = date1.IndexOf("-");
        int o2 = date1.IndexOf("-",o1 + 1);
        string str11 = date1.Substring(0,o1);
        string str12 = date1.Substring(o1 + 1, o2 - o1 - 1);
        string str13 = date1.Substring(o2 + 1);

        int o21 = date2.IndexOf("-");
        int o22 = date2.IndexOf("-", o1 + 1);
        string str21 = date2.Substring(0, o1);
        string str22 = date2.Substring(o1 + 1, o2 - o1 - 1);
        string str23 = date2.Substring(o2 + 1);

        if (Convert.ToInt32(str11) > Convert.ToInt32(str21))
        {
        }
        else if (Convert.ToInt32(str12) > Convert.ToInt32(str22))
        {
        }
        else if (Convert.ToInt32(str12) == Convert.ToInt32(str22) && Convert.ToInt32(str13) > Convert.ToInt32(str23))
        {
        }

5
-1: ทำไมไม่แยกแค่วันที่และใช้วิธีการของ @Quintin Robinson นี่คือรหัสที่ฉันคาดว่าจะเห็นใน The Daily WTF
William Hurst

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