convert timespan to datetime - c#

My function is :
public async Task<IHttpActionResult> RecentAddedTags(int daysago)
{
TimeSpan duration = DateTime.UtcNow - DateTime.Today.AddDays(-daysago);
DateTime days = DateTime.UtcNow - duration;
var ret = from tag in db.Tags
where tag.time.Equals(days)
select new
{
postedById = tag.AspNetUser.Id,
postedByName = tag.AspNetUser.UserName,
name = tag.name,
info = tag.info,
time = tag.time,
id = tag.Id,
};
return Ok(ret);
}
If I call the function as RecentAddedTags(2) it should return all tags created 2 days ago. But it gives the error:
Unable to create a constant value of type 'System.Object'. Only
primitive types or enumeration types are supported in this context.
There is some issue with days object. What I am doing wrong?

Compare Date in DateTime Object it will work for you
var ret = from tag in db.Tags.ToList()
where tag.time.Date == days.Date
select new
{
postedById = tag.AspNetUser.Id,
postedByName = tag.AspNetUser.UserName,
name = tag.name,
info = tag.info,
time = tag.time,
id = tag.Id,
};

You need to change
tag.time.Equals(days)
to
tag.time == days;
(not entirely sure why it works)

Related

How to display all Fridays Date between two dates

How to get a Friday date from the given start date and end date,
For Example:
25/03/2021 - starting date
14/08/2021 - endind date
I have a class
public static class DateUtils
{
public static List<DateTime> GetWeekdayInRange(this DateTime from, DateTime to, DayOfWeek day)
{
const int daysInWeek = 7;
var result = new List<DateTime>();
var daysToAdd = ((int)day - (int)from.DayOfWeek + daysInWeek) % daysInWeek;
do
{
from = from.AddDays(daysToAdd);
result.Add(from);
daysToAdd = daysInWeek;
}
while (from < to);
return result;
}
}
That is how i call it in main method:
var from = DateTime.Today; // 25/8/2019
var to = DateTime.Today.AddDays(23); // 23/9/2019
var allFriday = from.GetWeekdayInRange(to, DayOfWeek.Friday);
Console.WriteLine(allFriday);
Console.ReadKey();
Error i get:
System.Collections.Generic.List`1[System.DateTime]
I am new and still learning, how do I call in the main method so that my output be like all dates(fridays) between the range?
Link I followed
To Answer your question, instead of printing allFridays in one go, iterate over each element of list i.e allFridays, convert into string and then print
foreach(var friday in allFridays)
Console.WriteLine(friday);
Why you are getting System.Collections.Generic.List[System.DateTime] ?
Console.WriteLine(), for non primitive type by default calls
.ToString() function which prints type of it(if it is not overridden). In your case, you
need an individual date not a type of List, so you need to iterate
each DateTime from the list and print each date.
One Liner solution:
Console.WriteLine(string.Join(Environment.NewLine, allFridays));
Alternate solution:
public static List<DateTime> GetWeekdayInRange(this DateTime #from, DateTime to, DayOfWeek day)
{
//Create list of DateTime to store range of dates
var dates = new List<DateTime>();
//Iterate over each DateTime and store it in dates list
for (var dt = #from; dt <= to; dt = dt.AddDays(1))
dates.Add(dt);
//Filter date based on DayOfWeek
var filteredDates = dates.Where(x => x.DayOfWeek == day).ToList();
return filteredDates;
}
...
var #from = DateTime.Today; // 25/8/2019
var to = DateTime.Today.AddDays(23); // 23/9/2019
var allFriday = #from.GetWeekdayInRange(to, DayOfWeek.Friday);
Console.WriteLine(string.Join(Environment.NewLine, allFridays));
.NET FIDDLE
Since in your Usage section, you have successfully get the result via GetWeekdayInRange. You can print the dates with these methods:
Method 1:
allFriday.ForEach(x => Console.WriteLine(x.ToShortDateString()));
Method 2:
foreach (var friday in allFriday)
{
Console.WriteLine(friday.ToShortDateString());
}
Method 3:
for (var i = 0; i < allFriday.Count(); i++)
{
Console.WriteLine(allFriday[i].ToShortDateString());
}
Note: ToShortDateString() is one of the methods to display Date string. You can define your desired Date pattern with ToString().

Create a chain of tasks

I'm writing a background service which pulls historical data about products while my web server is running. I can only make requests at a specific rate, so for that reason, I need to create an executionQueue:
Creating this list of tasks is verbose and I don't see why it should be like this.
Maybe I'm just over complicating things:
public List<Task<Task<List<Candle>>>> BuildHistoricalDataTaskList(CryptoInfoContext context, string productId, DateTime totalStartDate, DateTime totalEndDate, Granularity[] granularities, int maxResults = 300)
{
var product = this.GetProductFromId(context, productId);
var executionQueue = new List<Task<Task<List<Candle>>>>();
foreach (var granularity in granularities)
{
var granularityMinutes = (int)granularity;
var startDate = totalStartDate;
var maxRangeMinutes = maxResults * granularityMinutes;
while (startDate <= totalEndDate)
{
var endDate = startDate.AddMinutes(maxRangeMinutes);
var task = new Task<Task<List<Candle>>>(() =>
{
return ProcessHistoricalDataAsync(productId, startDate, endDate, granularity);
});
executionQueue.Add(task);
startDate = endDate;
}
}
return executionQueue;
}
My return type seems a little verbose, is there a way i'm able to squash these Tasks down?
Maybe an observable is the way to go but I'm not sure how.
It looks like the middle Task is just behaving as a late execution closure. So you could replace that with a Func<Task<List<Candle>>> and get the same effect. That doesn't help anything, but it reduces the confusion introduced by Task<Task<...>>.
I'm assuming outside of this is something that processes the queue, so could you slim it down to an IEnumerable<Func<Task<List<Candle>>>>?
eg.
public IEnumerable<Func<Task<List<Candle>>>> BuildHistoricalDataTaskList(CryptoInfoContext context, string productId, DateTime totalStartDate, DateTime totalEndDate, Granularity[] granularities, int maxResults = 300)
{
var product = this.GetProductFromId(context, productId);
foreach (var granularity in granularities)
{
var granularityMinutes = (int)granularity;
var startDate = totalStartDate;
var maxRangeMinutes = maxResults * granularityMinutes;
while (startDate <= totalEndDate)
{
var endDate = startDate.AddMinutes(maxRangeMinutes);
yield return () =>
{
return ProcessHistoricalDataAsync(productId, startDate, endDate, granularity);
};
startDate = endDate;
}
}
}
it's not much better from a signature perspective. But it's slightly smaller.. Also you're not using product at all, that's likely costing you something.

Finding the month between a range

I have a datasource that returns dates and I have to find where the months falls within the month and day range buckets. The months and day range buckets are predefined so I put it in a Dictionary (not sure if that is even a good idea). I am using linq to find the min and Max dates and extracting the month from them. I need to find month from the dictionary where that month extracted falls within the range. For Example
Dictionary<int, int> MonthDayBuckets = new Dictionary<int, int>() { { 3,31 }, { 6,30 }, { 9,30 }, { 12,31 } };
var MinyDate = _dataSource.Min(x => x.values[0]);
var MaxDate = _dataSource.Max(x => x.values[0]);
var startMonth = Convert.ToDateTime(MinyDate).ToString("MM");
var endMonth = Convert.ToDateTime(MaxDate).ToString("MM");
Say startmonth return Jan so I want to be able to go to the dictionary and return only march (03.31) and if I get 10 for the Max (October) I am trying to return (12,31) December
If my understanding is correct, your MonthDayBuckets variable is meant to represent date ranges:
3/31 - 6/30
6/30 - 9/30
9/30 - 12/31
12/31 - 3/31
...and given a month, you're wanting to see what the end date is of the interval that the first of that month falls between? Like you gave the example of October returning 12/31.
This problem can be simplified since you'll get the same result saying "what's the next occurring date after this given date?" The next occurring date for 10/01 would be 12/31. So here's how you could rearrange your data:
var availableDates = new List<string> { "03/31", "06/30", "09/30", "12/31" };
Now you'll be able to find a match by finding the index of the first one that's greater than your given date. Note how I made the month/day combos lexicographical orderable.
var startMonth = Convert.ToDateTime(MinyDate).ToString("MM");
var startDate = startMonth + "/01";
var endMonth = Convert.ToDateTime(MaxDate).ToString("MM");
var endDate = endMonth + "/01";
// Wrap around to the first date if this falls after the end
var nextStartDate = availableDates.FirstOrDefault(d => d.CompareTo(startDate) >= 1) ?? availableDates[0];
var nextEndDate = availableDates.FirstOrDefault(d => d.CompareTo(endDate) >= 1) ?? availableDates[0];
You could use Linq for the purpose. For example,
var nearestKey = MonthDayBuckets.Keys.Where(x => x >= endMonth.Month).Min();
var nearestDate = new DateTime(DateTime.Now.Year,nearestKey,MonthDayBuckets[nearestKey]); // or whatever the year it needs to be represent
Though above query would get you the result, I would suggest you define a structure to store the Range itself, rather than using Dictionary
For example,
public class Range
{
public MonthDate StartRange{get;set;}
public MonthDate EndRange{get;set;}
public Range(MonthDate startRange,MonthDate endRange)
{
StartRange = startRange;
EndRange = endRange;
}
}
public class MonthDate
{
public MonthDate(int month,int date)
{
Month = month;
Date = date;
}
public int Month{get;set;}
public int Date{get;set;}
//Depending on if your Ranges are inclusive or not,you need to decide how to compare
public static bool operator >=(MonthDate source, MonthDate comparer)
{
return source.Month>= comparer.Month && source.Date>=comparer.Date;
}
public static bool operator <=(MonthDate source, MonthDate comparer)
{
return source.Month<= comparer.Month && source.Date<=comparer.Date;
}
}
Now you could define ranges as
var dateRanges = new Range[]
{
new Range(new MonthDate(12,31),new MonthDate(3,31)),
new Range(new MonthDate(3,31),new MonthDate(6,30)),
new Range(new MonthDate(6,30),new MonthDate(12,31)),
};
var result = dateRanges.First(x=>x.StartRange <= new MonthDate(endMonth.Month,endMonth.Day) && x.EndRange >= new MonthDate(endMonth.Month,endMonth.Day));

How to set a default value to a DateTime parameter

In my MVC application I want to set default values to the DateTime parameter.
[HttpPost]
public ActionResult BudgetVSActualTabular(DateTime startDate)
{
var Odata = _db.sp_BudgetedVsActualTabular(startDate).ToList();
string[] monthName = new string[12];
for (int i = 0; i < 12;i++ )
{
DateTime date = startDate;
date = date.AddMonths(i);
monthName[i] = date.ToString("MMMM") + " " + date.Year.ToString();
}
ViewBag.startDate = new SelectList(_db.DaymonFinancialYears, "startDate", "DateRange");
var MonthName = monthName.ToList();
ViewBag.Bdata = Odata;
ViewBag.Cdata = MonthName;
return View();
}
You cannot set a null to a DateTime but you can use a Nullable DateTime parameter instead:
[HttpPost]
public ActionResult BudgetVSActualTabular(DateTime? startDate = null )
{
if (startDate == null)
{
startDate = new DateTime(2016, 06, 01);
}
//You should pass startDate.Value
var Odata = _db.sp_BudgetedVsActualTabular(startDate.Value).ToList();
}
You can use the default keyword with this syntax
public ActionResult BudgetVSActualTabular(DateTime startDate = default(DateTime))
This will make possible to call the method without passing any parameter and inside your method the startDate variable will be equal to DateTime.MinValue
If you need the default to be a specific date instead of DateTime.MinValue you could write a simple test
public ActionResult BudgetVSActualTabular(DateTime startDate = default(DateTime))
{
if(startDate == DateTime.MinValue)
startDate = new DateTime(2014,6,1);
// After the check for a missing parameter pass the startDate as before
var Odata = _db.sp_BudgetedVsActualTabular(startDate).ToList();
.....
}
Named and optional (default) parameters are available starting from C# 4.0. in case you're using an older version, you may overload your method like:
public ActionResult BudgetVSActualTabular()
{
return BudgetVSActualTabular(new DateTime(2014,6,1));
}
I would suggest setting the DateTime to be nullable public ActionResult BudgetVSActualTabular(DateTime? startDate).
Inside your controller you can use DateTime.HasValue to set a default if the DateTime is null.
var nonNullableDate = startDate.HasValue ? startDate.Value : new DateTime();
[HttpPost]
public ActionResult BudgetVSActualTabular(DateTime? startDate)
{
var nonNullableDate = startDate.HasValue ? startDate.Value : new DateTime();
var Odata = _db.sp_BudgetedVsActualTabular(nonNullableDate).ToList();
string[] monthName = new string[12];
for (int i = 0; i < 12;i++ )
{
DateTime date = nonNullableDate;
date = date.AddMonths(i);
monthName[i] = date.ToString("MMMM") + " " + date.Year.ToString();
}
ViewBag.startDate = new SelectList(_db.DaymonFinancialYears, "startDate", "DateRange");
var MonthName = monthName.ToList();
ViewBag.Bdata = Odata;
ViewBag.Cdata = MonthName;
return View();
}

Rendering in IE with fullcalendar

I am using the fullcalendar,
but in IE 10 or 11 the events are not render correct,
I have this:
public static List<DiaryEvent> LoadAllAppointmentsInDateRange(double start, double end)
{
var fromDate = ConvertFromUnixTimestamp(start);
var toDate = ConvertFromUnixTimestamp(end);
using (LolaBikeContext ent = new LolaBikeContext())
{
var rslt = ent.AppointmentDiarys.Where(s => s.DateTimeScheduled >= fromDate && System.Data.Entity.DbFunctions.AddMinutes(s.DateTimeScheduled, s.AppointmentLength) <= toDate);
List<DiaryEvent> result = new List<DiaryEvent>();
foreach (var item in rslt)
{
DiaryEvent rec = new DiaryEvent();
rec.ID = item.Id;
rec.SomeImportantKeyID = item.SomeImportantKey;
rec.StartDateString = item.DateTimeScheduled.ToString("MMMM/dd/yyyy"); // "s" is a preset format that outputs as: "2009-02-27T12:12:22"
rec.StarEvent = item.DateTimeScheduled.ToString("HH:mm"); // ParseExact(start, "HH:mm", CultureInfo.CurrentCulture).ToString(); //item.DateTimeScheduled.ToString("MMMM/dd/yyyy");
rec.EndDateString = item.DateTimeScheduled.AddMinutes(item.AppointmentLength).ToString("yyyy-MM-ddTHH\\:mm\\:ss.fffffffzzz");// "yyyy-MM-ddTHH:mm:ss.fffZ"); // field AppointmentLength is in minutes
rec.Title = item.Title;// +" - " + item.AppointmentLength.ToString() + " mins";
rec.AppointmentLength = item.AppointmentLength.ToString();
rec.StatusString = Enums.GetName<AppointmentStatus>((AppointmentStatus)item.StatusENUM);
rec.StatusColor = Enums.GetEnumDescription<AppointmentStatus>(rec.StatusString);
string ColorCode = rec.StatusColor.Substring(0, rec.StatusColor.IndexOf(":"));
rec.ClassName = rec.StatusColor.Substring(rec.StatusColor.IndexOf(":") + 1, rec.StatusColor.Length - ColorCode.Length - 1);
rec.StatusColor = ColorCode;
result.Add(rec);
}
return result;
}
}
and especially this line:
rec.EndDateString = item.DateTimeScheduled.AddMinutes(item.AppointmentLength).ToString("yyyy-MM-ddTHH\\:mm\\:ss.fffffffzzz");// is not rendering correct.
I have read that it has to be in: ISO 8601, so I have looked at this thread:
Given a DateTime object, how do I get an ISO 8601 date in string format?
but that doesnt work. IE is rendering the events not correct
Thank you!!
see the different pictures
The correct image:
I think youare missing the "s" format specifier, which is described as Sortable date/time pattern; conforms to ISO 8601
The EventStart comes in ISO 8601 format and you will need to convert it. you can follow this example to convert current to ISO 8601:
DateTime.UtcNow.ToString ( "s", System.Globalization.CultureInfo.InvariantCulture )
Here's a post about that : Link
As for your code try this instead for your startdatestring and enddatestring:
rec.StartDateString = item.DateTimeScheduled.ToString("s");
rec.EndDateString = item.DateTimeScheduled.AddMinutes(item.AppointmentLength).ToString("s");

Categories