Comment tronquer des millisecondes de a.NET DateTime

j'essaie de comparer un horodatage d'une requête entrante à une valeur stockée dans une base de données. SQL Server garde bien sûr une précision de millisecondes sur le temps, et lorsqu'il est lu dans un .net DateTime, il inclut ces millisecondes. La requête entrante au système, cependant, n'offre pas cette précision, donc je dois simplement laisser tomber les millisecondes.

j'ai l'impression de rater quelque chose d'évident, mais je n'ai pas trouvé une manière élégante de le faire (C#).

270
demandé sur Jeff Putz 2009-06-17 05:43:19

13 réponses

ce qui suit fonctionnera pour une DateTime qui a une fraction de millisecondes, et préserve également la propriété Kind (Local, Utc ou non défini).

DateTime dateTime = ... anything ...
dateTime = new DateTime(
    dateTime.Ticks - (dateTime.Ticks % TimeSpan.TicksPerSecond), 
    dateTime.Kind
    );

ou l'équivalent et plus court:

dateTime = dateTime.AddTicks( - (dateTime.Ticks % TimeSpan.TicksPerSecond));

cela pourrait être généralisé en une méthode d'extension:

public static DateTime Truncate(this DateTime dateTime, TimeSpan timeSpan)
{
    if (timeSpan == TimeSpan.Zero) return dateTime; // Or could throw an ArgumentException
    return dateTime.AddTicks(-(dateTime.Ticks % timeSpan.Ticks));
}

, qui est utilisé comme suit:

dateTime = dateTime.Truncate(TimeSpan.FromMilliseconds(1)); // Truncate to whole ms
dateTime = dateTime.Truncate(TimeSpan.FromSeconds(1)); // Truncate to whole second
dateTime = dateTime.Truncate(TimeSpan.FromMinutes(1)); // Truncate to whole minute
...
471
répondu Joe 2014-02-25 06:56:46
var date = DateTime.Now;

date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Kind);
122
répondu benPearce 2015-04-30 07:49:28

Voici une méthode d'extension basée sur une réponse précédente qui vous permettra de tronquer à n'importe quelle résolution...

Utilisation:

DateTime myDateSansMilliseconds = myDate.Truncate(TimeSpan.TicksPerSecond);
DateTime myDateSansSeconds = myDate.Truncate(TimeSpan.TicksPerMinute)

Classe:

public static class DateTimeUtils
{
    /// <summary>
    /// <para>Truncates a DateTime to a specified resolution.</para>
    /// <para>A convenient source for resolution is TimeSpan.TicksPerXXXX constants.</para>
    /// </summary>
    /// <param name="date">The DateTime object to truncate</param>
    /// <param name="resolution">e.g. to round to nearest second, TimeSpan.TicksPerSecond</param>
    /// <returns>Truncated DateTime</returns>
    public static DateTime Truncate(this DateTime date, long resolution)
    {
        return new DateTime(date.Ticks - (date.Ticks % resolution), date.Kind);
    }
}
41
répondu Sky Sanders 2010-04-21 09:40:29
DateTime d = DateTime.Now;
d = d.AddMilliseconds(-d.Millisecond);
27
répondu chris.w.mclean 2009-06-17 01:45:57

au lieu de laisser tomber les millisecondes puis de comparer, pourquoi ne pas comparer la différence?

DateTime x; DateTime y;
bool areEqual = (x-y).TotalSeconds == 0;

ou

TimeSpan precision = TimeSpan.FromSeconds(1);
bool areEqual = (x-y).Duration() < precision;
9
répondu Bob 2009-06-17 01:55:33

moins évident mais plus de 2 fois plus rapide:

// 10000000 runs

DateTime d = DateTime.Now;

// 484,375ms
d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);

// 1296,875ms
d = d.AddMilliseconds(-d.Millisecond);
8
répondu Diadistis 2009-06-17 03:04:31

parfois vous voulez tronquer à quelque chose de calendrier basé, comme l'année ou le mois. Voici une méthode d'extension qui vous permet de choisir n'importe quelle résolution.

public enum DateTimeResolution
{
    Year, Month, Day, Hour, Minute, Second, Millisecond, Tick
}

