So was looking to see how to code a calendar in C# which is easy if your using asp.net. However, I'm using console application because i'm required to do so. Now coding for a one month was not to bad but I can't figure out how to code a whole year (January-December).
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
int current = 0;
int skip = 0;
int day = 1;
int endDay = 31;
string line = " Sun Mon Tue Wed Thu Fri Sat";
Console.WriteLine(line);
line = "";
while (skip < current)
{
line += " ";
skip++;
}
while (day <= endDay)
{
while (current < 7 && day <= endDay)
{
line += String.Format("{0,4}", day);
current++;
day++;
}
Console.WriteLine(line);
line = "";
current = 0;
}
Console.ReadLine();
}
}
}
after doing so this will display a one month calendar so the question is how could I display a full year calendar while still using console application and from the codes I already have?
You could do something like this. I tried to add comments for explanation:
static void Main(string[] args)
{
// Loop 12 times (once for each month)
for (int i = 1; i < 13; i++)
{
// Get the first day of the current month
var month = new DateTime(2017, i, 1);
// Print out the month, year, and the days of the week
// headingSpaces is calculated to align the year to the right side
var headingSpaces = new string(' ', 16 - month.ToString("MMMM").Length);
Console.WriteLine($"{month.ToString("MMMM")}{headingSpaces}{month.Year}");
Console.WriteLine(new string('-', 20));
Console.WriteLine("Su Mo Tu We Th Fr Sa");
// Get the number of days we need to leave blank at the
// start of the week.
var padLeftDays = (int)month.DayOfWeek;
var currentDay = month;
// Print out the day portion of each day of the month
// iterations is the number of times we loop, which is the number
// of days in the month plus the number of days we pad at the beginning
var iterations = DateTime.DaysInMonth(month.Year, month.Month) + padLeftDays;
for (int j = 0; j < iterations; j++)
{
// Pad the first week with empty spaces if needed
if (j < padLeftDays)
{
Console.Write(" ");
}
else
{
// Write the day - pad left adds a space before single digit days
Console.Write($"{currentDay.Day.ToString().PadLeft(2, ' ')} ");
// If we've reached the end of a week, start a new line
if ((j + 1) % 7 == 0)
{
Console.WriteLine();
}
// Increment our 'currentDay' to the next day
currentDay = currentDay.AddDays(1);
}
}
// Put a blank space between months
Console.WriteLine("\n");
}
Console.Write("\nDone!\nPress and key to exit...");
Console.ReadKey();
}
Output:
Related
I wrote a program that calculates the number of days before the event, there may be several events, I would like to know how to reduce or simplify this code.
namespace Determining_the_time_before_the_event_starts
{
class Program
{
struct Event
{
public string name;
public DateTime time;
}
static Event[] InPutEvents()
{
Console.Write("Number of events: ");
int n, year, month, day, hour, min;
n = int.Parse(Console.ReadLine());
Event[] time = new Event[n];
for(int i=0; i<n; i++)
{
Console.Write("Event name: ");
time[i].name = Console.ReadLine();
Console.Write("Event start year: ");
year = int.Parse(Console.ReadLine());
Console.Write("Month of the beginning of the event: ");
month = int.Parse(Console.ReadLine());
Console.Write("The first day of the event: ");
day = int.Parse(Console.ReadLine());
Console.Write("Watch the beginning of the event: ");
hour = int.Parse(Console.ReadLine());
Console.Write("Minutes before the event starts: ");
min = int.Parse(Console.ReadLine());
time[i].time = new DateTime(year, month, day, hour, min, 0);
Console.WriteLine();
}
return time;
}
static void Main(string[] args)
{
Event[] time = InPutEvents();
Console.WriteLine();
BeginEvent(time);
Console.ReadLine();
}
static void BeginEvent (Event[] time)
{
DateTime now = DateTime.Now;
for(int i = 0; i < time.Length; i++)
{
SearchTime(time[i], now);
Console.WriteLine();
}
}
static void SearchTime(Event time, DateTime now)
{
int year, month, day, hour, min;
year = time.time.Year - now.Year;
month = time.time.Month - now.Month;
day = time.time.Day - now.Day;
hour = time.time.Hour - now.Hour;
min = time.time.Minute - now.Minute;
if (min < 0)
{
min += 60;
hour--;
}
if (min > 60)
{
min -= 60;
hour++;
}
if (hour < 0)
{
hour += 24;
day--;
}
if (hour > 24)
{
hour -= 24;
day++;
}
if (day < 1)
{
day += 31;
month--;
}
if (day > 31)
{
day -= 31;
month++;
}
if (month < 1)
{
month += 12;
year--;
}
if (month > 12)
{
month -= 12;
year++;
}
day += (month * 31) + (year * 365);
Console.WriteLine($"Event {time.name} starts in {day} days, {hour}hours, and {min}m. ");
}
}
}
Subtracting a DateTime object from another DateTime Object creates a TimeSpan object. The TimeSpan object has properties like Days, Hours, Minutes and so forth.
Simply use these properties to build the solution you need.
private static void SearchTime(Event event, DateTime now)
{
var diff = event.time - now;
Console.WriteLine($"Event {event.name} starts in {diff.Days} days, {diff.Hours}hours, and {diff.Minutes}m. ");
}
How can I get the date of next coming Monday or next coming Friday in C#.
lets say today is Wednesday and I want to get date of coming Friday.
This is what I've done
DateTime time = DateTime.Now.Date;
DateTime NextFriday;
if (time.DayOfWeek == DayOfWeek.Wednesday)
{
NextFriday = DateTime.Now.AddDays(2);
}
with this approach I've to initiate 7 variables for each day and 7 conditions for ever day to find the next specific day.
Is there any better and clean code by which I can get the date of any of the next coming day.
Using the following
public int CalculateOffset(DayOfWeek current, DayOfWeek desired) {
// f( c, d ) = [7 - (c - d)] mod 7
// f( c, d ) = [7 - c + d] mod 7
// c is current day of week and 0 <= c < 7
// d is desired day of the week and 0 <= d < 7
int c = (int)current;
int d = (int)desired;
int offset = (7 - c + d) % 7;
return offset == 0 ? 7 : offset;
}
You can calculate how far you are from the desired day and then add that to the current date
DateTime now = DateTime.Now.Date;
int offset = CalculateOffset(now.DayOfWeek, DayOfWeek.Friday);
DateTime nextFriday = now.AddDays(offset);
DateTime today = DateTime.Today;
DateTime nextFriday = System.Linq.Enumerable.Range(0, 6)
.Select(i => today.AddDays(i))
.Single(day => day.DayOfWeek == DayOfWeek.Friday);
You should probably use a time library that supports this, such as NodaTime.
See date.Next(IsoDayOfWeek.Sunday) on https://nodatime.org/1.3.x/userguide/arithmetic
Here's an alternative solution (please don't use this):
DateTime F(DateTime t, DayOfWeek dayOfWeek) => t.AddDays((7 + (int)dayOfWeek - (int)t.DayOfWeek) % 7);
for (int i = 0; i < 7; i++)
Console.WriteLine((DayOfWeek)i + " " + F(DateTime.Now, (DayOfWeek)i));
Outputs (on Wednesday 4/25/2018):
Sunday 4/29/2018 12:00:00 AM
Monday 4/30/2018 12:00:00 AM
Tuesday 5/1/2018 12:00:00 AM
Wednesday 4/25/2018 12:00:00 AM
Thursday 4/26/2018 12:00:00 AM
Friday 4/27/2018 12:00:00 AM
Saturday 4/28/2018 12:00:00 AM
DayOfWeek is just an enum between 0 and 6, so with modular arithmetic you can use the difference between your date of interest and target day of week to compute the number of days you must add.
A quick warning, you need to take into account timezone of interest when you ask what is meant by "today". It means a different thing depending on which side of the date line you live.
using System;
public class Program
{
public static DateTime NextDayForDay(DayOfWeek dayOfWeek, DateTime occurringAfter)
{
return occurringAfter.AddDays(((dayOfWeek - occurringAfter.DayOfWeek + 6) % 7)+1);
}
public static void Main()
{
for (int i=0; i < 7; i++)
{
for (int j=0; j < 7; j++)
{
DayOfWeek dayOfWeek = (DayOfWeek)(((int)DayOfWeek.Sunday + j) % 7);
DateTime test = DateTime.Today.AddDays(i);
Console.WriteLine($"{test}=>Next {dayOfWeek} is {NextDayForDay(dayOfWeek, test)}");
}
}
}
}
I want to be able to find date based on input number(between 1-365). For e.g., if number entered as 40 then my program should output - Date:9 Month:2
I have tried the below code and was able to find dates for all months except January -
static void Main(string[] args)
{
int[] arryofdays = new int[] {31,28,31,30,31,30,31,31,30,31,30,31};
int num = Int32.Parse(Console.ReadLine());
int temp = num;
string date, month;
for (int i = 0; i < arryofdays.Length; i++)
{
temp = temp - arryofdays[i];
if (temp < arryofdays[i + 1])
{
Console.WriteLine("Date:" + temp.ToString());
Console.WriteLine("Month:" + (i+2).ToString());
break;
}
}
Console.ReadLine();
}
Please help!
Why don't you just try like this;
var datetime = new DateTime(2017, 1, 1).AddDays(40 - 1);
var month = datetime.Month; //2
var day = datetime.Day; //9
The reason why your code is not working for JAN month is, because on temp = temp - arryofdays[i]; statement you are getting negative values if your inout is less than 31.
You can modify your code like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
//Your code goes here
Console.WriteLine("Hello, world!");
int[] arryofdays = new int[] {31,28,31,30,31,30,31,31,30,31,30,31};
int num = Int32.Parse(Console.ReadLine());
int temp = num;
string date, month;
for (int i = 0; i < arryofdays.Length; i++)
{
temp =(temp - arryofdays[i]);
if (temp < arryofdays[i + 1] && temp >0)
{
Console.WriteLine("Date:" + temp.ToString());
Console.WriteLine("Month:" + (i+2).ToString());
break;
}else{//for handling first month
Console.WriteLine("Date:" +num);
Console.WriteLine("Month:" + 1);
break;
}
}
Console.ReadLine();
}
}
}
Working code : http://rextester.com/PAJQ64015
Hope that helps.
try like this ,take arugment and also check it you can able to convert in int form or not, make your program type safe
and also check validation that days value will be between 1 and 365
public static void Main(string[] args)
{
int days = 0;
if (args.Length > 0 && int.TryParse(args[0], out days))
{
if (!(days < 1 || days > 366))
{
DateTime date = new DateTime(DateTime.Now.Year, 1, 1).AddDays(days - 1);
Console.WriteLine("Date: {0}", date.Day);
Console.WriteLine("Date: {0}", date.Month);
}
}
else
{
Console.WriteLine("input vlaue is not correct or not present");
}
}
You can try it like this
static void Main(string[] args)
{
int[] arryofdays = new int[] {31,28,31,30,31,30,31,31,30,31,30,31};
int num = Int32.Parse(Console.ReadLine());
int days = 0;
int months = 0;
for (int i = 0; i < arryofdays.Length; i++) {
if (num > arryofdays[i]) {
num -= arryofdays[i];
months++;
} else {
days = num;
break;
}
}
Console.WriteLine("Date:" + days.ToString());
Console.WriteLine("Month:" + (months+1).ToString());
Console.ReadLine();
}
Assuming num = 40, on the first iteration of the for loop, it'll check if num > arryofdays[0] which is if 40 > 31. That'll return true, so 31 will be decremented from num making the value of num to be 9. months will be incremented. On the next iteration (i = 1), it'll check if num > arryofdays[1] which is if 9 > 28 which means there are only 9 days and we break because we don't need to go any further.
Your output will be
Date:9
Month:2
I am trying to get previous, current and next 3 quarters base on current quarter and year.
Example : Current Quarter = 3 & Year = 2014
I want Output,
Q2-2014
Q3-2014
Q4-2014
Q1-2015
Q2-2015
I am trying as under but output is NOT correct and also how to club previous quarter?
static void Main(string[] args)
{
int generateQuater = 5;
int currentQuater = 3;
int currentYear = DateTime.Now.Year;
List<string> lstQuaterYear = new List<string>();
for (int i = generateQuater; i > 0; i--)
{
lstQuaterYear.Add(string.Format("Q{0}-{1}", currentQuater, currentYear));
if (--currentQuater == 0)
{
currentQuater = 4;
currentYear++;
}
}
Console.ReadLine();
}
Change your loop as follows:
for (int i = 0; i < generateQuater; i++)
{
if(currentQuater%5 ==0)
{
currentQuater = 1;
currentYear++;
}
lstQuaterYear.Add(string.Format("Q{0}-{1}", currentQuater%5, currentYear));
currentQuater++;
}
Modulo 5 will return values in the range [0,4]. Quarter 0 can be interpreted as quarter 1 of the next year. Therefore, we handle that case by setting currentQuater to 1 and incrementing currentYear. This will go through the 4 quarters of each year, and on the 5th one, it will move to next year and restart counting from 1.
Demo
Finally this code with help of Tieson.
Question : Any other/linq approach for subjected problem also welcome.
int generateQuater = 4;
int currentQuater = 3;
int currentYear = DateTime.Now.Year;
List<string> lstQuaterYear = new List<string>();
//previous Quater
lstQuaterYear.Add(String.Format("Q{0}-{1}", (currentQuater - 1) + (((1) / 4) * 4), currentYear - ((1) / 4)));
for (int i = 0; i < generateQuater; i++)
{
if (currentQuater % 5 == 0)
{
currentQuater = 1;
currentYear++;
}
//current and next 3 Quater
lstQuaterYear.Add(string.Format("Q{0}-{1}", currentQuater % 5, currentYear));
currentQuater++;
}
Here i am calculating the server restart count.
i need the server restart count for last 24 hours.
string logType = "System";
EventLog ev = new EventLog(logType, System.Environment.MachineName);
int count=0;
for (int i = ev.Entries.Count - 1; i >= 0; i--)
{
EventLogEntry CurrentEntry = ev.Entries[i];
if (CurrentEntry.Source.ToUpper() == "USER32")
{
count = count + 1;
}
}
ev.Close();
and i have tried like
DateTime dt = DateTime.Now;
TimeSpan ts = dt.Subtract(CurrentEntry.TimeGenerated);
int hours = (ts.Days * 24) + ts.Hours;
Any suggestion?
var ev = new EventLog("system", System.Environment.MachineName);
var count = ev.Entries.Cast<EventLogEntry>()
.Where (e => e.TimeGenerated >= DateTime.Now.AddDays(-1)
&& e.Source.Equals("USER32", StringComparison.CurrentCultureIgnoreCase)).Count();
Edit:
Considering jCoder's comment about the enteries being sorted on TimeGenerated. Using this code will gain performance:
var ev = new EventLog("system", System.Environment.MachineName);
int count = 0;
var y = DateTime.Now.AddDays(-1);
for (int i = ev.Entries.Count - 1; i >= 0 ; i--)
{
if(ev.Entries[i].TimeGenerated < y)
break;
if(ev.Entries[i].Source.Equals("USER32", StringComparison.CurrentCultureIgnoreCase))
count++;
}
Use CurrentEntry.TimeGenerated to check when it has happened.
put one more condition at if (CurrentEntry.Source.ToUpper() == "USER32") to check if TimeGenerated is in last 24 hours
This code will give you the count of events, in tha last day, that have a source of USER32 in the System event log.
int count; //your result
//When yesterday became today
DateTime yesterday = DateTime.Now.Subtract(new TimeSpan(24, 0, 0));
using (EventLog appLog = new EventLog("System"))
{
count = appLog.Entries.OfType<EventLogEntry>().Where(
e => (e.Source.ToUpperInvariant == "USER32") &&
(e.TimeGenerated > yesterday)).Count();
}
EDIT: Or Even better, taking good bits from Mangus's answer
DateTime yesterday = DateTime.Now.AddDays(-1);
int count = 0;
using (Eventlog appLog = new EventLog("System"))
{
count = appLog.Entries.OfType<EventLogEntry>().Count(
e.Source.Equals("USER32", StringComparison.CurrentCultureIgnoreCase) &&
e.TimeGenerated > yesterday
)
}
If "USER32" events do not have a direct correllation with system restart events, this will not give you a count of system restarts.