Jump to content

Figuring out what week it is.


Recommended Posts

You could use the @YDAY macro and divide by 7 to give you quite a reasonable approximation.

<{POST_SNAPBACK}>

I thought the same thing.. It works well most of the time, the first week is usually a problem though. because when you're divding 1, 2, 3, 4, 5, and 6 by 7 it doesn't do very well when the first is on a Saturday for example...

.... And actually the problem with doing it this way is because your week is defined by the day that January first falls on.. If it falls on a Saturday, your weeks will be defined each Saturday, which is okay, but not when the first of January falls on like a Tuesday.

Edited by exodius
Link to comment
Share on other sites

Before I continue I should probably confirm that this is how weeks work. Is this right? --

Day of 1/1  Week 1 spans    Week 2 starts
-------------------------------------------
Sunday       1/1 -> 7/1       8/1
Monday       1/1 -> 6/1       7/1
Tuesday     1/1 -> 5/1        6/1
Wednesday     1/1 -> 4/1          5/1
Thursday       1/1 -> 3/1         4/1
Friday       1/1 -> 2/1       3/1
Saturday       1/1               2/1

What we need to do is offset the @YDAY macro according to what day it is on 1/1. We can use the _DateToDayOfWeek() UDF to help us with this.

Suppose that we had such a variable calculated; let's call it $output for now. It would equal 0 for 1/1 when 1/1 is a Sunday, and 6 for 1/1 when 1/1 is a Saturday.

We could then divide this variable by 7 which would give us 0 for the first week, 1 for the second week, etc. By adding 1 to this result we have the proper week number needed for any given date.

Link to comment
Share on other sites

#include <Date.au3>

; if ($firstDay = 1) then 1/1 was a Sun; if (@YDAY = 1) then $adjYDay should equal 0
; ···
; if ($firstDay = 7) then 1/1 was a Sat; if (@YDAY = 1) then $adjYDay should equal 6

local $firstDay = _dateToDayOfWeek(@YEAR, 1, 1)
local $adjYDay = @YDAY + $firstDay - 2
local $week = int($adjYDay / 7) + 1

msgBox(32, "Information", "We are in week " & $week & ".")

Edit: if I have the idea of week numbers slightly wrong and Week 1 of any given year should start from the first Sunday (e.g. the first Sunday is 4/1 and so 1/1 to 3/1 is 'Week 0') then just remove the '+ 1' from the $week calculation.

Edited by LxP
Link to comment
Share on other sites

I *think* this will work:

#include <Date.au3>

$week =  1 + _DateDiff("w", @Year & "/1/1", @Year & "/" & @Mon & "/" & Number(@MDay -1 + _DateToDayOfWeek(@Year,1,1)) )
MsgBox(0,"Result", "Week# " & $week)

Edit: Well, it fails when '@MDay -1 + _DateToDayOfWeek...' exceeds 31....

Edited by CyberSlug
Use Mozilla | Take a look at My Disorganized AutoIt stuff | Very very old: AutoBuilder 11 Jan 2005 prototype I need to update my sig!
Link to comment
Share on other sites

I *think* this will work:

#include <Date.au3>

$week =  1 + _DateDiff("w", @Year & "/1/1", @Year & "/" & @Mon & "/" & Number(@MDay -1 + _DateToDayOfWeek(@Year,1,1)) )
MsgBox(0,"Result", "Week# " & $week)

Edit:  Well, it fails when '@MDay -1 + _DateToDayOfWeek...' exceeds 31....

<{POST_SNAPBACK}>

Yeah.. it works for the middle weeks of the months.. but the first and last weeks usually have problems.
Link to comment
Share on other sites

How about this:

Func _ISOWeekNumber($Day=@MDAY, $Month=@MON, $Year=@YEAR, $WeekStart=0)
    local $firstDay = _dateToDayOfWeek($Year, 1, 1)
    Local $diff
    Local $WeekStart
        
    If $firstDay = 1 Then
        $diff = 1 - $firstDay + $WeekStart
    ElseIf  $firstDay = 2 Then
        $diff = 1 - $firstDay + $WeekStart
    ElseIf $firstDay <= 5 Then
        $diff = 1-$firstDay + $WeekStart
    ElseIf $firstDay > 5 Then
        $diff = 7 - ($firstDay -1) + $WeekStart
        
    EndIf
    
    $FirstWeekStart = _DateAdd ( 'd', $diff, $Year & "/01/01")
        
    If _DateDiff('d', $FirstWeekStart, $Year & "/" & $Month & "/" & $Day) >= 0 Then
        return _DateDiff( 'w',$FirstWeekStart, $Year & "/" & $Month & "/" & $Day) +1
    Else
        return _DateDiff( 'w',$Year-1 & "/01/01", $Year & "/" & $Month & "/" & $Day)
    EndIf

Endfunc

Just quickly put together so I might have overlooked something. I tried to implement it to follow the rules in Python reference:

The ISO year consists of 52 or 53 full weeks, and where a week starts on a Monday and ends on a Sunday. The first week of an ISO year is the first (Gregorian) calendar week of a year containing a Thursday. This is called week number 1, and the ISO year of that Thursday is the same as its Gregorian year.

