Convert TimeSpan.TotalMilliseconds to datetime and format it as hour:minute - c#

I kinda confuse about the date time conversion
in my model i have defined
public DateTime? Sent { get; set; }
public DateTime? Reply { get; set; }
public double ResponseTime { get; set; }
in linq part i am using
ResponseTime = (u.Reply - u.sent).TotalMilliseconds
which is not formated and displayed like this 979809803
I want to know how do i convert it to datetime format, and eventually will display the format as hour:minute, for instance 2:45 between the date sent and date reply.

Just return the TimeSpan and call .ToString("hh:mm").
TimeSpan.ToString
public TimeSpan ResponseTime { get; set; }
//usage in LINQ
ResponseTime = (u.Reply - u.Sent)
When displaying...
value.ResponseTime.ToString("hh:mm")

Subtracting a DateTime from a DateTime yields a TimeSpan. Have a look at the TimeSpan.ToString Method (String) to see how you can custom format the value.
You can change ResponseTime back to a TimeSpan and from there to a string.
TimeSpan ResponseTimeSpan = new TimeSpan(0, 0, 0, (int)ResponseTime);
string ResponseTimeDisplay = ResponseTimeSpan.ToString();

Related

MongoDB C# filter datetime stored as a string

I'm trying to create a filter and find records by a date range. The thing is, the dates in our mongo server are (sadly, its historically like this and was imported from another database) stored as string type, in the format of "dd/MM/yyyy hh:mm:ss". How can I filter from user input dates? No matter what I've tried I got wrong results.
Here's some code:
[Serializable]
public class Error
{
[BsonElement("projectName")]
public string projectName { get; set; }
[BsonElement("programName")]
public string programName { get; set; }
[BsonElement("errorDescription")]
public string errorDescription { get; set; }
[BsonElement("userDescription")]
public string userDescription { get; set; }
[BsonElement("logDateTime")]
[BsonSerializer(typeof(DateSerializer))]
public DateTime logDateTime { get; set; }
[BsonElement("writeDateTime")]
public string writeDateTime { get; set; }
}
And here's the DateSerializer:
public class DateSerializer: SerializerBase<DateTime>
{
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, DateTime value)
{
context.Writer.WriteString(value.ToString(CultureInfo.InvariantCulture));
}
public override DateTime Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var dateText = context.Reader.ReadString();
return convertToDate(dateText);
}
private DateTime convertToDate(string dateText)
{
CultureInfo ci = new CultureInfo(CultureInfo.CurrentCulture.Name);
ci.DateTimeFormat.ShortDatePattern = "dd'/'MM'/'yyyy";
ci.DateTimeFormat.LongTimePattern = "hh':'mm tt";
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
string format = "dd/MM/yyyy HH:mm:ss";
DateTime dateTime = DateTime.ParseExact(dateText, format, ci);
return dateTime;
}
}
on my filter:
DateTime dateTime2 = DateTime.ParseExact(date, format, ci);
var fromDateFilter = builder.Gte(x => x.error.logDateTime, dateTime2);
and eventually:
filter = filter & fromDateFilter;
var results = errorCollection.Find(filter).ToList();
I've tried many different ways but can't seem to get the comparison to work properly.
Edit: I only care about the dates. The time is not very important.
Edit 2 - Apparently it only compares the day, for example it returns that 01/06/2017 (dd/mm/yyyy) is smaller than 06/02/2017 (dd/mm/yyyy). This is also true for 02-05/06/2017 until 06/06/2017.

Translate ISO 8601 UTC time format to hh:mm of EST

I have a list of objects that I de-serialized from a json string that have a start/end time field expressed in UTC time. Eg: "2016-08-22T15:30:00Z" (which is 11:30AM EST). I need to transform the time to a user-friendly format (e.g, "11:30 AM") on the server before sending down the list in JSON for displaying on a web page. Is there a c# function that will help me accomplish this transform the time property to the desired result?
code example:
public class Event
{
public int EventId { get; set; } //1
public string Name { get; set; } //Karate class
public string StartAt { get; set; } //2016-08-22T15:30:00Z
public string EndAt { get; set; } //2016-08-22T16:30:00Z
}
public class Events
{
public List<Event> Events {get; set;}
}
//de-serialize from json string
string eventsForToday = "{}" //some json string from api
var eventList = (Events)JsonConvert.DeserializeObject(eventsForToday, typeof(Events));
foreach (var item in eventList.Events)
{
//needs to be 11:30AM instead of 2016-08-22T15:30:00Z
Console.WriteLine (item.StartAt)
}
I know that the logic is whatever the UTC time is it should be offset by 4 (or 5 depending on time of year). But what is the most straight-forward way to modify the objects? Is there a way to project a new list with the format changed, etc?
You can convert each string into a DateTime. DateTime has a method ToLocalTime() that will do the conversion for you as long as you specify the Kind property of the DateTime. For example,
foreach (var item in eventList.Events)
{
DateTime timeUtc = DateTime.SpecifyKind(DateTime.Parse(item.StartAt), DateTimeKind.Utc);
Console.WriteLine (timeUtc.ToLocalTime()); //Add .ToShortTimeString() if you just want the time (and not the date)
}
However, since your string has a trailing "Z", you should just be able to use Convert.ToDateTime(item.StartAt).ToWhateverString()

Timespan Specified cast is not valid

