Microsoft SQL Server
Transact-SQL

Первые и последнии дни периодов

Опубликовано: 28 сен 02
Рейтинг:

Автор: Cat2
Прислал: Cat2

--Некоторые полезные преобразования
set nocount on
declare @d datetime
set @d=convert(char(8),getdate(),112)
select 'Дата ',@d
 
select 'первый день месяца',
dateadd(day,1-day(@d),@d)
 
select  'последний день месяца',
dateadd(month,1,dateadd(day,1-day(@d),@d))-1
 
select 'первый день года',
dateadd(day,1-datepart(dayofyear,@d),@d),
convert(datetime,'1/1/'+convert(char(4),year(@d)),101)
 
select 'последний день года',
convert(datetime,'12/31/'+convert(char(4),year(@d)),101)
 

select 'первый день квартала',
convert(datetime,convert(varchar(2),(month(@d)-1)/3*3+1)+'/1/'+convert(char(4),year(@d)),101),
convert(datetime,convert(varchar(2),convert(varchar(2),(datepart(quarter,@d)-1)*3)+1)+'/1/'+convert(char(4),year(@d)),101)

 
select 'последний день квартала',
dateadd(month,3,convert(datetime,convert(varchar(2),(month(@d)-1)/3*3+1)+'/1/'+convert(char(4),year(@d)),101))-1
 
print 'Русская нумерация дней недели'
SET DATEFIRST 1
select datepart(weekday,getdate())

go

declare @i int
declare @m char(2),@y char(4)
set @y='2002'

set nocount on
SET DATEFIRST 1
set @i=1
while @i <=12
begin
set @m=convert(char(2),@i)
select @i as Месяц, dateadd(d,
--Первое воскресенье месяца
7-datepart(dw,convert(datetime,@m+'/1/'+@y,101)), 
convert(datetime,@m+'/1/'+@y,101)) Первое
--Последнее воскресенье месяца
, dateadd(d,
7-datepart(dw,dateadd(m,1,convert(datetime,@m+'/1/'+@y,101))), 
dateadd(m,1,convert(datetime,@m+'/1/'+@y,101)))-7 Последнее
set @i=@i+1
end
go
-- Вариант, предложеный  SM
declare @m char(2),@y char(4)
select @y=convert(char(4),year(getdate()))

select @m=convert(varchar(2),month(getdate()))
DECLARE @firstWDay int
SET  @firstWDay=datepart(dw,convert(datetime,@m+'/1/'+@y,101))

DECLARE @FirstSunDay datetime
SET @FirstSunDay=dateadd(d,
CASE @firstWDay WHEN 1 THEN 0 ELSE 7-@firstWDay+1 END, 
convert(datetime,@m+'/1/'+@y,101))

DECLARE @lastWDay int
SET  @lastWDay=datepart(dw,dateadd(d,-1,dateadd(m,1, convert(datetime,@m+'/1/'+@y,101))))

DECLARE @lastSunDay datetime
SET @lastSunDay=dateadd(d,
CASE @lastWDay WHEN 1 THEN 0 ELSE -1 * @lastWDay + 1 END, 
dateadd(d,-1,dateadd(m,1, convert(datetime,@m+'/1/'+@y,101)))
)
SELECT @y, @FirstSunDay, @lastSunDay

