Преобразование строки пользовательского формата в дату

#sql #sql-server #string #date #sql-server-2012

#sql #sql-сервер #строка #Дата #sql-server-2012

Вопрос:

Я получаю значения даты (в виде строки) из одной из исходных систем. Это всегда 8 символов, как показано ниже. Я действительно не уверен, почему они сохранились в этом формате.

 15/06-10
07/03-03
28/10-04
10/07-90
05/07-55
 

Но для моего приложения мне нужно преобразовать это в правильный формат даты (т. Е. DD-MON-YYYY ).

  • Первые 2 символа представляют Date
  • Следующие 2 символа (после / ) представляют Month
  • последние 2 представляют year

В Oracle я могу использовать to_date для достижения этой цели. Что-то вроде

 select to_date('15/06-10','yy/mm-dd') from dual;
 

Но в SQL Server я не смог найти такую функцию. Есть ли способ добиться этого? Самое близкое, что у меня есть, это

 DECLARE @d VARCHAR(100) = '15/06-10';
SELECT DATEFROMPARTS('20' SUBSTRING(@d,7,2),SUBSTRING(@d,4,2),SUBSTRING(@d,1,2))
 

Я не уверен, что это правильный путь. Кроме того, он выдает результаты только тогда, когда я жестко 20 кодирую для year . Но я получаю данные из 1950 . Поэтому я не могу жестко 19 запрограммировать или 20 ожидаемый результат для приведенного выше примера

  ---------- ------------- 
| 15/06-10 | 15-JUN-2010 |
 ---------- ------------- 
| 07/03-03 | 07-MAR-2003 |
 ---------- ------------- 
| 28/10-04 | 28-OCT-2004 |
 ---------- -------------   
| 10/07-90 | 10-JUL-1990 |
 ---------- ------------- 
| 05/07-55 | 05-JUL-1955 |
 ---------- -------------   
 

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

1. Y2K снова наносит удар! Никто не должен использовать 2-значные годы. Исправление ваших данных во время извлечения — лучшее решение, и использование правильного формата для дат намного лучше, чем этот странный. Но, конечно, ваш ответ заключается в том, что это невозможно. Итак, короткий ответ — все, что работает, — это «правильный путь». Адаптируйте логику Гордона для использования 2-значных лет с соответствующей строкой стиля, которую вы можете найти в документации.

2. Выглядит очень странный формат. Как вы узнаете, является ли это 19 или 20 ? Предположим, если данные есть 10/07-19 , то ожидаете ли вы 10-JUL-2019 или 10-JUL-1919 ? Именно по этой причине вы всегда должны использовать 4-значный формат.

3. Я согласен, что этот формат является большой проблемой. Мы предпринимаем действия, чтобы исправить это. Но сейчас мне нужно исправить текущие данные, и я получаю только даты с 1950 года. итак, из 50 в 99 я хочу 19 и 01 в 20 я хочу 20 . Для этого 10/07-19 мне нужен 10-JUL-2019 @ArunPalanisamy

Ответ №1:

SQL Server не имеет to_date() функции. Но вот более простой способ выполнить требуемое преобразование:

 select convert(date, replace('20'   str, '/', '-'))
from (values ('15/06-10'), ('07/03-03'), ('28/10-04')) v(str)
 

Выражение в select фактически изменяет формат на ГГГГ-ММ-ДД, который тривиально преобразуется в дату. Однако SQL Server convert() / cast() относительно умен в распознавании дат в строках.

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

1. Спасибо, Гордон. Но это дает мне неверный вывод. Например, 28/10-04 это дает 2028-10-04 , но я хочу. 28-OCT-2004 Также я не могу жестко 20 закодировать код. Потому что это может быть 19 также, поскольку я получаю дату 1950 и далее. Для этого я добавил образец. Извините, что я не передал это четко раньше

2. @Avinash . . . Это возвращает date . Если вам нужен определенный формат, вам нужно преобразовать дату в строку. Для записи код в вашем вопросе также возвращает дату. Вы можете использовать format() или convert() для создания строки с датой в определенном формате.

Ответ №2:

Один из вариантов использует datefromparts() и строковые функции:

 select datefromparts(
    '20'    left(@d, 2), 
    substring(@d, 4, 2),
    right(@d, 2)
) as dt
 

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

1. Спасибо @GMB. Но я не могу жестко 20 закодировать. Потому что это может быть и 19, поскольку я получаю дату с 1950 года. Извините, что я не передал это четко раньше