date - Date of the Day for the week num

Hey all,

was wondering if someone could help me figure out what’s the best way to do this:

overview:

  1. you specify a week of the year
  2. choose which day
  3. the year
  4. it find the day in that week and outputs the date

inputs:
#1----1, 2, 34, 23, 52 (week number in the year)
#2----Monday, Wednesday (Day of the week)
#3----1999, 2004, 2005 (year)

example:
input:
#1----2
#2----Monday
#3----2011

output:
1/3/11

saw this solution: https://secure.macscripter.net/viewtopic.php?id=32496

i get an error on 10.7.1. any help would be appreciated

-- Assuming the ISO standard that weeks begin on Mondays and
-- that the first week of the year is the one containing 4th January,
-- although that might begin in the previous calendar year.

-- Easily adapted for other week-start conventions.

on getdatesforweeknum(yearNum, weekNum)
   set Jan4 to date "Tuesday 4 January 2000 00:00:00" -- Or 4th January in any year after 1582.
   set Jan4's year to yearNum -- Make that 4th January in the given year.
   set baseMonday to date "Monday 3 January 2000 00:00:00" -- Or any Monday in the past.
   
   -- Derive the beginning of the week containing 4th January in the given year.
   set week1Start to Jan4 - (Jan4 - baseMonday) mod weeks
   -- . and from that, the beginning of the weekNumth week.
   set weekNStart to week1Start + (weekNum - 1) * weeks
   
   set datesInWeek to {}
   repeat with i from 0 to 6 * days by days
       set end of datesInWeek to weekNStart + i
   end repeat
   
   return datesInWeek
end getdatesforweeknum

getdatesforweeknum(2010, 52)

Answered in response to your query in that thread. Just to add here that when you complain that you “get an error”, you should say what it is! :slight_smile:

By the way, just out of curiosity, where did you get that “secure” url? I normally only see “http://macscripter.net/…”

Hello Nigel

The script assume that the hosting machine is running in English.
Maybe it’s what is the wrongdoer on the asker’s machine.
Here is a slightly modified version which isn’t localization dependent.


-- Assuming the ISO standard that weeks begin on Mondays and
-- that the first week of the year is the one containing 4th January,
-- although that might begin in the previous calendar year.

-- Easily adapted for other week-start conventions.

on getdatesforweeknum(yearNum, weekNum)
	set Jan4 to date (short date string of (current date))
	set day of Jan4 to 4
	set month of Jan4 to 1
	set year of Jan4 to 2000
	--log Jan4
--> (*date mardi 4 janvier 2000 00:00:00*)
	set baseMonday to Jan4 - 1 -- Or any Monday in the past.
	--log baseMonday
--> (*date lundi 3 janvier 2000 23:59:59*)
	set Jan4's year to yearNum -- Make that 4th January in the given year.
	--log Jan4
--> (*date lundi 4 janvier 2010 00:00:00*)
	-- Derive the beginning of the week containing 4th January in the given year.
	set week1Start to Jan4 - (Jan4 - baseMonday) mod weeks
	-- . and from that, the beginning of the weekNumth week.
	set weekNStart to week1Start + (weekNum - 1) * weeks
	
	set datesInWeek to {}
	repeat with i from 0 to 6 * days by days
		set end of datesInWeek to weekNStart + i
	end repeat
	
	return datesInWeek
end getdatesforweeknum

getdatesforweeknum(2010, 52)


Of course you may remove the log instructions which I inserted to check that everything was OK.

Yvan KOENIG (VALLAURIS, France) mercredi 5 octobre 2011 12:02:59

Thanks, Yvan.

Actually, my code assumes that the script will be compiled on a machine with the same Date and Time preferences as my own. Once it’s compiled, the script’s good anywhere, with no need to call the ‘current date’ function at run time, create a new date from its ‘short date string’, and perform three settings to change the value of that date.

Another possibility is:

set Jan4 to «data isot323030302D30312D3034» as date

This was briefly fashionable here a few years ago, but dropped out of favour because it’s not an official AppleScript coercion and may cease to work at any time. The numbers in the data object are hexadecimal representations of the ASCII codes for “20000104”.

For tidiness, I’d prefer this for your derivation of ‘baseMonday’:

set baseMonday to Jan4 - days

Edit: In fact:


-- Assuming the ISO standard that weeks begin on Mondays and
-- that the first week of the year is the one containing 4th January,
-- although that might begin in the previous calendar year.

-- Easily adapted for other week-start conventions.

on getdatesforweeknum(yearNum, weekNum)
	tell (current date) to set {day, its month, year, time, baseMonday} to {3, January, 2000, 0, it} -- A known Monday in the past.
	
	set Jan4 to baseMonday + days
	set Jan4's year to yearNum -- Make that 4th January in the given year.
	
	-- Derive the beginning of the week containing 4th January in the given year.
	set week1Start to Jan4 - (Jan4 - baseMonday) mod weeks
	-- . and from that, the beginning of the weekNumth week.
	set weekNStart to week1Start + (weekNum - 1) * weeks
	
	set datesInWeek to {}
	repeat with i from 0 to 6 * days by days
		set end of datesInWeek to weekNStart + i
	end repeat
	
	return datesInWeek
end getdatesforweeknum

getdatesforweeknum(2010, 52)

Just something similar I use

getDateFromYearByWeekNumAndDayInWeek(2011, 2, 0)

on getDateFromYearByWeekNumAndDayInWeek(theYear, weekNum, dayInWeek)
	--Accoring to ISO and NEN: week start at monday and week 1 is the week with 4th of jan
	--According to US: week starts at sunday and  week 2 if the week with 1st of jan
	
	--change the following line in chronologic order when the week starts on another day, in US for instance
	set aWeek to {Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}
	--change this value to 7 (Any day of week) when you want US
	set dayInWeekMustJan1 to 4
	
	set theDate to date ("01/01/" & theYear) --first of januari of given year
	
	repeat with DoW from 0 to 6
		if item (DoW + 1) of aWeek = weekday of theDate then exit repeat
	end repeat
	
	if DoW as integer < dayInWeekMustJan1 then
		set weekNum to weekNum - 1
	end if
	
	set theDate to theDate + (weekNum * 7 * 24 * 60 * 60) + ((dayInWeek - DoW) * 24 * 60 * 60)
	
	return theDate
end getDateFromYearByWeekNumAndDayInWeek

As you can see it returns a date object but for the rest it is an answer to TS’s question. As the settings are now it is ISO but you can easily change this handler. Or even with an extra parameter how the week numbers should work.

EDIT: parameter DayInWeek needs to be from 0 - 6 where 0 is equal to to the first day of week depending how ‘aWeek’ is defined

Very interesting, DJ. :slight_smile:

If you’re interested, AppleScript’s weekdays are coercible to integer, both explicitly and implicitly. (Sunday → 1, Saturday → 7.) Your weekday list and repeat could thus be replaced with some date arithmetic:

getDateFromYearByWeekNumAndDayInWeek(2011, 2, 2)

