Как округлить разницу во времени до ближайших секунд в строковом формате?

#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 vs Ceiling . Важнее, чем хотел задать один вопрос 🙂

Ответ №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 или моего?