i have:
jobElement.CreationDate = jobElement.CreationDate + TimeSpan.FromHours(24.0);
i would like to have not strictly 24 hours, but with +- 10 seconds Buffer. like 23.59.10 and 00.00.10
hot to reach that with c#?
This will generate CreationDate + 23:50 and CreationDate + 24:10 with equal probability:
Random random = new Random();
TimeSpan buffer = TimeSpan.FromSeconds(10);
TimeSpan span = TimeSpan.FromHours(24.0);
// 50% of the time do this
if(random.Next() % 2 == 0)
{
span += buffer;
}
// The rest of the time do this
else
{
span -= buffer;
}
jobElement.CreationDate = jobElement.CreationDate + span;
What do you need to do with that?
If you need to any comparison create custom class with overwritten equality operators.
I'm not 100% sure what you want here but I'll give it a shot
DateTime dt1 = DateTime.Now;
DateTime dt2 = DateTime.Now.AddDays(1).AddSeconds(8);
These two are now 24 hours and 8 seconds apart.
Then if you want to see if they are "almost" 24 hour appart, you can do something like this:
if( Math.Abs((dt1-dt2.AddDays(-1))) < 10 ){
//dt2 is 24 after dt1 +- 10 seconds
}else{
//they are not
}
First time (00.00.00) of current date -/+ 10 secs would be:
DateTime dateFrom = jobElement.CreationDate.Date.AddSeconds(-10);
DateTime dateTo = jobElement.CreationDate.Date.AddSeconds(10);
Is that it?
I'll add this variant. It's different from others because it isn't "second based" but "tick" based (the tick is the smallest time that a TimeSpan/DateTime can compute)
const int sec = 10; // +/- seconds of the "buffer"
const int ticksSec = 10000000; // There are 10000000 Ticks in a second
Random r = new Random();
int rng = r.Next(-sec * ticksSec, sec * ticksSec + 1); // r.Next is upper-bound exclusive
var ts = TimeSpan.FromHours(24) + TimeSpan.FromTicks(rng);
jobElement.CreationDate = jobElement.CreationDate + ts;
There are limits in the Random class (it can't generate a long, and generating a "constrained" long (a long with maxValue = x) is non-trivial based only on the Random class, so this will work for up to 3 minutes and something of "buffer" (214 seconds to be more exact).
If you want +/- 10 with all numbers between
Random r = new Random();
int x = r.Next(-10, 11);
var ts = TimeSpan.FromHours(24).Add(TimeSpan.FromSeconds((double)x));
jobElement.CreationDate = jobElement.CreationDate + ts;
Related
for (int i = 0; i < 23; i++)
{
var dt = RoundDown(DateTime.Now, TimeSpan.FromMinutes(5));
datestimes.Add(dt);
}
And
DateTime RoundDown(DateTime date, TimeSpan interval)
{
return new DateTime(
(long)Math.Floor(date.Ticks / (double)interval.Ticks) * interval.Ticks
);
}
datestimes is List<DateTime>
I need to make that the first time to be rounded will be the current DateTime.Now for example if it's 23:44 then round it down to 23:40 and this is what happens now.
But from this point I want to round down more 22 times for example 23:40, 23:35, 23:30, 23:25 like that more 22 times and to add each time the rounded date time to the List
Only do the round down once. Then, subtract the interval instead of rounding.
DateTime dt = RoundDown(DateTime.Now, TimeSpan.FromMinutes(5));
while ( dt.Minutes != 0 )
{
// your code
dt = dt.AddMinutes(-5);
}
Declare the DateTime.Now variable before the loop. Get the minutes and get the rounded value. And then run a for loop and keep on decreasing the minutes by 5 and add to your list.
To get the largest number smaller than or equal to a number N and divided by K you can write the simple method.
int findNum(int N, int K)
{
int rem = N % K;
if (rem == 0)
return N;
else
return N - rem;
}
In your case K is 5.
You forgot to actually decrease the date value that is being rounded down, which can be done with .AddMinutes(-5 * i).
Besides that, it's also more efficient to calculate the date only once. Doing so then also prevents race conditions in case your code runs while the clock changes behind the scenes to the next 5-minute interval.
Improved code:
var startDate = DateTime.Now;
for (int i = 0; i < 23; i++)
{
var dt = RoundDown(startDate.AddMinutes(-5 * i), TimeSpan.FromMinutes(5));
Console.WriteLine(dt);
}
Working demo: https://dotnetfiddle.net/6o5HyW
I have the sum of the working duration of Employees in a specific period. I need to convert this Working Duration into days, hours and minutes. The problem is my day is equal to 9 Hours, not 24 Hours. Means I am dividing my Duration with 9. But the result I am getting is in points and I can't convert to my yearning format. Following is my code:
var Durations = TimeSpan.FromMinutes(db.Attendances.Where(x => x.EmployeeId == id)
.Sum(x => TimeSpan.Parse(x.Duration).TotalMinutes));
var TotalDuration = string.Format("{0}:{1}", Durations.TotalHours, Durations.Minutes);
This one is working absolutely fine. I am getting results in the following format:
H:M
8:5
12:7
19:15
The problem is I need to convert hours into Days and Hours when I divide it by 9. E.g. 19. If I divide 19 by 9 I get 2.111111 Means 2 Days and 1 Hour. How can I get the answer in days and hours format?
I think this should answer your question:
TimeSpan s = new TimeSpan(20,0, 0);
int day = (int)s.TotalHours / 9;
int hour = (int)s.TotalHours % 9;
Console.WriteLine($"the duration in day is {day } hour {hour}");
You can add an extension method to TimeSpan.
public static (int day,int hour) GetDayAndHour(this TimeSpan timeSpan,int dayDuration == 9) {
var number= timeSpan.TotalHours/dayDuration;
int day = (int)Math.Truncate(number);
int hour= (int)Math.Truncate((number-day)*10);
return (day,hour);
}
I use C#7 tuple.If you use previous version, create costume datatype or use Tuple<int, int>.
int totalmins = 5000; // given input
int hourPerDay = 9 // given input
int dayHour = 60 * hourPerDay;
int days = totalmins / dayHour;
int hours = (totalmins % dayHour) / 60;
int mins = tot_mins % 60;
const double PERCENT = 0.25;
DateTime t1 = Convert.ToDateTime(txtB_StartT.Text);
DateTime t2 = Convert.ToDateTime(txtB_EndT.Text);
TimeSpan ts = t1.Subtract(t2);
I cant seem to get this to parse into a DateTime
double tsMin = Convert.ToDouble(ts);
double tsMinTot = ts.TotalMinutes;
short tsMinPercent = (short)(((double)tsMinTot) * PERCENT);
double tsAndPercentTot = tsMinPercent + tsMinTot;
My goal here was to find a timediff, find what 25% of that timediff is and add it to the timediff.
DateTime newTimeMinTot = Convert.ToDateTime(tsAndPercentTot);
int hours = newTimeMinTot.Hour;
int minutes = newTimeMinTot.Minute;
An attempt to get a calculated new Datetime
string newTimeStrg = string.Format("{0:d1}:{1:d2}", hours, minutes);
txtB_NewDelivT.Text = newTimeStrg;
Attempt to output new DateTime to TextBox.
Someone please explain. How can I make the user input in military time and make this work.
Do it like this:
const double PERCENT = 0.25;
DateTime t1 = Convert.ToDateTime(txtB_StartT.Text);
DateTime t2 = Convert.ToDateTime(txtB_EndT.Text);
TimeSpan ts = t1.Subtract(t2);
long tsMinPercent = ts.Ticks + (long)(ts.Ticks * PERCENT);
var tsAndPercentTot = TimeSpan.FromTicks(tsMinPercent);
string newTimeStrg = string.Format("{0:d1}:{1:d2}", tsAndPercentTot.Hours, tsAndPercentTot.Minutes);
txtB_NewDelivT.Text = newTimeStrg;
Here I am using DateTime.Ticks to calculate percentage of time of difference and TimeSpan.FromTicks to find DateTime again from calculated percentage DateTime.
Instead using TextBox you can use TimePicker.
to force your date/datetime format
DateTime mydate = DateTime.ParseExact(TextBox1.Text.Trim(), "dd/MM/yyyy", null);
Based on your comment where you write that the input values are "0945" and "1445", I suggest you to replace your TextBox controls with DateTimePicker controls.
Just to have them display values as you are doing right now, you'll have to set some properties as I show you here.
picker.Format = DateTimePickerFormat.Custom;
picker.CustomFormat = "HHmm";
picker.ShowUpDown = true;
later, the picker.Value will return a whole date with time, where minutes and seconds will resemble the input values.
You can obvously set the properties' values from the designer.
Regards,
Daniele.
Since I don't have your form, I'll leave out the UI interaction. Here's how you can parse an input stream. I've show how to parse a hh:mm format, as well as a hhmm format:
var start = TimeSpan.ParseExact("10:00", "hh\\:mm", CultureInfo.InvariantCulture);
var finish = TimeSpan.ParseExact("1100", "hhmm", CultureInfo.InvariantCulture);
Once you have the start and finish, all we have to do is the math. We'll create a new TimeSpan from the ticks (the smallest unit of measurement on a TimeSpan) multiplied by our percentage (0.25). Then we just add the adjustment to our start time and we're done! You can then assign that into where ever you need the output.
var diff = finish - start;
var adjustment = TimeSpan.FromTicks((long)(diff.Ticks * 0.25));
var adjustedStart = start + adjustment;
You can run the code out at dotNetFiddle. I've included output there so you can see the intermediate results along the way.
Ok well i took a different approach and it worked out fairly easy.
I'm not sure if I'm allowed to answer my own question but i figure it
will help someone with the same issue i had.
// Set Constant values.
const double PERCENT = .25;
const int HUN_PART = 100, SIXTY = 60, one = 1;
// Parse start time textbox value as int
// Calculate start time hours and minutes
int sT = int.Parse(textBox1.Text);
int sH = sT / HUN_PART;
int sM = sT % HUN_PART;
// Calculate total start time in minutes
int sH_M = sH * SIXTY;
int sTotM = sH_M + sM;
// Parse end time textbox value as int
// Calculate end time hours and minutes
int eT = int.Parse(textBox2.Text);
int eH = eT / HUN_PART;
int eM = eT % HUN_PART;
// Calculate total end time in minutes
int eH_M = eH * SIXTY;
int eTotM = eH_M + eM;
// Calculate time difference in minutea
// Calculate percent of time difference
double dT_M = Convert.ToInt32(eTotM - sTotM);
int perc = Convert.ToInt32(dT_M * PERCENT);
// Calculate new arrival time in total min then in hours
double newD_M = perc + eTotM;
double newD_H = newD_M / SIXTY;
// Calculate new arrivaltime in remaining minutes
double nD_H_Convert = Math.Truncate(newD_H);
int nD_H = Convert.ToInt32(nD_H_Convert);
int nD_Hours = nD_H * HUN_PART;
double nD_Min = nD_H * SIXTY;
int nD_M = Convert.ToInt32(newD_M - nD_Min);
int newDeliveryTime = (nD_H * HUN_PART) + nD_M;
// Put values for new arive time hours and minutes in appropriate string format
string newTime = string.Format("{0:d4}", newDeliveryTime);
// Output arrival time string in textbox
textBox3.Text = newTime;
I was apparently trying to do more than was actually required, so by using a few simple calculations the issue was resolved.
Thank you for the help everyone.
I would like to calculate the remaining minutes to the "next" half an hour or hour.
Say i get a start time string of 07:15, i want it to calculate the remaining minutes to the nearest half an hour (07:30).
That would be 15min.
Then i can also have an instance where the start time can be 07:45 and i want it to calculate the remaining minutes to the nearest hour (08:00).
That would also be 15min.
So any string less then 30min in a hour would calculate to the nearest half an hour (..:30) and any string over 30min would calculate to the nearest hour (..:00).
I don't want to do a bunch of if statements, because i get from time strings that can start from and minute in an hour.
This is what i do not want to do:
if (int.Parse(fromTimeString.Right(2)) < 30)
{
//Do Calculation
}
else
{
//Do Calculation
}
public static string Right(this String stringValue, int noOfCharacters)
{
string result = null;
if (stringValue.Length >= noOfCharacters)
{
result = stringValue.Substring(stringValue.Length - noOfCharacters, noOfCharacters);
}
else
{
result = "";
}
return result;
}
Is there not an easier way with linq or with the DateTime class
Use modulo operator % with 30. Your result will be equal to (60 - currentMinutes) % 30. About LINQ its used for collections so i can't realy see how it can be used in your case.
You can use this DateTime tick-round approach to get the timespan until next half hour:
var minutes = 30;
var now = DateTime.Now;
var ticksMin = TimeSpan.FromMinutes(minutes).Ticks;
DateTime rounded = new DateTime(((now.Ticks + (ticksMin/2)) / ticksMin) * ticksMin);
var diff=rounded-now;
var minUntilNext = diff.TotalMinutes > 0 ? diff.TotalMinutes : minutes + diff.TotalMinutes;
var minutesToNextHalfHour = (60 - yourDateTimeVariable.Minutes) % 30;
This should do it:
int remainingMinutes = (current.Minute >= 30)
? 60 - current.Minute
: 30 - current.Minute;
var hhmm = fromTimeString.Split(':');
var mins = int.Parse(hhmm[1]);
var remainingMins = (60 - mins) % 30;
var str = "7:16";
var datetime = DateTime.ParseExact(str, "h:mm", new CultureInfo("en-US"));
var minutesPastHalfHour = datetime.Minute % 30;
var minutesBeforeHalfHour = 30 - minutesPastHalfHour;
I would use modulo + TimeSpan.TryParse:
public static int ComputeTime(string time)
{
TimeSpan ts;
if (TimeSpan.TryParse(time, out ts))
{
return (60 - ts.Minutes) % 30;
}
throw new ArgumentException("Time is not valid", "time");
}
private static void Main(string[] args)
{
string test1 = "7:27";
string test2 = "7:42";
Console.WriteLine(ComputeTime(test1));
Console.WriteLine(ComputeTime(test2));
Console.ReadLine();
}
Suppose i have a DateTime, e. g. 2010.12.27 12:33:58 and i have an interval frames of, suppose, 2 seconds, excluding the last border.
So, i have the following frames:
12:33:58(incl.)-12:34:00(excl.) - let it be interval 1
12:34:00(incl.)-12:34:02(excl.) - let it be interval 2
12:34:02(incl.)-12:34:04(excl.) - let it be interval 3
and so on.
I'm given a random DateTime value and i have to correlate that value according the above rules.
E. g. the value "12:33:58" falls into interval 1, "12:33:59" falls into interval 1, "12:34:00" falls into interval 2 and so on.
In code it should look like the following:
var dt = DateTime.Now;
DateTime intervalStart = apply_the_algorythm(dt);
It seems to be some simple arithmetic action(s) with float or something, any decisions are welcome!
If the interval is only second resolution and always divided 86400, then take the number of seconds that have passed today, divide it by the interval, round it to an integer value, multiply it, and add it back to today. Something like dateinquestion.Subtract(dateinquestion.Date).TotalSeconds, ((int)seconds/interval)*interval, dateinquestion.Date.AddSeconds(...)
If you want the range of all your intervals to span several days, possibly a long time, you might want to express your DateTime values in UNIX-seconds (the number of seconds since 1970-01-01). Then you just find out when your very first interval started, calculate how many seconds passed since then, and divide by two:
int secondsSinceFirstInterval = <currDate in UNIX time>
- <start of first interval in UNIX time>;
int intervalIndex = secondsSinceFirstInterval / 2;
Otherwise you're better off just counting from midnight.
Use TimeSpan.TotalSeconds and divide the result by the size of the interval.
const long intervalSize = 2;
DateTime start = new DateTime(2010, 12, 27, 12, 33, 58);
TimeSpan timeSpan = DateTime.Now - start;
long intervalInSeconds = (long)timeSpan.TotalSeconds;
long intervalNumber = 1 + intervalInSeconds / intervalSize;
DateTime start = new DateTime(2010, 12, 31, 12, 0, 0);
TimeSpan frameLength = new TimeSpan(0, 0, 3);
DateTime testTime = new DateTime(2010, 12, 31, 12, 0, 4);
int frameIndex = 0;
while (testTime >= start)
{
frameIndex++;
start = start.Add(frameLength);
}
Console.WriteLine(frameIndex);
dates = new List<DateTime>
{
DateTime.Now.AddHours(-1),
DateTime.Now.AddHours(-2),
DateTime.Now.AddHours(-3)
};
dates.Sort((x, y) => DateTime.Compare(x.Date, y.Date));
DateTime dateToCheck = DateTime.Now.AddMinutes(-120);
int place = apply_the_algorythm(dateToCheck);
Console.WriteLine(dateToCheck.ToString() + " is in interval :" +(place+1).ToString());
private int apply_the_algorythm(DateTime date)
{
if (dates.Count == 0)
return -1;
for (int i = 0; i < dates.Count; i++)
{
// check if the given date does not fall into any range.
if (date < dates[0] || date > dates[dates.Count - 1])
{
return -1;
}
else
{
if (date >= dates[i]
&& date < dates[i + 1])
return i;
}
}
return dates.Count-1;
}