Weekday date component from Objective C's Foundation

Attempting to return a weekend date component from Objective C’s Foundation via AppleScript, I can derive a year, month, day, but not a weekday.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
set aString to "03-31-2019"
set anNSDate to my getDatesIn:aString
set theCal to current application's class "NSCalendar"'s currentCalendar()
set theComponents to theCal's components:254 fromDate:anNSDate
set y to theComponents's |year|()
set m to theComponents's |month|()
set d to theComponents's |day|()
set wkd to theComponents's |weekday|()
{y, m, d}-->returns {2019, 3, 31}
{wkd}--> returns {9.22337203685478E+18}
set DateFormatter to current application's NSDateFormatter's new()
DateFormatter's setDateFormat:"EEEE"
set wkd to (DateFormatter's stringFromDate:anNSDate) as text
{wkd}--> returns {"Monday"}


on getDatesIn:aString
	# Convert string to NSString 
	set anNSString to current application's NSString's stringWithString:aString
	# Create data detector
	set theDetector to current application's NSDataDetector's dataDetectorWithTypes:(current application's NSTextCheckingTypeDate) |error|:(missing value)
	# Find first match in string; returns an NSTextCheckingResult object
	set theMatch to theDetector's firstMatchInString:anNSString options:0 range:{0, anNSString's |length|()}
	# Get the date property of the NSTextCheckingResult
	set anNSDate to theMatch's |date|()
end getDatesIn:

  1. As the above weekday component returns 9.22337203685478E+18, from component bit mask 254, what mask number or flag will return a weekday value, in addition to year, month and day?
  2. Would defining a string from DateFormatter’s setDateFormat method, and returning the weekday and the other components as text provide a better method?

The value you pass in components:fromDate: has to reflect the components you want. NSCalendarUnitWeekday is equal to 512, so use:

set theComponents to theCal's components:766 fromDate:anNSDate

Shane,
Thanks for your insight on the bit mask number. Although I do understand your method of addition, I do not understand how the integer 254 was derived.

In regard to my prior second question, I thought that one of your 2016 macsripter postings at https://macscripter.net/viewtopic.php?id=45406 , might provide a more concise method of listing date components from an instance of an NSDate:

set DateFormatter to current application's NSDateFormatter's new()
	DateFormatter's setDateFormat:"EEEE yyyy-MM-dd"
	set {wkd, y4, m2, d2} to {word 1, word 2, word 3, word 4} of ((DateFormatter's stringFromDate:anNSDate) as text)
       -->returns {"Sunday", "2019", "03", "31"}

It was presumably based on the code you copied it from, which was probably looking for different values.

You can do it the long way:

set theComponents to theCal's components:((current application's NSCalendarUnitYear) + (get current application's NSCalendarUnitMonth) + (get current application's NSCalendarUnitDay) + (get current application's NSCalendarUnitWeekday)) fromDate:anNSDate

But if you just run:

((current application's NSCalendarUnitYear) + (get current application's NSCalendarUnitMonth) + (get current application's NSCalendarUnitDay) + (get current application's NSCalendarUnitWeekday))

you can use the resulting value for the sake of brevity (and some efficiency). It looks like the original code was also getting some other unit, but the above returns 540.

It might be more concise, but it’s less efficient – and considerably uglier.

Shane,
I appreciate all of your explanations. I now have a much better understanding of Foundation’s date components, NSCalendarUnit bit mask formulation, and two methods of deriving components of an NSDate.
Thank you.

The original value was containing the value of NSCalendarUnitHour (32)

I wish to add that we may use the names with a bit of caution.
When Shane wrote Everyday AppleScriptObjC 3ed, the correct spelling was

NSCalendarUnit
which is now deprecated and replaced by
NSCalendarUnit

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

(get current application's NSCalendarUnitEra) --> 2
log result
(get current application's NSCalendarUnitYear) --> 4
log result
(get current application's NSCalendarUnitMonth) --> 8
log result
(get current application's NSCalendarUnitDay) --> 16
log result
(get current application's NSCalendarUnitHour) --> 32
log result
(get current application's NSCalendarUnitMinute) --> 64
log result
(get current application's NSCalendarUnitSecond) --> 128
log result
(get current application's NSCalendarUnitWeekday) --> 512
log result
(get current application's NSCalendarUnitQuarter) --> 2048
log result

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 1 avril 2019 10:04:03

It’s worth keeping in mind that these enum deprecations are fairly soft, and if you use the new versions, the resulting scripts will not run under older versions of the OS.

That’s why Script Debugger offers the ability to define enums as properties. Doing so means they work, regardless of what version you run them under, because the value comes from the script rather than being queried at run-time.