Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • How many Saturdays from a month Date variable

    Hi ,

    Given the following dataset, how to get the # of Saturdays in each month(observation) ?
    I add some date function ( Stata 18.5) to , hopefully, helps in the answer.

    Code:
    clear
    input float datevar_m
    747
    748
    749
    750
    751
    752
    753
    754
    755
    end
    format %tm datevar_m
    convdate daily datevar_d = datevar_m
    gen int daysinmonth = daysinmonth( datevar_d  )
    gen int firstdayofmonth=firstdayofmonth( datevar_d )
    gen int lastdayofmonth=lastdayofmonth( datevar_d )
    gen firstdayofmonthDOW = dow( firstdayofmonth  )
    gen lastdayofmonthDOW = dow( lastdayofmonth  )
    gen int datevar_mN =datepart( datevar_d,"month" )
    
    . list
    
         +----------------------------------------------------------------------------------------+
         | dateva~m   datevar_d   daysin~h   firstd~h   lastda~h   firstd~W   lastda~W   dateva~N |
         |----------------------------------------------------------------------------------------|
      1. |   2022m4   01apr2022         30      22736      22765          5          6          4 |
      2. |   2022m5   01may2022         31      22766      22796          0          2          5 |
      3. |   2022m6   01jun2022         30      22797      22826          3          4          6 |
      4. |   2022m7   01jul2022         31      22827      22857          5          0          7 |
      5. |   2022m8   01aug2022         31      22858      22888          1          3          8 |
         |----------------------------------------------------------------------------------------|
      6. |   2022m9   01sep2022         30      22889      22918          4          5          9 |
      7. |  2022m10   01oct2022         31      22919      22949          6          1         10 |
      8. |  2022m11   01nov2022         30      22950      22979          2          3         11 |
      9. |  2022m12   01dec2022         31      22980      23010          4          6         12 |
         +----------------------------------------------------------------------------------------+

    thanks


  • #2
    Assuming you are using the current version of Stata:
    Code:
    gen start_of_month = dofm(datevar_m)
    format start_of_month %td
    
    gen first_saturday = start_of_month + mod(daysuntildow(start_of_month, 6), 7)
    format first_saturday %td
    
    gen end_of_month = lastdayofmonth(start_of_month)
    format end_of_month %td
    
    gen number_of_saturdays = floor((end_of_month - first_saturday)/7)+1
    This code will not work in earlier versions, because the function -daysuntildow()- was first introduced in version 18. Do remember that the FAQ, which you should be familiar with, points out the need to state what version you are using if it isn't the current one.

    Added: If you don't have the -daysuntildow()- function you can replace that command with:
    Code:
    gen first_saturday = start_of_month + 6 - dow(start_of_month)
    Last edited by Clyde Schechter; 04 Feb 2025, 19:13.

    Comment


    • #3
      Here's another way to do it, which uses fewer of the specialist datetime functions. It relies on the logic that the number of occurrences of a day in a month is by default 4. It becomes 5 in months where the day falls within the first (x-28) days of the month, x being the number of days in the month. So a 28 day month repeats no days 5 times; in a 29 day month, the first day is repeated 5 times; in a 30 day month, the first 2 days are repeated 5 times, and so on.

      Code:
      gen double datevar_d = dofm(datevar_m)
      gen byte daysinmonth = daysinmonth(datevar_d)
      gen byte excess_days = daysinmonth - 28
      gen byte first_day = dow(firstdayofmonth(datevar_d))
      gen byte num_saturdays = 4 + cond(excess_days > 0, inrange(6, first_day, first_day + excess_days - 1), 0)
      drop datevar_d
      which produces:

      Code:
      . list , noobs sep(0) abbrev(13)
      
        +-------------------------------------------------------------------+
        | datevar_m   daysinmonth   excess_days   first_day   num_saturdays |
        |-------------------------------------------------------------------|
        |    2022m4            30             2           5               5 |
        |    2022m5            31             3           0               4 |
        |    2022m6            30             2           3               4 |
        |    2022m7            31             3           5               5 |
        |    2022m8            31             3           1               4 |
        |    2022m9            30             2           4               4 |
        |   2022m10            31             3           6               5 |
        |   2022m11            30             2           2               4 |
        |   2022m12            31             3           4               5 |
        +-------------------------------------------------------------------+
      Last edited by Hemanshu Kumar; 05 Feb 2025, 02:27.

      Comment


      • #4
        Thanks Clyde and Hemanshu for the quick reply,

        below, I extended Hemanshu's approach to recover all days of the week from a month Date variable.


        Code:
        clear
        input float datevar_m
        747
        748
        749
        750
        751
        752
        753
        754
        755
        end
        format %tm datevar_m
        gen double datevar_d = dofm(datevar_m)
        gen byte daysinmonth = daysinmonth(datevar_d)
        gen byte excess_days = daysinmonth - 28
        gen byte first_day = dow(firstdayofmonth(datevar_d))
        forvalues i=0/6 {
        gen byte num_`i' = 4 + cond(excess_days > 0, inrange(`i', first_day, first_day + excess_days - 1), 0)
        }
        label variable num_0 "# of Sundays"
        
        list , noobs sep(0) abbrev(13)
          +-----------------------------------------------------------------------------------------------------------------------+
          | datevar_m   datevar_d   daysinmonth   excess_days   first_day   num_0   num_1   num_2   num_3   num_4   num_5   num_6 |
          |-----------------------------------------------------------------------------------------------------------------------|
          |    2022m4       22736            30             2           5       4       4       4       4       4       5       5 |
          |    2022m5       22766            31             3           0       5       5       5       4       4       4       4 |
          |    2022m6       22797            30             2           3       4       4       4       5       5       4       4 |
          |    2022m7       22827            31             3           5       4       4       4       4       4       5       5 |
          |    2022m8       22858            31             3           1       4       5       5       5       4       4       4 |
          |    2022m9       22889            30             2           4       4       4       4       4       5       5       4 |
          |   2022m10       22919            31             3           6       4       4       4       4       4       4       5 |
          |   2022m11       22950            30             2           2       4       4       5       5       4       4       4 |
          |   2022m12       22980            31             3           4       4       4       4       4       5       5       5 |
          +-----------------------------------------------------------------------------------------------------------------------+

        Comment

        Working...
        X