Date Time Offset not working - c#

I am not very familiar with dealing with date time spans etc in C#
Please see my test below
I am giving it 2 dates
I then want to change the dates to be offset from the replay date
This works perfect for the first date
But my second date is not working I need it to be 13:05 but its 13:00
var dates = new List<DateTime>()
{
Convert.ToDateTime("29/06/2018 10:00"),
Convert.ToDateTime("29/06/2018 10:05")
};
var replayDate = Convert.ToDateTime("29/06/2018 13:00");
for (var index = 0; index < dates.Count; index++)
{
var date = dates[index];
var time = replayDate.TimeOfDay - date.TimeOfDay;
var newTime = date.Add(time);
dates[index] = newTime;
}
Assert.AreEqual(Convert.ToDateTime("29/06/2018 13:00"), dates[0]);
Assert.AreEqual(Convert.ToDateTime("29/06/2018 13:05"), dates[1]);
Whats the best approach to do this?
Paul

Maybe try the following:
var dates = new List<DateTime>
{
Convert.ToDateTime("29/06/2018 10:00"),
Convert.ToDateTime("29/06/2018 10:05")
};
var replayDate = Convert.ToDateTime("29/06/2018 13:00");
// process the offset once (before the loop) -- here it will be 3 hours
var offset = replayDate.TimeOfDay - dates[0].TimeOfDay;
for (var index = 0; index < dates.Count; index++)
{
// shift all your dates by that offset
dates[index] = dates[index].Add(offset);
}
Assert.AreEqual(Convert.ToDateTime("29/06/2018 13:00"), dates[0]);
Assert.AreEqual(Convert.ToDateTime("29/06/2018 13:05"), dates[1]);
As per my comment:
time should be replayDate.TimeOfDay - dates[0].TimeOfDay - you want the offset to be the difference between your replayDate and the first date, this should therefore also be outside (before) the loop.
Here is a code snippet to demonstrate.
Note that I formatted the date strings as MM/dd/yyyy HH:mm because of the server's culture.

Related

How to display all Fridays Date between two dates

