Best way to convert string to DateTimeOffset? - c#

I am trying to convert string to DateTimeOffset.I am using DatetimeOffset.Parse(string).Parse obviously throws an exception when string is not in correct format.It is not able to parse 0000-00-00.
I want a single line of code saying me the best possible way to tackle this situation.If input is 0000-00-00 then it should be converted to current DateTimeOffset.
Any other string also apart from 0000-00-00 that cant be parsed should be changed to DateTimeOffset.Now.

If I understand your question correctly, you are looking for
DateTimeOffset dto = (input == "0000-00-00" ? DateTimeOffset.Now : DateTimeOffset.Parse(input));
EDIT
Based on your clarification that all invalid dates should default to the current time, the following will do that:
DateTimeOffset dto;
if(!DateTimeOffset.TryParse(input, out dto))
dto = DateTimeOffset.Now;

You can not change the logic of DateTimeOffset.Parse method. You can write a helper method which will check for the value "0000-00-00" and return current DateTimeOffset else try to parse the input value to DateTimeOffset and return respective value
public class DateTimeOffsetHelper
{
public static DateTimeOffset FromString(string offsetString)
{
DateTimeOffset offset;
if (!DateTimeOffset.TryParse(offsetString, out offset))
{
offset = DateTimeOffset.Now;
}
return offset;
}
}
And you can use it as following.
var offsetString = "2017-05-30";
var offset = DateTimeOffsetHelper.FromString(offsetString);
This should help you resolve you issue.

Here's a fairly simple one-liner.
Func<string, DateTimeOffset> parseDateTimeOffset = input =>
input == "0000-00-00" || DateTimeOffset.TryParse(input, out DateTimeOffset output)
? DateTimeOffset.Now
: output;
It is C#7 though.

Related

How I can check a Time Input with DateTime?

how i can check a string for a time:
for example I want to input 12:22 and the program must check with dateTime.
The Programm is in C#
Use DateTime.TryParse and if it returns true, the string is a valid date.
Looks like you want to check for a Timespan and not for a datetime, therefore use TimeSpan.TryParse instead.
If you want a specific format, use TimeSpan.TryParseExact.
http://msdn.microsoft.com/en-us/library/3z48198e(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/dd784009(v=vs.110).aspx
The correct approach here is to not use DateTime but to use TimeSpan as you are dealing with a time rather than a date.
var inputText = "12:22"; // get this from whatever your input is
TimeSpan result;
if (!TimeSpan.TryParse(inputText, out result))
{
// handle error
}
else
{
// everything okay
}
Use DateTime.TryParseExact Method as the following:
if (DateTime.TryParseExact(timeStringValue, timeStringFormat,
new CultureInfo("en-US"),
DateTimeStyles.None,
out dateTimeValue))
{
}
else
{
}
You can try in this way,
TimeSpan t1 = (Convert.ToDateTime(TextBox1.Text)).TimeOfDay;
TimeSpan t2 = DateTime.Now.TimeOfDay;
if(t1 == t2) // Something as you want
Let us know the Output.

Date not in correct format

I have a function that checks for null values then converts dates if they are not null
the below function just had "08/09/13" sent to it (English format) and i got "String was not recognized as a valid DateTime."
anyone help me as to why? do i need to tell the something somewhere is uses English format?
Thanks
public static DateTime DateTimeCheck(object objDateTime)
{
if (objDateTime == null || objDateTime == "")
return default(DateTime);
return Convert.ToDateTime(objDateTime);
}
I don't understand why you passed an object as a parameter instead of string first of all.
Try this instead;
public static DateTime DateTimeCheck(object objDateTime)
{
...
return DateTime.ParseExact(objDateTime.ToString(),"dd/MM/yy",CultureInfo.InvariantCulture);
}
Of course, this throws exception if your object is not formatted same as with "dd/MM/yy".
Take a look at;
Custom Date and Time Format Strings
You can use the overloaded method that accepts the culture information:
Convert.ToDateTime(o, new CultureInfo("en-Gb"));
To get or set the current culture you can use:
System.Threading.Thread.CurrentThread.CurrentCulture
You might be in a different culture with a different default date format. However you can use ParseExact to parse in the expected format. For example:
CultureInfo provider = CultureInfo.InvariantCulture;
DateTime result = DateTime.ParseExact("25/12/82","dd/MM/yy",provider);
I know this not what you are looking for but that's how to be sure that some object has date time value in it something like that :
public static DateTime DateTimeCheck(object objDateTime)
{
DateTime dateTime ;
if (objDateTime != null)
{
if (DateTime.TryParse(objDateTime.ToString(), out dateTime))
{
return Convert.ToDateTime(objDateTime);
}
}
return default(DateTime);
}
Try this:
DateTime.ParseExact((string)objDateTime,"dd/MM/yyyy",CultureInfo.InvariantCulture);

