How do you calculate Daylight Savings Time in C# with DateTime.Now? DST starts on the Second
Sunday in March. And ends on the first Sunday in November. These can be calculated thru the DayOfWeek in DateTime.
DayOfWeek dow;
string p = "3" + "/" + dy.ToString() + "/" + yr.ToString() + " " + "3" + ":" + mn.ToString() + ":" + sc.ToString();
DateTime start = DateTime.Parse(p);
p = "11" + "/" + dy.ToString() + "/" + yr.ToString() + " " + "1" + ":" + mn.ToString() + ":" + sc.ToString();
DateTime end = DateTime.Parse(p);
DateTime current;
for (dys = 1; dys <= 17; dys++)
{
p = "3" + "/" + dys.ToString() + "/" + yr.ToString() + " " + "3" + ":" + mn.ToString() + ":" + sc.ToString();
current = DateTime.Parse(p);
dow = current.DayOfWeek;
if ((mo == 3) && (aaa == 0) && (dow == DayOfWeek.Sunday))
{
aaa = 1;
}
if ((aaa == 1) && (dow == DayOfWeek.Sunday))
{
start = DateTime.Parse(p);
aaa = 2;
}
}
for (dye = 1; dye <= 14; dye++)
{
p = "11" + "/" + dye.ToString() + "/" + yr.ToString() + " " + "1" + ":" + mn.ToString() + ":" + sc.ToString();
current = DateTime.Parse(p);
dow = current.DayOfWeek;
if ((mo == 11) && (bbb == 0) && (dow == DayOfWeek.Sunday))
{
bbb = 1;
end = DateTime.Parse(p);
}
}
if ((start >= DateTime.Now) && (end <= DateTime.Now))
{
dsts = 0;
}
else
{
dsts = 1;
}
You can check these microsoft implementations. They already handle timezones and daylight saving time conversions. We do not need to implement them.
You need DateTimeOffset and TimeZoneInfo classes to deal with all these.
Always work with DateTimeOffset class instead of DateTime when dealing with timezones. https://learn.microsoft.com/en-us/dotnet/api/system.datetimeoffset?view=net-6.0
link1: https://learn.microsoft.com/en-us/dotnet/api/system.timezoneinfo?view=net-6.0
Convert time from one timezone to other https://learn.microsoft.com/en-us/dotnet/api/system.timezoneinfo.converttime?view=net-6.0
Something like below
DateTimeOffset thisTime = DateTimeOffset.Now;
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
bool isDaylight = tzi.IsDaylightSavingTime(thisTime);
DateTimeOffset timeInUtcTimeZone = TimeZoneInfo.ConvertTimeToUtc(thisTime);
DateTimeOffset timeInPstTimeZone = TimeZoneInfo.ConvertTimeToUtc(thisTime, tzi);
Similarly you can convert time from any timezone to any other timezone. And also the comparisons (Equals, greater than, less than) across the timezone will work well and handled by the framework.
Related
void SaveKurByDayAsync(DateTime firstDay , DateTime lastDay)
{
List<DateTime> dateList = new();
for (DateTime date = firstDay; date <= lastDay; date = date.AddDays(1))
{
dateList.Add(date);
}
foreach (DateTime date in dateList)
{
string day = date.Day.ToString();
string year = date.Year.ToString();
string month = date.Month.ToString();
if (int.Parse(month) < 10)
month = "0" + month;
if (int.Parse(day) < 10)
day = "0" + day;
string format = null;
if (date == DateTime.Today)
format = "https://www.tcmb.gov.tr/kurlar/today.xml";
format = "https://www.tcmb.gov.tr/kurlar/" + year + month + "/" + day + month + year + ".xml";
List<XElement> exchangeList = XElement.Load(format).Elements().ToList();
foreach (XElement exchangeItem in exchangeList)
{
Console.WriteLine(decimal.Parse(exchangeItem.Element("ForexBuying").Value, NumberStyles.Number, CultureInfo.InvariantCulture));
}
}
}
I have a method that gets exchange rate information published in xml format every day. But on public holidays xml is not published here and I get NotFound error in 'Load' method. I want to skip that day and move on to the next day, but I couldn't figure it out.
I have 2 variables
DateTime closingTime
TimeSpan diffTime = DateTime.Now.Subtract(endtime);
I would like to check 3 cases:
the store is open n hours and n minutes
the store is open n minutes
the store is closed
my code:
if(diffTime.Minutes > 0 || diffTime.Hours == 0 )
_timeLeft = "Noch " + diffTime.Minutes.ToString() + " Minuten geöffnet";
if (diffTime.Hours > 0)
_timeLeft = "Noch " + diffTime.Hours.ToString() + " Stunden und " + diffTime.Minutes.ToString() + " Minuten geöffnet";
else
//Der Markt ist derzeit geschlossen,
_timeLeft = "Feierabend!";
Is it possible without the "openingTime"?
No way to proof all 3 cases just with closingTime and DateTime.Now
if ((DateTime.Now > openingTime) && (DateTime.Now < closingTime) && diffTime.Hours == 0)
_timeLeft = "Noch " + diffTime.Minutes.ToString() + " Minuten geöffnet";
else if ((DateTime.Now > openingTime) && (DateTime.Now < closingTime))
_timeLeft = "Noch " + diffTime.Hours.ToString() + " Stunden und " + diffTime.Minutes.ToString() + " Minuten geöffnet";
else
//Der Markt ist derzeit geschlossen,
_timeLeft = "Feierabend!";
I am quite concerned about whether or not the code in CurrentRentWeek.cs is future-proof, is it good practice to have this many else if statements? If not, what would be the best way to refactor it?
MainWindow.Xaml.cs
public MainWindow()
{
InitializeComponent();
// Set current rent week
var datecheckObject = new CurrentRentWeek();
CurrentRentWeekTextBlock.Text = datecheckObject.DateCheck(CurrentRentWeekTextBlock.Text);
}
CurrentRentWeek.cs
public string DateCheck(string rentWeek)
{
if (_today.DayOfWeek == DayOfWeek.Monday)
{
_cRentWeekStart = _today.AddDays(-5);
_cRentWeekEnd = _today.AddDays(2);
rentWeek = "Current Rent Week: " + _cRentWeekStart.ToString("dd/MM/yyyy") + " - " +
_cRentWeekEnd.ToString("dd/MM/yyyy");
}
else if (_today.DayOfWeek == DayOfWeek.Tuesday)
{
_cRentWeekStart = _today.AddDays(-6);
_cRentWeekEnd = _today.AddDays(1);
rentWeek = "Current Rent Week: " + _cRentWeekStart.ToString("dd/MM/yyyy") + " - " +
_cRentWeekEnd.ToString("dd/MM/yyyy");
}
else if (_today.DayOfWeek == DayOfWeek.Wednesday)
{
_cRentWeekStart = _today.AddDays(0);
_cRentWeekEnd = _today.AddDays(7);
rentWeek = "Current Rent Week: " + _cRentWeekStart.ToString("dd/MM/yyyy") + " - " +
_cRentWeekEnd.ToString("dd/MM/yyyy");
}
else if (_today.DayOfWeek == DayOfWeek.Thursday)
{
_cRentWeekStart = _today.AddDays(-1);
_cRentWeekEnd = _today.AddDays(6);
rentWeek = "Current Rent Week: " + _cRentWeekStart.ToString("dd/MM/yyyy") + " - " +
_cRentWeekEnd.ToString("dd/MM/yyyy");
}
else if (_today.DayOfWeek == DayOfWeek.Friday)
{
_cRentWeekStart = _today.AddDays(-2);
_cRentWeekEnd = _today.AddDays(5);
rentWeek = "Current Rent Week: " + _cRentWeekStart.ToString("dd/MM/yyyy") + " - " +
_cRentWeekEnd.ToString("dd/MM/yyyy");
}
else if (_today.DayOfWeek == DayOfWeek.Saturday)
{
_cRentWeekStart = _today.AddDays(-3);
_cRentWeekEnd = _today.AddDays(4);
rentWeek = "Current Rent Week: " + _cRentWeekStart.ToString("dd/MM/yyyy") + " - " +
_cRentWeekEnd.ToString("dd/MM/yyyy");
}
else if (_today.DayOfWeek == DayOfWeek.Sunday)
{
_cRentWeekStart = _today.AddDays(-4);
_cRentWeekEnd = _today.AddDays(3);
rentWeek = "Current Rent Week: " + _cRentWeekStart.ToString("dd/MM/yyyy") + " - " +
_cRentWeekEnd.ToString("dd/MM/yyyy");
}
else
{
rentWeek = "";
}
return rentWeek;
}
You can start out with a generalized function to get the start of the week for any give date:
public static DateTime StartOfWeek(DateTime date)
{
while (date.DayOfWeek != DayOfWeek.Wednesday)
date = date.AddDays(-1);
return date;
}
Then you can simply call that method, add a fixed number of days to get to the end of the week, and create the string for those dates:
public string DateCheck()
{
var startOfWeek = StartOfWeek(_today);
var endOfWeek = startOfWeek.AddDays(7);
return string.Format("Current Rent Week: {0} - {1}",
startOfWeek.ToString("dd/MM/yyyy"),
endOfWeek.ToString("dd/MM/yyyy"));
}
You want that Wednesday is the beginning of the week? You can use this:
int daysDiff = (int)_today.DayOfWeek - (int)DayOfWeek.Wednesday;
if (daysDiff >= 0)
_cRentWeekStart = _today.AddDays(-daysDiff);
else
_cRentWeekStart = _today.AddDays(-(7 + daysDiff));
_cRentWeekEnd = _cRentWeekStart.AddDays(7);
This will return the last week's wednesday if today is "less" than wednesday which seems to be desired.
I think a switch statement would be much clearer for your case and give time savings but I doubt thats an issue.
switch (_today.DayOfWeek)
{
case DayOfWeek.Monday:
_cRentWeekStart = _today.AddDays(-5);
_cRentWeekEnd = _today.AddDays(2);
rentWeek = "Current Rent Week: " + _cRentWeekStart.ToString("dd/MM/yyyy") + " - " +_cRentWeekEnd.ToString("dd/MM/yyyy");
break;
case DayOfWeek.Tuesday:
//...
break;
//rest of cases
}
I want to find the exact time elapsed between two dates with a condition that if any value is "0" its measurement units should disappear. for example if hours and minutes are o than the elapsed time should come like 1 day 40 seconds not like 1 day 0 hours 0 minutes 40 seconds.
TimeSpan elapsed = completdDate.Subtract(insertdDate);
int daysEl= elapsed.Days;
int hrsEl= elapsed.Hours;
int minsEl = elapsed.Minutes;
int secEl = elapsed.Seconds;
string totalTime = string.Empty;
string days = string.Empty;
string hours = string.Empty;
string mins = string.Empty;
string secs = string.Empty;
if (daysEl == 0 )
days = days.Replace(daysEl.ToString() , "");
else
days = daysEl.ToString();
if (hrsEl==0)
hours = hours.Replace(hrsEl.ToString() , "");
else
hours = hrsEl.ToString();
if (minsEl == 0)
mins = mins.Replace(minsEl.ToString(), "");
else
mins = minsEl.ToString();
if (secEl == 0)
secs = secs.Replace(secEl.ToString(), "");
else
secs = secEl.ToString();
totalTime = days + "days"
+ hours + "hours"
+ mins + "minutes"
+ secs + "seconds";
********************************Output*****************************
You can get rid of the intermediate strings and if statements:
totalTime =
(daysEl == 0 ? "" : (daysEl + " days "))
+ (hoursEl == 0 ? "" : (hoursEl + " hours "))
+ (minsEl == 0 ? "" : (minsEl + " minutes "))
+ (secsEl == 0 ? "" : (secsEl + " seconds "));
If you want to omit zero values, you're more likely looking at a formatting issue, not a calculation one, and it might be easier to use a StringBuilder.
var sb = new StringBuilder();
if (elapsed.Days != 0)
sb.AppendFormat("{0} days ", elapsed.Days);
if (elapsed.Hours != 0)
sb.AppendFormat("{0} hours ", elapsed.Hours);
if (elapsed.Minutes != 0)
sb.AppendFormat("{0} minutes ", elapsed.Minutes);
if (elapsed.Seconds != 0)
sb.AppendFormat("{0} seconds ", elapsed.Seconds);
if (sb.Length == 0)
return "instant!";
// get rid of the last space in there!
return sb.ToString().Substring(0,sb.Length-1);
By using a format, you're able to more succinctly bind the value with the units (ie "14 seconds") and thus put the whole portion into an if statement, bypassing the section entirely if it's zero.
void Main()
{
TimeSpan elapsed = DateTime.Now - DateTime.Now.AddDays(-1);
int daysEl= elapsed.Days;
int hrsEl= elapsed.Hours;
int minsEl = elapsed.Minutes;
int secEl = elapsed.Seconds;
var sb = new StringBuilder();
if (daysEl != 0 )
sb.Append(daysEl + " days ");
if (hrsEl != 0)
sb.Append(hrsEl + " hours ");
if (minsEl != 0)
sb.Append(minsEl + " mins ");
if (secEl != 0)
sb.Append(secEl + " secs ");
string totalTime = sb.ToString();
Console.WriteLine (totalTime);
}
I have this:
StringBuilder sb = new StringBuilder(time.Text);
if (DateTime.Parse(time.Text) > DateTime.Parse("12:00:00 AM")
&& DateTime.Parse(time.Text) < DateTime.Parse("11:59:59 AM"))
{
time.Text = time.Text + " AM";
}
else
{
time.Text = time.Text + " PM";
}
What I have now is 16:34 PM,
I want it to display 04:34 PM
Simply
string strTime = DateTime.Now.ToString(#"hh\:mm\:ss tt");
in your case, it will be:
time.Text=DateTime.Parse(time.Text).ToString(#"hh\:mm\:ss tt");
and make sure about custom formats, like HH is 24 hrs format, MM is for month
try
time.Text = DateTime.Parse(time.Text).ToString("hh:mm:ss tt");
public static string FormattedTime(this TimeSpan TimeIn24Hours)
{
String TimeIn12Hours = string.Empty;
if (TimeIn24Hours != null)
{
TimeIn12Hours = DateTime.MinValue.AddHours(TimeIn24Hours.Hours).AddMinutes(TimeIn24Hours.Minutes).ToString("hh:mm");
}
return TimeIn12Hours;
}
private void UpdateTime()
{
int hours, mins, sec;
string TimeofDate = "AM";
currentTime = DateTime.Now;
hours = Convert.ToInt32(currentTime.Hour.ToString());
mins = Convert.ToInt32(currentTime.Minute.ToString());
sec = Convert.ToInt32(currentTime.Second.ToString());
// lbCurrentTime.Text = currentTime.ToLongTimeString();
// label2.Text = hours.ToString() + ":" + mins.ToString() + ":" + sec.ToString();
if (hours >= 12)
{
hours = hours - 12;
TimeofDate = "PM";
}
else TimeofDate = "AM";
lbCurrentTime.Text = hours.ToString() + ":" + mins.ToString() + ":" + sec.ToString()+" "+TimeofDate;
}