How to get a Friday date from the given start date and end date,
For Example:
25/03/2021 - starting date
14/08/2021 - endind date
I have a class
public static class DateUtils
{
public static List<DateTime> GetWeekdayInRange(this DateTime from, DateTime to, DayOfWeek day)
{
const int daysInWeek = 7;
var result = new List<DateTime>();
var daysToAdd = ((int)day - (int)from.DayOfWeek + daysInWeek) % daysInWeek;
do
{
from = from.AddDays(daysToAdd);
result.Add(from);
daysToAdd = daysInWeek;
}
while (from < to);
return result;
}
}
That is how i call it in main method:
var from = DateTime.Today; // 25/8/2019
var to = DateTime.Today.AddDays(23); // 23/9/2019
var allFriday = from.GetWeekdayInRange(to, DayOfWeek.Friday);
Console.WriteLine(allFriday);
Console.ReadKey();
Error i get:
System.Collections.Generic.List`1[System.DateTime]
I am new and still learning, how do I call in the main method so that my output be like all dates(fridays) between the range?
Link I followed
To Answer your question, instead of printing allFridays in one go, iterate over each element of list i.e allFridays, convert into string and then print
foreach(var friday in allFridays)
Console.WriteLine(friday);
Why you are getting System.Collections.Generic.List[System.DateTime] ?
Console.WriteLine(), for non primitive type by default calls
.ToString() function which prints type of it(if it is not overridden). In your case, you
need an individual date not a type of List, so you need to iterate
each DateTime from the list and print each date.
One Liner solution:
Console.WriteLine(string.Join(Environment.NewLine, allFridays));
Alternate solution:
public static List<DateTime> GetWeekdayInRange(this DateTime #from, DateTime to, DayOfWeek day)
{
//Create list of DateTime to store range of dates
var dates = new List<DateTime>();
//Iterate over each DateTime and store it in dates list
for (var dt = #from; dt <= to; dt = dt.AddDays(1))
dates.Add(dt);
//Filter date based on DayOfWeek
var filteredDates = dates.Where(x => x.DayOfWeek == day).ToList();
return filteredDates;
}
...
var #from = DateTime.Today; // 25/8/2019
var to = DateTime.Today.AddDays(23); // 23/9/2019
var allFriday = #from.GetWeekdayInRange(to, DayOfWeek.Friday);
Console.WriteLine(string.Join(Environment.NewLine, allFridays));
.NET FIDDLE
Since in your Usage section, you have successfully get the result via GetWeekdayInRange. You can print the dates with these methods:
Method 1:
allFriday.ForEach(x => Console.WriteLine(x.ToShortDateString()));
Method 2:
foreach (var friday in allFriday)
{
Console.WriteLine(friday.ToShortDateString());
}
Method 3:
for (var i = 0; i < allFriday.Count(); i++)
{
Console.WriteLine(allFriday[i].ToShortDateString());
}
Note: ToShortDateString() is one of the methods to display Date string. You can define your desired Date pattern with ToString().

Get date of last seven days

I want to get date of last seven days from now.For example current date is
02-10-2016, get date of seven days like this
01-10-2016,30-09-2016,29-09-2016,28-09-2016,27-09-2016,26-09-2016
My code
string dt = DateTime.Now.ToString("yyyy-MM-dd");
DateTime lastWeek = dt.AddDays(-7.0);
AddDays is a part of DateTime, not of string.
You need to build your dates iteratively and then convert it to a string.
DateTime[] last7Days = Enumerable.Range(0, 7)
.Select(i => DateTime.Now.Date.AddDays(-i))
.ToArray();
foreach (var day in last7Days)
Console.WriteLine($"{day:yyyy-MM-dd}"); // Any manipulations with days go here
Without LINQ, with a simple loop:
DateTime dt = DateTime.Now;
for (int i=0;i<7;i++)
{
dt = dt.AddDays(-1);
Console.WriteLine(dt.Date.ToShortDateString());
}
Try using Linq:
var date = new DateTime(2016, 10, 2);
var result = Enumerable.Range(1, 7)
.Select(day => date.Date.AddDays(- day))
.ToArray(); // if you want to represent dates as an array
Test
// 01-10-2016,30-09-2016,29-09-2016,28-09-2016,27-09-2016,26-09-2016,25-09-2016
Console.Write(string.Join(",", result.Select(d => d.ToString("dd-MM-yyyy"))));
You are almost there, the AddDays method will add only a specific number of days to the given data and dives you the resulted date. But here in your case you need a list of dates, so you have to loop through those dates and get them as well. I hope the following method will help you to do this:
public static string GetLast7DateString()
{
DateTime currentDate = DateTime.Now;
return String.Join(",",Enumerable.Range(0, 7)
.Select(x => currentDate.AddDays(-x).ToString("dd-MM-yyyy"))
.ToList());
}
Note : If you want to exclude the current date means you have to take the range from 7 and the count should be 7. You can read more about Enumerable.Range here
If you call this method like the following means you will get the output as 24-10-2016,23-10-2016,22-10-2016,21-10-2016,20-10-2016,19-10-2016,18-10-2016
string opLast7Days = GetLast7DateString();
public static List<DateTime> getLastSevenDate(DateTime currentDate)
{
List<DateTime> lastSevenDate = new List<DateTime>();
for (int i = 1; i <= 7; i++)
{
lastSevenDate.Add(currentDate.AddDays(-i));
}
return lastSevenDate;
}

How can I get a collection of months between two Dates?

Below is my code. I am only getting the difference between two dates, but I want the name of that month which comes between the from and to dates.
public static int GetMonthsBetween(DateTime from, DateTime to)
{
if (from > to) return GetMonthsBetween(to, from);
var monthDiff = Math.Abs((to.Year * 12 + (to.Month - 1)) - (from.Year * 12 + (from.Month - 1)));
if (from.AddMonths(monthDiff) > to || to.Day < from.Day)
{
return monthDiff - 1;
}
else
{
return monthDiff;
}
}
Based on your code you could substract the month difference from the "to" DateTime to get DateTime difference from your input.
public static List<DateTime> GetMonthsBetween(DateTime from, DateTime to)
{
if (from > to) return GetMonthsBetween(to, from);
var monthDiff = Math.Abs((to.Year * 12 + (to.Month - 1)) - (from.Year * 12 + (from.Month - 1)));
if (from.AddMonths(monthDiff) > to || to.Day < from.Day)
{
monthDiff -= 1;
}
List<DateTime> results = new List<DateTime>();
for (int i = monthDiff; i >= 1; i--)
{
results.Add(to.AddMonths(-i));
}
return results;
}
To get the name of the month just format the DateTime to "MMM".
var dts = GetMonthsBetween(DateTime.Today, DateTime.Today.AddMonths(5));
foreach (var dateTime in dts)
{
Console.WriteLine(dateTime.ToString("MMM"));
}
If you want the names of all months between two dates, use something like this:
var d1 = new DateTime(2015,6,1);
var d2 = new DateTime(2015,9,1);
var monthlist = new List<string>();
string format = d1.Year == d2.Year ? "MMMM" : "MMMM yyyy";
for (var d = d1; d <= d2; d = d.AddMonths(1))
{
monthlist.Add(d.ToString(format));
}
The full list is now in monthlist - you will want to return that from your method.
Assuming you're using Java and JodaTime there are several flaws in your code.
You cant use from > to to evaluate if a date is after an other. Use from.isAfter(to) instead.
JodaTime already supplies a method to calculate the amount of whole months between two given Dates Months.monthsBetween(start,end).
With the calculated month difference you can instantiate a new DateTime object that holds a date in your desired month and output its name via yourNewDateTimeObject.month().getAsText().
edit: Just found out you're using C# so ignore my text above this. Below here I will try to answer your question in C#.
Why dont you just subtract the from from the to date and obtain your difference?
The resulting TimeSpan can be used to determine the amount of whole months between your two given dates.
To obtain the resulting month name you could use yourDateTime.ToString("MMMM");

C# DateTime to Int and RadCalendar

I am trying to parse out a RadCalendar Date and disable the dates prior to our Start Date of an event.
We get our StartDateTime from a database and I would like to disable the dates from our Future StartDateTime all the way back to the beginning of the current (this) month.
EDIT: More specific
Example: My StartDateTime is in November 2014 but I want to disable all dates from that future date until back to the beginning of this current month (this month is August 2014).
Below is the code we currently have, but it is only looking back i < 31. This is why I would like to the DateTime get the number of days as an int all the way back to the beginning (the 1st) of the current month.
if (nextAvailableTime != null && nextAvailableTime.StartDateTime > DateTime.Today)
{
//DISABLE dates prior to next available date
DateTime dt = nextAvailableTime.StartDateTime.AddDays(-1);
for (var i = 0; i < 31; i++) //Would like to change this to beginning of current month.
{
tkCalendar.SpecialDays.Add(new RadCalendarDay(tkCalendar) { Date = dt.Date.AddDays(i * -1), IsDisabled = true, IsSelectable = false });
}
}
Why not subtract the 2 dates and get the difference in days? I used my own variable because I was unclear what your variables were. My loop is disabling going forward instead of multiplying by -1. You may need to edit the loop to be <= or start from 1 depending on if you want the first and last date to be included.
if (nextAvailableTime != null && nextAvailableTime.StartDateTime > DateTime.Today)
{
//DISABLE dates prior to next available date
DateTime currentDate = DateTime.Now;
DateTime futureDate = DateTime.Now.AddMonths(3);
int daysBetween = (futureDate - currentDate).Days;
for (var i = 0; i < daysBetween; i++)
{
tkCalendar.SpecialDays.Add(new RadCalendarDay(tkCalendar) { Date = currentDate.AddDays(i), IsDisabled = true, IsSelectable = false });
}
}
The answer we came up with was to get the next available date and then the beginning date of the current month and get the difference using DayOfYear.
Solution is below:
if (nextAvailableTime != null && nextAvailableTime.StartDateTime > DateTime.Today)
{
//DISABLE dates prior to next available date
DateTime dt = nextAvailableTime.StartDateTime.AddDays(-1);
DateTime nextDate = nextAvailableTime.StartDateTime;
//Gate the calendar to just go get the product's next available date and then get block out everything until the beginning of the current month.
var now = DateTime.Now;
var startOfMonth = new DateTime(now.Year, now.Month, 1);
TimeSpan daysBetween = (futureDate - startOfMonth);
// for (var i = 0; i < 31; i++)//Original from 31 days from next available.
for (var i = 0; i < daysBetween.Days; i++) //Get difference between next available and beginning of current month.
{
tkCalendar.SpecialDays.Add(new RadCalendarDay(tkCalendar) { Date = dt.Date.AddDays(i * -1), IsDisabled = true, IsSelectable = false });
}
}

C# iterate backwards over date

I am looking for a C# solution that will allow me to iterate backwards over a date.
Starting at the current date or provided date I would like to loop over the date subtracting one day each time through the loop for a given number of days. It should of course be able to detect when the month has changed or it is a leap year etc., and return the date in MM-DD-YYYY format.
Should be easy enough:
var givenNumberOfDays = 30;
for( DateTime day = DateTime.Now; day > DateTime.Now.AddDays( -givenNumberOfDays); day = day.AddDays(-1) )
{
//perform your logic here
var dateInCorrectFormat = day.ToString("MM-dd-yyyy");
}
public IEnumerable<DateTime> Dates(int nDays)
{
DateTime dt = DateTime.Now;
yield return dt;
for(int i=0;i<nDays-1;i++)
{
dt = dt.AddDays(-1);
yield return dt;
}
}
foreach (var dt in Dates(10))
{
Console.WriteLine(dt.ToString("MM-dd-yyyy"));
}
this would iterate backwords:
class Program
{
static void Main(string[] args)
{
DateTime myDate = DateTime.Now;
for (int i = 0; i < 10; i++)
{
Console.WriteLine(myDate.AddDays(-i).ToString("MM-dd-yyyy"));
}
}
}
You can use Dateadd function, that let you add or subtract an interval of time to/from a date and returning the resulting date.
In your case, the interval is "d" (day).
See here.

Categories