I want to know how to calculate different pay rates between certain hours.
For example: If someone works from 9am - 5pm they will recieve 1x rate.
if that same person works from 9am - 7pm they will get 1x rate from 9am-5pm and then 1.5x rate from 5pm - 7pm.
However, I am currently using a DateTime.Now for when they start work and a DateTime.Now when they finish the using a time span to calculate the hours in between.
I haven't tried anything because I dunno how to do it.
Here's a try:
static double Rate = 20.0; // 20$ per hour 9am to 5pm
static double TotalPayment(DateTime startTime, DateTime endTime)
{
if (startTime > endTime)
throw new ArgumentException("start must be before end");
if (startTime.Date != endTime.Date)
throw new NotImplementedException("start and end must be on same day");
double totalHours = (endTime - startTime).TotalHours;
double startOfOrdinaryRate = Math.Max(9.0, startTime.TimeOfDay.TotalHours);
double endOfOrdinaryRate = Math.Min(17.0, endTime.TimeOfDay.TotalHours);
double ordinaryHours;
if (startOfOrdinaryRate > endOfOrdinaryRate)
ordinaryHours = 0.0;
else
ordinaryHours = endOfOrdinaryRate - startOfOrdinaryRate;
return 1.0 * Rate * ordinaryHours
+ 1.5 * Rate * (totalHours - ordinaryHours);
}
Do test if it works.
Related
I'm trying to find better way to convert DateTime to unix timestamp in C#
I find out that there is a DateTimeOffset.ToUnixTimeMilliseconds method:
public long ToUnixTimeMilliseconds()
{
return this.UtcDateTime.Ticks / 10000L - 62135596800000L;
}
What this method means? What the constants are used?
UPD:
I guess 10000L is converting from FRAME to Milliseconds. But what about 62135596800000L?
To explain this method:
public long ToUnixTimeMilliseconds()
{
return this.UtcDateTime.Ticks / 10000L - 62135596800000L;
}
DateTime.Ticks units are 100 nanosecond intervals.
Dividing this by 10_000 yields milliseconds, which explains the division by 10000L.
This is because one nanosecond is one billionth of a second, or one millionth of a millisecond.
To convert a nanosecond to a millisecond you would therefore divide by 1_000_000.
However, the ticks are 100 nanosecond units, so instead of dividing by 1_000_000 you would have to divide by 1_000_000/100 = 10_000. That's why you divide the 100 nanosecond units by 10_000 to get milliseconds.
The Unix epoch (which corresponds to a Unix time of zero) is midnight on 1st January 1970.
The DateTime epoch (which corresponds to a DateTime.Ticks value of zero) is 1st January 0001.
The number of milliseconds between 1st January 0001 and 1st January 1970 is 62135596800000. This explains the subtraction of 62135596800000.
And there you have it!
Note: You can compute an approximate value for the number of milliseconds as follows:
Approximate number of days per year = 365.24219
Number of years between 0001 and 1970 = 1969
Thus, total approx milliseconds = 1969 * 365.24219 * 24 * 60 * 60 * 1000
= 62135585750000
The exact figure is much harder to calculate, but it comes out to 62135596800000 as used in the formula above.
In fact, from inspection of the source code we can find the following:
public long ToUnixTimeSeconds() {
// Truncate sub-second precision before offsetting by the Unix Epoch to avoid
// the last digit being off by one for dates that result in negative Unix times.
//
// For example, consider the DateTimeOffset 12/31/1969 12:59:59.001 +0
// ticks = 621355967990010000
// ticksFromEpoch = ticks - UnixEpochTicks = -9990000
// secondsFromEpoch = ticksFromEpoch / TimeSpan.TicksPerSecond = 0
//
// Notice that secondsFromEpoch is rounded *up* by the truncation induced by integer division,
// whereas we actually always want to round *down* when converting to Unix time. This happens
// automatically for positive Unix time values. Now the example becomes:
// seconds = ticks / TimeSpan.TicksPerSecond = 62135596799
// secondsFromEpoch = seconds - UnixEpochSeconds = -1
//
// In other words, we want to consistently round toward the time 1/1/0001 00:00:00,
// rather than toward the Unix Epoch (1/1/1970 00:00:00).
long seconds = UtcDateTime.Ticks / TimeSpan.TicksPerSecond;
return seconds - UnixEpochSeconds;
}
// Number of days in a non-leap year
private const int DaysPerYear = 365;
// Number of days in 4 years
private const int DaysPer4Years = DaysPerYear * 4 + 1; // 1461
// Number of days in 100 years
private const int DaysPer100Years = DaysPer4Years * 25 - 1; // 36524
// Number of days in 400 years
private const int DaysPer400Years = DaysPer100Years * 4 + 1; // 146097
// Number of days from 1/1/0001 to 12/31/1600
private const int DaysTo1601 = DaysPer400Years * 4; // 584388
// Number of days from 1/1/0001 to 12/30/1899
private const int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
// Number of days from 1/1/0001 to 12/31/1969
internal const int DaysTo1970 = DaysPer400Years * 4 + DaysPer100Years * 3 + DaysPer4Years * 17 + DaysPerYear; // 719,162
Which we can now use to calculate the number of milliseconds to 1970:
719162 (DaysTo1970) * 24 (hours) * 60 (minutes) * 60 (seconds) * 1000 (milliseconds)
= 62135596800000
621355968000000000 is the correct amount of Ticks defined by DateTime
The accepted answer makes it appear like DateTime may produce undefined output different from what you can expect if you actually use it.
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks
// 621355968000000000
Run it online yourself: https://dotnetfiddle.net/jU0SIp
/// <summary>
/// Convert Ticks to Unix Timestamp
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
public static long ToUnixTimestamp(long time)
{
return (time - 621355968000000000) / TimeSpan.TicksPerMillisecond;
}
You could replace TimeSpan.TicksPerMillisecond with 10000 if you wanted (like your example), It is just a constant for There is 10,000 ticks in a millisecond
I have completed Loan Amortization/ Loan Repayment calculation for monthly. Now i required for weekly calculation formula in c#.
Can any one please help me to answer this?
Here loan amount is 10000, Interest Rate is 10% and Terms 7 Months
This is my monthly calculation. but i need weekly calculation like this
loanAmount = 10000;
var periods = 7; //Months
var monthlyRate = (Convert.ToDouble(10) / 100) / 12;
var monthlyPayment = Math.Round(monthlyRate / (1 - Math.Pow((1 + monthlyRate), -(periods))) * loanAmount ,2);
Thanks in advance,
Mani
Without seeing exactly how you are calculating it, it should be as simple as switching out months for weeks. For example, instead of something like this:
monrthly payments = (balance * APR) / 12 months
Do this:
weekly payments = (balance * APR) / 52 weeks
Obviously you'll change it depending on what you're calculating and how you're calculating it. You've already done the hard part now you just have to change the time frame, does that make sense?
Hey everyone I want to know that working of get minutes from hours.
I understand this:
test sample 1:-
var result = TimeSpan.FromHours(2.5);
var hours = (int)result.TotalHours;
var minutes = result.Minutes;
output
hours = 2
minutes = 30
it's calculate minute 6*5 = 30
test sample 2:-
var result = TimeSpan.FromHours(2.123);
var hours = (int)result.TotalHours;
var minutes = result.Minutes;
output
hours = 2
minutes = 7
how it calculate minute = 7
please help me
When you're getting TimeSpan from hours with floats, the float part is considered as percentage of minutes in hour. Hour has 60 minutes, so 0.123 from 60 = 7 (12.3%).
you are converting 2.5 and 2.123 to int and int will truncate the rest of the value after the . thats why you get 2
the 30 comes from the 2.5 because 0.5 is half which is 1/2 and 1/2 * 60 = 30
same thing happens with the.123 and the 7 minutes
Internally, TimeSpan holds the duration as a single long, in units of 100 nanoseconds. It calls these ticks.
The implementation defines the following constants:
public const long TicksPerMillisecond = 10000;
private const double MillisecondsPerTick = 1.0 / TicksPerMillisecond;
public const long TicksPerSecond = TicksPerMillisecond * 1000; // 10,000,000
private const double SecondsPerTick = 1.0 / TicksPerSecond; // 0.0001
public const long TicksPerMinute = TicksPerSecond * 60; // 600,000,000
private const double MinutesPerTick = 1.0 / TicksPerMinute; // 1.6666666666667e-9
public const long TicksPerHour = TicksPerMinute * 60; // 36,000,000,000
private const double HoursPerTick = 1.0 / TicksPerHour; // 2.77777777777777778e-11
public const long TicksPerDay = TicksPerHour * 24; // 864,000,000,000
private const double DaysPerTick = 1.0 / TicksPerDay; // 1.1574074074074074074e-12
When you create a TimeSpan from a number of hours, it simply performs something similar to the following calculation (I've simplified this a bit from the actual code by removing the rounding and error checking code):
long _ticks = (long)(hours * TicksPerHour);
When you ask a TimeSpan for TotalMinutes it converts the ticks to minutes as follows:
public double TotalMinutes {
get { return _ticks * MinutesPerTick; }
}
There's nothing at all complicated going on here.
0.1 h -> 6 min
0.2 h -> 12 min
...
0.5 h -> 30 min
...
1.0 h -> 60 min respectively 1h 0 min
See MSDN:
TimeSpan.Minutes Gets the minutes component of the time interval represented by the current TimeSpan structure. Returns
int
and
TimeSpan.TotalMinutes Gets the value of the current TimeSpan structure expressed in whole and fractional minutes. Returns
double
I have a custom solution that checks if a web-site is online, every 1 hour.
The result is something like this: (there is one entry per day)
There are 24 entries in a day (every hour). And every hour has a availability percentage (100%, 95%, 0% ... and so forth).
My questions are:
how can I get up-time and downtime in percentage?
how can I calculate up-time and downtime using these values between 2 dates DateTime and get the result in seconds?
The up-time is easy:
sum of all values divided by 24 (entries) which is 99.67%
Then for downtime, can I just do 100 - 99.67 = 0.33 % ?
I have some issues in getting the up-time/downtime in seconds between 2 dates DateTime
For example: if the range dates are 20.04.2015 - 26.05.2015
I think I should do like this:
For each day calculate the up-time as above (sum of all daily values divided by 24 entries) and assuming the following values:
20.04.2015: 96.67%
21.04.2015: 100.00%
22.04.2015: 92.00%
23.04.2015: 96.67%
24.04.2015: 100.00%
25.04.2015: 100.00%
26.04.2015: 100.00%
Now the sum of the above values divided by the number of days (7 days between 20.04 and 26.04) which makes 97.91 % availability between 20.04 and 26.04.
I assume to get 97.91 % up-time in seconds I should do like this:
CultureInfo provider = CultureInfo.InvariantCulture;
DateTime first = DateTime.ParseExact("20.04.2015", "dd.MM.yyyy", provider);
DateTime last = DateTime.ParseExact("26.04.2015", "dd.MM.yyyy", provider);
TimeSpan time = last - first;
decimal secondsUptime = ((time.Days * 86400)/100) * 97.91m; //97.91 is the uptime calculated above for the time period.
// The problem is how to get this?
decimal secondsDowntime = ?
What I have done so far, is this the correct approach?
How to get the secondsDowntime?
If you already have the Up time percent, All you have to do is very simple math:
decimal PercentDownTime = 100 - PercentUpTime;
decimal SecondsUpTime = (time.Seconds / 100) * PercentUpTime;
decimal SecondsDownTime = (time.Seconds / 100) * PercentDownTime;
Thanks to Robert for reminding us the TotalSeconds property of TimeSpan, but In this case it's ok to use the Seconds property.
Hold up... Ur input numbers are wrong. If u measure once per hour and display the hourly results than how does ur 11:00 have 97%? It should be 100% or 0% its either up or down that hour.... Unless u actually do more calculations in that hour... But even then to get 97 u would have to do at least 100 tests that hour and 3 of them were down.
But if ur numbers are correct the formulas are this...
Uptime % = (sum of the uptime percentages) / (number of measurements) × 100
Uptime % = (sum of uptime) / 24 × 100
Downtime % = 100 - (uptime %)
Seconds of uptime = (number of hours measured or to consider) × 3600 × (uptime %) / 100
Seconds of downtime = (number of hours measure or to consider × 3600) - (seconds of uptime)
Note 3600 is the number of sec in an hour so we multiply the hours by that to get us to the wanted time unit of seconds.
Note Replace uptime % with a number between 0 and 100. Not 0 and 1. If u use 0 to 1 then dont do the last division by 100.
I can't figure out how to recursively calculate the rate of return on an investment, where the principal is unknown, and only the rates and the duration of the rates are known.
For example, if I had an investment for 2 years at 10% (or 0.1), the RoR would equal 0.21 (or 21%). This is calculated non-recursively as,
0.21 = 2 * 0.1 + (0.1 ^ 2)
// or
ror = duration * rate + (rate ^ duration)
Since I may not want to only know the final calculation, but the intermittent years of that investment, I must do this recursively (e.g. if the duration is 5 years, I want to know what the rate of return is after the first year, the second year and so on).
Since this is an algorithm, C# isn't required, but that is what I will be programming it in.
The easiest to calculate recursively is 1.0+RoR:
double calculateRateOfReturnPlus1(double rate, int periods) {
if (periods == 0)
return 1.0;
return (1.0 + rate) * calculateRateOfReturnPlus1(rate, periods - 1);
}
This returns 1.21 for rate=0.1, periods=2 and 1.331 for rate=0.1, periods=3. You can then subtract 1.0 to obtain pure RoR. Alternatively, you can compute RoR directly like this:
double calculateRateOfReturn(double rate, int periods) {
if (periods == 0)
return 0.0;
return (1.0 + rate) * (calculateRateOfReturn(rate, periods - 1) + 1.0) - 1.0;
}
Also, you can calculate RoR iteratively like this:
double calculateRateOfReturn(double rate, int periods) {
double RoR = 1.0;
for (int i = 0; i < periods; i++) {
RoR = RoR * (1.0 + rate);
}
return RoR - 1.0;
}
The last two functions return 0.21 for rate=0.1, periods=2 and 0.331 for rate=0.1, periods=3.
In practice one would simply rely on the Math.Pow() function:
double calculateRateOfReturn(double rate, int periods) {
return Math.Pow(1.0+rate, periods) - 1.0;
}
A LINQ version:
double rate = 0.1;
int totalYears = 5;
var results = Enumerable.Range(1, totalYears).Select(i => new { Year = i, RoR = Math.Pow(1 + rate, i) - 1 });
This gives you the rate of return for every year within the period.
I've done similar "modelling" in a spreadsheet, and the easiest way to do this is to calculate the compound interest for every year, and then in another column calculate the difference between successive years.
If you still want to use recursionto calculate yearly (or any other period) you could input the result of the calculation (starting with 1) as the principal for the next period.
So period 0 "rate" would be 1, then period 1 would be 1.1, period 2 would be 1.21 etc.