How to get DateTime From Database in Solar Date Fromat (Shamsi Date)? - c#

I am trying to get DataTime from database in Persian Date Fromat,
For this task i made an extinsion method,
and my App Culture is FA-fa, So the DateTime.Now returning Persian Date.
Here is cultureInfo
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("fa-AF");
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("fa-AF");
Here is My Code in ViewModel Which makes error:
long mntRevenue = (long)db.StudentFees
.Where(f => DateConverter.ToPersianDate(f.Date).Month == DateTime.Now.Month).Sum(s => s.Pay);
Error is:
System.InvalidOperationException: 'The LINQ expression 'DbSet()
.Where(s => (DateTime?)s.Date
.ToPersianDate().Month == DateTime.Now.Month)' could not be translated. Additional information: Translation of method 'SchoolViewModel.ViewModels.DateConverter.ToPersianDate' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information.
Translation of method 'SchoolViewModel.ViewModels.DateConverter.ToPersianDate' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'
My Extinsion Method is:
public static class DateConverter
{
#region Static Methods
public static DateTime ToPersianDate(this DateTime? dt)
{
try
{
DateTime dateTime = dt ?? DateTime.Now;
PersianCalendar persianCalendar = new PersianCalendar();
string year = persianCalendar.GetYear(dateTime).ToString();
string month = persianCalendar.GetMonth(dateTime).ToString()
.PadLeft(2, '0');
string day = persianCalendar.GetDayOfMonth(dateTime).ToString()
.PadLeft(2, '0');
string hour = dateTime.Hour.ToString().PadLeft(2, '0');
string minute = dateTime.Minute.ToString().PadLeft(2, '0');
string second = dateTime.Second.ToString().PadLeft(2, '0');
return DateTime.Parse(String.Format("{0}/{1}/{2} {3}:{4}:{5}", year, month, day, hour, minute, second));
}
catch { return DateTime.Now; }
}
#endregion
}
I want to get date from database and compare it with Current Month and give the compare result to linq expression. The DateTime should be in the Persian Format (Shamsi Date).

Thanks for all who leaves comments, Specially #lets do it.
I found the solution,
I just Remove the ToPersianDate Extinsion Method and Add DateAndPay class,
DateAndPay Class:
public class DateAndPay
{
public DateTime Date { get; set; }
public int Pay { get; set; }
}
Here it is:
PersianCalendar persianCalendar = new PersianCalendar();
int month = persianCalendar.GetMonth(DateTime.Now);
using AppDbContext db = new();
List<DateAndPay> studentFee = await db.StudentFees.Select(f => new DateAndPay { Date= f.Date,Pay= f.Pay }).ToListAsync();
long mntRevenue = (long)studentFee.Where(f => persianCalendar.GetMonth(f.Date) == month).Sum(f=> f.Pay);

Related

MongoDB .NET Driver - Convert string to DateTime and for Filter Builder

var builder = Builders<ModelClass>.Filter;
var filter = builder.Where(x => x.Active);
if (fromDate.HasValue)
{
var date = fromDate.Value;
var subfilter = builder.Where(x => DateTime.Parse(x.EnrollmentDate) >= date);
filter &= subfilter;
}
Enrollment Date is saved as a string:
public string EnrollmentDate { get; set; }
, I need to filter docs within a set of date range, but how do I compare this? I need to filter like this.
I get
System.InvalidOperationException: Parse({document}{EnrollmentDate}) is not supported.
Error in subfilter line.
I think you need to achieve with MongoDB query as below:
{
"$expr": {
"$gte": [
{ "$toDate": "$EnrollmentDate" },
date
]
}
}
While I think it is not achievable with MongoDB .Net Driver LINQ syntax, you convert the query as BsonDocument:
var subfilter = new BsonDocument("$expr",
new BsonDocument("$gte",
new BsonArray {
new BsonDocument("$toDate", "$EnrollmentDate"),
date
}
)
);
filter &= subfilter;
You have problem here when you want to do DateTime.Parse()
Can you post format of your string EnrollmentDate? And your variable date , is it only Date or DateTime?
This one maybe can help you here
Also, try to use
var subfilter = builder.Gte(x=>x.Y, Z)

Formatting DateTime string inside of a linq statement

