#c# #.net #linq #string.format
#c# #.net #linq #string.format
Вопрос:
Я пытаюсь вычесть 2 даты и времени и получить разницу во времени в формате минут и секунд, но как округлить разницу до ближайших секунд в строковом формате.
У меня есть даты, подобные приведенным ниже:
1)
StartDate= 2016-10-11 04:31:06.513 EndDate= 2016-10-11 04:31:09.457
Differrence : 2.94
Output I am getting is : 00 : 02
Expected Output : 00 : 03 (round up time to the nearest)
2)
StartDate = 2016-10-14 16:43:18.530 EndDate= 2016-10-14 16:43:50.457
Difference : 31.93
Output I am getting is : 00 : 31
Expected Output : 00 : 32 (round up time to the nearest)
Вот приведенный ниже запрос linq, я пытаюсь вычислить разницу во времени:
var output = Attendance.Select
(
t => new
{
TimeDifference = string.Format("{0:00}:{1:00}", (int)t.EndDateTime.Value.Subtract(t.StartDateTime.Value).Minutes, (int)t.EndDateTime.Value.Subtract(t.StartDateTime.Value).Seconds),
}
).ToList()
Комментарии:
1. Внимание при чтении ответов: поскольку в вопросе не указано, что должно произойти со значением like
3.1
, большинство ответов интерпретировали «округление» как «любое дробное значение должно быть округлено в большую сторону», поэтому предлагается «Математика. Потолок». Например.Math.Ceiling(3.1)
=>4
. Если вместо этого вы хотите «округлять только значения 0,5 и больше», вместо этого используйте »Math.Round
» в ответе.
Ответ №1:
Как сказал Dawnkeeper в своем ответе, вы должны использовать математику.Потолок, но вместо получения Seconds
свойства вы должны использовать TimeSpan .Итоговые секунды, например:
var TimeDifference = string.Format("{0:00}:{1:00}", (int)EndDateTime.Subtract(StartDateTime).Minutes, (int)Math.Ceiling(EndDateTime.Subtract(StartDateTime).TotalSeconds));
Редактировать
Хенрик прав, приведенный выше код не работает. Давайте сделаем это правильно:
var diff=EndDateTime.Subtract(StartDateTime);
double seconds= Math.Ceiling(diff.Seconds diff.Milliseconds*0.001);
var TimeDifference = string.Format("{0:00}:{1:00}",diff.Minutes,seconds);
Сейчас я нахожусь на своем телефоне, поэтому не могу попробовать, но я думаю, что это должно сработать
Комментарии:
1. Мне жаль писать это, но это решение потерпит неудачу, если промежуток времени превысит 1 минуту, потому что TotalSeconds включает в себя весь промежуток времени (годы, часы, дни, минуты, секунды, миллисекунды).
2. @HenrikHansen: Можете ли вы дать мне пример ввода, при котором этот приведенный выше ответ завершится неудачей??
3. @Learning: начало даты и времени = новая дата и время(2016, 10, 11, 04, 30, 06, 513); Дата-время окончания = новая дата-время(2016, 10, 11, 04, 31, 09, 457);
4. @Хенрихансен: Вы правы. Это не работает с приведенными выше данными, которые вы ввели
5. @ToolmakerSteve согласился. Я был просто удивлен, но, конечно, я рад, что вы прояснили вопрос на случай, если кто-то попадет сюда в поисках чего-то другого.
Ответ №2:
Вы также могли бы сделать это:
DateTime start = new DateTime(2016, 10, 11, 04, 31, 06, 513);
DateTime end = new DateTime(2016, 10, 11, 04, 31, 09, 457);
var diff = end - start;
Console.WriteLine($"{diff.Hours:00}:{diff.Minutes:00}:{diff.Seconds diff.Milliseconds / 1000.0:00}");
Ответ №3:
Для этого вы можете использовать Math.Ceiling()
функцию.
(int)Math.Ceiling(t.EndDateTime.Value.Subtract(t.StartDateTime.Value).Seconds)
Но есть еще одна проблема. Seconds
свойство получает полные секунды в виде целых чисел. Вам также понадобятся частичные секунды, поэтому правильный ответ:
(int)Math.Ceiling(t.EndDateTime.Value.Subtract(t.StartDateTime.Value).TotalSeconds)
Комментарии:
1. Получение ошибки: вызов неоднозначен между следующими методами или свойствами: System.Math. Потолок (двойной) и System.Math. Потолок (десятичный)
2. Исправьте это так (int) Математика. Потолок ((Двойной) т. EndDateTime. Значение. Вычесть(т.StartDateTime. Значение). Секунды)
3. @Learning исправил это
4. @ToolmakerSteve Это именно то, что было целью, Округление
Ответ №4:
Вы говорите «округлить», и вы получите это с Потолком, как уже было сказано. Но что бы вы сделали, если бы были такие времена?:
2016-10-10 00:00:00.000
2016-10-10 00:00:00.001
Следует ли считать это 1 секундой? Имя вашей коллекции — attendance, и для системы посещаемости это было бы не так, я думаю. Если округление должно быть вверх или вниз или основано на средней точке, тогда используйте математику.Round(). ie:
var output = Attendance.Select
(
t => new
{
TimeDifference =
TimeSpan.FromSeconds(Math.Round(
t.EndDateTime.Value.Subtract(t.StartDateTime.Value).TotalSeconds, 0))
.ToString(@"mm:ss")
}
).ToList();
Комментарии:
1. Да, с этим вводом :2016-10-10 00:00:00.000 2016-10-10 00:00:00.001 выходные данные должны быть такими: 00: 01
2. Наконец-то кто-то, кто говорит «Круглый» вместо «Потолка», учитывая, что заявленная цель — Округлить!
3. @ToolmakerSteve, спасибо. Но OP меня тоже смутил. На самом деле ему не нужны круглые или потолочные значения. Он говорит, что даже миллисекунда будет считаться минутой (комментарий выше). Я не был уверен, что ему действительно нужно.
4. @CetinBasoz — ах-ха — Я не видел этого комментария. очень странно. В примерах в его вопросе дельты заканчивались на
.9
, поэтому я предположил, что он хотел того, что обычно требуется при показе времени (round). Ну что ж, я добавил комментарий к вопросу, чтобы будущие читатели были предупреждены оRound
vsCeiling
. Важнее, чем хотел задать один вопрос 🙂
Ответ №5:
Для округления секунд используйте TotalSeconds вместо секунд и окружите его математикой.Потолок:
DateTime startDate = DateTime.Parse("2016-10-14 16:43:18.530");
DateTime endDate = DateTime.Parse("2016-10-14 16:43:50.457 ");
Console.WriteLine( Math.Ceiling(endDate.Subtract(startDate).TotalSeconds));
Вывод: 32
Комментарии:
1. В чем этот ответ отличается от Dawnkeeper или моего?