As others have said, it is impossible to know the exact time remaining due to other factors influencing the speed of your program. You could however put milestones in and reference past runs to get a semi-accurate time calculated from the variance in actual time so far this run compared to previous runs, as is done when copying large directories of files on Windows for instance or when downloading large files in Chrome.
So you don't specify your exact problem, but let's say it's something like processing 100,000 operations that require contacting a 3rd party system on the internet and it normally takes ~15 minutes to complete. You could keep track of 1) Start Time, 2) Expected End Time, and 3) Portion completed. So say when you're 1/2 done, you could take the elapsed time and say that is how long is remaining. Basically get the rate in operations per second and divide the remaining operations by that to get the number of seconds remaining.
double speed = completedOperations / elapsedSeconds;
double remainingSeconds = remainingOperations / speed;
This can change however. Say you start the process and after getting 1/4 the way through in 5 minutes that offsite backups start, not only thrashing the computer's disks, but your internet connection. Now things are processing at 1/10th the speed. Your estimated completion time will start out being 20 min, then at 5 minutes in it will be 15 min. However it slows at that point so you are only 1/2 done after 30 minutes, and your remaining time at that point will be 30 minutes. Now say the backups complete, you will actually be done in 10 minutes but it says there is 30 minutes remaining.
There is no way around an issue like this that is out of your control. You could do a couple of things to mitigate it. You might want to take the speed over just the last 30 seconds of processing. That will be the most accurate if things continue at the current speed. You could record the average speed at times of the day historically if that is an issue. You could average the total run speed and the last minute speed if the speed fluctuates.
Another thing that might throw it off is variance in the data. For example if you are looking at customers and processing them based on the date they became customers, your first 10,000 operations might be on loyal customers that have been with you for years and have tons of data to process while the last 10,000 might be new customers with little data that process faster. You could then use the underlying amount of data instead of the customer count...
However, if you want to be exact for some reason (most of the time), you could fake it at the cost of time. Take the largest normal run time and just use the amount of time taken since the start to provide the progress and time left. Then when all the actual work is done, put in a sleep()
command to wait out the remaining time. There will always be a chance that system load or something makes it take exceptionally long though, but you could then change your maximum time to that new value.
The times of your runs are probably on some kind of curve, the longer you make the time, the more likely any single run will complete in that time, but then more of the runs will be waiting around for nothing:
# ^
# |
### |
### |
##### R
####### U
########### N
################### S
Time-------------->
Granted this seems silly, but your application will run at different speeds due to variables you cannot control, and if a near constant run time is important to you this is the only way.