Yair Nevet
Yair Nevet

Reputation: 13013

How to parse string with long milliseconds (nanoseconds) part to DateTime?

I'm trying to figure-out the right string format of the following given date-time literal:

18-JUN-13 12.17.36.000000000

Using MSDN, I managed to composed the following format:

"d'-'MMM'-'y'T'h'.'m'.'s'.'fff"

But when using the DateTime.ParseExact, the parsing fails with a FormatException: String was not recognized as a valid DateTime.

My code:

DateTime.ParseExact("18-JUN-13 12.17.36.000000000", "d'-'MMM'-'y'T'h'.'m'.'s'.'fff", null);

Upvotes: 6

Views: 4969

Answers (3)

Lance U. Matthews
Lance U. Matthews

Reputation: 16612

You can't directly parse (i.e. ParseExact()) a time string with more than seven digits after the decimal point unless, as suggested by juharr's comment on DateTime format throws exception, you parse the excess digits as literal characters:

string before = "18-JUN-13 12.17.36.000000000";
string format = "d'-'MMM'-'y' 'h'.'m'.'s'.'fffffff'00'";
DateTime value = DateTime.ParseExact(before, format, null);
string after = value.ToString(format);

Console.WriteLine(before);// 18-JUN-13 12.17.36.000000000
Console.WriteLine(after); // 18-Jun-13 12.17.36.000000000

Otherwise, you'll need to truncate the excess digits, as in Soner Gönül's answer.

It's unfortunate that neither the exception message nor the documentation calls out why fffffff/FFFFFFF is the limit, because the reason is simple but easy to overlook.

0.0000001 seconds is:

  • One ten-millionth of a second, or...
  • 100 nanoseconds, or...
  • One tick

A tick is the smallest interval a DateTime can represent. Format strings such as ffffffff (eight significant digits) and beyond can't be valid because that would require a DateTime to be able to store fractions of a tick. While "String was not recognized as a valid DateTime" does describe the problem, in this case it's not just that the input doesn't match the specified format, it's also that the input can't be precisely represented by a DateTime, anyways.

Upvotes: 0

Soner Gönül
Soner Gönül

Reputation: 98848

You can use

dd-MMM-yy hh.mm.ss.fffffff

with english based culture like InvariantCulture for example. I'm on mobile right now, so I can't try it :(

AFAIK, milliseconds part parsing limit is 7, that's why you can't parse your string without manipulate it. You can use it like;

var dt = DateTime.ParseExact("18-JUN-13 12.17.36.0000000",
                             "dd-MMM-yy HH.mm.ss.fffffff",
                             CultureInfo.InvariantCulture);

Looks like that's why probably we have The "fffffff" custom format as top character of milliseconds. From docs;

Although it is possible to display the ten millionths of a second component of a time value, that value may not be meaningful. The precision of date and time values depends on the resolution of the system clock. On the Windows NT 3.5 (and later) and Windows Vista operating systems, the clock's resolution is approximately 10-15 milliseconds.

You asked;

How would you have manipulate the string?

Well, one way to get last index of comma and substring it to 8 index after that like;

string s = "18-JUN-13 12.17.36.000000000";
var dateString = s.Substring(0, s.LastIndexOf(".") + 8);

Upvotes: 6

user3036342
user3036342

Reputation: 1045

You have a bunch of single quotes in there which isn't a correct format. Try this

DateTime.ParseExact("18-JUN-13 12.17.36.000000000", "d-MMM-yTh.m.s.fff", null);

Upvotes: -1

Related Questions