I have a .netapp application (C#) that I use to extract data from an API.
It is having a problem just now as we are running this for December 2017.. but we want it to name as January 2018. (well 01/01/2018)
I think they way we have written it means it's looking for 13/2017 which obviously doesn't exist.
Can anyone recommend how to ammend this so we can run it just now and how we can ensure we don't run into this issue again next December?
public override string ToString()
{
var reportDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month + 1, 1);
if (!String.IsNullOrWhiteSpace(AppConfigHelper.EndDate))
{
var year = Int32.Parse(AppConfigHelper.EndDate.Substring(6, 4));
var month = Int32.Parse(AppConfigHelper.EndDate.Substring(3, 2));
var day = Int32.Parse(AppConfigHelper.EndDate.Substring(0, 2));
reportDate = new DateTime(year, month, day);
reportDate = reportDate.AddDays(1);
}
You can use DateTime.Today.AddMonths(1):
var nextMonth = DateTime.Today.AddMonths(1);
reportDate = new DateTme(nextMonth.Year, nextMonth.Month, 1);
// ...
By the way, you don't need string methods and int.Parse to get the DateTime, use ParseExact:
if (!String.IsNullOrWhiteSpace(AppConfigHelper.EndDate))
{
reportDate = DateTime.ParseExact(AppConfigHelper.EndDate, "ddMMyyyy", null);
reportDate = reportDate.AddDays(1);
}
Related
I want to get only weeks for the whole year where I want to get the start date (Monday) and end date (Friday) in C#.
For example: 1/52 = 02 Jan (Monday) - 09 Jan (Sunday) 2/52 = 10 Jan (Monday) - 17 Jan (Sunday)
and so on.
I can get current week dates but no idea how to get for the year.
// We Set the Monday as the first day of the week.
DayOfWeek day = datetime.DayOfWeek;
int days = day - DayOfWeek.Monday;
if (days == -1)
{
days = 6; // this is when we have sunday as a DayOfWeek day
}
DateTime start = datetime.AddDays(-days);
DateTime end = start.AddDays(6);
Without making it complicated you can simply use while like below.
while (datetime.DayOfWeek != DayOfWeek.Monday)
{
datetime= datetime.AddDays(1);
}
DateTime start = datetime;
DateTime end = start.AddDays(6);
Or you want to find week from the week index 1/52 for any year then write function like below. Use it like GetWeek(1, 2020) to get 06.01.2020 - 12.01.2020. Format it as per your requirement.
public DateTime GetNextMonday(DateTime datetime)
{
return datetime.AddDays((7 - (int)datetime.DayOfWeek + (int)DayOfWeek.Monday) % 7);
}
public string GetWeek(int week, int year)
{
var start = GetNextMonday(new DateTime(year, 1, 1).AddDays((week-1)*7));
var end = start.AddDays(6);
return start.ToShortDateString() + " - " + end.ToShortDateString();
}
As far as I have understood, probably this will help, I tried the below and it displayed for me the start and end dates for the specified years:
DateTime starting = new DateTime(2020, 1, 1);
DateTime ending = new DateTime(2020, 12, 1);
DateTime currentDay = starting;
DateTime start = currentDay;
DateTime end = currentDay;
while (ending.Year >= currentDay.Year)
{
if (currentDay.DayOfWeek == DayOfWeek.Monday)
{
start = currentDay;
end = start.AddDays(6);
currentDay = end;
Console.WriteLine(start + "(" + start.DayOfWeek + ")");
Console.WriteLine(end + "(" + end.DayOfWeek + ")");
}
else
{
currentDay = currentDay.AddDays(1);
}
}
You can use methods below to calculate start day of any week of any year
public static DateTime StartOfNthWeekOfYear(int year, int weekNumber, DayOfWeek firstDayOfWeek)
{
if(weekNumber < 1)
{
throw new ArgumentOutOfRangeException(nameof(weekNumber));
}
DateTime startOfWeek = StartOfFirstWeekOfYear(year, firstDayOfWeek).AddDays((weekNumber - 1) * 7);
DateTime endOfWeek = startOfWeek.AddDays(6);
if(endOfWeek.Year != year || startOfWeek.Year != year)
{
throw new ArgumentOutOfRangeException(nameof(weekNumber));
}
return startOfWeek;
}
public static DateTime StartOfFirstWeekOfYear(int year, DayOfWeek firstDayOfWeek)
{
DateTime startOfYear = new DateTime(year, 1, 1);
if (startOfYear.DayOfWeek != firstDayOfWeek)
{
return StartOfWeek(startOfYear, firstDayOfWeek).AddDays(7);
}
return startOfYear;
}
public static DateTime StartOfWeek(DateTime value, DayOfWeek firstDayOfWeek)
{
if (value.DayOfWeek != firstDayOfWeek)
{
return value.AddDays(-((7 + (int)value.DayOfWeek - (int)firstDayOfWeek) % 7));
}
return value;
}
I think this should work for Gregorian calendars and takes into account different cultures:
public static IList<DateTime> GetFirstDayOfWeekDates(CultureInfo cultureInfo, int year)
{
var lastDateOfYear = new DateTime(year, 12, 31);
var firstDate = new DateTime(year, 1, 1);
var dayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;
while (firstDate.DayOfWeek != dayOfWeek)
{
firstDate = firstDate.AddDays(1);
}
var numberOfWeeksInYear = cultureInfo.Calendar.GetWeekOfYear(lastDateOfYear, cultureInfo.DateTimeFormat.CalendarWeekRule, dayOfWeek);
var firstDayOfWeekDates = new List<DateTime>();
firstDayOfWeekDates.Add(firstDate);
var currentDate = firstDate;
for (int i = 0; i < numberOfWeeksInYear; i++)
{
var weekLater = currentDate.AddDays(7);
if (weekLater.Year == year)
{
currentDate = weekLater;
firstDayOfWeekDates.Add(currentDate);
}
}
return firstDayOfWeekDates;
}
You can test this with a console app like this (make the method static):
static void Main(string[] args)
{
var ci = new CultureInfo("en-GB");
var dates = GetFirstDayOfWeekDates(ci, DateTime.Now.Year);
foreach (var dt in dates)
{
Console.WriteLine("Date: " + dt.ToShortDateString());
}
Console.ReadLine();
}
It brings back the following:
If you want to include the end date of the week as well then you can tweak this slightly by adding a new class called WeekDate:
public class WeekDate
{
public DateTime StartOfWeek { get; set; }
public DateTime EndOfWeek { get; set; }
}
GetFirstDayOfWeekDates then becomes:
public static IList<WeekDate> GetFirstDayOfWeekDates(CultureInfo cultureInfo, int year)
{
var lastDateOfYear = new DateTime(year, 12, 31);
var firstDate = new DateTime(year, 1, 1);
var dayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;
while (firstDate.DayOfWeek != dayOfWeek)
{
firstDate = firstDate.AddDays(1);
}
var numberOfWeeksInYear = cultureInfo.Calendar.GetWeekOfYear(lastDateOfYear, cultureInfo.DateTimeFormat.CalendarWeekRule, dayOfWeek);
var firstDayOfWeekDates = new List<WeekDate>();
firstDayOfWeekDates.Add(new WeekDate { StartOfWeek = firstDate, EndOfWeek = firstDate.AddDays(6) });
var currentDate = firstDate;
for (int i = 0; i < numberOfWeeksInYear; i++)
{
var weekLater = currentDate.AddDays(7);
if (weekLater.Year == year)
{
currentDate = currentDate.AddDays(7);
firstDayOfWeekDates.Add(new WeekDate { StartOfWeek = currentDate, EndOfWeek = currentDate.AddDays(6) });
}
}
return firstDayOfWeekDates;
}
Which returns:
I am having an issue in parsing two integers to datetime in C#. I have two integers as follows:
int day = 25;
int month = 08;
var currentYear = DateTime.Now.Year;
var scheduledDate = "25/08/2018";
What I want is to convert day, month and the current year to format dd/MM/yyyy and compare this date to scheduledDate which is in the format of dd/MM/yyyy. Can someone please help me with this ?
Rather than converting DateTime object to String you should always convert String to DateTime object and then compare it.
int day = 25;
int month = 08;
var currentYear = DateTime.Now.Year;
var scheduledDate = "25/08/2018";
var dtScheduledDate = DateTime.ParseExact(scheduledDate, "dd/MM/yyyy", System.Globalization.CultureInfo.InvariantCulture);
var dtCurrentDate = new DateTime(currentYear, month, day);
if (dtScheduledDate < dtCurrentDate)
{
// ...
}
var yourDateTime = new DateTime(currentYear, month, day);
var yourDateString = yourDateTime.ToString("dd/MM/yyyy");
// compare
If you want to compare only date then you can use Date Property of DateTime
int day = 25;
int month = 08;
var currentYear = DateTime.Now.Year;
var dateToCompare = new DateTime(currentYear, month, day);
var scheduledDt = "25/08/2018";
var scheduledDate = DateTime.ParseExact(scheduledDt, "dd/MM/yyyy", System.Globalization.CultureInfo.InvariantCulture);
if(dateToCompare.Date == scheduledDate.Date)
{
//Your logic
}
POC: .Net Fiddler
Try the following, you could use DateTime.ToString() method to convert it into the format you need.
int day = 25;
int month = 08;
var currentYear = DateTime.Now.Year;
var date = new DateTime(DateTime.Now.Year, month, day);
var formattedDate = date.ToString("dd/MM/yyyy");
var scheduledDate = "25/08/2018";
// Compare formattedDate and scheduledDate
OR
You could consider converting the scheduledDate string to date time and compare the date time objects, if that's more appropriate:
var scheduledDate = "25/08/2018";
var parsedDate = DateTime.ParseExact(scheduledDate, "dd/MM/yyyy", CultureInfo.InvariantCulture);
var date = new DateTime(DateTime.Now.Year, month, day);
// compare date & parsed date
bool areEqual = date.Equals(parsedDate);
If I understand your question, just keep the proceeding zero,
int day = 25;
int month = 08;
var currentYear = DateTime.Now.Year;
var targetDate = $"{day}/{month.ToString().PadLeft(2,'0')}/{currentYear}";
var scheduledDate = "25/08/2018";
var difference = DateTime.Compare(DateTime.Parse(targetDate),
DateTime.Parse(scheduledDate));
In case you just want to convert it to a string, this should be the easiest way:
int day = 25;
int month = 08;
var currentYear = DateTime.Now.Year;
// {day:D2} is equivalent to day.ToString("D2") which pads integers to a length of two
var createdDate = $"{day:D2}/{month:D2}/{currentYear}";
var scheduledDate = "25/08/2018";
EDIT
Picking up on a few things people here said, parsing both to a DateTime might be more suitable for the comparing part:
DateTime createdDateTime = new DateTime(currentYear, month, day);
DateTime scheduledDateTime = DateTime.ParseExact(scheduledDate, "dd/MM/yyyy", CultureInfo.InvariantCulture);
// Compare if it's the same day
if (createdDateTime.Date == scheduledDateTime.Date)
{
// do stuff
}
// Get the difference in Days
int dayDifference = (createdDateTime - scheduledDateTime).Days;
Alternatively .TotalDays instead of .Days returns a double
int day = 25;
int month = 08;
var currentYear = DateTime.Now.Year;
var scheduledDate = "25/08/2018";
// parse string into DateTime structure
var ci = new CultureInfo("en-UK");
var dtScheduledDate = DateTime.Parse(scheduledDate, ci);
var dtOther = new DateTime(currentYear, month, day);
if(dtOther > dtScheduledDate)
{
...
}
In this case if your variable scheduleDate is a string you can convert the other variables (day,month and currentYear) into a string in the format you want:
var dt = day + "/" + month + "/" + currentYear;
So to compare you do this:
if(dt.Equals(scheduleDate))
//Do some
else
//other thing
static void Main(string[] args)
{
int transactionDate = 20201010;
int? transactionTime = 210000;
var agreementDate = DateTime.Today;
var previousDate = agreementDate.AddDays(-1);
var agreementHour = 22;
var agreementMinute = 0;
var agreementSecond = 0;
var startDate = new DateTime(previousDate.Year, previousDate.Month, previousDate.Day, agreementHour, agreementMinute, agreementSecond);
var endDate = new DateTime(agreementDate.Year, agreementDate.Month, agreementDate.Day, agreementHour, agreementMinute, agreementSecond);
DateTime selectedDate = Convert.ToDateTime(transactionDate.ToString().Substring(6, 2) + "/" + transactionDate.ToString().Substring(4, 2) + "/" + transactionDate.ToString().Substring(0, 4) + " " + string.Format("{0:00:00:00}", transactionTime));
Console.WriteLine("Selected Date : " + selectedDate.ToString());
Console.WriteLine("Start Date : " + startDate.ToString());
Console.WriteLine("End Date : " + endDate.ToString());
if (selectedDate > startDate && selectedDate <= endDate)
Console.WriteLine("Between two dates..");
else if (selectedDate <= startDate)
Console.WriteLine("Less than or equal to the start date!");
else if (selectedDate > endDate)
Console.WriteLine("Greater than end date!");
else
Console.WriteLine("Out of date ranges!");
}
Output:
Selected Date : 10.10.2020 21:00:00
Start Date : 8.10.2020 22:00:00
End Date : 9.10.2020 22:00:00
Greater than end date!
I have a list of filename in my folder and I convert the folder into a list. The file name is the same except for their postfix (number after the file name).
I want to get the latest postfix in that file list.
For example: In my list, I have 4 files. file_20160101 has the largest postfix. There for I want to get the name 'file_20160101' and add to my string.
[0] C:\\Desktop\\file_20130101.csv
[1] C:\\Desktop\\file_20140101.csv
[2] C:\\Desktop\\file_20150101.csv
[3] C:\\Desktop\\file_20160101.csv
Here is my code:
string fileDir = "C:\\Desktop\\"
List<string> list = new List<string>(Directory.GetFiles(fileDir));
string largestPrefix = //file_20160101.csv
You can get it like this:
List<string> list = new List<string>(Directory.GetFiles(fileDir));
var numericParts = Directory.GetFiles(fileDir).Select(f => int.Parse(Regex.Match(f, #"\d+").Value)).ToArray();
var max = numericParts.Max(); //do whatever you want with the largest number
You can even call the Max directly in the case you don't need other numeric parts:
var max = Directory.GetFiles(fileDir).Select(f => int.Parse(Regex.Match(f, #"\d+").Value)).ToArray().Max();
Considering you are looking for the most recent file.You can try this (but yeah linq solution is better.:))
string output = string.Empty;
DateTime max = new DateTime();
foreach(string str in list)
{
DateTime tempDate = new DateTime();
DateTime.TryParseExact(str.Substring(str.IndexOf("_") + 1, 8), "yyyyMMdd", CultureInfo.GetCultureInfo("en-Us"), DateTimeStyles.None , out tempDate);
if(tempDate > max)
{
max = tempDate;
output = str;
}
}
Below code can give you result very quickly if you know that prefix will be always like "file_"
list.Max(f => int.Parse(f.Replace("file_", string.Empty)))
You can do something like this
DateTime date = new DateTime();
string result = "";
foreach (var item in list)
{
int year = int.Parse(item.Substring(5 , 4));
int month = int.Parse(item.Substring(9, 2));
int day = int.Parse(item.Substring(11, 2));
DateTime currentDate = new DateTime(year, month, day);
if (currentDate > date)
{
date = currentDate;
result = item;
}
}
Console.WriteLine(result);
I have made a function to cound the weeks in a year, and that works fine. The problem is that I need a method to get the mondaydate of the week. This is a swedish calendar.
The code below works well for years that have 52 weeks, but some years(like 2009) has 53 weeks. Then I got a date from januari as the mondaydate(cant be right). So please help me to get it to work for all years.
What I probably could do is check if the year has 53 weeks and then do some checks but I'd like it to go smooth without special checks.
Here's what I've come up with:
public static DateTime GetDateFromWeek(int year, int week)
{
//First day of the year
DateTime d = new DateTime(year, 1, 1);
GregorianCalendar calendar = new GregorianCalendar(GregorianCalendarTypes.MiddleEastFrench);
d = calendar.AddWeeks(d, week);
d = d.AddDays(1 - (double)d.DayOfWeek);
return d;
}
I think your base problem is the assumption that DateTime d = new DateTime(year, 1, 1); is in the first week of the year, but it could belong to week 52/53 of the previous year.
You will find a solution here.
This should do it:
public static DateTime GetDateFromWeek(int year, int week)
{
GregorianCalendar calendar = new GregorianCalendar(GregorianCalendarTypes.MiddleEastFrench);
DateTime d = new DateTime(year, 12, 31);
int weeksInYear = calendar.GetWeekOfYear(d, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
int weeksToSubtract = weeksInYear - week;
d = calendar.AddWeeks(d, -weeksToSubtract);
d = d.AddDays(1 - (int)d.DayOfWeek);
return d;
}
You might want to have a look at the following question, I think it is what you are asking:
Get date of first Monday of the week?
if (cmb_mode_of_service.SelectedItem.ToString() == "Weekly Service")
{
int year = 0;
if (cmb_term_of_service.SelectedItem.ToString() == "One Year")
{
year = 1;
}
if (cmb_term_of_service.SelectedItem.ToString() == "Two Year")
{
year = 2;
}
if (cmb_term_of_service.SelectedItem.ToString() == "three year")
{
year = 3;
}
DateTime currentdate = Convert.ToDateTime(service_start_date.Text);
DateTime Enddate = currentdate.AddYears(+year);
char c1 = 'A';
int c2 = 1;
for (var dt1 = currentdate; dt1 <= Enddate; dt1 = dt1.AddDays(7))
{
DataRow dr = dt.NewRow();
dr["SN"] = c2++;
dr["serviceid"] = "S4-" + c1++;
dr["servicedate"] = dt1.ToString();
dr["servicestatus"] = "Pending";
dr["serviceexcutive"] = "Not Alowed";
dt.Rows.Add(dr);
}
dataGridView1.DataSource = dt;
}
I can't think of an easy one or two liner that would get the previous months first day and last day.
I am LINQ-ifying a survey web app, and they squeezed a new requirement in.
The survey must include all of the service requests for the previous month. So if it is April 15th, I need all of Marches request ids.
var RequestIds = (from r in rdc.request
where r.dteCreated >= LastMonthsFirstDate &&
r.dteCreated <= LastMonthsLastDate
select r.intRequestId);
I just can't think of the dates easily without a switch. Unless I'm blind and overlooking an internal method of doing it.
var today = DateTime.Today;
var month = new DateTime(today.Year, today.Month, 1);
var first = month.AddMonths(-1);
var last = month.AddDays(-1);
In-line them if you really need one or two lines.
The way I've done this in the past is first get the first day of this month
dFirstDayOfThisMonth = DateTime.Today.AddDays( - ( DateTime.Today.Day - 1 ) );
Then subtract a day to get end of last month
dLastDayOfLastMonth = dFirstDayOfThisMonth.AddDays (-1);
Then subtract a month to get first day of previous month
dFirstDayOfLastMonth = dFirstDayOfThisMonth.AddMonths(-1);
using Fluent DateTime https://github.com/FluentDateTime/FluentDateTime
var lastMonth = 1.Months().Ago().Date;
var firstDayOfMonth = lastMonth.FirstDayOfMonth();
var lastDayOfMonth = lastMonth.LastDayOfMonth();
DateTime LastMonthLastDate = DateTime.Today.AddDays(0 - DateTime.Today.Day);
DateTime LastMonthFirstDate = LastMonthLastDate.AddDays(1 - LastMonthLastDate.Day);
I use this simple one-liner:
public static DateTime GetLastDayOfPreviousMonth(this DateTime date)
{
return date.AddDays(-date.Day);
}
Be aware, that it retains the time.
An approach using extension methods:
class Program
{
static void Main(string[] args)
{
DateTime t = DateTime.Now;
DateTime p = t.PreviousMonthFirstDay();
Console.WriteLine( p.ToShortDateString() );
p = t.PreviousMonthLastDay();
Console.WriteLine( p.ToShortDateString() );
Console.ReadKey();
}
}
public static class Helpers
{
public static DateTime PreviousMonthFirstDay( this DateTime currentDate )
{
DateTime d = currentDate.PreviousMonthLastDay();
return new DateTime( d.Year, d.Month, 1 );
}
public static DateTime PreviousMonthLastDay( this DateTime currentDate )
{
return new DateTime( currentDate.Year, currentDate.Month, 1 ).AddDays( -1 );
}
}
See this link
http://www.codeplex.com/fluentdatetime
for some inspired DateTime extensions.
The canonical use case in e-commerce is credit card expiration dates, MM/yy. Subtract one second instead of one day. Otherwise the card will appear expired for the entire last day of the expiration month.
DateTime expiration = DateTime.Parse("07/2013");
DateTime endOfTheMonthExpiration = new DateTime(
expiration.Year, expiration.Month, 1).AddMonths(1).AddSeconds(-1);
If there's any chance that your datetimes aren't strict calendar dates, you should consider using enddate exclusion comparisons...
This will prevent you from missing any requests created during the date of Jan 31.
DateTime now = DateTime.Now;
DateTime thisMonth = new DateTime(now.Year, now.Month, 1);
DateTime lastMonth = thisMonth.AddMonths(-1);
var RequestIds = rdc.request
.Where(r => lastMonth <= r.dteCreated)
.Where(r => r.dteCreated < thisMonth)
.Select(r => r.intRequestId);
DateTime now = DateTime.Now;
int prevMonth = now.AddMonths(-1).Month;
int year = now.AddMonths(-1).Year;
int daysInPrevMonth = DateTime.DaysInMonth(year, prevMonth);
DateTime firstDayPrevMonth = new DateTime(year, prevMonth, 1);
DateTime lastDayPrevMonth = new DateTime(year, prevMonth, daysInPrevMonth);
Console.WriteLine("{0} {1}", firstDayPrevMonth.ToShortDateString(),
lastDayPrevMonth.ToShortDateString());
This is a take on Mike W's answer:
internal static DateTime GetPreviousMonth(bool returnLastDayOfMonth)
{
DateTime firstDayOfThisMonth = DateTime.Today.AddDays( - ( DateTime.Today.Day - 1 ) );
DateTime lastDayOfLastMonth = firstDayOfThisMonth.AddDays (-1);
if (returnLastDayOfMonth) return lastDayOfLastMonth;
return firstDayOfThisMonth.AddMonths(-1);
}
You can call it like so:
dateTimePickerFrom.Value = GetPreviousMonth(false);
dateTimePickerTo.Value = GetPreviousMonth(true);
var lastMonth = DateTime.Today.AddMonths(-1);
dRet1 = new DateTime(lastMonth.Year, lastMonth.Month, 1);
dRet2 = new DateTime(lastMonth.Year, lastMonth.Month, DateTime.DaysInMonth(lastMonth.Year, lastMonth.Month));