[C#] Date comparisons zonder milliseconden

Pagina: 1
Acties:
  • 129 views sinds 30-01-2008
  • Reageer

  • pjonk
  • Registratie: November 2000
  • Laatst online: 22-11 20:39
Vandaag liep ik tegen een stukje code aan die 2 datums ging vergelijken, date1=9-12-2006 17:08:02 en date2=9-12-2006 17:08:02. Hieronder het stukje code:
C#:
1
2
3
4
if (date1 > date2)
{
  // date 1 is nieuwer
}

Tot mijn verbazing was date 1 nieuwer dan date2. Na even uitzoeken kwam ik erachter dat er in date 1 nog 220 milliseconden was opgeslagen en in date2 zaten geen milliseconden. Een DateComparison in C# werkt blijkbaar met een precisie in milliseconden. Ik heb nu zelf een CompareDates geschreven die de milliseconden negeert zie hieronder:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private void button1_Click(object sender, EventArgs e)
{
  DateTime x = new DateTime(2006, 12, 9, 17, 28, 10, 50);
  DateTime y = new DateTime(2006, 12, 9, 17, 28, 10, 0);
  bool result = (x > y); 
  MessageBox.Show(result.ToString()); // geeft true zoals verwacht 50 ms > 0 ms
  result = (CompareDates(x, y) == 0); 
  MessageBox.Show(result.ToString()); // geeft true datums zijn gelijk
}

private int CompareDates(DateTime d1, DateTime d2)
{
  DateTime x = new DateTime(d1.Year, d1.Month, d1.Day, d1.Hour, d1.Minute, d1.Second);
  DateTime y = new DateTime(d2.Year, d2.Month, d2.Day, d2.Hour, d2.Minute, d2.Second);
  if (x < y)
  {
    return -1;
  }
  else if (x == y)
  {
    return 0;
  }
  else
  {
    return 1;
  }
}

Mijn functie werkt dus wel, maar ik vind de manier een beetje omslachtig. Zijn er misschien toch een Date comparsions mogelijk in .NET zonder milliseconden precisie?

[ Voor 0% gewijzigd door pjonk op 09-12-2006 19:05 . Reden: Wel even die enorm slechte fout eruit halen ]

It’s nice to be important but it’s more important to be nice


Verwijderd

Misschien is het mogelijk om in plaats van een uitgebreidere check uit te voeren, gewoon bij elke date de miliseconden te resetten op 000?

  • eek
  • Registratie: Februari 2001
  • Laatst online: 06-04-2020

eek

@MagickNET

Waarom zet je bij het inlezen van die datum uit je database de ms niet op 0?

code:
1
2
DateTime vDate = ReadDateTimeFromDB();
vDate = vDate.AddMilliseconds(-1 * vDate.Millisecond);

Skill is when luck becomes a habit.


  • pjonk
  • Registratie: November 2000
  • Laatst online: 22-11 20:39
AddMilliseconds had ik nog niet aangedacht :). Ik heb mijn functie herschreven, zo werkt hij denk ik nog wat efficienter:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private int CompareDates(DateTime d1, DateTime d2)
{
  d1 = d1.AddMilliseconds(-d1.Millisecond);
  d2 = d2.AddMilliseconds(-d1.Millisecond);
  if (d1 < d2)
  {
    return -1;
  }
  else if (d1 == d2)
  {
    return 0;
  }
  else
  {
    return 1;
  }
}

@Eek: Deze oplossing gaat dus niet werken, want we hebben een nog fijnere eenheid die kan verschillen namelijk ticks. Dan moet ik daar ook weer rekening mee gaan houden. Denk dat ik het bij mijn oorspronkelijke functie ga houden.

[ Voor 21% gewijzigd door pjonk op 09-12-2006 18:45 ]

It’s nice to be important but it’s more important to be nice


  • eek
  • Registratie: Februari 2001
  • Laatst online: 06-04-2020

eek

@MagickNET

Wat je trouwens ook kan doen is:
C#:
1
  return x.CompareTo(y);

Skill is when luck becomes a habit.


  • Dido
  • Registratie: Maart 2002
  • Laatst online: 19:15

Dido

heforshe

Is iets met een timedif < 1 seconde een heel erg eenvoudige optie?

(dus simpel: als tijd 1 - tijd 2 < 1 seconde, dan zijn ze gelijk. Ik denk vast veel te simpel, er zijn vast heel goede redenen om aparte functies te schrijven voor zoiets :D )

[ Voor 57% gewijzigd door Dido op 11-12-2006 11:13 ]

Wat betekent mijn avatar?


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:52

.oisyn

Moderator Devschuur®

Demotivational Speaker

Dido schreef op maandag 11 december 2006 @ 11:11:
Is iets met een timedif < 1 seconde een heel erg eenvoudige optie?
Nee. Als je even puur naar de seconden kijkt: de tijden 2.9 en 3.1 verschillen maar 200 milliseconden, toch zouden ze in dit geval als verschillend gezien moeten worden.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • DaCoTa
  • Registratie: April 2002
  • Laatst online: 17:51
