четверг, 12 мая 2011 г.

Конвертация даты из внутреннего формата MSSQL

Переводил базу из MsSQL в MYSQL. Стандартные инструменты из MySQL Migration Toolkit оказались бессильны перед этой базой - кодировка портилась, хоть тресни. Пришлось конвертить ручками, через SQL скрипты. Все было хорошо.. пока не обнаружилось, что в MSSQL-ном скрипте в некоторых таблицах данные типа DateTime оказались записаны в виде:
CAST(0x00008F5800000000 AS DateTime) //2000-06-21 00:00:00
CAST(0x00008F5900000000 AS DateTime) //2000-06-22 00:00:00
Это - внутренний формат даты в MSSQL. Вопрос - как из внутреннего формата преобразовать дату в нормальный вид?

Оказалось, проблема известна, и народ этот формат уже расковырял. Привожу функцию на C#, для конвертации внутреннего формата даты MSSQL в стандартный DateTime:
 public static DateTime ConvertSqlBinaryToDate(String value) {
  const String HEXADECIMAL_PREFIX = "0x";

  if (value == null) {
      throw new Exception("value is null");
  }
  if (value.Length != 18) {
      throw new Exception("value should have length 18 bytes");
  }

  if (!value.StartsWith(HEXADECIMAL_PREFIX)) {
      throw new Exception(String.Format("value should starts from {0}", HEXADECIMAL_PREFIX));
  }

  String first_part = value.Substring(2, 8);
  String second_part = value.Substring(10, 8);

  Double first_part_value = long.Parse(first_part, System.Globalization.NumberStyles.HexNumber);
  Double second_part_value = long.Parse(second_part, System.Globalization.NumberStyles.HexNumber);

  if (first_part_value > Int32.MaxValue) {
      first_part_value = UInt32.MaxValue - first_part_value;
  }

  //Each unit of the value of the second 4 bytes matching a clock-tick
  //Equivalent to 3.33 milliseconds.         
  const double MILLISECONDS_PRECISION = 3.33333333;

  DateTime result = new DateTime(1900, 1, 1);
  result = result.AddDays(first_part_value);

  result = result.AddMilliseconds(second_part_value * MILLISECONDS_PRECISION);

  return result;
}
Оригинал на VB по ссылке выше, в комментариях.

Комментариев нет:

Отправить комментарий