Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Проблема с преобразованием даты  [new]
StJack
Member

Откуда:
Сообщений: 36
Камрады, нужна помощь!

Не могу корректно преобразовать дату. Нужно сделать так, чтобы от данных в формате datetime осталась только дата, время при этом должно обнулиться. Вот, например, такое:

declare @d datetime
select @d='2013-09-01 19:41:02.677'
select cast(cast(@d as int) as datetime)

выдаёт 2013-09-02 00:00:00.000, а должно быть 2013-09-01 00:00:00.000. Не пойму, в чём дело.
18 сен 13, 16:35    [14855649]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с преобразованием даты  [new]
Glory
Member

Откуда:
Сообщений: 104751
StJack
Не пойму, в чём дело.

Вы знаете, что такое округление чисел ?

Сообщение было отредактировано: 18 сен 13, 16:41
18 сен 13, 16:41    [14855680]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с преобразованием даты  [new]
StJack
Member

Откуда:
Сообщений: 36
Glory
Вы знаете, что такое округление чисел ?


Конечно :-) И вижу, что оно округляет в ближайшую сторону. Поэтому и прошу у вас совета, как решить эту проблему.
18 сен 13, 16:43    [14855697]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с преобразованием даты  [new]
Гузы
Guest
StJack,
cast('2013-09-01 19:41:02.677' as date)
У меня так.
18 сен 13, 16:45    [14855708]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с преобразованием даты  [new]
Glory
Member

Откуда:
Сообщений: 104751
StJack
Конечно :-) И вижу, что оно округляет в ближайшую сторону. Поэтому и прошу у вас совета, как решить эту проблему.

Ну так раз уж вам так нравится работать с датой, как с числом, то наверное нужно округлять по-другому ?
18 сен 13, 16:48    [14855729]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с преобразованием даты  [new]
StJack
Member

Откуда:
Сообщений: 36
Гузы
cast('2013-09-01 19:41:02.677' as date)
У меня так.

Дело в том, что это делается на MS SQL 2000, который не знает данных типа date. У него только datetime.

Поэтому select cast('2013-09-01 19:41:02.677' as date) выдаёт:
Type date is not a defined system type.

А select cast('2013-09-01 19:41:02.677' as datetime) выдаёт:
2013-09-01 19:41:02.677
18 сен 13, 16:52    [14855754]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с преобразованием даты  [new]
StJack
Member

Откуда:
Сообщений: 36
Сделал!

declare @d datetime
declare @c datetime
select @d='2013-09-01 19:41:02.677'
select @c=convert(varchar(8),@d,112)
select convert(datetime,@c,112)

Выдаёт 2013-09-01 00:00:00.000
Ура!
18 сен 13, 17:06    [14855835]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с преобразованием даты  [new]
ambarka_max
Member

Откуда: Россия
Сообщений: 517
Можно было загялнуть вот сюда https://www.sql.ru/faq/faq_topic.aspx?fid=110
18 сен 13, 17:08    [14855849]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с преобразованием даты  [new]
Гузы
Guest
StJack,
Все это есть в факе
можно и так:
dateadd(dd,0,(datediff(dd,0,@dt))
18 сен 13, 17:11    [14855863]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с преобразованием даты  [new]
StJack
Member

Откуда:
Сообщений: 36
Гузы
можно и так:
dateadd(dd,0,(datediff(dd,0,@dt)))

Да, супер! Так тоже работает. Спасибо!
18 сен 13, 18:30    [14856299]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с преобразованием даты  [new]
StarikNavy
Member

Откуда: Москва
Сообщений: 2407
А такой вариант?

 declare @d datetime
set @d='2013-09-01 19:41:02.677'
select cast ( ROUND( cast(@d as float),0,1) as datetime)
19 сен 13, 10:01    [14857724]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с преобразованием даты  [new]
Knyazev Alexey
Member

Откуда: Екб -> Мск
Сообщений: 10233
Блог
StarikNavy
А такой вариант?

все эти варианты уже 100 раз пережеваны:

1) Самый известный и документированный способ – это конвертация даты в строку в нужном формате и обратно в дату:

SELECT CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE(), 112)) 


2) Второй способ – это использование функций даты и времени (dateadd, datediff):

SELECT DATEADD(d, DATEDIFF(d, 0, GETDATE()), 0) 


3) Третий способ – это конвертация даты в тип float и использование математической функции floor, которая возвращает наибольшее целое число, меньшее или равное указанному числовому выражению или математическую функцию round:

SELECT CONVERT(DATETIME, FLOOR(CONVERT(FLOAT, GETDATE()))) 
SELECT CONVERT(DATETIME, ROUND(CONVERT(FLOAT, GETDATE()), 0, 1)) 


4) Четвёртый способ отталкивается от особенностей типа datetime.

Выдержка из русскоязычного BOL:

Значения типа datetime хранятся в виде 4-байтовых целых чисел. Первые четыре байта содержат количество дней до или после даты отсчета: 1 января 1900 года. Дата отсчета является системной датой. Вторые четыре байта содержат текущее значение времени, представленного в виде трехсотых долей секунды, прошедших после полуночи.

SELECT CAST(CAST(CAST(CAST(GETDATE() as BINARY(8)) as BINARY(4)) as BINARY(8)) as DATETIME) 


5) Пятый способ – это синтаксис OLE DB/ODBC, который SQL Server отлично понимает:

SELECT CONVERT(DATETIME, {fn CURDATE()}) SELECT CONVERT(DATETIME, {fn CURRENT_DATE()}) 


6) Тип данных date, новый тип данных, который появится в MS SQL Server 2008, сохраняет дату без компонента времени. Диапазон – от 1 января 0001 года до 31 декабря 9999 года (от 0001-01-01 до 9999-12-31). Каждая переменная даты требует трех байтов для хранения и имеет точность в 10 цифр. Точность типа данных ограничена отдельным днем.
19 сен 13, 10:07    [14857754]     Ответить | Цитировать Сообщить модератору
 Re: Проблема с преобразованием даты  [new]
ambarka_max
Member

Откуда: Россия
Сообщений: 517
Я бы еще добавил одну нужную формулку

7) Округление кратно целым часам/минутам/секундам

--округление времени кратно 10 минутам
SELECT DATEADD(minute,FLOOR(DATEDIFF(minute,'20130101', '20130919 23:49:59.997')/10.0) * 10.0, '20130101') 

Вместо FLOOR (округление вниз) можно использовать CEILING (округление вверх) или ROUND (математическое окргуление) - кому что по душе.

Но с минутами и секундами следует быть осторожным: разность между датами может зашкаливать за границы int, потому нужно позаботиться самому, чтобы она лежала в пределах [-2,147,483,648 .. 2,147,483,647]
19 сен 13, 11:23    [14858213]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить