I need to work with dates in string format and later, to compare the dates, I convert to Date again but I’m getting this error:
Can’t make «script» into type string. (error -1700)
I’m using xcode 3.2
Here is a small code I made to test this:
script testdateAppDelegate
on applicationWillFinishLaunching_(aNotification)
set now to (current date) + 4 * hours
-- convert to string
set nowString to now as string
-- and back to Date
set newNow to date nowString
if newNow > (current date) then -- I got the error here
log ("greater than")
end if
end applicationWillFinishLaunching_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return my NSTerminateNow
end applicationShouldTerminate_
end script
It looks like forming dates from a string is broken in ASObjC – if you add “log class of NewNow” after “set newNow to date nowString”, you’ll see it’s returning a script object rather than a date. Log it as a bug.
Having said that, forming dates from strings is a pretty fragile business in 10.6; it fails if the format is not exactly right. Is there some reason you need to convert to and from text?
Thanks for your response, I better look another way.
Well yeah, I need to save the date into user defaults but in a previous test using setObject_forKey_ I can’t save the date directly, that is why i take the road to convert to string. I think that I need to look again over there.
[i]Defaults are grouped in domains. Each domain has a name by which it’s identified and stores defaults as key-value pairs in an NSDictionary object. Each default is made up of three components:
The domain in which the default is stored
The name by which the default is identified (an NSString object)
The default’s value, which can be any property-list object (NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary)[/i]
The problem is that NSDate and AS dates aren’t interchangeable. If the OP can use NSDates from the start, there’ll be no problem, but if they need dates in AS, it will still be complicated.
Thanks for your responses. This make perfectly sense to me, I’m now changing my logic to use NSDate as my internal Date representation and use Shane’s code from another post to convert to AS Dates as needed to show in the user interface.
again thanks to Shane and Stefan for the guidelines, here my final code:
script testdateAppDelegate
property NSUserDefaults : class "NSUserDefaults" of current application
on applicationWillFinishLaunching_(aNotification)
set Expiration to readPrefs("Expiration")
set now to current application's class "NSDate"'s |date|()
if now's compare_(Expiration) is current application's NSOrderedDescending then
set Expiration to now's dateByAddingTimeInterval_(4 * 60 * 60) --Expiration is 4 hour in the future
savePref("Expiration", Expiration)
log ("greater than" & ASDate(Expiration))
-- Code when time expire
else
log ("Lower or equal")
-- Code when not expire
end if
end applicationWillFinishLaunching_
on applicationShouldTerminate_(sender)
-- Insert code here to do any housekeeping before your application quits
return my NSTerminateNow
end applicationShouldTerminate_
on ASDate(theDate)
-- Created by Shane Stanley
set theCal to current application's class "NSCalendar"'s currentCalendar()
set theComponents to theCal's components_fromDate_(254, theDate)
--The 254 is a mask for which components we want the result to contain; 254 means year, month, day, hour, minute, second, but there are others.
--The NSDateComponents class has methods for extracting the components individually, so
set theYear to theComponents's |year|()
set theMonth to theComponents's |month|()
set theDay to theComponents's |day|()
set theHour to theComponents's hour()
set theMinute to theComponents's minute()
set theSecond to theComponents's |second|()
--Now you need to make an AS date, and set the various components:
set theDate to current date
set day of theDate to 1 -- important
set seconds of theDate to theSecond
set year of theDate to theYear
set month of theDate to theMonth
set day of theDate to theDay
set hours of theDate to theHour
set minutes of theDate to theMinute
return theDate as text
end ASDate
on savePref(thePrefName, thePrefValue)
tell NSUserDefaults
tell its standardUserDefaults()
its setObject_forKey_(thePrefValue, thePrefName)
end tell
end tell
end savePref
on readPrefs(thePrefName)
tell NSUserDefaults
tell its standardUserDefaults()
set returnPref to its objectForKey_(thePrefName)
end tell
end tell
return returnPref
end readPrefs
end script
You can also go from NSDate to AS date in fewer lines based on an approach Chris Nebel suggested:
set theDiff to theDate's timeIntervalSinceReferenceDate()
set ASDate to (date "Monday, January 1, 2001 12:00:00 AM") + theDiff div 1 + (time to GMT) -- date string will need to match your settings
That was buggy before 10.6.2 when run as 64-bit, but seems OK in 10.6.2.
The other thing probably worth mentioning is that you can, in a long-winded fashion, use the enumerations in the mask rather than “magic” numbers like 254. I’m not sure if this is something new in 10.6.2, or something I just missed in earlier versions. So this:
set theComponents to theCal's components_fromDate_(254, theDate)
becomes something like:
set theComponents to theCal's ¬
components_fromDate_((current application's NSYearCalendarUnit as integer) ¬
+ (current application's NSMonthCalendarUnit as integer) ¬
+ (current application's NSDayCalendarUnit as integer) ¬
+ (current application's NSHourCalendarUnit as integer) ¬
+ (current application's NSMinuteCalendarUnit as integer) ¬
+ (current application's NSSecondCalendarUnit as integer) ¬
, theDate)
That’s a lot more typing, but it’s also much more readable code.
I see that approach too, but not used because the comment about 64-bit issue. Anyway the code is working so far and see pretty safe to me, so I will stay with the longer version.
if now's compare_(Expiration) is current application's NSOrderedDescending then --Not Working
set Expiration to now's dateByAddingTimeInterval_(4 * 60 * 60) --Expiration is 4 hour in the future
savePref("Expiration", Expiration)
log ("greater than" & ASDate(Expiration))
-- Code when time expire
instead of current application’s NSOrderedDescending I write 1 then works, must be obvious but I don’t get it
EDIT: seem like is working on 10.6.2, tomorrow I’m going to check what version have on the macbook because there is where is not woking