SQL Server dateformat questionable behavior











up vote
-3
down vote

favorite












Put this piece of code in query analyzer and hit F5.



declare @aaa datetime
set @aaa='01/12/2011'
set dateformat dmy
select month(@aaa)


It gives you 1. Hit F5 again, it gives you 12. Why?










share|improve this question




















  • 4




    Query Analyzer? Have I been time-warped back 10 years?
    – Aaron Bertrand
    Feb 21 '12 at 15:03






  • 1




    If you use a language-/location-independent string-based date (e.g. the ISO-8601 standard format YYYYMMDD) - e.g. set @aaa = '20111201' - then you can switch around between date formats as many times as you like - you'll ALWAYS get 12 for the month ......
    – marc_s
    Feb 21 '12 at 15:04

















up vote
-3
down vote

favorite












Put this piece of code in query analyzer and hit F5.



declare @aaa datetime
set @aaa='01/12/2011'
set dateformat dmy
select month(@aaa)


It gives you 1. Hit F5 again, it gives you 12. Why?










share|improve this question




















  • 4




    Query Analyzer? Have I been time-warped back 10 years?
    – Aaron Bertrand
    Feb 21 '12 at 15:03






  • 1




    If you use a language-/location-independent string-based date (e.g. the ISO-8601 standard format YYYYMMDD) - e.g. set @aaa = '20111201' - then you can switch around between date formats as many times as you like - you'll ALWAYS get 12 for the month ......
    – marc_s
    Feb 21 '12 at 15:04















up vote
-3
down vote

favorite









up vote
-3
down vote

favorite











Put this piece of code in query analyzer and hit F5.



declare @aaa datetime
set @aaa='01/12/2011'
set dateformat dmy
select month(@aaa)


It gives you 1. Hit F5 again, it gives you 12. Why?










share|improve this question















Put this piece of code in query analyzer and hit F5.



declare @aaa datetime
set @aaa='01/12/2011'
set dateformat dmy
select month(@aaa)


It gives you 1. Hit F5 again, it gives you 12. Why?







sql-server






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 21 '12 at 15:09









Aaron Bertrand

206k27360401




206k27360401










asked Feb 21 '12 at 15:00









Florin

11




11








  • 4




    Query Analyzer? Have I been time-warped back 10 years?
    – Aaron Bertrand
    Feb 21 '12 at 15:03






  • 1




    If you use a language-/location-independent string-based date (e.g. the ISO-8601 standard format YYYYMMDD) - e.g. set @aaa = '20111201' - then you can switch around between date formats as many times as you like - you'll ALWAYS get 12 for the month ......
    – marc_s
    Feb 21 '12 at 15:04
















  • 4




    Query Analyzer? Have I been time-warped back 10 years?
    – Aaron Bertrand
    Feb 21 '12 at 15:03






  • 1




    If you use a language-/location-independent string-based date (e.g. the ISO-8601 standard format YYYYMMDD) - e.g. set @aaa = '20111201' - then you can switch around between date formats as many times as you like - you'll ALWAYS get 12 for the month ......
    – marc_s
    Feb 21 '12 at 15:04










4




4




Query Analyzer? Have I been time-warped back 10 years?
– Aaron Bertrand
Feb 21 '12 at 15:03




Query Analyzer? Have I been time-warped back 10 years?
– Aaron Bertrand
Feb 21 '12 at 15:03




1




1




If you use a language-/location-independent string-based date (e.g. the ISO-8601 standard format YYYYMMDD) - e.g. set @aaa = '20111201' - then you can switch around between date formats as many times as you like - you'll ALWAYS get 12 for the month ......
– marc_s
Feb 21 '12 at 15:04






If you use a language-/location-independent string-based date (e.g. the ISO-8601 standard format YYYYMMDD) - e.g. set @aaa = '20111201' - then you can switch around between date formats as many times as you like - you'll ALWAYS get 12 for the month ......
– marc_s
Feb 21 '12 at 15:04














2 Answers
2






active

oldest

votes

















up vote
1
down vote













This is because your line set dateformat dmy is half way through the script.



This is switching your date format after the initial assignment for the first 'F5' but then this is persisted for the second 'F5'



If you make it the first line it should be consistent and return 12 each time



To be clear - the set dateformat dmy makes a difference for the set @aaa='01/12/2011' line as it affects the way that the string '01/12/2011' is parsed to a datetime.



On the first run, the @aaa will actually contain the date '12-Jan-2011', whereas after you set dateformat dmy it will contain the date '01-Dec-2011'.