Linq-to-EF DateTime.ToLocalTime not supported

DateTime.ToLocalTime is not supported in Linq to EF.
What's the alternative? I am running out of idea.
Instead of using .ToLocalTime() inside your Linq query, use the opposite conversion outside of the query on the parameters.
var dateUniversal = dateParam.ToUniversalTime();
var query = myTable.Where( t => t.DateTime > dateUniversal );
I used a combination of Extensions plus relying on the value passed from the front-end of my app to be in LocalTime. So, If I had two date times.. like.. a start date and end date parameter for a report, I'd put them up there.. let the user submit in LocalTime.. then on the back end part of my Controller.. I'd use the sdate and edate variables in my Linq to Entities Query. The static extension methods I threw into a static helper class. Sorry that I'm over a year late. : )
DateTime sdate = CalcHelper.AbsoluteStart(model.StartDate);
DateTime edate = CalcHelper.AbsoluteEnd(model.EndDate);
public static DateTime AbsoluteStart(this DateTime dateTime)
{
return dateTime.Date.ToUniversalTime();
}
public static DateTime AbsoluteEnd(this DateTime dateTime)
{
return AbsoluteStart(dateTime).AddDays(1).AddTicks(-1).ToUniversalTime();
}
if you get the timezone offset from the server you might be able to use EntityFunctions to apply the offset in your linq query
var offset = TimeZoneInfo.Local.BaseUtcOffset.TotalMinutes;
var result = db.Dates.Where(a =>
EntityFunctions.DiffDays(EntityFunctions.AddMinutes(a.Date, offset), DateTime.Now) == 0);
You can try like this:
var promotions = _promotionService.GetAll(
x => (DbFunctions.TruncateTime(x.CreatedDate.Value) >= viewModel.GTXFromDate.Date)
&& (DbFunctions.TruncateTime(x.CreatedDate.Value) <= viewModel.GTXToDate.Date));
As a rule, you should store dates and times in UTC in your database.
Convert any local date/times to UTC in your code before you store them in the database.
Similarly, if you need to show local time from the UTC in the database, then convert it in code after the database fetch.
Convert DateTime to String for comparison, for example:
const string DATE_FORMAT = "yyyy/MM/dd";
var query = sampleTable.Where(x => x.DateTime.ToString(DATE_FORMAT) > DateTime.Now.ToString(DATE_FORMAT));
Found the solution on this question
public partial class Person {
partial void OnLoaded() {
this._BirthDate = DateTime.SpecifyKind(this._BirthDate, DateTimeKind.Utc);
}
}

String was not recognized as a valid DateTime

I want to add a date in session (date1) like this:
Session["DateLesson"] = date1.ToString("dd.MM.yyyy");
Now from the session I want take this value:
var asd = Session["DateLesson"];
/*asd = "20.04.2012"*/
var datelesson = DateTime.Parse((string) asd);
And it gives me this exception:
FormatException not recognized as a valid DateTime
A period is not a valid/standard separator character in most locales. You'll need to use DateTime.ParseExact() in combination with a format string to tell the function how to read it. More importantly, if reading it back to a datetime is your main goal, why not just put the datetime in the session as is? That seems way more efficient, easier, and more maintainable to me.
Why persist your date as a string?
You could simply store it like this:
Session["DateLesson"] = date1;
And then retrieve it like this:
var datelesson = (DateTime)Session["DateLesson"];
string value = "20.04.2012";
DateTime datetime = DateTime.ParseExact(value, "dd.MM.yyyy", null);
This will return 4/20/2012 12:00:00:00 AM
Don't keep value as a string but as an object of the initial type:
public DateTime? DateLesson
{
get
{
DateTime? dateTime = Session["DateLesson"] as DateTime?;
if (dateTime.HasValue) // not null
{
// use dateTime.Value
}
}
set
{
Session["DateLesson"] = value;
}
}

Convert the TimeSpan datatype to DateTime?