on getDateFromYearByWeekNumAndDayInWeek(theYear, weekNum, dayInWeek)
	--Accoring to ISO and NEN: week start at monday and week 1 is the week with 4th of jan
	--According to US: week starts at sunday and  week 2 if the week with 1st of jan
	
	-- Change this to your preferred week-start day.
	set weekStart to Monday
	--change this value to 7 (Any day of week) when you want US
	set dayInWeekMustJan1 to 4
	
	set theDate to date ("01/01/" & theYear) --first of januari of given year
	
	set DoW to ((theDate's weekday) - weekStart + 7) mod 7
	
	if DoW < dayInWeekMustJan1 then
		set weekNum to weekNum - 1
	end if
	
	set theDate to theDate + (weekNum * weeks) + ((dayInWeek - DoW) * days)
	
	return theDate
end getDateFromYearByWeekNumAndDayInWeek

I think it would be nicer to be able to specify ‘dayInWeek’ as a integer from 1 to 7 and let the handler itself make any necessary adjustments, but I haven’t interfered with that. :slight_smile:

Thanks Nigel! It’s always a pleasure when you’re around in a discussion/topic. Keeps me sharp and point em sometimes in direction I never thought of. I’m fascinated how you came op with the arithmetic for DoW. Now I’ve seen it, it’s simple, but like most things “ understanding or creating something are two huge differences.

The reason I use 0 - 6 is that I created the handler that I posted here comes originally from an older handler I’ve used in software before “ there is no special reason in this case.

Developing the mathematics still further. :slight_smile:


getDateFromYearByWeekNumAndDayInWeek(2011, 2, 2)

-- Based on a handler by "DJ Bazzie Wazzie". In this version, the weekNum and dayInWeek parameters number from 1. (They numbered from 0 in the original.)
on getDateFromYearByWeekNumAndDayInWeek(theYear, weekNum, dayInWeek)
	--According to ISO and NEN: week start at monday and week 1 is the week with 4th of jan
	--According to US: week starts at sunday and week 1 if the week with 1st of jan
	-- According to much of the Middle East: week starts on Saturday and week 1 contains 1st of Jan.
	
	-- Change this to the preferred week-start day.
	set weekStart to Monday
	--change this value to 1 when you want US or Middle East (much of the).
	set JanuaryDayInWeek1 to 4
	
	tell (current date) to set {its day, its month, its year, its time, knownDateInWeek1} to {JanuaryDayInWeek1, January, theYear, 0, it}
	
	set yearStart to knownDateInWeek1 - (((knownDateInWeek1's weekday) - weekStart + 7) mod 7) * days
	
	set theDate to yearStart + (weekNum - 1) * weeks + (dayInWeek - 1) * days
	
	return theDate
end getDateFromYearByWeekNumAndDayInWeek

. which can of course be further reduced to .


getDateFromYearByWeekNumAndDayInWeek(2011, 2, 2)

-- Based on a handler by "DJ Bazzie Wazzie". In this version, the weekNum and dayInWeek parameters number from 1. (They numbered from 0 in the original.)
on getDateFromYearByWeekNumAndDayInWeek(theYear, weekNum, dayInWeek)
	--According to ISO and NEN: week start at monday and week 1 is the week with 4th of jan
	--According to US: week starts at sunday and week 1 if the week with 1st of jan
	-- According to much of the Middle East: week starts on Saturday and week 1 contains 1st of Jan.
	
	-- Change this to the preferred week-start day.
	set weekStart to Monday
	--change this value to 1 when you want US or Middle East (much of the).
	set JanuaryDayInWeek1 to 4
	
	tell (current date) to set {its day, its month, its year, its time, knownDateInWeek1} to {JanuaryDayInWeek1, January, theYear, 0, it}
	
	return knownDateInWeek1 + (weekNum * 7 + dayInWeek - 8 - ((knownDateInWeek1's weekday) - weekStart + 7) mod 7) * days
end getDateFromYearByWeekNumAndDayInWeek

. or perversely .


getDateFromYearByWeekNumAndDayInWeek(2011, 2, 2)

-- Based on a handler by "DJ Bazzie Wazzie". In this version, the weekNum and dayInWeek parameters number from 1. (They numbered from 0 in the original.)
on getDateFromYearByWeekNumAndDayInWeek(theYear, weekNum, dayInWeek)
	--According to ISO and NEN: week start at monday and week 1 is the week with 4th of jan
	--According to US: week starts at sunday and week 1 if the week with 1st of jan
	-- According to much of the Middle East: week starts on Saturday and week 1 contains 1st of Jan.
	
	-- Change this to the preferred week-start day.
	set weekStart to Monday
	--change this value to 1 when you want US or Middle East (much of the).
	set JanuaryDayInWeek1 to 4
	
	tell (current date)
		set {its day, its month, its year, its time} to {JanuaryDayInWeek1, January, theYear, 0}
		return it + (weekNum * 7 + dayInWeek - 8 - ((its weekday) - weekStart + 7) mod 7) * days
	end tell
end getDateFromYearByWeekNumAndDayInWeek

fascinating as always :smiley:

:applause: Truly a great piece of work!