Есть ли лучший способ обрезать DateTime с определенной точностью?
Какой лучший способ обрезать объект DateTime с определенной точностью? Например, если у меня есть DateTime со значением '2008-09-29 09:41:43', но я хочу только, чтобы точность была на минуту, есть ли лучший способ сделать это, чем это?
private static DateTime TrimDateToMinute(DateTime date)
{
return new DateTime(
date.Year,
date.Month,
date.Day,
date.Hour,
date.Minute,
0);
}
Мне бы очень хотелось, чтобы он был переменным, чтобы я мог установить его точность во вторую, минуту, час или день.
Ответы
Ответ 1
static class Program
{
//using extension method:
static DateTime Trim(this DateTime date, long roundTicks)
{
return new DateTime(date.Ticks - date.Ticks % roundTicks, date.Kind);
}
//sample usage:
static void Main(string[] args)
{
Console.WriteLine(DateTime.Now);
Console.WriteLine(DateTime.Now.Trim(TimeSpan.TicksPerDay));
Console.WriteLine(DateTime.Now.Trim(TimeSpan.TicksPerHour));
Console.WriteLine(DateTime.Now.Trim(TimeSpan.TicksPerMillisecond));
Console.WriteLine(DateTime.Now.Trim(TimeSpan.TicksPerMinute));
Console.WriteLine(DateTime.Now.Trim(TimeSpan.TicksPerSecond));
Console.ReadLine();
}
}
Ответ 2
Вы можете использовать перечисление
public enum DateTimePrecision
{
Hour, Minute, Second
}
public static DateTime TrimDate(DateTime date, DateTimePrecision precision)
{
switch (precision)
{
case DateTimePrecision.Hour:
return new DateTime(date.Year, date.Month, date.Day, date.Hour, 0, 0);
case DateTimePrecision.Minute:
return new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, 0);
case DateTimePrecision.Second:
return new DateTime(date.Year, date.Month, date.Day, date.Hour, date.Minute, date.Second);
default:
break;
}
}
и развернуть по мере необходимости.
Ответ 3
Есть несколько хороших решений, представленных здесь, но когда мне нужно это сделать, я просто делаю:
DateTime truncDate;
truncDate = date.Date; // trim to day
truncDate = date.Date + TimeSpan.Parse(string.Format("{0:HH:00:00}", date)); // trim to hour
truncDate = date.Date + TimeSpan.Parse(string.Format("{0:HH:mm}", date)); // trim to minute
truncDate = date.Date + TimeSpan.Parse(string.Format("{0:HH:mm:ss}", date)); // trim to second
Надеюсь, что это поможет.
Ответ 4
Мне нравится этот метод. Кто-то упомянул, что было бы хорошо сохранить тип даты и т.д. Это достигается потому, что вам не нужно создавать новый объект DateTime. DateTime правильно клонируется из исходного DateTime и просто вычитает оставшиеся отметки.
private DateTime FloorToMinute(DateTime dt)
{
return dt.AddTicks(-1 * (dt.Ticks % TimeSpan.TicksPerMinute));
}
Ответ 5
static DateTime TrimDate(DateTime date, long roundTicks)
{
return new DateTime(date.Ticks - date.Ticks % roundTicks);
}
//sample usage:
static void Main(string[] args)
{
Console.WriteLine(DateTime.Now);
Console.WriteLine(TrimDate(DateTime.Now, TimeSpan.TicksPerDay));
Console.WriteLine(TrimDate(DateTime.Now, TimeSpan.TicksPerHour));
Console.WriteLine(TrimDate(DateTime.Now, TimeSpan.TicksPerMillisecond));
Console.WriteLine(TrimDate(DateTime.Now, TimeSpan.TicksPerMinute));
Console.WriteLine(TrimDate(DateTime.Now, TimeSpan.TicksPerSecond));
Console.ReadLine();
}
Ответ 6
DateTime dt = new DateTime()
dt = dt.AddSeconds(-dt.Second)
Выше кода будет обрезать секунды.
Ответ 7
Если у вас есть время & date как (непрерывный) номер, похожий на time_t, вы можете просто использовать modulo для получения полных минут (% 60), часов и т.д.
По моему опыту, значения, похоже, совпадают с реальным временем (по модулю 60 происходит в полную минуту), но это, скорее всего, не гарантируется нигде.
Вот код, чтобы получить то, что вы хотите (с подсезонным разрешением):
/*
* Returns millisecond timing (in seconds) for the current time.
*
* Note: This function should be called once in single-threaded mode in Win32,
* to get it initialized.
*/
double now_secs(void) {
#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
/*
* Windows FILETIME values are "100-nanosecond intervals since
* January 1, 1601 (UTC)" (MSDN). Well, we'd want Unix Epoch as
* the offset and it seems, so would they:
*
* <http://msdn.microsoft.com/en-us/library/ms724928(VS.85).aspx>
*/
SYSTEMTIME st;
FILETIME ft;
ULARGE_INTEGER uli;
static ULARGE_INTEGER uli_epoch; // Jan 1st 1970 0:0:0
if (uli_epoch.HighPart==0) {
st.wYear= 1970;
st.wMonth= 1; // Jan
st.wDay= 1;
st.wHour= st.wMinute= st.wSecond= st.wMilliseconds= 0;
//
st.wDayOfWeek= 0; // ignored
if (!SystemTimeToFileTime( &st, &ft ))
FAIL( "SystemTimeToFileTime", GetLastError() );
uli_epoch.LowPart= ft.dwLowDateTime;
uli_epoch.HighPart= ft.dwHighDateTime;
}
GetSystemTime( &st ); // current system date/time in UTC
if (!SystemTimeToFileTime( &st, &ft ))
FAIL( "SystemTimeToFileTime", GetLastError() );
uli.LowPart= ft.dwLowDateTime;
uli.HighPart= ft.dwHighDateTime;
/* 'double' has less accuracy than 64-bit int, but if it were to degrade,
* it would do so gracefully. In practise, the integer accuracy is not
* of the 100ns class but just 1ms (Windows XP).
*/
return (double)(uli.QuadPart - uli_epoch.QuadPart) / 10000000.0;
#else
struct timeval tv;
// {
// time_t tv_sec; /* seconds since Jan. 1, 1970 */
// suseconds_t tv_usec; /* and microseconds */
// };
int rc= gettimeofday( &tv, NULL /*time zone not used any more (in Linux)*/ );
assert( rc==0 );
return ((double)tv.tv_sec) + ((tv.tv_usec)/1000) / 1000.0;
#endif
}