Question

I receive a string with following value:

0001-01-01T12:30:00

I only need the time portion when saving to the database.

But I can't save 0001 year in MSSQL Server (field is SmallDateTime type) as it requires 1900+.

Currently I check what the year is and recreate the date using the following code:

...
DateTime i = Convert.ToDateTime("0001-01-01T12:30:00");
DateTime d = new DateTime(1900, 1, 1, i.hour, i.minute, i.seconds);

Is there an easier way to use a date format where year is set to 0001?

I don't know all of the fields I'm importing that might have this value and I don't want to add this code for all of the fields.

Was it helpful?

Solution

You can use the DateTime.Add() method in conjunction with the DateTime.TimeOfDay property.

If this were a regular SQL datetime you could use the SqlDateTime.MinValue helper, and add your DateTime to it.

SqlDateTime.MinValue.Value.Add(Convert.ToDateTime("0001-01-01T12:30:00").TimeOfDay)

For the smalldatetime you can create your own.

new DateTime(1900, 1, 1).Add(Convert.ToDateTime("0001-01-01T12:30:00").TimeOfDay)

OTHER TIPS

If the time portion is all you care about then what you have is the best thing to do. Even the regular DateTime data type in SQL Server only goes back to 1753 due to calendar issues.

If you want an essentially unconstrained date datatype that will accept years starting at 0001 then use DateTime2

If you don't care about the date component, this should do you :

public static DateTime String2SqlAcceptableDateTimeValue( string iso8601DateTimeValue )
{
  CultureInfo ci = CultureInfo.InvariantCulture ;
  DateTime timestamp ;
  bool converted = DateTime.TryParseExact( iso8601DateTimeValue , "yyyy-MM-ddTHH:mm:ss" , ci ,DateTimeStyles.None, out timestamp ) ;

  if ( !converted ) throw new ArgumentException("Not an ISO 8601 Date/Time value" , "iso8601DateTimeValue");

  DateTime epoch = new DateTime(1900,1,1) ;
  DateTime sqlAcceptableValue = epoch + timestamp.TimeOfDay ;

  return sqlAcceptableValue ;
}

It might easier to just toss exclude the date component from the conversion to DateTime. That makes it a 1-liner (well, 2-liner):

CultureInfo ci = CultureInfo.InvariantCulture ;
string tod = "0001-01-01T12:34:56".Substring(11) ;
DateTime dtx = new DateTime(1900,1,1) + DateTime.ParseExact(tod,"HH:mm:ss",ci).TimeOfDay ;

I think that makes the intent much clearer ;

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top