share|improve this answer





















  • set dateformat dmy it has to be there. @aaa is just a parmeter received by the stored procedure. The first 2 lines is to try the procedure at design time
    – Florin
    Feb 21 '12 at 15:09








  • 1




    @Florin: That wasn't stated in the question - the more information you give, the better an answer you get. Where is the stored proc called from?
    – Jon Egerton
    Feb 21 '12 at 15:20










  • OK. Sorry. Let's see. You have this procedure: CREATE PROCEDURE [dbo].[Test] @dDate datetime AS BEGIN SET NOCOUNT ON; set dateformat dmy select month(@dDate) END If you execute the procedure it return 1 instead of 12
    – Florin
    Feb 21 '12 at 15:24










  • @Florin: That still doesn't state where the proc is called from. Are you calling from sql code, or from elsewhere (eg .net)
    – Jon Egerton
    Feb 21 '12 at 15:26






  • 1




    'dd/mm/yyyy' is not a type.
    – Aaron Bertrand
    Feb 21 '12 at 15:36


















up vote
1
down vote













Because the first time you ran the code, the date was stored internally as January 12th. The set setting sticks to your session, then you ran it again so you redeclared the variable, and this time it was interpreted as December 1st. The set setting doesn't affect datepart functions like MONTH() because the date has already been interpreted and isn't stored internally the way you've typed it.



Instead of declaring date literals with regional and ambiguous formatting, you should always use safe, unambiguous formats. For datetime/smalldatetime:



yyyymmdd
yyyy-mm-ddThh:mm:ss


For date:



yyyy-mm-dd


