@@ -419,6 +419,249 @@ static void Main(string[] args)
419419 } ) ;
420420 }
421421
422+ [ TestMethod ]
423+ public void DateTimeOffsetLessThanDateTime_ProducesDiagnostic ( )
424+ {
425+ string source = @"
426+ using System;
427+ using System.Threading;
428+
429+ namespace ConsoleApp1
430+ {
431+ internal class Program
432+ {
433+ static void Main(string[] args)
434+ {
435+ DateTimeOffset first = DateTimeOffset.Now;
436+
437+ Thread.Sleep(10);
438+
439+ DateTime second = DateTime.Now;
440+
441+ if (first < second)
442+ {
443+ Console.WriteLine(""Time has passed..."");
444+ }
445+ }
446+ }
447+ }" ;
448+
449+ VerifyCSharpDiagnostic ( source ,
450+ new DiagnosticResult
451+ {
452+ Id = "INTL0202" ,
453+ Severity = DiagnosticSeverity . Warning ,
454+ Message = "Using 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' or 'new DateTimeOffset(DateTime)' can result in unpredictable behavior" ,
455+ Locations =
456+ [
457+ new DiagnosticResultLocation ( "Test0.cs" , 17 , 25 )
458+ ]
459+ } ) ;
460+ }
461+
462+ [ TestMethod ]
463+ public void NullableDateTimeOffsetLessThanDateTime_ProducesDiagnostic ( )
464+ {
465+ string source = @"
466+ using System;
467+ using System.Threading;
468+
469+ namespace ConsoleApp1
470+ {
471+ internal class Program
472+ {
473+ static void Main(string[] args)
474+ {
475+ DateTimeOffset? first = DateTimeOffset.Now;
476+
477+ Thread.Sleep(10);
478+
479+ DateTime second = DateTime.Now;
480+
481+ if (first < second)
482+ {
483+ Console.WriteLine(""Time has passed..."");
484+ }
485+ }
486+ }
487+ }" ;
488+
489+ VerifyCSharpDiagnostic ( source ,
490+ new DiagnosticResult
491+ {
492+ Id = "INTL0202" ,
493+ Severity = DiagnosticSeverity . Warning ,
494+ Message = "Using 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' or 'new DateTimeOffset(DateTime)' can result in unpredictable behavior" ,
495+ Locations =
496+ [
497+ new DiagnosticResultLocation ( "Test0.cs" , 17 , 25 )
498+ ]
499+ } ) ;
500+ }
501+
502+ [ Ignore ]
503+ [ TestMethod ]
504+ public void PropertyBasedDateTimeLessThanDateTimeOffset_ProducesDiagnostic ( )
505+ {
506+ string source = @"
507+ using System;
508+
509+ namespace ConsoleApp1
510+ {
511+ class Pair
512+ {
513+ public DateTime DateTime { get; set; }
514+ public DateTimeOffset DateTimeOffset { get; set; }
515+ }
516+
517+ internal class Program
518+ {
519+ static void Main(string[] args)
520+ {
521+ Pair pair = new Pair();
522+ _ = pair.DateTime < pair.DateTimeOffset;
523+ }
524+ }
525+ }" ;
526+
527+ VerifyCSharpDiagnostic ( source ,
528+ new DiagnosticResult
529+ {
530+ Id = "INTL0202" ,
531+ Severity = DiagnosticSeverity . Warning ,
532+ Message = "Using 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' or 'new DateTimeOffset(DateTime)' can result in unpredictable behavior" ,
533+ Locations =
534+ [
535+ new DiagnosticResultLocation ( "Test0.cs" , 18 , 17 )
536+ ]
537+ } ) ;
538+ }
539+
540+ [ Ignore ]
541+ [ TestMethod ]
542+ public void PropertyComparisonInsideLinqLambda_ProducesDiagnostic ( )
543+ {
544+ string source = @"
545+ using System;
546+ using System.Collections.Generic;
547+ using System.Linq;
548+
549+ namespace ConsoleApp1
550+ {
551+ class Pair
552+ {
553+ public DateTime DateTime { get; set; }
554+ public DateTimeOffset DateTimeOffset { get; set; }
555+ }
556+
557+ internal class Program
558+ {
559+ static void Main(string[] args)
560+ {
561+ List<Pair> list = new List<Pair>();
562+ _ = list.Where(pair => pair.DateTime < pair.DateTimeOffset);
563+ }
564+ }
565+ }" ;
566+
567+ VerifyCSharpDiagnostic ( source ,
568+ new DiagnosticResult
569+ {
570+ Id = "INTL0202" ,
571+ Severity = DiagnosticSeverity . Warning ,
572+ Message = "Using 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' or 'new DateTimeOffset(DateTime)' can result in unpredictable behavior" ,
573+ Locations =
574+ [
575+ new DiagnosticResultLocation ( "Test0.cs" , 20 , 36 )
576+ ]
577+ } ) ;
578+ }
579+
580+ [ Ignore ]
581+ [ TestMethod ]
582+ public void ExtractedPropertyVariablesInLinqLambda_ProducesDiagnostic ( )
583+ {
584+ string source = @"
585+ using System;
586+ using System.Collections.Generic;
587+ using System.Linq;
588+
589+ namespace ConsoleApp1
590+ {
591+ class Pair
592+ {
593+ public DateTime DateTime { get; set; }
594+ public DateTimeOffset DateTimeOffset { get; set; }
595+ }
596+
597+ internal class Program
598+ {
599+ static void Main(string[] args)
600+ {
601+ List<Pair> list = new List<Pair>();
602+ _ = list.Where(pair =>
603+ {
604+ DateTime dt = pair.DateTime;
605+ DateTimeOffset dto = pair.DateTimeOffset;
606+ return dt < dto;
607+ });
608+ }
609+ }
610+ }" ;
611+
612+ VerifyCSharpDiagnostic ( source ,
613+ new DiagnosticResult
614+ {
615+ Id = "INTL0202" ,
616+ Severity = DiagnosticSeverity . Warning ,
617+ Message = "Using 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' or 'new DateTimeOffset(DateTime)' can result in unpredictable behavior" ,
618+ Locations =
619+ [
620+ new DiagnosticResultLocation ( "Test0.cs" , 24 , 24 )
621+ ]
622+ } ) ;
623+ }
624+
625+ [ Ignore ]
626+ [ TestMethod ]
627+ public void IQueryableWhereWithDateTimePropertyComparison_ProducesDiagnostic ( )
628+ {
629+ string source = @"
630+ using System;
631+ using System.Linq;
632+
633+ namespace ConsoleApp1
634+ {
635+ class TimeEntry
636+ {
637+ public DateTimeOffset EndDate { get; set; }
638+ }
639+
640+ internal class Program
641+ {
642+ static DateTimeOffset EndDate { get; set; }
643+
644+ static void Main(string[] args)
645+ {
646+ IQueryable<TimeEntry> entries = null;
647+ _ = entries.Where(te => te.EndDate <= EndDate.Date.AddDays(1).AddTicks(-1));
648+ }
649+ }
650+ }" ;
651+
652+ VerifyCSharpDiagnostic ( source ,
653+ new DiagnosticResult
654+ {
655+ Id = "INTL0202" ,
656+ Severity = DiagnosticSeverity . Warning ,
657+ Message = "Using 'DateTimeOffset.implicit operator DateTimeOffset(DateTime)' or 'new DateTimeOffset(DateTime)' can result in unpredictable behavior" ,
658+ Locations =
659+ [
660+ new DiagnosticResultLocation ( "Test0.cs" , 20 , 44 )
661+ ]
662+ } ) ;
663+ }
664+
422665 protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer ( )
423666 {
424667 return new Analyzers . BanImplicitDateTimeToDateTimeOffsetConversion ( ) ;
0 commit comments