How do you get a specific time in the past in C#? - c#

For example: Let's say I wanted a random time from the date 01/03/20 -> It can return 23:23:45 or 07:12:34 etc.. It that possible in C# ?

You can try:
public static DateTime GetRandomTime(DateTime date)
{
Random rnd = new Random();
return date.Date.AddSeconds(rnd.Next(60 * 60 * 24));
}

Related

Calculating next time and rounding date-time

I have datetime like 2019-02-10 20:39:23 and I want to round this time to the next one apart 15 min to the closest one. So it means the next one should be 2019-02-10 21:45:00 or another example 21:24:17 should became 21:45:00... The code below works fine until I have datetime like 2019-02-10 23:54:20. Then the next one rounded should be 2019-03-10 00:00:00 but I get 2019-02-10 00:00:00.
Here is how I'm doing it:
static void Main(string[] args)
{
DateTime dt = DateTime.Parse("2019-02-10 23:54:23");
var interval = TimeSpan.FromMinutes(15);
DateTime last = NextTime(dt, interval);
Console.WriteLine(last);
}
private static DateTime NextTime(DateTime value, TimeSpan interval)
{
var temp = value.Add(new TimeSpan(interval.Ticks / 2));
var time = new TimeSpan((temp.TimeOfDay.Ticks / interval.Ticks) * interval.Ticks);
return value.Date.Add(time);
}
For output I get 2019-02-10 00:00:00 instead of 2019-03-10 00:00:00
Can't figure out why doesn't turn to next day...
The return value is being calculated from the wrong variable. Use temp instead of value:
private static DateTime NextTime(DateTime value, TimeSpan interval)
{
var temp = value.Add(new TimeSpan(interval.Ticks / 2));
var time = new TimeSpan((temp.TimeOfDay.Ticks / interval.Ticks) * interval.Ticks);
return temp.Date.Add(time);
}
The reason for this is because you're adding your interval to the value. If it rolls over a midnight/end of day your value.Date will return the wrong day. Since you store temp, you can return temp.Date.Add(time)
Using DateTime.Add(TimeSpan) the time is concat in the date.
I'v changed your code in this way and it did the trick:
private static DateTime NextTime(DateTime value, TimeSpan interval)
{
var temp = value.Add(new TimeSpan(interval.Ticks / 2));
var time = new TimeSpan((temp.TimeOfDay.Ticks / interval.Ticks) * interval.Ticks);
if (time == new TimeSpan(0, 0, 0)) { time = new TimeSpan(24, 0,0); }
var timeDiff = time - value.TimeOfDay;
var finalDate = value.AddHours(timeDiff.Hours);
finalDate = finalDate.AddMinutes(timeDiff.Minutes);
finalDate = finalDate.AddSeconds(timeDiff.Seconds);
return finalDate;
}
I believe that must have some way more beautifull to do that but it works.

Generate 10 unique integers in C# for Unity

I want to generate 10 'random' numbers, but they have to be unique. I have tried something, but is there someone who can help me out with something better?
My code:
List<int> ran = new List<int>();
Random rnd = new Random();
public static int randomValue;
int tempRandom;
public int randomNum()
{
if(ran.Count == 0)
{
ran.Add(0);
ran.Add(1);
ran.Add(2);
ran.Add(3);
ran.Add(4);
ran.Add(5);
ran.Add(6);
ran.Add(7);
}
tempRandom = rnd.Next(0, ran.Count);
randomValue = ran[randomValue];
ran.RemoveAt(tempRandom);
return randomValue;
}
Is this what you're trying to say? If not, please specify how you mean further. This code should give you a number between 1-10 that hasn't been already used. This code will only work 10 times.
Random rnd = new Random();
List<int> usedNumbers = new List<int>();
public int RandomNum(){
int number;
do {
number = rnd.Next(1, 10);
} while(usedNumbers.IndexOf(number) == -1);
usedNumbers.Add(number);
return number;
}
Straight answer to your question (not regarding if you actually want what you are asking for):
Random.Range( int.MinValue, int.MaxValue );
This simply produces a random int in the range of all integers. For 10 numbers, the probability of duplicates is so little that every number will be unique.

How to get both Random Date and Time C#

