Convert custom formatted string to DateTime - c#

I am trying to convert a string into a DateTime:
DateTime newDate = new DateTime();
DateTime.TryParse("20150620 800", out newDate);
The default value (1/1/0001 12:00:00 AM) is returned, how can this be correctly converted?

Use ParseExact to take a custom string and convert it,
According to MSDN:
If format is a custom format pattern that does not include date or
time separators (such as "yyyyMMdd HHmm"), use the invariant culture
for the provider parameter and the widest form of each custom format
specifier. For example, if you want to specify hours in the format
pattern, specify the wider form, "HH", instead of the narrower form,
"H".
This conversion is not possible, unless you change your input data.
You would expect this to work: (This really confused me for a bit while writing this)
DateTime newDate = DateTime.ParseExact("20150620 800", "yyyyMMdd Hmm", CultureInfo.InvariantCulture);
But since H must be in its widest form, it must be HH, as it thinks 80 is out of range for the hour measurement. You will need to add a space between 8 and 00, or add a 0 before 8.
These solutions will work:
DateTime newDate = DateTime.ParseExact("20150620 8 00", "yyyyMMdd H mm", CultureInfo.InvariantCulture);
DateTime newDate = DateTime.ParseExact("20150620 0800", "yyyyMMdd HHmm", CultureInfo.InvariantCulture);
If you cannot change this input data (eg, from a database), just perform a substring operation to insert a space between the minutes and hours so .NET can tell which is which:
var text = "20150620 800";
DateTime newDate = DateTime.ParseExact(text.Insert(text.Length - 2, " "), "yyyyMMdd H mm", CultureInfo.InvariantCulture);

DateTime.ParseExact(newDate,"yyyyMMdd Hmm", new DateFormatInfo());
Should work. Double check the .Net date format string reference to make sure it is what you want.

Related

C# Datetime.ParseExact for a parsing a string containing UTC text

I have a date time string that looks like this:
13.08.2014 17:17:45.000 UTC-60
I am trying to parse it into a C# date time object but it is not working as I expected.
Here is what I tried:
DateTime.ParseExact(dateToParse, "dd.MM.yyyy hh:mm:ss.fff Z", CultureInfo.InvariantCulture);
DateTime.ParseExact(dateToParse, "dd.MM.yyyy hh:mm:ss.fff UTC", CultureInfo.InvariantCulture);
DateTime.ParseExact(checkInDate, "dd.MM.yyyy hh:mm:ss.fff", CultureInfo.InvariantCulture);
They all return same error
{"String was not recognized as a valid DateTime."}
Some of the existing questions like this did not help either.
Any suggestions?
First, your main problem there with parsing is that your're using hh for 24h format. That should be HH. This should work:
DateTime.ParseExact("13.08.2014 17:17:45.000", "dd.MM.yyyy HH:mm:ss.fff", null, System.Globalization.DateTimeStyles.AssumeUniversal)
As for the UTC part, that's not standard format, so I suggest you to create a helper method that splits this string in 2, parse the first part as provided above, and parse the number after UTC and either add that to your DateTime:
myDate.AddMinutes(Int32.Parse("-60"))
Or create a DateTimeOffset. In either case, you must parse them individually.
How much control do you have over the time format.
.Net datetime parsing expects 2 things that are wrong with the current time format that you are trying to parse:
First, you have 24 hour time, so in your format you must use HH for hours, the lower case hh implies that the hours will be 12 hour format.
The UTC issue is another one that will require you to modify the string first, .Net expects timezone information in the form of HH:mm, so the following string and conversion will work, notice the key differences
var dateToParse = "13.08.2014 17:17:45.000 -01:00";
var value = DateTimeOffset.ParseExact(dateToParse, "dd.MM.yyyy HH:mm:ss.fff zzz", CultureInfo.InvariantCulture);
Use DateTimeOffset to maintain the TimeZone information
HH to map the hours
zzz to map the timezone information
So, to address you question, how can we parse the string into a format that we can then use to parse into a date time:
dateToParse = "13.08.2014 17:17:45.000 UTC-60";
string utc = null;
if (dateToParse.Contains("UTC"))
{
var tokens = dateToParse.Split(new string[] { "UTC" }, StringSplitOptions.None);
dateToParse = tokens[0];
utc = tokens[1];
int minutes = int.Parse(utc);
var offset = TimeSpan.FromMinutes(minutes);
bool negative = offset.Hours < 0;
dateToParse += (negative ? "-" : "") + Math.Abs(offset.Hours).ToString().PadLeft(2,'0') + ":" + offset.Minutes.ToString().PadLeft(2,'0');
}
var value = DateTimeOffset.ParseExact(dateToParse, "dd.MM.yyyy HH:mm:ss.fff zzz", CultureInfo.InvariantCulture);
To be honest, that was more complicated than I thought, there might be some regex expressions that might help, but this first principals approach to manipulating the string first works with your string.
Finally, now that we have a DateTimeOffset value, you can easily convert this into any local or other timezone without too much hassel, if you need to:
var asUtc = dateValue.UtcDateTime;
var asLocal = dateValue.LocalDateTime;
var asSpecific = dateValue.ToOffset(TimeSpan.FromHours(10)).DateTime;