I have a web api set up where I'm displaying information on my site via entity framework. I'm filtering my data so it only pulls back the specific parts I want, which includes a DateTime value.
[HttpGet]
public IEnumerable<Log> XmlLog()
{
var userLog = _db.Logs.Where(x => x.EngineType == "Xml");
return userLog .ToList();
}
This displays my date as:
2019-02-05T15:11:50.39
What I need to do is change the DateTime format to be something else. Ideally:
Saturday 2 February 9:12:30
On my linq call I've tried the following:
[HttpGet]
public IEnumerable<Log> XmlLog()
{
var userLog = _db.Logs.Select(d => d.LogDate.ToString("f")).Where(x => x.EngineType == "Xml");
return userLog .ToList();
}
And on my model itself I have tried the following attributes:
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:yyyy/MM/dd HH:mm:ss}")]
public DateTime LogDate { get; set; }
Neither of my attempts has worked. What is it I'm doing wrong in my statements?
The above is written in DotNet 4.7 and not in DotNetCore.
As John has commented, your LINQ should be throwing an exception, because you first select strings, and then try to filter them as though they are objects.
But this approach is backwards anyway. This is just about getting the data, so it should just stay as it is, without any formatting. Let your view layer be responsible for formatting.
The DisplayFormat attribute is great, but only if you are using Html.DisplayFor/Html.EditorFor helpers. If you are doing just something like #Model.LogDate in your view, consider calling ToString(format) with the format you need.
Finally, your format does not look like example you wish it was. The correct format you are looking for is: dddd, dd MMMM HH:mm:ss.
All in all, leave the filter as it is, and either use DisplayFor with this annotation:
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:dddd, dd MMMM HH:mm:ss}")]
public DateTime LogDate { get; set; }
...
#Html.DisplayFor(m => m[i].LogDate)
Or don't bother with any annotations, and just use
#Model[i].LogDate.ToString("dddd, dd MMMM HH:mm:ss")

Convert string to MM/yyyy in c# to sort

I have seen previous questions which are related my query but couldn't figure out on how to resolve my issue.
I have a list "Sites" with one of the items as "Year". It is defined as string and is in the format "MM/yyyy". When I try to sort the list based on the year, I'm facing a small problem.
Data for "Year" is
01/2012
04/2012
01/2013
06/2012
When I sort the list by using orderby, the output I'm getting is
01/2012
01/2013
04/2012
06/2012
which is incorrect.
Cannot convert the string using Convert.ToDateTime as the string format doesn't contain day value. How should I go forward with this? How to implement DateTime.TryParseExact without changing the format of the string?
Note : The format should be the same and the list should be sorted.
you could try something like this without having to change the input this will give you the order that you like also look at the OrderByDescending property if you need it in a different sort order
var dateList = new List<string> { "01/2012", "04/2012", "01/2013", "06/2012" };
var orderedList = dateList.OrderBy(x => DateTime.Parse(x)).ToList();
You can still convert the string to a date within a LINQ statement, and the items will stay as strings.
var strings = new[]
{
"01/2012",
"04/2012",
"01/2013",
"06/2012"
};
var ordered = strings.OrderBy(s =>
{
var split = s.Split('/');
return new DateTime(int.Parse(split[1]), int.Parse(split[0]), 1);
});
Your last item will then be "01/2013".
As MethodMan showed in his answer, DateTime.Parse() will be able to parse a MM/yyyy formatted dated. However, if you need to perform anything that takes more than one line, this would be how you can do that. NB: This will not work in any query against a DbContext!
Implement System.IComparable interface:
public int CompareTo(object obj)
{
// Check null
if (obj == null)
return 1;
// Check types
if (this.GetType() != obj.GetType())
throw new ArgumentException("Cannot compare to different type.", "obj");
// Extract year and month
var year = int.Parse(this.Year.SubString(3, 4));
var month = int.Parse(this.Year.SubString(0, 2));
// Extract year and month to compare
var site = (Sites)obj;
var objyear = int.Parse(site.Year.SubString(3, 4));
var objmonth = int.Parse(site.Year.SubString(0, 2));
// Compare years first
if (year != objyear)
return year - objyear;
// Same year
// Compare months
return month - objmonth;
}
you also can create a new list with Dates converted to DateTime format and sort it after. It's a lot of lines but good for learning.
class Sites
{
public string Year { get; set; }
}
class MainClass
{
static void Main()
{
List<Sites> ListOfSites = new List<Sites>();
ListOfSites.Add(new Sites { Year = "01/2012" });
ListOfSites.Add(new Sites { Year = "04/2012" });
ListOfSites.Add(new Sites { Year = "01/2013" });
ListOfSites.Add(new Sites { Year = "06/2012" });
DateTime SiteYear;
List<DateTime> listWithDates = new List<DateTime>();
foreach (var item in ListOfSites)
{
if(DateTime.TryParse(item.Year, out SiteYear))
{
listWithDates.Add(SiteYear);
}
}
Display(SortAscending(listWithDates), "Sort Ascending");
}
static List<DateTime> SortAscending(List<DateTime> list)
{
list.Sort((a, b) => a.CompareTo(b));
return list;
}
static void Display(List<DateTime> list, string message)
{
Console.WriteLine(message);
foreach (var datetime in list)
{
Console.WriteLine(datetime);
}
Console.WriteLine();
}
}

