C# 我的时间计算给了我一个负数

C# 我的时间计算给了我一个负数,c#,.net,datetime,.net-core,C#,.net,Datetime,.net Core,以下几点效果相当不错: using System; using System.Threading; namespace cursor_position { class Program { static void Main(string[] args) { DateTime startTime = DateTime.Now;; TimeSpan timeRemaining; i

以下几点效果相当不错:

using System;
using System.Threading;

namespace cursor_position
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime startTime = DateTime.Now;;
            TimeSpan timeRemaining;
            int intCount = 119;
            
            for (int i = 0; i <= intCount; i++)
            {
                Thread.Sleep(2000);
                
                Console.Clear();

                timeRemaining = TimeSpan.FromTicks(DateTime.Now.Subtract(startTime).Ticks * (intCount - (i+1)) / (i+1));

                Console.SetCursorPosition(0, 0);
                Console.Write("ETA: ");
                Console.Write(String.Format("{0} Minutes, {1} Seconds", timeRemaining.Minutes, timeRemaining.Seconds));

                Console.WriteLine();
            }
        }
    }
}
使用系统;
使用系统线程;
名称空间游标位置
{
班级计划
{
静态void Main(字符串[]参数)
{
DateTime startTime=DateTime.Now;;
时间跨度剩余时间;
整数=119;

对于(inti=0;i来说,当你试图用那样的数学计算时间差时,总是有问题的。最好不要使用计数器来强化你的代码

请尝试以下代码:

DateTime startTime = DateTime.Now;
DateTime targetTime = startTime.AddMinutes(1.0);

while (true)
{
    DateTime now = DateTime.Now;
    if (now > targetTime)
    {
        break;
    }
    else
    {
        TimeSpan timeRemaining = targetTime.Subtract(now);

        Console.Write("ETA: ");
        Console.Write(String.Format("{0} Minutes, {1} Seconds", timeRemaining.Minutes, timeRemaining.Seconds));

        Console.WriteLine();

        Thread.Sleep(1000);
    }
}

我认为在您当前的问题中使用
Thread.Sleep(1000)
(在您最初的问题中)和
Thread.Sleep(2000)
,使我不清楚您是否要计算不确定进程的剩余时间,例如复制文件。在我看来,您只是在进行“计时器倒计时”

让我们编写一个通用函数,用于估计不确定进程的剩余时间

public TimeSpan ComputeRemaining((int count, DateTime time) start, (int count, DateTime time) current, int end) =>
    current.count - start.count == 0
        ? TimeSpan.MaxValue
        : TimeSpan.FromSeconds((end - current.count) * current.time.Subtract(start.time).TotalSeconds / (current.count - start.count));
给定开始计数和
日期时间
,给定
当前计数和
日期时间
,以及所需的
结束
计数,此函数生成剩余时间

它可以在计数上升或下降的情况下工作

让我们看看它的实际行动

var now = DateTime.Now;
var start = (count: 0, time: now.Subtract(TimeSpan.FromSeconds(5.0)));
var current = (count: 50, time: now);
var end = 100;
Console.WriteLine(ComputeRemaining(start, current, end).TotalSeconds);
因此,这个示例是一个在
5.0
秒前启动的过程,现在它完成了50%——需要多长时间?
5.0
秒。此代码正确地写出
5

让我们使用您的示例应用程序进行尝试:

static void Main(string[] args)
{
    var random = new Random();
    
    DateTime startTime = DateTime.Now;
    int intCount = 30;

    for (int i = 0; i <= intCount; i++)
    {
        Thread.Sleep(random.Next(100, 2000));

        TimeSpan timeRemaining = ComputeRemaining((0, startTime), (i, DateTime.Now), intCount);

        Console.Write("ETA: ");
        Console.Write(String.Format("{0} Minutes, {1} Seconds", timeRemaining.Minutes, timeRemaining.Seconds));

        Console.WriteLine();
    }
}
static void Main(字符串[]args)
{
var random=新的random();
DateTime startTime=DateTime.Now;
int计数=30;

对于(int i=0;i来说,您似乎有括号问题

假设我们已经设置了
intCount=1
,那么基于您的代码,
循环将执行两次。一次用于
i=0
,一次用于
i=1

i=0
我们有:
1234*(intCount-(i+1))/(i+1)=>1234*(1-(0+1))/(0+1)

上面的代码等于
1234*A/B
,其中A是
(intCount-(i+1))
,B是
(i+1)
。因此首先计算
1234*A
,然后将结果除以B

所以我们有
1234*(1-(0+1))
等于0,然后
0/1
等于0

i=1
时,我们有`1234*(intCount-(i+1))/(i+1)=>1234*(1-(1+1))/(1+1)=-617

我们有
1234*(1-(1+1))
等于-1234,然后是
-1234/1
等于-1234

要解决此问题,您需要将
for
循环更改为:

for (int i = 0; i < intCount; i++)

这是因为更大的时间延迟,较大的蜱与乘以1(考虑的情况下,i=59你剩余的时间通过蜱*(59-60)/ 60计算)。你为什么不倒计时几秒?我会考虑使用微软的反应框架(NuGET)系统。-然后您可以这样做:
DateTime startTime=DateTime.Now;DateTime targetTime=startTime.AddMinutes(1.0);var query=Observable.Interval(TimeSpan.FromSeconds(1.0)).Select(x=>targetTime.Subtract(DateTime.Now));query.Subscribe(x=>Console.WriteLine($“ETA:{x.Minutes}分钟,{x.Seconds}秒”))你的数学错了。
-1/2==0
。如果它是
-1.0/2.0
,那么它将等于
-0.5
,但不等于整数。@Enigmativity你是对的,我已经更新了答案,数学仍然是错的。当你有
ticks=1234
intCount=1
,和
I=1
,那么
(滴答声*(整数计数-(i+1))/(i+1))==-617
。你的思路是正确的,但你显示了一些令人困惑的数字。而且你仍然显示出一个双重困惑的
-0.5
。我真是太粗心了:-我不知道如何将此应用到我的代码中,因为我不知道要花多长时间才能提前完成。@oshirowanen-是的,你有。你正在设置
intCount
,你有
Thread.Sleep(X)
你知道你在向前计算
intCount*X
毫秒。@oshirowanen-哦,这是一个移动的估计吗?这就像当你移动一个文件时,它显示了移动完成之前的估计时间吗?所以使用
Thread.Sleep(2000)
只是为了模拟工作?@oshirowanen-这就是你想要计算的东西吗?你到底需要什么?
for (int i = 0; i < intCount; i++)
timeRemaining = TimeSpan.FromTicks(DateTime.Now.Subtract(startTime).Ticks * ((intCount - (i + 1)) / (i + 1)));