Ik ken C# niet, maar dit soort geintjes zijn volgens mij nogal duur. Kun je niet ergens de julian date (of whatever milliseconde notatie er in C# zit) vandaan toveren en die beide delen door 1000, voor je gaat vergelijken? Zeker als deze code vaak uitgevoerd moet worden.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:52

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik ken C# niet
Klopt. DateTime is namelijk een value-type object, en de new alloceert dus geen memory :)
Maar evt. zou je nog dit kunnen doen:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private int CompareDates(DateTime d1, DateTime d2) 
{ 
    long t1 =
        10000000000L * d1.Year +
          100000000L * d1.Month +
            1000000L * d1.Day +
              10000L * d1.Hour +
                100L * d1.Minute +
                       d1.Second;

    long t2 =
        10000000000L * d2.Year +
          100000000L * d2.Month +
            1000000L * d2.Day +
              10000L * d2.Hour +
                100L * d2.Minute +
                       d2.Second;

    return Math.Sign(t1 - t2);
}


Nog makkelijker (en het efficientst) is:
C#:
1
2
3
4
5
6
private int CompareDates(DateTime d1, DateTime d2) 
{ 
    long t1 = d1.Ticks / 10000;
    long t2 = d2.Ticks / 10000;
    return Math.Sign(t1 - t2);
}

Maar ik weet niet of dat wel goed werkt ivm schrikkelseconden e.d.

[ Voor 88% gewijzigd door .oisyn op 11-12-2006 15:24 . Reden: cruciaal woordje 'niet' vergeten :P ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • TimTil
  • Registratie: Mei 2005
  • Laatst online: 19-10 20:19
Probeer anders dit eens :

C#:
1
2
3
4
if(date1.Ticks > date2.Ticks)
{
   // Date1 is recenter
}

  • Plekuz
  • Registratie: September 2002
  • Laatst online: 23-07 21:42

Plekuz

available in strong mint

eek schreef op maandag 11 december 2006 @ 10:51:
Wat je trouwens ook kan doen is:
C#:
1
  return x.CompareTo(y);
Precies (net ff anders maar ok), dan wordt de CompareDates functie van de TS een stuk kleiner, maar één functie namelijk:

C#:
1
2
3
  return DateTime.Compare(
     new DateTime(d1.Year, d1.Month, d1.Day, d1.Hour, d1.Minute, d1.Second), 
     new DateTime(d2.Year, d2.Month, d2.Day, d2.Hour, d2.Minute, d2.Second));

[ Voor 6% gewijzigd door Plekuz op 11-12-2006 17:04 ]

"There he goes. One of God's own prototypes. Some kind of high powered mutant never even considered for mass production. Too weird to live, and too rare to die."


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 14:52

.oisyn

Moderator Devschuur®

Demotivational Speaker

TimTil schreef op maandag 11 december 2006 @ 13:05:
Probeer anders dit eens :

C#:
1
2
3
4
if(date1.Ticks > date2.Ticks)
{
   // Date1 is recenter
}
Hoe lost dat het milliseconde probleem op dan?
Weakling schreef op maandag 11 december 2006 @ 13:19:
[...]


Precies (net ff anders maar ok), dan wordt je eigen compare functie een stuk kleiner, maar 1 regel namelijk:

C#:
1
  return DateTime.Compare(new DateTime(d1.Year, d1.Month, d1.Day, d1.Hour, d1.Minute, d1.Second), new DateTime(d2.Year, d2.Month, d2.Day, d2.Hour, d2.Minute, d2.Second));
1 regel != beter leesbaar of efficienter.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Plekuz
  • Registratie: September 2002
  • Laatst online: 23-07 21:42

Plekuz

available in strong mint

.oisyn schreef op maandag 11 december 2006 @ 14:04:
1 regel != beter leesbaar of efficienter.
Leesbaar mee eens en aangepast. Efficienter is alleen maar te bepalen door een performance test. Het kan efficienter zijn, of net zo efficient of minder efficient. Dat is vooraf niet zondermeer te bepalen. Overigens, daarmee bedoel ik dus efficientie door de functie van de TS te herschrijven naar 1 regel code en niet efficientie door identieke code in 1 regel te proppen, want dat zet geen zoden aan de dijk ;)

[ Voor 22% gewijzigd door Plekuz op 11-12-2006 17:58 ]

"There he goes. One of God's own prototypes. Some kind of high powered mutant never even considered for mass production. Too weird to live, and too rare to die."


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
ik ben net vandaag begonnen met C#, maar ik gooi het even over een andere boeg (:P dit heb ik nog niet gezien op inet)

Bij VisualBasic6 kon je dit voor elkaar krijgen door te definieren welk gedeelte van een datum je wilde bekijken. dan wordt het iets als

Visual Basic:
1
2
3
4
5
Dim dDate1 As Date
Dim dDate2 As Date

'vergelijk functie
If dDate1(DD, MM, YY) > dDate2(DD, MM, YY) Then MsgBox "tada"


Niet zeker of dit werkt, je zou ook kunnen proberen om dag maand en jaar uit te lezen, deze in een array te pompen, en dan te vergelijken.

~ Mijn prog blog!

Pagina: 1