Formatted DateTime e.g. "Since last year" - c#

I'm trying to print the DateTime of the posts but in format like this (Since one hour, Since yesterday, or Since last year), I succeeded to do it using the following code.
But, Is there a better way to do it like this code??
Note: there is a property called Date in this code.
public string GetFormattedDate()
{
var now = DateTime.Now;
var years = now.Year - Date.Year;
// Calculating leap year
if (Date.Date > now.AddYears(-years)) years--;
if (years > 0)
{
return "Since " + ((years > 1) ? $"{years} years" : "last year");
}
var months = now.Month - Date.Month;
if (months > 0)
{
return "Since " + ((months > 1) ? $"{months} months" : "last month");
}
var days = now.Day - Date.Day;
if (days > 0)
{
return "Since " + ((days > 1) ? $"{days} days" : "yesterday");
}
var hours = now.Hour - Date.Hour;
if (hours > 0)
{
return "Since " + ((hours > 1) ? $"{hours} hours" : "one hour");
}
var minutes = Math.Abs(now.Minute - Date.Minute);
if (minutes > 0)
{
return "Since " + ((minutes > 1) ? $"{minutes} minutes" : "one minute");
}
return "Now";
}

This is another Algorithm which is way better than mine.
Thanks to all the contributors in Humanizr and of course to Tieson T.
public static class DateTimeHumanize
{
public static string Humanize(this DateTime input, DateTime comparisonBase)
{
var ts = new TimeSpan(Math.Abs(comparisonBase.Ticks - input.Ticks));
int seconds = ts.Seconds, minutes = ts.Minutes, hours = ts.Hours, days = ts.Days;
int years = 0, months = 0;
// start approximate from smaller units towards bigger ones
if (ts.Milliseconds >= 999)
{
seconds += 1;
}
if (seconds >= 59)
{
minutes += 1;
}
if (minutes >= 59)
{
hours += 1;
}
if (hours >= 23)
{
days += 1;
}
// month calculation
if (days >= 30 & days <= 31)
{
months = 1;
}
if (days > 31 && days < 365)
{
var factor = Convert.ToInt32(Math.Floor((double)days / 30));
var maxMonths = Convert.ToInt32(Math.Ceiling((double)days / 30));
months = (days >= 30 * factor) ? maxMonths : maxMonths - 1;
}
// year calculation
if (days >= 365 && days <= 366)
{
years = 1;
}
if (days > 365)
{
var factor = Convert.ToInt32(Math.Floor((double)days / 365));
var maxMonths = Convert.ToInt32(Math.Ceiling((double)days / 365));
years = (days >= 365 * factor) ? maxMonths : maxMonths - 1;
}
if (years > 0)
{
return "Since " + ((years > 1) ? $"{years} years" : "last year");
}
if (months > 0)
{
return "Since " + ((months > 1) ? $"{months} months" : "last month");
}
if (days > 0)
{
return "Since " + ((days > 1) ? $"{days} days" : "yesterday");
}
if (hours > 0)
{
return "Since " + ((hours > 1) ? $"{hours} hours" : "one hour");
}
if (minutes > 0)
{
return "Since " + ((minutes > 1) ? $"{minutes} minutes" : "one minute");
}
return "Now";
}

public static string RelativeDate(DateTime theDate)
{
Dictionary<long, string> thresholds = new Dictionary<long, string>();
int minute = 60;
int hour = 60 * minute;
int day = 24 * hour;
thresholds.Add(60, "{0} seconds ago");
thresholds.Add(minute * 2, "a minute ago");
thresholds.Add(45 * minute, "{0} minutes ago");
thresholds.Add(120 * minute, "an hour ago");
thresholds.Add(day, "{0} hours ago");
thresholds.Add(day * 2, "yesterday");
thresholds.Add(day * 30, "{0} days ago");
thresholds.Add(day * 365, "{0} months ago");
thresholds.Add(long.MaxValue, "{0} years ago");
long since = (DateTime.Now.Ticks - theDate.Ticks) / 10000000;
foreach (long threshold in thresholds.Keys)
{
if (since < threshold)
{
TimeSpan t = new TimeSpan((DateTime.Now.Ticks - theDate.Ticks));
return string.Format(thresholds[threshold], (t.Days > 365 ? t.Days / 365 : (t.Days > 0 ? t.Days : (t.Hours > 0 ? t.Hours : (t.Minutes > 0 ? t.Minutes : (t.Seconds > 0 ? t.Seconds : 0))))).ToString());
}
}
return "";
}

Related

Create user DateTime class

I have to create my own DateTime class with fields seconds,minutes,hours,days,months and years. I've had a problem with realization method void AddDays(int N),which adds N days(N may be negative). I do not understand what idea should lie in this function to add days worked correctly. I was trying to understand how the system class works, but for now it's difficult for me.
public TimeDate(int second, int minute, int hour,
int day, int month, int year)
{
_second = second;
_minute = minute;
_hour = hour;
_day = day;
_month = month;
_year = year;
}
private long _second;
private long _minute;
private long _hour;
private long _day;
private long _month;
private long _year;
private long[] dayYear = {0,31,28,31,30,31,30,31,31,30,31,30,31};
private long[] dayYearLeap ={0,31,29,31,30,31,30,31,31,30,31,30,31};
private bool isLeap()
{
if (_year % 4 == 0)
{
if (_year % 100 == 0)
{
if (_year % 400 == 0)
{
return true;
}
return false;
}
return true;
}
return false;
}
public void AddDays(int N)
{
long N_in_second = N * 60*60*24;
long second_now = _second + _minute * 60 + _hour * 60 * 60 + _day * 60 * 60 * 24;
if (isLeap())
{
second_now += _month*3600*24*dayYearLeap[_month]+
_year * 60 * 60 * 24 * dayYearLeap[_month] * 12;
}
else
{
second_now += _month * 3600 * 24 * dayYear[_month] +
_year * 60 * 60 * 24 * dayYear[_month] * 12;
}
second_now += N_in_second;
_year = second_now / (60*60*24*12*dayYear[_month]);
second_now -= 60 * 60 * 24 * 12 * dayYear[_month];
_month = second_now / (60 * 60 * 24 * dayYear[_month]) % 12;
if (_month == 0) _month = 12;
second_now -= (60 * 60 * 24 * dayYear[_month]);
_day = second_now / (60 * 60 * 24) % dayYear[_month];
second_now -= (60 * 60 * 24);
_hour = second_now / (60 * 60) % 24;
second_now -= (60 * 60);
_minute = second_now / 60 % 60;
second_now -= 60;
_second = second_now % 60;
}
in main function I wrote TimeDate date = new TimeDate(34,27,13,28,2,2019); date.AddDays(5); output was: Second: 34, Minute: 27, Hour: 13, Day: 12, Month: 3,Year: 2019, but it's extra 7 days. Where did I go wrong? if the year becomes a leap year after the summation, how can I catch this?
public void AddDays(int N)
{
if (N >= 0)
{
for (int i = 0; i < N; i++)
{
_day++;
if (isLeap())
{
if (_day > dayYearLeap[_month])
{
_day = 1;
_month++;
if (_month > 12)
{
_year++;
_month = 1;
}
}
}
else
{
if (_day > dayYear[_month])
{
_day = 1;
_month++;
if (_month > 12)
{
_year++;
_month = 1;
}
}
}
}
}
else
{
for (int i = 0; i < Math.Abs(N); i++)
{
_day--;
if (_day == 0)
{
_month--;
if (isLeap())
{
if (_month < 1)
{
_year--;
_month = 12;
}
_day = dayYearLeap[_month];
}
else
{
if (_month < 1)
{
_year--;
_month = 12;
}
_day = dayYear[_month];
}
}
}
}
}

how to calculated the age on birthday date for shamsi calendar with WPF in GridView

I have a grid view in wpf(C#) which contain Birth Day Date. I used bellow code for calculated the age for first row.
Now how to calculated the all row (ages)?
private void Window_Loaded(object sender, RoutedEventArgs e)
{
string birth_day = "";
var query = from u in db.tbl_User select u;
var result = query.ToList();
if (result.Count > 0)
{
birth_day = result[0].BirthDayDate;
DateTime birthdaydate = DateTime.Parse(ShamsiToMiladi(birth_day));
DateTime todaydate = DateTime.Parse(ShamsiToMiladi(PublicVariable.TodayDate));
int days = todaydate.Day - birthdaydate.Day;
if (days < 0)
{
todaydate = todaydate.AddMonths(-1);
days += DateTime.DaysInMonth(todaydate.Year, todaydate.Month);
}
int months = todaydate.Month - birthdaydate.Month;
if (months < 0)
{
todaydate = todaydate.AddYears(-1);
months += 12;
}
int years = todaydate.Year - birthdaydate.Year;
MessageBox.Show(string.Format("{0} year{1}, {2} month{3} and {4} day{5}",
years, (years == 1) ? "" : "s",
months, (months == 1) ? "" : "s",
days, (days == 1) ? "" : "s"));
}
Just a simple foreach:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var query = db.tbl_User.ToList();
if (!query.Any())return;
var results = new List<string>();
foreach(var user in query){
var birth_day = user.BirthDayDate;
DateTime birthdaydate = DateTime.Parse(ShamsiToMiladi(birth_day));
DateTime todaydate = DateTime.Parse(ShamsiToMiladi(PublicVariable.TodayDate));
int days = todaydate.Day - birthdaydate.Day;
if (days < 0)
{
todaydate = todaydate.AddMonths(-1);
days += DateTime.DaysInMonth(todaydate.Year, todaydate.Month);
}
int months = todaydate.Month - birthdaydate.Month;
if (months < 0)
{
todaydate = todaydate.AddYears(-1);
months += 12;
}
int years = todaydate.Year - birthdaydate.Year;
results.Add(
string.Format(
"{0} year{1}, {2} month{3} and {4} day{5}",
years, (years == 1) ? "" : "s",
months, (months == 1) ? "" : "s",
days, (days == 1) ? "" : "s"
)
);
}
}
Not enough rep to comment but to use foreach:
if (result.Count > 0)
{
birth_day = result[0].BirthDayDate;
becomes
foreach (var item in result)
{
// Use result.BirthDayDate

Multiple while conditions

I want to output a timer in console which goes from 00h00m00s to 23h59m59s.
My code only outputs until 00h00m59s.
Must be the conditions in after the while, but i think it is correct.
Who knows how to solve this ?
static void Main(string[] args)
{
int uur = 0;
int min = 0;
int sec = 0;
while (uur != 23 && min!=60 && sec!=60)
{
if (sec == 60)
{
min++;
sec = 0;
}
if (min == 60)
{
uur++;
min = 0;
}
string strSec = String.Format("{0:00}", sec);
string strMin = String.Format("{0:00}", min);
string strUur = String.Format("{0:00}", uur);
Console.WriteLine(strUur + "h" + strMin + "m" + strSec + "s");
sec++;
}
Console.ReadLine();
}
Use the following condition:
while (uur != 23 || min != 59 || sec != 60)
You might also want to try this simpler approach:
int total_second_in_day = 24*60*60;
for (int second_in_day = 0; second_in_day < total_second_in_day; second_in_day++)
{
int uur = second_in_day / 3600;
int min = (second_in_day % 3600) / 60;
int sec = (second_in_day % 3600) % 60;
string strSec = String.Format("{0:00}", sec);
string strMin = String.Format("{0:00}", min);
string strUur = String.Format("{0:00}", uur);
Console.WriteLine(strUur + "h" + strMin + "m" + strSec + "s");
}
Console.ReadLine();
Although your question is basically about understanding while conditions this is how you could achieve printing all times:
using System;
public class Program
{
public static void Main()
{
var time = new TimeSpan(0,0,0,0);
var oneSec = new TimeSpan(0,0,0,1);
var wakeywakey = new TimeSpan(0,23,59,59);
while (time <= wakeywakey)
{
Console.WriteLine(time);
time += oneSec;
}
}
}

how to display Date and Time in a well mannered format [duplicate]

This question already has answers here:
Calculate relative time in C#
(41 answers)
Closed 9 years ago.
if I want to retrieve the date and time from db and show it in format
"2 mins ago, just now, or 6 months ago" kinda etc.,
how can i do it.. :)
Can any one suggest me how to do this please,
string gettime(DateTime updatedat)
{
string toren = "A moment earlier";
TimeSpan ts = DateTime.Now - updatedat;
if (ts.TotalSeconds<60)
{
toren = ts.TotalSeconds.ToString() + " seconds ago";
}
else if (ts.TotalMinutes < 60)
{
toren = ts.TotalMinutes.ToString() + " minutes ago";
}
else if (ts.TotalHours < 24)
{
toren = ts.TotalHours.ToString() + " hours ago";
}
else if (ts.TotalDays < 30)
{
toren = ts.TotalDays.ToString() + " days ago";
}
else
{
double month = ts.TotalDays / 30;
if (month<13)
{
toren = month.ToString() + " months ago";
}
else
{
double year = month / 12;
toren = year.ToString() + " years ago";
}
}
return toren;
}
Change/Optimize it according to your need.
Quoted answer from here:
const int SECOND = 1;
const int MINUTE = 60 * SECOND;
const int HOUR = 60 * MINUTE;
const int DAY = 24 * HOUR;
const int MONTH = 30 * DAY;
if (delta < 0)
{
return "not yet";
}
if (delta < 1 * MINUTE)
{
return ts.Seconds == 1 ? "one second ago" : ts.Seconds + " seconds ago";
}
if (delta < 2 * MINUTE)
{
return "a minute ago";
}
if (delta < 45 * MINUTE)
{
return ts.Minutes + " minutes ago";
}
if (delta < 90 * MINUTE)
{
return "an hour ago";
}
if (delta < 24 * HOUR)
{
return ts.Hours + " hours ago";
}
if (delta < 48 * HOUR)
{
return "yesterday";
}
if (delta < 30 * DAY)
{
return ts.Days + " days ago";
}
if (delta < 12 * MONTH)
{
int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
return months <= 1 ? "one month ago" : months + " months ago";
}
else
{
int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
return years <= 1 ? "one year ago" : years + " years ago";
}
And yes, I do quote. Because this answer meets exactly what the PO wants. :)
EDIT:
Question by PO: One more thing.. What if I am retrieving the date and time field from database. How can I imply this code?
Without knowing your structure or code, it would look something like this:
var cmd = new SqlCommand(yourConnection);
cmd.CommandText = "SELECT yourDateColumn FROM yourTable";
using (var sr = cmd.ExecuteReader)
{
if (sr.Read)
{
var yourDateTime = sr.GetDateTime(0);
}
}

how to resolve jquery custom Timer issue?

I have created a custom Jquery Timer. but i am facing little problem i dont know that is not working for me. below is my code.
function show(Hos, mins, secds) {
var hours = Hos;
var minutes = mins;
var seconds = secds;
var dn = "AM";
if (hours > 12) {
dn = "PM"
hours = hours - 12
}
if (hours == 0)
hours = 12
document.getElementById('<%= Label1.ClientID %>').innerHTML = hours + ":" + minutes + ":" + seconds + " " + dn
if (parseInt(seconds) == 59) {
seconds = 0;
if (parseInt(minutes) == 59) {
if (parseInt(hours) == 12) {
hours = 0;
} else {
hours = parseInt(hours) + 1;
}
} else {
minutes = parseInt(minutes) + 1;
}
} else {
seconds = parseInt(seconds) + 1;
}
setTimeout("show('" + hours + "','" + minutes + "','" + seconds + "'" + " )", 1000)
}
This code is working fine i am passing the hours,mins,seconds first time from the code behind using c#.Now my problem is i want to add "0" if the seconds is less than 9 and minutes less than 9 and hours less than 9. i have tried the following trick but i dont know why its not working for me..
if (seconds <= 9) {
seconds = '0' + parseInt(seconds);
}
Please help me..Actually what happens when i tried this . its concatenate 0 with seconds upto 9 but as 9 comes it restarts from 1. That is the problem.
seconds = '0' + parseInt(seconds) will do string addition, since '0', is a string.
When you add a string to a number in javascript, the number will be appended to the string.
Remove the quotes for 0, then it will be treated like number.
P.S. I guess this is the problem you are trying to crack
i have resolve this problem using some trick that is as follow:
function show(Hos, mins, secds) {
var hours = Hos;
var minutes = mins;
var seconds = parseInt(secds, 10);
if (hours == 0)
hours = 12
if (parseInt(seconds, 10) < 10) {
seconds = "0" + parseInt(seconds, 10);
}
if (parseInt(hours, 10) < 10) {
hours= "0" + parseInt(hours, 10);
}
if (parseInt(minutes, 10) < 10) {
minutes= "0" + parseInt(minutes, 10);
}
document.getElementById('<%= Label1.ClientID %>').innerHTML = hours + ":" + minutes + ":" + seconds + " "
if (parseInt(seconds) == 59) {
seconds = 0;
if (parseInt(minutes, 10) == 59) {
if (parseInt(hours, 10) == 24) {
hours = 0;
} else {
hours = parseInt(hours, 10) + 1;
}
} else {
minutes = parseInt(minutes, 10) + 1;
}
} else {
seconds = parseInt(seconds, 10) + 1;
}
setTimeout("show('" + hours + "','" + minutes + "','" + seconds + "'" + " )", 1000)
}

Categories