web-dev-qa-db-ja.com

.NET DateTimeからミリ秒を切り捨てる方法

着信リクエストからのタイムスタンプをデータベースに保存されている値と比較しようとしています。もちろん、SQL Serverはミリ秒単位の精度を保持しており、.NET DateTimeに読み込まれると、それらのミリ秒が含まれます。ただし、システムへの着信要求ではその精度が得られないため、ミリ秒単位で単純にドロップする必要があります。

明らかな何かを見逃しているように感じますが、エレガントな方法を見つけていません(C#)。

300
Jeff Putz

以下は、ミリ秒の小数部を持つDateTimeで機能し、Kindプロパティ(Local、Utc、またはUndefined)も保持します。

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

または同等の短い:

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

これは、拡張メソッドに一般化できます。

public static DateTime Truncate(this DateTime dateTime, TimeSpan timeSpan)
{
    if (timeSpan == TimeSpan.Zero) return dateTime; // Or could throw an ArgumentException
    if (dateTime == DateTime.MinValue || dateTime == DateTime.MaxValue) return dateTime; // do not modify "guard" values
    return dateTime.AddTicks(-(dateTime.Ticks % timeSpan.Ticks));
}

次のように使用されます。

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
...
508
Joe
var date = DateTime.Now;

date = new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second, date.Kind);
133
benPearce

これは、以前の回答に基づいた拡張方法であり、任意の解像度に切り捨てることができます...

使用法:

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

クラス:

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);
    }
}
48
Sky Sanders
DateTime d = DateTime.Now;
d = d.AddMilliseconds(-d.Millisecond);
27
chris.w.mclean

ミリ秒を削除してから比較する代わりに、違いを比較してみませんか?

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

または

TimeSpan precision = TimeSpan.FromSeconds(1);
bool areEqual = (x-y).Duration() < precision;
9
Bob

それほど明白ではないが、2倍以上高速:

// 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
Diadistis

年や月など、カレンダーに基づいたものに切り捨てたい場合があります。以下に、任意の解像度を選択できる拡張メソッドを示します。

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
KingPong

シンプル...

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

もっと...

//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
Sergio Cabral

秒に切り捨てるには:

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

TicksPerMinuteに置き換えて、分に切り捨てます。


コードがパフォーマンスに敏感な場合、注意が必要です

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

私のアプリは System.DateTime.GetDatePart でCPU時間の12%を費やしていました。

1
Colonel Panic

Diadistisの応答について。これは私にとってはうまくいきましたが、乗算の前に除算の小数部分を削除するためにFloorを使用しなければなりませんでした。そう、

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

になる

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

2つのLong値を除算するとLongになり、小数部分が削除されると予想していましたが、乗算後に正確に同じ値を残してDoubleとして解決します。

てんかん

1
eppsy

新しい方法

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

//文字列パスパラメータdd-mmm-yyyyを定義します

またはテキストボックスに表示

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

// PageonLoadを配置します

1
Dhawal Shukal

2上記のソリューションの拡張方法

    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;
    }

使用法:

bool liesAfter = myObject.DateProperty.LiesAfterOrEqualsIgnoringMilliseconds(startDateTime, DateTimeKind.Utc);
1
HerbalMart
DateID.Text = DateTime.Today.ToShortDateString();

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

そしての使用によって

ToLongDateString() // its show 19 February 2016.

:P

1
Dhawal Shukal

私の場合、秒とミリ秒を保存せずに、datetimePickerツールからTimeSpanを保存することを目指していました。これが解決策です。

最初にdatetimePicker.valueを目的の形式(「HH:mm」)に変換してから、TimeSpanに変換します。

var datetime = datetimepicker1.Value.ToString("HH:mm");
TimeSpan timeSpan = Convert.ToDateTime(datetime).TimeOfDay;
0
Thinker Bell