Converting string in yyyy-MM-ddTHH:mm:ss zzz format to DateTime

I am receiving a JSON DateTime from a web service in the following format
yyyy-MM-ddTHH:mm:ss zzz
For example:
2016-04-18T15:09:21 01:00
However, I am unable to convert this into a DateTime object. I have tried the following:
var date = DateTime.ParseExact("2016-04-18T15:09:21 01:00", "yyyy-MM-ddTHH:mm:ss zzz", CultureInfo.InvariantCulture);
var date2 = DateTimeOffset.ParseExact("2016-04-18T15:09:21 01:00", "yyyy-MM-ddTHH:mm:ss zzz", CultureInfo.InvariantCulture);
Both of these lines throw the System.FormatException exception with the message:
String was not recognized as a valid DateTime.
How can I parse 2016-04-18T15:09:21 01:00 as a DateTime object?
Unfortunately the "zzz" expects a sign on the timezone.
This will work.
var date = DateTime.ParseExact("2016-04-18T15:09:21 +01:00", "yyyy-MM-ddTHH:mm:ss zzz",System.Globalization.CultureInfo.InvariantCulture);
date.Dump();
So add a plus sign.
var dt="2016-04-18T15:09:21 01:00";
dt.Insert(20,"+").Dump();
Dmitriy has the right answer, from The "zzz" custom format specifier documentation;
The offset is always displayed with a leading sign. A plus sign (+)
indicates hours ahead of UTC, and a minus sign (-) indicates hours
behind UTC. A single-digit offset is formatted with a leading zero.
If your string is always in yyyy-MM-ddTHH:mm:ss HH:mm format, you have to manipulate it if you wanna parse it to DateTimeOffset.
I would suggest to you split your string with a white space, call DateTime.Parse and TimeSpan.Parse on those strings and use those values in a DateTimeOffset(DateTime, TimeSpan) constructor which;
Initializes a new instance of the DateTimeOffset structure using the
specified DateTime value and offset.
var str = "2016-04-18T15:09:21 01:00";
var parts = str.Split(' ');
var date = DateTime.Parse(parts[0]);
var offset = TimeSpan.Parse(parts[1]);
var dto = new DateTimeOffset(date, offset);
Now you have a DateTimeOffset as {18.04.2016 15:09:21 +01:00} and you can use it's DateTime, LocalDateTime or UtcDateTime properties whichever you want.

Convert string to Time

I have a time that is 16:23:01. I tried using DateTime.ParseExact, but it's not working.
Here is my code:
string Time = "16:23:01";
DateTime date = DateTime.ParseExact(Time, "hh:mm:ss tt", System.Globalization.CultureInfo.CurrentCulture);
lblClock.Text = date.ToString();
I want it to show in the label as 04:23:01 PM.
"16:23:01" doesn't match the pattern of "hh:mm:ss tt" - it doesn't have an am/pm designator, and 16 clearly isn't in a 12-hour clock. You're specifying that format in the parsing part, so you need to match the format of the existing data. You want:
DateTime dateTime = DateTime.ParseExact(time, "HH:mm:ss",
CultureInfo.InvariantCulture);
(Note the invariant culture, not the current culture - assuming your input genuinely always uses colons.)
If you want to format it to hh:mm:ss tt, then you need to put that part in the ToString call:
lblClock.Text = date.ToString("hh:mm:ss tt", CultureInfo.CurrentCulture);
Or better yet (IMO) use "whatever the long time pattern is for the culture":
lblClock.Text = date.ToString("T", CultureInfo.CurrentCulture);
Also note that hh is unusual; typically you don't want to 0-left-pad the number for numbers less than 10.
(Also consider using my Noda Time API, which has a LocalTime type - a more appropriate match for just a "time of day".)
string Time = "16:23:01";
DateTime date = DateTime.Parse(Time, System.Globalization.CultureInfo.CurrentCulture);
string t = date.ToString("HH:mm:ss tt");
This gives you the needed results:
string time = "16:23:01";
var result = Convert.ToDateTime(time);
string test = result.ToString("hh:mm:ss tt", CultureInfo.CurrentCulture);
//This gives you "04:23:01 PM" string
You could also use CultureInfo.CreateSpecificCulture("en-US") as not all cultures will display AM/PM.
The accepted solution doesn't cover edge cases.
I found the way to do this with 4KB script. Handle your input and convert a data.
Examples:
00:00:00 -> 00:00:00
12:01 -> 12:01:00
12 -> 12:00:00
25 -> 00:00:00
12:60:60 -> 12:00:00
1dg46 -> 14:06
You got the idea...
Check it https://github.com/alekspetrov/time-input-js