Specified cast is not valid exception

This is my code
var result = (from row1 in table.AsEnumerable()
join row2 in tabelPopup.AsEnumerable()
on row1.Field<string>("CallID") equals
row2.Field<string>("callID")
where row1.Field<string>("Direction") == "I"
select new
{
Agent = row1.Field<string>("Agent"),
StartTime = row1.Field<DateTime>("StartTime"),
Reason = row2.Field<string>("Reason")
});
where table and tablePopup are datatable variables.
I got this exception:
Specified cast is not valid
on this code:
new
{
Agent = row1.Field<string>("Agent"),
StartTime = row1.Field<DateTime>("StartTime"),
Reason = row2.Field<string>("Reason")
}
Make sure your column definitions match the type you're using in row1.field<>. i.e. Agent is string, StartTime is datetime and Reason is string. This is likely due to StartTime not being a datetime type.
Probably StartTime is not from Type DateTime. Because of that you receive this exception. Try to convert it. If this is correct you should convert it to DateTime or just retrieve string value.

Setting a DateTime appointment schedule

Newbie question about using the DateTime method to set a schedule inside a Telerik calendar. I want to use the Telerik controls calendar to set a schedule for a music bands tour schedule.
I can't seem to get the desired results. Below is the code in my SampleAppointmentSource CS file. I thought that by setting the DateTime.Parse("5/19/2013") that then in all of the appointments when I use the AddDays(1) or AddDays(20) the appointemnts would follow the DateTime.Parse("5/19/2013") pattern but it doesn't. The appointments always use the current date and time (Now). When I add the days, the appointments aren't added to the Parsed date ("5/19/2013"), they are added to the current DateTime. Like the appointments are always referenced to the current system date.
I hope that wasn't to confusing....
What do I need to use to get the desired results?
Is it because of the DateTime.Now.AddDays(1) line? Should it not be DateTime.Now?
{
public class SampleAppointmentSource : AppointmentSource
{
public SampleAppointmentSource()
{
DateTime date = new DateTime();
date = DateTime.Parse("5/19/2013");
}
public override void FetchData(DateTime startDate, DateTime endDate)
{
this.AllAppointments.Clear();
this.AllAppointments.Add(new SampleAppointment()
{
StartDate = DateTime.Now.AddDays(1),
EndDate = DateTime.Now.AddDays(1),
Subject = "Jackson W/Warren Hayes",
AdditionalInfo = "Fain Feild",
Location = "LoserVille,Kentucky",
});
Fleshing out my comment to your question. You create a DateTime object called date and never use it. DateTime.Now will always return an object containing the current DateTime. You need give your date DateTime object module Level scope so you can access it in your FetchData method. See if something like this works for your.
public class SampleAppointmentSource : AppointmentSource
{
DateTime date;
public SampleAppointmentSource()
{
date = DateTime.Parse("5/19/2013");
}
public override void FetchData(DateTime startDate, DateTime endDate)
{
this.AllAppointments.Clear();
this.AllAppointments.Add(new SampleAppointment()
{
StartDate = date.AddDays(1),
EndDate = date.AddDays(1),
Subject = "Jackson W/Warren Hayes",
AdditionalInfo = "Fain Feild",
Location = "LoserVille,Kentucky",
});
}
}

Categories