How to refine this code, in terms of performance and readability? - c#

My Desired output :
if the difference is less than a minute the result should be "Updated just now" and if the difference is than greater than a minute and less than an hour then the result should be "Updated X mintues ago"
Code:
string result = "";
if (difference.Days == 0)
{
if (difference.Hours == 0)
{
if (difference.Minutes == 0)
{
result = "Updated just now";
}
else
{
result = "Updated " + difference.Minutes.ToString() + " minutes ago";
}
}
else
{
result = "Updated " + difference.Hours.ToString() + " hours ago";
}
}
else
{
result = "Updated " + difference.Days.ToString() + " days ago";
}

string format = "Updated {0} {1} ago";
string result = "Updated just now";
// this test can be deleted
if(difference.TotalSeconds > 60)
{
if(difference.Days != 0)
result = string.Format(format, difference.Days, "days");
else if (difference.Hours != 0)
result = string.Format(format, difference.Hours, "Hours");
else if (difference.Minutes != 0)
result = string.Format(format, difference.Minutes, "Minutes");
}
so that the result is cleaner, replace "days" by difference.Days > 1 ? "Days" : "Day"
the purpose of the format string, is to avoid memory leak and to allow user change text format easily and for multilang

string result = "Updated ";
if (difference.Days != 0)
result += difference.Days.ToString() + " days ago";
else if (difference.Hours != 0)
result += difference.Hours.ToString() + " hours ago";
else if (difference.Minutes != 0)
result += difference.Minutes.ToString() + " minutes ago";
else
result += "just now";

Related

I'm curious about the logic that checks only once at a certain time

I would like help.
There are some problems with the code.
I want to do only one inspection at a certain time every day.
In particular, the problem is the most serious in DateTime.Now.Hour == 11 part.
I am having difficulty checking certain times. I need to write code that can be checked only once at 11:00 in the whlie statement.
I created a license file and checked the date of the file.
public static CResult Dailytime(string date)
{
CResult result = new CResult();
if(result.nRet == 0)
{
while (true)
{
if (result.nRet == 1 || result.nRet == 2)
{
return result;
}
if (DateTime.Now.Hour == 11)
{
result = DailyCheckData(date);
if(result.nRet == 1 || result.nRet == 2)
{
return result;
}
}
System.Threading.Thread.Sleep(60 * 30 * 1000);
}
}
return result;
}
public static CResult DailyCheckData(string data)
{
CResult result = new CResult();
DateTime licenseDate = Convert.ToDateTime(data);
string dateNow = DateTime.Now.ToString("yyyy-MM-dd");
int compareDate = DateTime.Compare(Convert.ToDateTime(data), DateTime.Now);
if (licenseDate.ToString("yyyy-MM-dd") == dateNow)
{
result = ExpirationCertificate();
Console.WriteLine("Result = " + result.Result + " Msg = " + result.Msg + " nRet = " + result.nRet);
return result;
}
else
{
if (compareDate > 0)
{
result = TrueCertificate();
Console.WriteLine("Result = " + result.Result + " Msg = " + result.Msg + " nRet = " + result.nRet);
}
else if (compareDate <= 0)
{
result = ExpirationCertificate();
Console.WriteLine("Result = " + result.Result + " Msg = " + result.Msg + " nRet = " + result.nRet);
}
return result;
}
}
CResult class
nRet= 0 or 1 or 2
0 = fasle date
1 = false file
2 = true
Suggest or suggest ways to improve.
Can you try create a variable for DateTime.Now, after a line of code that value change.
DateTime licenseDate = Convert.ToDateTime(data);
string dateNow = DateTime.Now.ToString("yyyy-MM-dd");
int compareDate = DateTime.Compare(Convert.ToDateTime(data), DateTime.Now);
To
DateTime licenseDate = Convert.ToDateTime(data);
var now = DateTime.Now;
string dateNow = now.ToString("yyyy-MM-dd");
int compareDate = DateTime.Compare(licenseDate, now);
you shouldn't use Thread.Sleep() method for such a long duration. It is poor programming logic to make the thread sleep for such a long period.
What you can do to solve this is, is to make a Timer. There's an example attached in the link. A simple snippet to match your logic would be:
licenseStart = //setYours
lastCheck = DateTime.Now;
nextCheck = now.AddDays(1); // now.AddHours(1)
var timer = new Timer(o=>{/* Do work*/}, null, TimeSpan.Zero, nextCheck);
Hope it helps!
I asked about logic that can only loop once at 11 o'clock.
But I could not find the right answer and I found the answer.
I do not speak English well.
That's why others do not understand the intent of the question.
bool bOnce = true;
//bool s0nce = true;
while (true)
{
if (DateTime.Now.Hour == 11 && bOnce)
{
//run code
}
if (bOnce == true)
bOnce = false;
else
bOnce = true;
Thread.Sleep(10 * 60 * 1000);
}

Refactoring else if statement that returns current week from Wednesday

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
}

Time elapsed between two dates

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);
}

ASP .NET C# Change from Military time to Standard Time

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;
}

TimeSpan to Localized String in C#

Is there an easy way (maybe built in solution) to convert TimeSpan to localized string? For example new TimeSpan(3, 5, 0); would be converted to 3 hours, 5minutes (just in polish language).
I can of course create my own extension:
public static string ConvertToReadable(this TimeSpan timeSpan) {
int hours = timeSpan.Hours;
int minutes = timeSpan.Minutes;
int days = timeSpan.Days;
if (days > 0) {
return days + " dni " + hours + " godzin " + minutes + " minut";
} else {
return hours + " godzin " + minutes + " minut";
}
}
But this gets complicated if i want to have proper grammar involved.
The easiest way to do this is to put the format string in a localized resource, and translate appropriately for each supported language.
Unfortunately there's no standard way to do such thing.
Nobody seems to agree in what should be the proper way.... :-\
And people like us that write software for multiple languages suffer.
I do not think this is possible. What you can do is something like this:
public static string ConvertToReadable(this TimeSpan timeSpan) {
return string.Format("{0} {1} {2} {3} {4} {5}",
timeSpan.Days, (timeSpan.Days > 1 || timeSpan.Days == 0) ? "days" : "day",
timeSpan.Hours, (timeSpan.Hours > 1 || timeSpan.Hours == 0) ? "hours" : "hour",
timeSpan.Minutes, (timeSpan.Minutes > 1 || timeSpan.Minutes == 0) ? "minutes" : "minute");
}
Here's the code that I've cooked out:
public static string ConvertToReadable(this TimeSpan timeSpan) {
int hours = timeSpan.Hours;
int minutes = timeSpan.Minutes;
int days = timeSpan.Days;
string hoursType;
string minutesType;
string daysType;
switch (minutes) {
case 1:
minutesType = "minuta";
break;
case 2:
case 3:
case 4:
minutesType = "minuty";
break;
default:
minutesType = "minut";
break;
}
switch (hours) {
case 1:
hoursType = "godzina";
break;
case 2:
case 3:
case 4:
hoursType = "godziny";
break;
default:
hoursType = "godzin";
break;
}
switch (days) {
case 1:
daysType = "dzieƄ";
break;
default:
daysType = "dni";
break;
}
if (days > 0) {
return days + " " + daysType + " " + hours + " " + hoursType + " " + minutes + " " + minutesType;
}
return hours + " " + hoursType + " " + minutes + " " + minutesType;
}

Categories