【问题标题】:How to create a Date in SQL Server given the Day, Month and Year as Integers如何在 SQL Server 中以整数形式创建日期、月份和年份
【发布时间】:2016-06-05 06:10:21
【问题描述】:

FOR 例如,如果我有:

DECLARE @Day int = 25
DECLARE @Month int  = 10 
DECLARE @Year int = 2016

我想回来

2016-10-25

作为日期或日期时间

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    在 SQL Server 2012+ 中,您可以使用datefromparts():

    select datefromparts(@year, @month, @day)
    

    在早期版本中,您可以强制转换字符串。这是一种方法:

    select cast(cast(@year*10000 + @month*100 + @day as varchar(255)) as date)
    

    【讨论】:

    • 你的意思是@year 而不是year?
    • 安装了这个year*100000,应该是@year*10000
    • 字符串/日期时间转换是不确定的,除非使用 CONVERT(而不是 CAST)指定样式。 msdn.microsoft.com/en-us/library/ms178091(SQL.90).aspx
    • @RileyMajor 。 . .如果确定性很重要,那么您确实需要一种格式。但是,无论任何国际化格式如何,YYYYMMDD 格式的字符串始终都能正确转换。
    • @RileyMajor 。 . .文档位于docs.microsoft.com/en-us/sql/t-sql/data-types/…,特别是“六位或八位字符串始终解释为 ymd。”
    【解决方案2】:

    在 SQL Server 2012+ 中,您可以使用DATEFROMPARTS():

    DECLARE @Year int = 2016, @Month int = 10, @Day int = 25;
    SELECT DATEFROMPARTS (@Year, @Month, @Day);
    

    在早期版本中,一种方法是创建和转换字符串。

    无论日期、语言或国际化设置如何,SQL Server 都能可靠地解释一些字符串日期格式。

    六位或八位字符串始终被解释为 ymd。这个月 并且天必须始终为两位数。

    https://docs.microsoft.com/en-us/sql/t-sql/data-types/datetime-transact-sql

    因此,格式为“yyyymmdd”的字符串将始终被正确解释。

    (ISO 8601-- YYYY-MM-DDThh:mm:ss-- 也可以,但您必须指定时间,因此它比您需要的要复杂。)

    虽然您可以简单地将 CAST 这个字符串作为日期,但您必须使用 CONVERT 来指定样式,而您必须使用 must specify a style in order to be deterministic(如果这对您很重要)。

    “yyyymmdd”格式为样式 112,因此您的转换如下所示:

    DECLARE @Year int = 2016, @Month int = 10, @Day int = 25;
    SELECT CONVERT(date,CONVERT(varchar(50),(@Year*10000 + @Month*100 + @Day)),112);
    

    结果是:

    2016-10-25

    从技术上讲,ISO/112/yyyymmdd 格式甚至适用于指定的其他样式。例如,使用样式为 104 的文本格式(德语,dd.mm.yyyy):

    DECLARE @Year int = 2016, @Month int = 10, @Day int = 25;
    SELECT CONVERT(date,CONVERT(varchar(50),(@Year*10000 + @Month*100 + @Day)),104);
    

    仍然会导致:

    2016-10-25

    其他格式没有那么健壮。例如:

    SELECT CASE WHEN CONVERT(date,'01-02-1900',110) = CONVERT(date,'01-02-1900',105) THEN 1 ELSE 0 END;
    

    结果:

    0

    附带说明,使用此方法时,请注意无意义的输入可能会产生有效但不正确的日期:

    DECLARE @Year int = 2016, @Month int = 0, @Day int = 1025;
    SELECT CONVERT(date,CONVERT(varchar(50),(@Year*10000 + @Month*100 + @Day)),112);
    

    也产生:

    2016-10-25

    DATEFROMPARTS 保护您免受无效输入的影响。这个:

    DECLARE @Year int = 2016, @Month int = 10, @Day int = 32;
    SELECT DATEFROMPARTS (@Year, @Month, @Day);
    

    产量:

    消息 289,级别 16,状态 1,行 2 无法构造数据类型日期, 一些参数的值无效。

    另外请注意,此方法不适用于 1000-01-01 之前的日期。例如:

    DECLARE @Year int = 900, @Month int = 1, @Day int = 1;
    SELECT CONVERT(date,CONVERT(varchar(50),(@Year*10000 + @Month*100 + @Day)),112);
    

    产量:

    Msg 241, Level 16, State 1, Line 2 转换时转换失败 字符串中的日期和/或时间。

    这是因为生成的字符串“9000101”不是“yyyymmdd”格式。为了确保格式正确,您必须用前导零填充它,但会牺牲一些性能。例如:

    DECLARE @Year int = 900, @Month int = 1, @Day int = 1;
    SELECT CONVERT(date,RIGHT('000' + CONVERT(varchar(50),(@Year*10000 + @Month*100 + @Day)),8),112);
    

    结果:

    0900-01-01

    除了字符串转换还有其他方法。在“Create a date with T-SQL”的回答中提供了几个。 A notable example 涉及通过将年、月和日添加到“零日期”来创建日期。

    (这个答案的灵感来自Gordon Linoff'sanswer,我对此进行了扩展并提供了额外的文档和注释。)

    【讨论】:

      【解决方案3】:

      我相信以下代码应该适用于所有版本的 sql server:

      SELECT CAST(CONCAT(CAST(@Year AS VARCHAR(4)), '-',CAST(@Month AS VARCHAR(2)), '-',CAST(@Day AS VARCHAR(2))) AS DATE)
      

      【讨论】:

      【解决方案4】:

      旧版 Microsoft Sql Sever (

      RETURN dateadd(month, 12 * @year + @month - 22801, @day - 1)  
      

      【讨论】:

        【解决方案5】:

        所以,你可以试试这个解决方案:

        DECLARE @DAY INT = 25
        DECLARE @MONTH INT  = 10 
        DECLARE @YEAR INT = 2016
        DECLARE @DATE AS DATETIME
        
        SET @DATE = CAST(RTRIM(@YEAR * 10000 + @MONTH * 100 + @DAY) AS DATETIME) 
        
        SELECT REPLACE(CONVERT(VARCHAR(10), @DATE, 102), '.', '-') AS EXPECTDATE
        

        或者你可以试试这几行代码:

        DECLARE @DAY INT = 25
        DECLARE @MONTH INT  = 10 
        DECLARE @YEAR INT = 2016
        
        SELECT CAST(RTRIM(@YEAR * 10000 +'-' +  @MONTH * 100+ '-' + @DAY) AS DATE) AS EXPECTDATE
        

        【讨论】:

        【解决方案6】:

        选择转换(varchar(11), transfer_date, 106)

        得到我想要的日期格式为 2018 年 3 月 7 日的结果

        我的列“transfer_date”是一个日期时间类型列,我在 azure 上使用 SQL Server 2017

        【讨论】:

          【解决方案7】:

          在 SQL 中使用 MONTH YEAR 创建日期::

          DECLARE @FromMonth int=NULL,
          @ToMonth int=NULL,
          @FromYear int=NULL,
          @ToYear int=NULL
          
          /**Region For Create Date**/
                  DECLARE @FromDate DATE=NULL
                  DECLARE @ToDate DATE=NULL
          
              SET @FromDate=DateAdd(day,0, DateAdd(month, @FromMonth - 1,DateAdd(Year, @FromYear-1900, 0)))
              SET @ToDate=DateAdd(day,-1, DateAdd(month, @ToMonth - 0,DateAdd(Year, @ToYear-1900, 0)))
          /**Region For Create Date**/
          

          【讨论】:

            【解决方案8】:

            对于 SQL Server 2008 用户,我做了一个自定义函数:

            CREATE FUNCTION sql2012_datefromparts
            (   
                @Year int, @Month int, @Day int
            )
            RETURNS DATETIME
            AS
            BEGIN
                RETURN convert(datetime,convert(varchar,@year)+right('0'+convert(varchar,@month),2)+right('0'+convert(varchar,@day),2)) 
            END
            GO
            

            使用它:

            DECLARE @day int=29, @month int=10, @year int=1971
            SELECT dbo.sql2012_datefromparts(@year,@month,@day)
            

            【讨论】:

              【解决方案9】:

              简单且最灵活的解决方案

              使用 FORMAT 函数制作您喜欢的任何类型的格式。 这是复制粘贴工作示例:

              DECLARE @year int = 2021, @month int = 12, @day int = 16
              DECLARE @date varchar(20)
              SET @date = cast((format(@year,'####') +'-'+format(@month,'##')+'-'+format(@day,'##')) as date)
              SELECT @date
              

              它还将在几天和几个月内显示前导零。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2018-10-15
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-11-26
                相关资源
                最近更新 更多