Sign in to follow this  
Followers 0
exodius

Figuring out what week it is.

13 posts in this topic

Is there a way to figure out which week of the year (1-52) it is with AutoIt?

Share this post


Link to post
Share on other sites



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

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

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

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

#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

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

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!

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

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

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

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

It's my job to comfort the disturbed and to disturb the comfortable.
My Projects: Profiler, MakeSFX, UserInfo

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

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

Share this post


Link to post
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
Sign in to follow this  
Followers 0