I am trying to display the time in a gridview column but when loading the information I get this error:
Specified cast is not valid.
protected override void FillObject(DataRow dr)
{
ID = Convert.ToInt32(dr["ID"]);
if (dr["Company_ID"] != DBNull.Value)
CompanyID = Convert.ToInt32(dr["Company_ID"]);
if (dr["LoginTime"] != DBNull.Value)
LoginTime = (TimeSpan)(dr["LoginTime"]); //error
}
Get/Set code:
public TimeSpan LoginTime { get; set; }
As #TimS. pointed out, you need to use a DateTime variable in your code to consume a Sql Server DATETIME. From that, you can convert it into a TimeSpan if necessary.
public DateTime LoginTime { get; set; }
LoginTime = (DateTime)(dr["LoginTime"]);
To convert between the two, see How to get TimeSpan from DateTime

Date format change upon update event

I'm facing an issue with date formatting. Upon calling up the UpdateItem action, the date format for CreatedAt gets messed up. I'm using JSON by the way, so must be something to do with date serialization.
Model:
public class Item
{
public int ItemId { get; set; }
public string ItemName { get; set; }
public string CreatedBy { get; set; }
public DateTime? CreatedAt { get; set; }
public string UpdatedBy { get; set; }
public DateTime? UpdatedAt { get; set; }
}
Create action:
public int CreateItem(Item item)
{
var item = new Item();
viewModel.CopyToItem(item);
item.CreatedBy = WebSecurity.CurrentUserName;
item.CreatedAt = DateTime.Now;
db.Items.Add(item);
db.SaveChanges();
return item.ItemId;
}
Update action:
public void UpdateItem(Item item)
{
item.UpdatedBy = WebSecurity.CurrentUserName;
item.UpdatedAt = DateTime.Now;
db.SaveChanges();
}
The incorrect date format:
/Date(1395366469723)/
It should be:
2014-03-21T09:50:01.747
I tried this in the controller but get a String was not recognized as a valid DateTime' error.
string isoJson = JsonConvert.SerializeObject(DateTime.Now, new IsoDateTimeConverter());
item.CreatedAt = DateTime.ParseExact(isoJson, "yyyy-MM-dd hh:mm:ss.ttt", CultureInfo.InvariantCulture);
Using non-nullable DateTime in the model didn't fix it either.
Javascript uses Unix Time. If you are wanting to get a DateTime object with the given javascript date value, create a new DateTime object from 1/1/1970 and then add the milliseconds.
Observe:
var dt = new DateTime(1970, 1, 1).AddMilliseconds(1395366469723);
// "21/03/2014 1:47:49 AM"

Just Date or Time

I'm just wondering ..
I have and object like this
public class Entry{
public DateTime? Date { get; set;} // This is just Date
public DateTime? StartTime { get; set; } //This is just Time
public TimeSpan Duration { get; set; } //Time spent on entry
}
Is there a more appropriate type than DateTime or better strategy to handling just Time and Date? Without the pain of having to add a DateTime.MinDate() to all my Start and End Times?
--- update ---
1 - I like to be able to request if Date or StartTime is Null seperartly on the Entry object.
2 - Entry should allow the user to input Duration without indication of date. Even a default date like DateTime.MinDate() seems like a poor design. (This is why i choose TimeSpan not Start and EndTime)
Don't split up the date and time components where you store the data. You can provide properties to extract those if you like:
public class Entry {
public DateTime StartPoint { get; set; }
public TimeSpan Duration { get; set; }
public DateTime StartDate { get { return StartPoint.Date; } }
public TimeSpan StartTime { get { return StartPoint.TimeOfDay; } }
public DateTime EndPoint { get { return StartPoint + Duration; } }
public DateTime EndDate { get { return EndPoint.Date; } }
public TimeSpan EndTime { get { return EndPoint.TimeOfDay; } }
}
Update:
If you want to have null values for date and time, you can add properties for that without having to split the date and time:
public class Entry{
private DateTime _startPoint;
public bool HasStartDate { get; private set; }
public bool HasStartTime { get; private set; }
public TimeSpan Duration { get; private set; }
private void EnsureStartDate() {
if (!HasStartDate) throw new ApplicationException("Start date is null.");
}
private void EnsureStartTime() {
if (!HasStartTime) throw new ApplicationException("Start time is null.");
}
public DateTime StartPoint { get {
EnsureStartDate();
EnsureStartTime();
return _startPoint;
} }
public DateTime StartDate { get {
EnsureStartDate();
return _startPoint.Date;
} }
public TimeSpan StartTime { get {
EnsureStartTime();
return _startPoint.TimeOfDay;
} }
public DateTime EndPoint { get { return StartPoint + Duration; } }
public DateTime EndDate { get { return EndPoint.Date; } }
public TimeSpan EndTime { get { return EndPoint.TimeOfDay; } }
public Entry(DateTime startPoint, TimeSpan duration)
: this (startPoint, true, true, duration) {}
public Entry(TimeSpan duration)
: this(DateTime.MinValue, false, false, duration) {}
public Entry(DateTime startPoint, bool hasStartDate, bool hasStartTime, TimeSpan duration) {
_startPoint = startPoint;
HasStartDate = hasStartDate;
HasStartTime = hasStartTime;
Duration = duration;
}
}
You could use a TimeSpan for your StartTime and EndTime properties. That's what the DateTime.TimeOfDay property returns.
There's also the DateTime.Date property which returns a DateTime with the time element set to midnight.
Having said that, I would probably recommend ditching your Date property altogether and storing full DateTimes (ie, date and time) in your StartTime and EndTime properties.
You're far better off leaving your references as DateTimes. If you only store the time, then you have issues when your Entry spans more than a 24-hour period. Store them as DateTimes as you have them now, and apply whatever formatting is necessary to represent just the time portion to your end-user.
I'd like to compliment Guffa's answer with two more best practices:
Store all of your dates as UTC in the database.
Avoid System.DateTime and favor System.DateTimeOffset.
SQL Server 2008’s datetimeoffset type is the equivalent of DateTimeOffset.

Categories

Resources