I'm trying to write a code the generate random date and time where all values of (yyyy-mm-dd hh:mm:ss) are changed
I used this code but it change only the date and fix the time
DateTime RandomDay()
{
DateTime start = new DateTime(2013, 1, 1 , 1 , 1 ,1);
Random gen = new Random();
int range = (DateTime.Today - start).Days;
return start.AddDays(gen.Next(range));
}
I said ok if I write a code that generate a random date, and store it in a variable1, then write another code that generate random time, and store it in variable2, then pick the date only from variable1, and pick the time only from variable2, then combine variable1 and variable2 together , so I can generate random date and time
therefore, I wrote this another method to generate the time
DateTime RandomTime()
{
DateTime start = new DateTime(2013, 1, 1, 1, 1, 1);
Random gen = new Random();
int range = (DateTime.Today - start).Hours;
return start.AddHours(gen.Next(range));
}
now the problem in the RandomTime method, it generate Random hours only, doesn't change the values of the minutes and seconds,
is there any suggestion to solve the code problem? is there anyway to generate random values for all (yyyy-mm-dd hh:mm:ss) ?
Here's a method that'll randomly generate every portion of the date and time.
It uses appropriate limits so the generated date is valid (years within 1-9999, months within 1-12, a call to DateTime.DaysInMonth so we don't end up with Feb 31, etc).
public IEnumerable<DateTime> GenerateRandomDates(int numberOfDates)
{
var rnd = new Random(Guid.NewGuid().GetHashCode());
for (int i = 0; i < numberOfDates; i++)
{
var year = rnd.Next(1, 10000);
var month = rnd.Next(1, 13);
var days = rnd.Next(1, DateTime.DaysInMonth(year, month) + 1);
yield return new DateTime(year, month, days,
rnd.Next(0, 24), rnd.Next(0, 60), rnd.Next(0, 60), rnd.Next(0, 1000));
}
}
To generate 10,000 of them:
var randomDateTimes = GenerateRandomDates(10000);
Here is the one line solution. 1 line for the return part ;)
private static Random _ran = new Random();
public static DateTime RandomDateTime()
{
return
DateTime.MinValue.Add(
TimeSpan.FromTicks((long) (_ran.NextDouble()*DateTime.MaxValue.Ticks)));
}
Note 1: _ran.NextDouble() gives random value between 0 and 1. so the amount of ticks you add to minimum datetime would be between 0 and DateTime.MaxValue.Ticks. So the random date time would be between minimum and maximum date time.
Note 2: DateTime.Min.Ticks is equal to 0. so this process will never overflow even if you add maximum date time ticks.
Here is how to generate 10k random date times.
DateTime[] datetimes = new DateTime[10000];
for (int i = 0; i < datetimes.Length; i++)
{
datetimes[i] = RandomDateTime();
}
You can also use this method if you want to define ranges.
public static DateTime RandomDateTime(DateTime min, DateTime max)
{
return
DateTime.MinValue.Add(
TimeSpan.FromTicks(min.Ticks + (long) (_ran.NextDouble()*(max.Ticks - min.Ticks))));
}

Storing DateTimes in 30 min intervals to array