Комментарии


  • Большой спасиб от верного ВАМ плагиатора.

  • Cat2,
    Ваше определение последней даты месяца работает не во всех случаях. Если попытаться вставить его в вычисляемое поле таблицы, то получите ошибку. Вообще, строго говоря, корректнее писать так:
    dateadd(day,-1,dateadd(month,(1),dateadd(day,(1)-datepart(day,@d),@d)))

  • Добрый день.
    решил попробовать как в примере но с одним изменением.
    мне необходимо дату задавать самому а не через getdate().
    вот написал код:
    declare @d date
    set @d=convert(date,'2014-04-06',20)
    select 'первый день месяца',
    dateadd(day,1-day(@d),@d)
    ----------------------------------
    set @d=convert(date,'2014-04-06',20)
    select 'последний день месяца',dateadd(month,1,dateadd(day,1-day(convert(date,'2014-04-06',20)),
    convert(date,'2014-04-06',20)))-1

    первый запрос работает и дает мне первое число месяца. у второго ругается на int и date(то что я из dateadd хочу 1 вычесть)
    подскажите как исправить

  • Добрый день.
    решил попробовать как в примере но с одним изменением.
    мне необходимо дату задавать самому а не через getdate().
    вот написал код:
    declare @d date
    set @d=convert(date,'2014-04-06',20)
    select 'первый день месяца',
    dateadd(day,1-day(@d),@d)
    ----------------------------------
    set @d=convert(date,'2014-04-06',20)
    select 'последний день месяца',dateadd(month,1,dateadd(day,1-day(convert(date,'2014-04-06',20)),
    convert(date,'2014-04-06',20)))-1

    первый запрос работает и дает мне первое число месяца. у второго ругается на int и date(то что я из dateadd хочу 1 вычесть)
    подскажите как исправить

  • кудесники благого ремесла))

  • Первый и последний дни квартала
    [SRC]declare @date datetime=getdate()
    select @date, DATEADD(Q,DATEDIFF(Q,0,@date),0), DATEADD(D,-1,DATEADD(Q,DATEDIFF(Q,0,@date)+1,0))[/SRC]

  • В предыдущем комменте ошибка, вот правильный вариант
    SELECT DATEDIFF(D,
    DATEADD(day,1-DATEPART(y,@d),@d),
    DATEADD(YY,1,DATEADD(day,1-DATEPART(y,@d),@d))
    )

  • Количество дней в году:

    SELECT DATEDIFF(D,
    DATEADD(day,1-DATEPART(y,@d),@d),
    DATEADD(YY,1,DATEADD(day,1-DATEPART(y,@d),@d))-1
    )

  • Огромное спасибо!

  • 03 марта 2010, 13:03 Дмитрий25

    Супер! Спасибо)

  • 03 марта 2010, 12:54 Дмитрий25

    Супер! Спасибо)

  • Цены вам нет!

  • 30 сентября 2008, 04:15 Даниил Пакоv

    Спасибо. Всё наглядно и просто!

  • Спасибо! :)

  • уже наверное тысячный раз захожу сюда за кодом)))
    спасибо

  • Насчет месяцев - создал в БД справочник месяцев, заполнил его при помощи Excel до 2050 г. и весьма доволен результатом. В итоге в БД появился идентификатор м/с, по которому можно получить все реквизиты, или например узнать начальную дату позапрошлого м/с. Ид. используется как часть ключа во многих таблицах. Таблица закрыта от редактирования триггером.

  • пример самого дубового получения
    последней даты предыдущего месяца

    declare @CurrentYear varchar(8)
    declare @LastDayOfMonth varchar(8)

    --Год
    if month(getdate()) = 1
    set @CurrentYear = year(getdate()) - 1
    else
    set @CurrentYear = year(getdate())

    --Месяц
    set @LastDayOfMonth =
    (
    select
    case
    when month(getdate()) = 1 THEN @CurrentYear + '1231'
    when month(getdate()) = 2 THEN @CurrentYear + '0131'
    when month(getdate()) = 3 THEN @CurrentYear + '0228'
    when month(getdate()) = 4 THEN @CurrentYear + '0331'
    when month(getdate()) = 5 THEN @CurrentYear + '0430'
    when month(getdate()) = 6 THEN @CurrentYear + '0531'
    when month(getdate()) = 7 THEN @CurrentYear + '0630'
    when month(getdate()) = 8 THEN @CurrentYear + '0731'
    when month(getdate()) = 9 THEN @CurrentYear + '0831'
    when month(getdate()) = 10 THEN @CurrentYear + '0930'
    when month(getdate()) = 11 THEN @CurrentYear + '1031'
    when month(getdate()) = 12 THEN @CurrentYear + '1130'
    end
    )

    select 'Последний день предыдущего месяца', @LastDayOfMonth

  • Здесь везде учитывается, что MDY. Но в системе по-разному бывает...

    Первый день квартала:
    dateadd(day, 1-day(@d1), cast(floor(cast(dateadd(month, (datepart(qq, @d1)-1)*3+1 - month(@d1), @d1) as float)) as datetime))

  • select 'последний день года',
    dateadd (year, datediff( year, 0, getdate()) + 1, 0) - 1

  • 'первый день месяца',
    dateadd( month, datediff( month, 0, @date), 0);

  • это 5!

  • спасибо)



Необходимо войти на сайт, чтобы оставлять комментарии

Раздел FAQ: Microsoft SQL Server / Transact-SQL / Первые и последнии дни периодов