SET DATEFIRST in FUNCTION

前端 未结 4 1045
悲哀的现实
悲哀的现实 2020-12-16 01:37

I want to SET DATEFIRST in my function but it is not allowed.

SET DATEFIRST 1

I can add the code in a SP and call the SP from the function

相关标签:
4条回答
  • 2020-12-16 02:05

    My usual workaround is to use "known-good" dates for my comparisons.

    Say, for instance, that I need to check that a date is a saturday. Rather than relying on DATEFIRST or language settings (for using DATENAME), I instead say:

    DATEPART(weekday,DateToCheck) = DATEPART(weekday,'20120714')
    

    I know that 14th July 2012 was a Saturday, so I've performed the check without relying on any external settings.


    The expression (DATEPART(weekday,DateToCheck) + @@DATEFIRST) % 7 will always produce the value 0 for Saturday, 1 for Sunday, 2 for Monday, etc.

    So, I'd advise you to create a table:

    CREATE TABLE WorkingDays (
        NormalisedDay int not null,
        DaysInMonth int not null,
        WorkingDays int not null
    )
    

    Populating this table is a one off exercise. NormalisedDay would be the value computed by the expression I've given above.

    To compute the DaysInMonth given a particular date, you can use the expression:

    DATEDIFF(day,
          DATEADD(month,DATEDIFF(month,0,DateToCheck),0),
          DATEADD(month,DATEDIFF(month,'20010101',DateToCheck),'20010201'))
    

    Now all your function has to do is look up the value in the table.

    (Of course, all of the rows where DaysInMonth is 28 will have 20 as their result. It's only the rows for 29,30 and 31 which need a little work to produce)

    0 讨论(0)
  • 2020-12-16 02:17

    If you need Monday as firstday follow this code snippet

    declare @MyDate datetime = getdate()
                       select CASE WHEN DATEPART(DW,@MyDate) = 1   
                                THEN 7 
                              WHEN DATEPART(DW,@MyDate) <= 7 
                                THEN DATEPART(DW,@MyDate) - 1                            
                         END 
    
    0 讨论(0)
  • Instead of

    SET DATEFIRST 1
    

    You can do

    SELECT (DATEPART(weekday, GETDATE()) + @@DATEFIRST - 2) % 7 + 1
    
    0 讨论(0)
  • 2020-12-16 02:27

    Alternative way is to explicitly specify the first day of week value as parameter and avoid depending on @@DATEFIRST setting. You can use the following formula to achieve that in your function:

    (DATEPART(dw, GETDATE()) + @@DATEFIRST + 6 - @WeekStartDay) % 7 + 1
    

    where @WeekStartDay is the first day of the week you want for your system (from 1 to 7 which means from Monday to Sunday).

    I have wrapped it into below function so we can reuse it easily:

    CREATE FUNCTION [dbo].[GetDayInWeek](@InputDateTime DATETIME, @WeekStartDay INT)
    RETURNS INT
    AS
    BEGIN
        --Note: @WeekStartDay is number from [1 - 7] which is from Monday to Sunday
        RETURN (DATEPART(dw, @InputDateTime) + @@DATEFIRST + 6 - @WeekStartDay) % 7 + 1 
    END
    

    Example usage: GetDayInWeek('2019-02-04 00:00:00', 1)

    It is equivalent to following (but independent to DATEFIRST setting):

    SET DATEFIRST 1
    DATEPART(dw, '2019-02-04 00:00:00')
    
    0 讨论(0)
提交回复
热议问题