public static DateTime Truncate(this DateTime self, DateTimeResolution resolution = DateTimeResolution.Second)
{
    switch (resolution)
    {
        case DateTimeResolution.Year:
            return new DateTime(self.Year, 1, 1, 0, 0, 0, 0, self.Kind);
        case DateTimeResolution.Month:
            return new DateTime(self.Year, self.Month, 1, 0, 0, 0, self.Kind);
        case DateTimeResolution.Day:
            return new DateTime(self.Year, self.Month, self.Day, 0, 0, 0, self.Kind);
        case DateTimeResolution.Hour:
            return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerHour));
        case DateTimeResolution.Minute:
            return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerMinute));
        case DateTimeResolution.Second:
            return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerSecond));
        case DateTimeResolution.Millisecond:
            return self.AddTicks(-(self.Ticks % TimeSpan.TicksPerMillisecond));
        case DateTimeResolution.Tick:
            return self.AddTicks(0);
        default:
            throw new ArgumentException("unrecognized resolution", "resolution");
    }
}
8
répondu KingPong 2014-03-02 03:07:28

Simple...

//Remove milliseconds
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH:mm:ss"), "yyyy-MM-dd HH:mm:ss", null);

et plus...

//Remove seconds
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH:mm"), "yyyy-MM-dd HH:mm", null);

//Remove minutes
DateTime date = DateTime.Now;
date = DateTime.ParseExact(date.ToString("yyyy-MM-dd HH"), "yyyy-MM-dd HH", null);

//and go on...
2
répondu Sergio Cabral 2017-09-02 01:22:53

concernant la réponse de Diadistis. Cela a fonctionné pour moi, sauf que j'ai dû utiliser le plancher pour enlever la partie fractionnaire de la division avant la multiplication. So,

d = new DateTime((d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);

devient

d = new DateTime(Math.Floor(d.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond);

Je m'attendais à ce que la division de deux valeurs longues aboutisse à une longue, supprimant ainsi la partie décimale, mais elle se résout comme un Double laissant la même valeur exacte après la multiplication.

Eppsy

1
répondu 2009-07-22 07:15:49

2 méthodes D'Extension pour les solutions mentionnées ci-dessus

    public static bool LiesAfterIgnoringMilliseconds(this DateTime theDate, DateTime compareDate, DateTimeKind kind)
    {
        DateTime thisDate = new DateTime(theDate.Year, theDate.Month, theDate.Day, theDate.Hour, theDate.Minute, theDate.Second, kind);
        compareDate = new DateTime(compareDate.Year, compareDate.Month, compareDate.Day, compareDate.Hour, compareDate.Minute, compareDate.Second, kind);

        return thisDate > compareDate;
    }


    public static bool LiesAfterOrEqualsIgnoringMilliseconds(this DateTime theDate, DateTime compareDate, DateTimeKind kind)
    {
        DateTime thisDate = new DateTime(theDate.Year, theDate.Month, theDate.Day, theDate.Hour, theDate.Minute, theDate.Second, kind);
        compareDate = new DateTime(compareDate.Year, compareDate.Month, compareDate.Day, compareDate.Hour, compareDate.Minute, compareDate.Second, kind);

        return thisDate >= compareDate;
    }

utilisation:

bool liesAfter = myObject.DateProperty.LiesAfterOrEqualsIgnoringMilliseconds(startDateTime, DateTimeKind.Utc);
1
répondu HerbalMart 2012-07-13 11:00:56
DateID.Text = DateTime.Today.ToShortDateString();

Use ToShortDateString() //Date 2-02-2016
Use ToShortDateString() // Time 

Et Par Utilisation De

ToLongDateString() // its show 19 February 2016.

: P

1
répondu Dhawal Shukal 2016-02-19 16:27:21

Nouvelle Méthode

String Date = DateTime.Today.ToString("dd-MMM-yyyy"); 

// définition de la Chaîne de passer le paramètre jj-mmm-aaaa retour 24-feb-2016

ou indiqué sur la boîte de texte

txtDate.Text = DateTime.Today.ToString("dd-MMM-yyyy");

// mettre sur PageonLoad

1
répondu Dhawal Shukal 2016-02-24 19:11:07

d'arrondir À la baisse pour la deuxième:

dateTime.AddTicks(-dateTime.Ticks % TimeSpan.TicksPerSecond)

remplacer par TicksPerMinute pour arrondir à la minute.


si votre code est sensible aux performances, soyez prudent à propos de

new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second)

mon application passait 12% du temps CPU dans le système .DateTime.GetDatePart .

0
répondu Colonel Panic 2016-10-25 08:42:53