If you want to display dates in these friendly but confusing formats, by all means do that at the presentation layer. But don't try to confuse SQL Server with them. Please read this blog post and this article by Tibor Karaszi.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9379756%2fsql-server-dateformat-questionable-behavior%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote













    This is because your line set dateformat dmy is half way through the script.



    This is switching your date format after the initial assignment for the first 'F5' but then this is persisted for the second 'F5'



    If you make it the first line it should be consistent and return 12 each time



    To be clear - the set dateformat dmy makes a difference for the set @aaa='01/12/2011' line as it affects the way that the string '01/12/2011' is parsed to a datetime.



    On the first run, the @aaa will actually contain the date '12-Jan-2011', whereas after you set dateformat dmy it will contain the date '01-Dec-2011'.






    share|improve this answer





















    • set dateformat dmy it has to be there. @aaa is just a parmeter received by the stored procedure. The first 2 lines is to try the procedure at design time
      – Florin
      Feb 21 '12 at 15:09








    • 1




      @Florin: That wasn't stated in the question - the more information you give, the better an answer you get. Where is the stored proc called from?
      – Jon Egerton
      Feb 21 '12 at 15:20










    • OK. Sorry. Let's see. You have this procedure: CREATE PROCEDURE [dbo].[Test] @dDate datetime AS BEGIN SET NOCOUNT ON; set dateformat dmy select month(@dDate) END If you execute the procedure it return 1 instead of 12
      – Florin
      Feb 21 '12 at 15:24










    • @Florin: That still doesn't state where the proc is called from. Are you calling from sql code, or from elsewhere (eg .net)
      – Jon Egerton
      Feb 21 '12 at 15:26






    • 1




      'dd/mm/yyyy' is not a type.
      – Aaron Bertrand
      Feb 21 '12 at 15:36















    up vote
    1
    down vote













    This is because your line set dateformat dmy is half way through the script.



    This is switching your date format after the initial assignment for the first 'F5' but then this is persisted for the second 'F5'



    If you make it the first line it should be consistent and return 12 each time



    To be clear - the set dateformat dmy makes a difference for the set @aaa='01/12/2011' line as it affects the way that the string '01/12/2011' is parsed to a datetime.



    On the first run, the @aaa will actually contain the date '12-Jan-2011', whereas after you set dateformat dmy it will contain the date '01-Dec-2011'.






    share|improve this answer





















    • set dateformat dmy it has to be there. @aaa is just a parmeter received by the stored procedure. The first 2 lines is to try the procedure at design time
      – Florin
      Feb 21 '12 at 15:09








    • 1




      @Florin: That wasn't stated in the question - the more information you give, the better an answer you get. Where is the stored proc called from?
      – Jon Egerton
      Feb 21 '12 at 15:20










    • OK. Sorry. Let's see. You have this procedure: CREATE PROCEDURE [dbo].[Test] @dDate datetime AS BEGIN SET NOCOUNT ON; set dateformat dmy select month(@dDate) END If you execute the procedure it return 1 instead of 12
      – Florin
      Feb 21 '12 at 15:24










    • @Florin: That still doesn't state where the proc is called from. Are you calling from sql code, or from elsewhere (eg .net)
      – Jon Egerton
      Feb 21 '12 at 15:26






    • 1




      'dd/mm/yyyy' is not a type.
      – Aaron Bertrand
      Feb 21 '12 at 15:36













    up vote
    1
    down vote










    up vote
    1
    down vote









    This is because your line set dateformat dmy is half way through the script.



    This is switching your date format after the initial assignment for the first 'F5' but then this is persisted for the second 'F5'



    If you make it the first line it should be consistent and return 12 each time



    To be clear - the set dateformat dmy makes a difference for the set @aaa='01/12/2011' line as it affects the way that the string '01/12/2011' is parsed to a datetime.



    On the first run, the @aaa will actually contain the date '12-Jan-2011', whereas after you set dateformat dmy it will contain the date '01-Dec-2011'.






    share|improve this answer












    This is because your line set dateformat dmy is half way through the script.



    This is switching your date format after the initial assignment for the first 'F5' but then this is persisted for the second 'F5'



    If you make it the first line it should be consistent and return 12 each time



    To be clear - the set dateformat dmy makes a difference for the set @aaa='01/12/2011' line as it affects the way that the string '01/12/2011' is parsed to a datetime.



    On the first run, the @aaa will actually contain the date '12-Jan-2011', whereas after you set dateformat dmy it will contain the date '01-Dec-2011'.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Feb 21 '12 at 15:03









    Jon Egerton

    29.4k1070112




    29.4k1070112












    • set dateformat dmy it has to be there. @aaa is just a parmeter received by the stored procedure. The first 2 lines is to try the procedure at design time
      – Florin
      Feb 21 '12 at 15:09








    • 1




      @Florin: That wasn't stated in the question - the more information you give, the better an answer you get. Where is the stored proc called from?
      – Jon Egerton
      Feb 21 '12 at 15:20










    • OK. Sorry. Let's see. You have this procedure: CREATE PROCEDURE [dbo].[Test] @dDate datetime AS BEGIN SET NOCOUNT ON; set dateformat dmy select month(@dDate) END If you execute the procedure it return 1 instead of 12
      – Florin
      Feb 21 '12 at 15:24










    • @Florin: That still doesn't state where the proc is called from. Are you calling from sql code, or from elsewhere (eg .net)
      – Jon Egerton
      Feb 21 '12 at 15:26






    • 1




      'dd/mm/yyyy' is not a type.
      – Aaron Bertrand
      Feb 21 '12 at 15:36


















    • set dateformat dmy it has to be there. @aaa is just a parmeter received by the stored procedure. The first 2 lines is to try the procedure at design time
      – Florin
      Feb 21 '12 at 15:09








    • 1




      @Florin: That wasn't stated in the question - the more information you give, the better an answer you get. Where is the stored proc called from?
      – Jon Egerton
      Feb 21 '12 at 15:20










    • OK. Sorry. Let's see. You have this procedure: CREATE PROCEDURE [dbo].[Test] @dDate datetime AS BEGIN SET NOCOUNT ON; set dateformat dmy select month(@dDate) END If you execute the procedure it return 1 instead of 12
      – Florin
      Feb 21 '12 at 15:24










    • @Florin: That still doesn't state where the proc is called from. Are you calling from sql code, or from elsewhere (eg .net)
      – Jon Egerton
      Feb 21 '12 at 15:26






    • 1




      'dd/mm/yyyy' is not a type.
      – Aaron Bertrand
      Feb 21 '12 at 15:36
















    set dateformat dmy it has to be there. @aaa is just a parmeter received by the stored procedure. The first 2 lines is to try the procedure at design time
    – Florin
    Feb 21 '12 at 15:09






    set dateformat dmy it has to be there. @aaa is just a parmeter received by the stored procedure. The first 2 lines is to try the procedure at design time
    – Florin
    Feb 21 '12 at 15:09






    1




    1




    @Florin: That wasn't stated in the question - the more information you give, the better an answer you get. Where is the stored proc called from?
    – Jon Egerton
    Feb 21 '12 at 15:20




    @Florin: That wasn't stated in the question - the more information you give, the better an answer you get. Where is the stored proc called from?
    – Jon Egerton
    Feb 21 '12 at 15:20












    OK. Sorry. Let's see. You have this procedure: CREATE PROCEDURE [dbo].[Test] @dDate datetime AS BEGIN SET NOCOUNT ON; set dateformat dmy select month(@dDate) END If you execute the procedure it return 1 instead of 12
    – Florin
    Feb 21 '12 at 15:24




    OK. Sorry. Let's see. You have this procedure: CREATE PROCEDURE [dbo].[Test] @dDate datetime AS BEGIN SET NOCOUNT ON; set dateformat dmy select month(@dDate) END If you execute the procedure it return 1 instead of 12
    – Florin
    Feb 21 '12 at 15:24












    @Florin: That still doesn't state where the proc is called from. Are you calling from sql code, or from elsewhere (eg .net)
    – Jon Egerton
    Feb 21 '12 at 15:26




    @Florin: That still doesn't state where the proc is called from. Are you calling from sql code, or from elsewhere (eg .net)
    – Jon Egerton
    Feb 21 '12 at 15:26




    1




    1




    'dd/mm/yyyy' is not a type.
    – Aaron Bertrand
    Feb 21 '12 at 15:36




    'dd/mm/yyyy' is not a type.
    – Aaron Bertrand
    Feb 21 '12 at 15:36












    up vote
    1
    down vote













    Because the first time you ran the code, the date was stored internally as January 12th. The set setting sticks to your session, then you ran it again so you redeclared the variable, and this time it was interpreted as December 1st. The set setting doesn't affect datepart functions like MONTH() because the date has already been interpreted and isn't stored internally the way you've typed it.



    Instead of declaring date literals with regional and ambiguous formatting, you should always use safe, unambiguous formats. For datetime/smalldatetime:



    yyyymmdd
    yyyy-mm-ddThh:mm:ss


    For date:



    yyyy-mm-dd


    If you want to display dates in these friendly but confusing formats, by all means do that at the presentation layer. But don't try to confuse SQL Server with them. Please read this blog post and this article by Tibor Karaszi.






    share|improve this answer



























      up vote
      1
      down vote













      Because the first time you ran the code, the date was stored internally as January 12th. The set setting sticks to your session, then you ran it again so you redeclared the variable, and this time it was interpreted as December 1st. The set setting doesn't affect datepart functions like MONTH() because the date has already been interpreted and isn't stored internally the way you've typed it.



      Instead of declaring date literals with regional and ambiguous formatting, you should always use safe, unambiguous formats. For datetime/smalldatetime:



      yyyymmdd
      yyyy-mm-ddThh:mm:ss


      For date:



      yyyy-mm-dd


      If you want to display dates in these friendly but confusing formats, by all means do that at the presentation layer. But don't try to confuse SQL Server with them. Please read this blog post and this article by Tibor Karaszi.






      share|improve this answer

























        up vote
        1
        down vote










        up vote
        1
        down vote









        Because the first time you ran the code, the date was stored internally as January 12th. The set setting sticks to your session, then you ran it again so you redeclared the variable, and this time it was interpreted as December 1st. The set setting doesn't affect datepart functions like MONTH() because the date has already been interpreted and isn't stored internally the way you've typed it.



        Instead of declaring date literals with regional and ambiguous formatting, you should always use safe, unambiguous formats. For datetime/smalldatetime:



        yyyymmdd
        yyyy-mm-ddThh:mm:ss


        For date:



        yyyy-mm-dd


        If you want to display dates in these friendly but confusing formats, by all means do that at the presentation layer. But don't try to confuse SQL Server with them. Please read this blog post and this article by Tibor Karaszi.






        share|improve this answer














        Because the first time you ran the code, the date was stored internally as January 12th. The set setting sticks to your session, then you ran it again so you redeclared the variable, and this time it was interpreted as December 1st. The set setting doesn't affect datepart functions like MONTH() because the date has already been interpreted and isn't stored internally the way you've typed it.



        Instead of declaring date literals with regional and ambiguous formatting, you should always use safe, unambiguous formats. For datetime/smalldatetime:



        yyyymmdd
        yyyy-mm-ddThh:mm:ss


        For date:



        yyyy-mm-dd


        If you want to display dates in these friendly but confusing formats, by all means do that at the presentation layer. But don't try to confuse SQL Server with them. Please read this blog post and this article by Tibor Karaszi.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 10 at 22:50

























        answered Feb 21 '12 at 15:04









        Aaron Bertrand

        206k27360401




        206k27360401






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9379756%2fsql-server-dateformat-questionable-behavior%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Florida Star v. B. J. F.

            Danny Elfman

            Lugert, Oklahoma