My objective is to populate a combo box with time intervals of 30 min for 24 hours. I.E - 12.00am, 12.30am, 1.00am, 1.30am and so on. I need to know how to put these details into array. Thank you
Perhaps:
string[] comboboxDataSource = Enumerable.Range(0, 2 * 24)
.Select(min => DateTime.Today.AddMinutes(30 * min).ToString("h.mmtt", CultureInfo.InvariantCulture))
.ToArray();
One way is to iterate 30 minutes in a day and add this DateTime values with a specific string representation to your list. Like;
List<string> list = new List<string>();
DateTime start = DateTime.Today;
DateTime end = DateTime.Today.AddDays(1);
while (end > start)
{
list.Add(start.ToString("h.mmtt", CultureInfo.InvariantCulture));
start = start.AddMinutes(30);
}
If you wanna get them as an array, just use list.ToArray() to get it. Also time designators are in .NET Framework are mostly (I haven't check all of them) upper case. That means, you will get AM or PM when you use tt specifier, not am or pm. In such a case, you need to replace these values with their lower cases.
Don't know exactly what you mean. I would start with something like this:
private IEnumerable<Timespan> Get30MinuteIntervalls()
{
var currentValue = new Timespan(0);
while (currentValue <= Timespan.FromHours(24)
{
yield return currentValue;
currentValue = currentValue.Add(Timespan.FromMinutes(30));
}
}
var values = Get30MinuteIntervalls().ToArray();
Try:
var d = new DateTime();
d = d.Date.AddHours("0").AddMinutes("0");
for (int i = 0; i < 48; i++)
{
d.AddMinutes(30);
cbo.AddItem(d.TimeOfDay.ToString());
}

Random date in C#

I'm looking for some succinct, modern C# code to generate a random date between Jan 1 1995 and the current date.
I'm thinking some solution that utilizes Enumerable.Range somehow may make this more succinct.
private Random gen = new Random();
DateTime RandomDay()
{
DateTime start = new DateTime(1995, 1, 1);
int range = (DateTime.Today - start).Days;
return start.AddDays(gen.Next(range));
}
For better performance if this will be called repeatedly, create the start and gen (and maybe even range) variables outside of the function.
This is in slight response to Joel's comment about making a slighly more optimized version. Instead of returning a random date directly, why not return a generator function which can be called repeatedly to create a random date.
Func<DateTime> RandomDayFunc()
{
DateTime start = new DateTime(1995, 1, 1);
Random gen = new Random();
int range = ((TimeSpan)(DateTime.Today - start)).Days;
return () => start.AddDays(gen.Next(range));
}
I have taken #Joel Coehoorn answer and made the changes he adviced - put the variable out of the method and put all in class. Plus now the time is random too. Here is the result.
class RandomDateTime
{
DateTime start;
Random gen;
int range;
public RandomDateTime()
{
start = new DateTime(1995, 1, 1);
gen = new Random();
range = (DateTime.Today - start).Days;
}
public DateTime Next()
{
return start.AddDays(gen.Next(range)).AddHours(gen.Next(0,24)).AddMinutes(gen.Next(0,60)).AddSeconds(gen.Next(0,60));
}
}
And example how to use to write 100 random DateTimes to console:
RandomDateTime date = new RandomDateTime();
for (int i = 0; i < 100; i++)
{
Console.WriteLine(date.Next());
}
Well, if you gonna present alternate optimization, we can also go for an iterator:
static IEnumerable<DateTime> RandomDay()
{
DateTime start = new DateTime(1995, 1, 1);
Random gen = new Random();
int range = ((TimeSpan)(DateTime.Today - start)).Days;
while (true)
yield return start.AddDays(gen.Next(range));
}
you could use it like this:
int i=0;
foreach(DateTime dt in RandomDay())
{
Console.WriteLine(dt);
if (++i == 10)
break;
}
Start with a fixed date object (Jan 1, 1995), and add a random number of days with AddDays (obviusly, pay attention not surpassing the current date).
Random rnd = new Random();
DateTime datetoday = DateTime.Now;
int rndYear = rnd.Next(1995, datetoday.Year);
int rndMonth = rnd.Next(1, 12);
int rndDay = rnd.Next(1, 31);
DateTime generateDate = new DateTime(rndYear, rndMonth, rndDay);
Console.WriteLine(generateDate);
//this maybe is not the best method but is fast and easy to understand
One more solution to the problem, this time a class to which you provide a range you want the dates in. Its down to random minutes in the results.
/// <summary>
/// A random date/time class that provides random dates within a given range
/// </summary>
public class RandomDateTime
{
private readonly Random rng = new Random();
private readonly int totalMinutes;
private readonly DateTime startDateTime;
/// <summary>
/// Initializes a new instance of the <see cref="RandomDateTime"/> class.
/// </summary>
/// <param name="startDate">The start date.</param>
/// <param name="endDate">The end date.</param>
public RandomDateTime(DateTime startDate, DateTime endDate)
{
this.startDateTime = startDate;
TimeSpan timeSpan = endDate - startDate;
this.totalMinutes = (int)timeSpan.TotalMinutes;
}
/// <summary>
/// Gets the next random datetime object within the range of startDate and endDate provided in the ctor
/// </summary>
/// <returns>A DateTime.</returns>
public DateTime NextDateTime
{
get
{
TimeSpan newSpan = new TimeSpan(0, rng.Next(0, this.totalMinutes), 0);
return this.startDateTime + newSpan;
}
}
}
Use it like this to spit out 5 random dates between january 1st 2020 and december 31 2022:
RandomDateTime rdt = new RandomDateTime(DateTime.Parse("01/01/2020"), DateTime.Parse("31/12/2022"));
for (int i = 0; i < 5; i++)
Debug.WriteLine(rdt.NextDateTime);
I am a bit late in to the game, but here is one solution which works fine:
void Main()
{
var dateResult = GetRandomDates(new DateTime(1995, 1, 1), DateTime.UtcNow, 100);
foreach (var r in dateResult)
Console.WriteLine(r);
}
public static IList<DateTime> GetRandomDates(DateTime startDate, DateTime maxDate, int range)
{
var randomResult = GetRandomNumbers(range).ToArray();
var calculationValue = maxDate.Subtract(startDate).TotalMinutes / int.MaxValue;
var dateResults = randomResult.Select(s => startDate.AddMinutes(s * calculationValue)).ToList();
return dateResults;
}
public static IEnumerable<int> GetRandomNumbers(int size)
{
var data = new byte[4];
using (var rng = new System.Security.Cryptography.RNGCryptoServiceProvider(data))
{
for (int i = 0; i < size; i++)
{
rng.GetBytes(data);
var value = BitConverter.ToInt32(data, 0);
yield return value < 0 ? value * -1 : value;
}
}
}
Small method that returns a random date as string, based on some simple input parameters. Built based on variations from the above answers:
public string RandomDate(int startYear = 1960, string outputDateFormat = "yyyy-MM-dd")
{
DateTime start = new DateTime(startYear, 1, 1);
Random gen = new Random(Guid.NewGuid().GetHashCode());
int range = (DateTime.Today - start).Days;
return start.AddDays(gen.Next(range)).ToString(outputDateFormat);
}
Useful extension based of #Jeremy Thompson's solution
public static class RandomExtensions
{
public static DateTime Next(this Random random, DateTime start, DateTime? end = null)
{
end ??= new DateTime();
int range = (end.Value - start).Days;
return start.AddDays(random.Next(range));
}
}

Categories

Resources