I'm converting a small MSAccess application to a web-based ASP.NET app, using C# 3.5. I was wondering what's the best way to work with dates in C#, when converting some of this VBA code over to C#.
Here is an example of the VBA Code:
Coverage1=IIf(IsNull([EffDate1]),0,IIf([CurrDate]<=[EndDate1],[CurrDate]-[EffDate1],[EndDate1]-[EffDate1]+1))
Here is what my current C# code looks like with the errors denoted in the commented code:
public DateTime CalculateCoverageOne(DateTime dateEffDateOne, DateTime dateCurrentDate, DateTime dateEndDateOne)
{
if (dateCurrentDate.Date <= dateEndDateOne.Date)
{
return null; //Get "cannot convert null to System.DateTime because it is a non-nullable value type" error
}
else
{
if (dateCurrentDate.Date <= dateEndDateOne)
{
return dateCurrentDate.Subtract(dateEffDateOne); //Gets error "cannot implicitly convert system.timepsan to system.datetime
}
else
{
return dateEndDateOne.Subtract(dateEffDateOne.AddDays(1)); //Gets error "cannot implicitly convert system.timepsan to system.datetime
}
}
}
cannot convert null to System.DateTime because it is a non-nullable value type" error
The DateTime type is a value type, which means that it cannot hold a null value. To get around this you can do one of two things; either return DateTime.MinValue, and test for that when you want to use the value, or change the function to return DateTime? (note the question mark), which is a nullable DateTime. The nullable date can be used like this:
DateTime? nullable = DateTime.Now;
if (nullable.HasValue)
{
// do something with nullable.Value
}
cannot implicitly convert system.timepsan to system.datetime
When you subtract a DateTime from another DateTime, the result is a TimeSpan, representing the amount of time between them. The TimeSpan does not represent a specific point in time, but the span itself. In order to get the date, you can use the Add method or the Subtract method overload of a DateTime object that accepts a TimeSpan. Exactly how that should look I can't say, since I don't know what the different dates in your code represent.
In the last case, you can simply use the return value from the AddDays method, but with a negative value (in order to subtract one day, instead of adding one):
return dateEffDateOne.AddDays(-1);
It looks like your VB is actually returning a time span, presumably in days. Here's the closest direct translation:
public TimeSpan CalculateCoverageOne(DateTime EffDate1, DateTime CurrDate, DateTime? EndDate1)
{
return (EndDate1 == null) ? TimeSpan.Zero :
(CurrDate < EndDate1) ? (CurrDate - EffDate1) :
(EndDate1.AddDays(1) - EffDate1);
}
If instead you just wanted a count of days, just return the TimeSpan's Days property:
public int CalculateCoverageOne(DateTime EffDate1, DateTime CurrDate, DateTime? EndDate1)
{
return ((EndDate1 == null) ? TimeSpan.Zero :
(CurrDate < EndDate1) ? (CurrDate - EffDate1) :
(EndDate1.AddDays(1) - EffDate1)).Days;
}
And for good measure, this is how I would clean up your final version:
public int CalculateCoverageOne(DateTime dateCurrentDate, DateTime dateEffectiveDate, DateTime dateEffDateOne, DateTime dateEndDateOne)
{
TimeSpan ts;
if (dateEffDateOne == DateTime.MinValue)
{
ts = TimeSpan.Zero;
}
else if (dateEffectiveDate <= dateEndDateOne)
{
ts = dateCurrentDate - dateEffDateOne;
}
else
{
ts = (dateEndDateOne - dateEffDateOne) + new TimeSpan(1, 0, 0, 0);
}
return ts.Days;
}
Get the TimeSpan, then subtract that from the DateTime to get the date you want. For your inner IF statement, it would look like this:
TimeSpan estSpan = dateCurrentDate.Subtract(dateEffDateOne);
return dateCurrentDate.Subtract(estSpan);
EDIT: You may also want to return DateTime.MaxValue and have the calling function check for the max value, instead of returning null.
DateTime is a value type. So, you cannot assign null to DateTime.
But you can use a special value like DateTime.MinValue to indicate whatever you were trying to indicate by null.
DateTime represents a date (and time), like "July 22, 2009". This means, you shouldn't use this type to represent time interval, like, "9 days". TimeSpan is the type intended for this.
dateCurrentDate.Subtract(dateEffDateOne) (or, equivalently, dateCurrentDate-dateEffDateOne) is a difference between two dates, that is, time interval. So, I suggest you to change return type of your function to TimeSpan.
TimeSpan is also a value type, so you could use, for instance, TimeSpan.Zero instead of null.
After some excellent answers (I've up-voted you guys), I've finally hammered out what I think is my answer. Turns out that returning an int, as the number of days, is what worked for me in this situation.
Thanks everyone, for providing your awesome answers. It helped me get on the right track.
public int CalculateCoverageOne(DateTime dateCurrentDate, DateTime dateEffectiveDate, DateTime dateEffDateOne, DateTime dateEndDateOne)
{
//Coverage1=
//IIf(IsNull([EffDate1]),0,
//IIf([CurrDate]<=[EndDate1],
//[CurrDate]-[EffDate1],
//[EndDate1]-[EffDate1]+1))
if (dateEffDateOne.Equals(TimeSpan.Zero))
{
return (TimeSpan.Zero).Days;
}
else
{
if (dateEffectiveDate <= dateEndDateOne)
{
return (dateCurrentDate - dateEffDateOne).Days;
}
else
{
return (dateEndDateOne - dateEffDateOne).Add(new TimeSpan(1, 0, 0, 0)).Days;
}
}
}

Categories