The only difference is that you can set the starting weekday (0= Sun, 1 = Mon).

No error checking for input values yet.

Tested with the following values:

ConsoleWrite(@CRLF & "Result 1: Current Week# " & __ISOWeekNumber())

ConsoleWrite(@CRLF & "Result 2 (Expected = W53): Week# " & _ISOWeekNumber(28,12,2004, 1))

ConsoleWrite(@CRLF & "Result 3 (Expected=W1): Week# " & _ISOWeekNumber(03,01,2001, 1))

ConsoleWrite(@CRLF & "Result 4 (Expected = W1): Week# " & _ISOWeekNumber(03,01,2002, 1))

ConsoleWrite(@CRLF & "Result 5 (Expected = W52): Week# " & _ISOWeekNumber(01,01,2006, 1))

ConsoleWrite(@CRLF & "Result 6 (Expected = W53): Week# " & _ISOWeekNumber(31,12,2004, 1))

Edit: Tested with year starting on Sunday:

ConsoleWrite(@CRLF & "Result 7 (Expected = W1): Week# " & _ISOWeekNumber(2,1,2005))

ConsoleWrite(@CR & "--------------- TEST 11 ---------------" & @CR)

ConsoleWrite(@CRLF & "Result 8 (Expected = W52): Week# " & _ISOWeekNumber(2,1,2005, 1))

Both European (correct :) ) and US way. Seems to work. Please let me know if you find any situations where this fails.

Edited by tuape
Link to comment
Share on other sites

Hi,

Tested this a lot more and it seems to work. At least with European style where week is starting from Monday.

I added some error handling and made an UDF out of this. Please try it out and make it better. I know this isn't the best code but as far as it works, I'm happy.

#include <Date.au3>
;===============================================================================
;
; Function Name:  _ISOWeekNumber()
; Description:  Find out the week number of current date OR date given in parameters
;                   
; Parameter(s):   $Day  - Day value (default = current day)
;               $Month  - Month value (default = current month)

;               $Year   - Year value (default = current year)
;               $Weekstart - Week starts from Sunday (0, default) or Monday (1)
; Requirement(s):   AutoIt3 with _Date UDF's
; Return Value(s):  On Success   - Returns week number of given date
;                  On Failure    - returns -1  and sets @ERROR = 1 on faulty parameters values
;               On non-acceptable weekstart value sets @ERROR = 99 and uses default (Sunday) as starting day
; Author(s):        Tuape
;
;===============================================================================
;
Func _ISOWeekNumber($Day=@MDAY, $Month=@MON, $Year=@YEAR, $WeekStart=0)
    local $firstDay
    Local $diff
    Local $WeekStart
    
; Check for erroneous input in $Day, $Month & $Year
    If  $Day > 31 or $Day < 1 Then 
        SetError(1)
        Return -1
    ElseIf $Month > 12 or $Month < 1 Then
        SetError(1)
        Return -1
    ElseIf $Year < 1 or $Year > 2999 Then
        SetError(1)
        Return -1
    EndIf
    
; check if $WeekStart parameter is ok (= Sun / Mon)
    If Not IsInt($WeekStart) Or $WeekStart > 1 or $WeekStart < 0 Then
        $WeekStart = 0
        SetError(99)
    EndIf
    
; Find out the first day of real week 1
    $firstDay = _dateToDayOfWeek($Year, 1, 1)
    
    If $firstDay = 1 Then
        $diff = 1 - $firstDay + $WeekStart
    ElseIf  $firstDay = 2 Then
        $diff = 1 - $firstDay + $WeekStart
    ElseIf $firstDay <= 5 Then
        $diff = 1-$firstDay + $WeekStart
    ElseIf $firstDay > 5 Then
        $diff = 7 - ($firstDay -1) + $WeekStart
        
    EndIf
    
    $FirstWeekStart = _DateAdd ( 'd', $diff, $Year & "/01/01")
    
; Compare to real first day of week 1 and find out the difference in weeks
    If _DateDiff('d', $FirstWeekStart, $Year & "/" & $Month & "/" & $Day) >= 0 Then
        return _DateDiff( 'w',$FirstWeekStart, $Year & "/" & $Month & "/" & $Day) +1
    Else
        return _DateDiff( 'w',$Year-1 & "/01/01", $Year & "/" & $Month & "/" & $Day)
    EndIf

Endfunc

Edit: I was overlooking values returned by @macros (as commented on the next post by Marc). They don't return ints. Well I think we don't even need that check anyway.

Edited by tuape
Link to comment
Share on other sites

Hi Tuape,

seems to work for me :)

One thing I had to Change is the use of "StringIsInt" instead of "IsInt",

because the macros like @mday seem to be strings, so "_IsoWeekNumber()" returned "-1".

Best regards,

Marc

Edited by Marc

Any of my own codes posted on the forum are free for use by others without any restriction of any kind. (WTFPL)

Link to comment
Share on other sites

Doh!  :)

@Marc: Thanks for noticing this. I don't think we even need that check anyway. Updated the previous post of mine. Hopefully it works also with default values now.

<{POST_SNAPBACK}>

It works really well for me too, It'd be really nice to see this make it into the Date Include functions... Edited by exodius
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...