Conversion to Time 12 hour Format From String containing Time in 24 hour format

I have a varchar(5) column in a table which contains the hour and minutes in 24 hour format time. I want to convert this 24 hour format to 12 hour format and finally embed this 12 hour format time into a DateTime Variable along with a Date value. Below is an example of demonstration.
For Example
8:18 should be converted into 8:18:00 AM and then should be embedded
with a Date like 8/10/2012 8:18:50 AM to be able to store in DateTime
column of DB.
22:20......10:20:00 PM.......8/10/2012 10:20:00 PM
The Date will not be current date it can be any date value like 8/8/2012 or 7/8/2012
You can do something like this:
string input = "22:45";
var timeFromInput = DateTime.ParseExact(input, "H:m", null, DateTimeStyles.None);
string timeIn12HourFormatForDisplay = timeFromInput.ToString(
"hh:mm:ss tt",
CultureInfo.InvariantCulture);
var timeInTodayDate = DateTime.Today.Add(timeFromInput.TimeOfDay);
And now the important parts to take in consideration:
The format for parsing uses "H:m" so it assumes a 24H value that does not use a zero to prefix single digits hours or minutes;
The format for printing uses "hh:mm:ss tt" because it seems to be the format you desire, however you need to use CultureInfo.InvariantCulture to be certain that you get a AM/PM designator that is in fact AM or PM. If you use another culture, the AM/PM designator may change;
The full date and time is constructed based on DateTime.Today which returns the today date with a zeroed time and then we just add the time we read from input.
To create the final date and time from another date you can instead use:
var timeInAnotherDate = new DateTime(2000, 1, 1).Add(timeFromInput.TimeOfDay);
Reference material:
DateTime Structure;
Custom Date and Time Format Strings;
Standard DateTime Format Strings.
create function dbo.COMBINE_DATE_TIME(
#DatePart DateTime, -- DateTime
#TimePart varchar(5)) -- Time
returns DateTime
as begin
return DATEADD(day, DATEDIFF(day,0,#DatePart),
CONVERT(DateTime,ISNULL(#TimePart,''),14))
end
go
string strDate = DateTime.ParseExact("8:18","HHmm",CultureInfo.CurrentCulture).ToString("hh:mm tt");
string fromTime = Convert.ToStr(reader["TimeFrom"]);
string toTime = Convert.ToStr(reader["TimeTo"]);
item.Time=DateTime.Parse(fromTime,CultureInfo.CurrentCulture).ToString("hh:mm tt");
here the property of your model(item.Time here) should be the string.

How can I get this DateTime format in .NET

I'm trying to format some DateTime into this W3C DateTime format :-
Complete date plus hours and minutes:
eg. YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
where:
YYYY = four-digit year
MM = two-digit month (01=January, etc.)
DD = two-digit day of month (01 through 31)
hh = two digits of hour (00 through 23) (am/pm NOT allowed)
mm = two digits of minute (00 through 59)
ss = two digits of second (00 through 59)
s = one or more digits representing a decimal fraction of a second
TZD = time zone designator (Z or +hh:mm or -hh:mm)
I originally had this...
var myDateTime = someDateTime.ToString("s",
System.Globalization.CultureInfo.InvariantCulture);
But that results in a string of :
2011-08-31T08:46:00
Can anyone help?
You want "o":
var myDateTime = someDateTime.ToString("o",
System.Globalization.CultureInfo.InvariantCulture);
Use the following:
yourDateTime.ToString( "yyyy-MM-ddTHH:mmK", CultureInfo.InvariantCulture );
Here is more than you'll ever want to know on DateTime formats:
http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
I believe you want
"yyyy-MM-ddTHH:mmK"
Note:
HH rather than hh to be 24 hour
K to specify the time zone; this relies on the DateTime.Kind being UTC or local; unspecified will end up with an empty string
You should also use CultureInfo.InvariantCulture to make sure no funky culture information is used. (You could quote the - and : as an alternative, but I'd use the invariant culture to make sure.)
You can format it like this:
someDateTime.ToString("yyyy-MM-dd");
Here's the documentation of the 'standard' supported datetime format strings:
http://msdn.microsoft.com/en-us/library/az4se3k1(v=VS.100).aspx
someDateTime.ToUniversalTime().ToString("u");
Will get you pretty close => '2011-09-02 10:22:48Z'. If that isn't good enough, then you can create a custom format string that includes the "T" (see 'Custom Date and Time Format Strings').

Categories