Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typeLongDateTime suggested fix #5

Open
ronzo99 opened this issue Jun 16, 2021 · 4 comments
Open

typeLongDateTime suggested fix #5

ronzo99 opened this issue Jun 16, 2021 · 4 comments

Comments

@ronzo99
Copy link

ronzo99 commented Jun 16, 2021

A couple of tweaks to handle AppleScript typeLongDateTime:

  1. unpackAsDate calls unpackAsInteger, which does not handle typeLongDateTime. Add to unpackAsInteger:
    case typeLongDateTime:
        result = T(exactly: Int64(bigEndian: try decodeFixedWidthValue(descriptor.data)))

or alternatively modify existing case:

    case typeSInt64, typeLongDateTime:
        result = T(exactly: Int64(bigEndian: try decodeFixedWidthValue(descriptor.data)))
  1. now that unpackAsDate has computed the TimeInterval delta, fix a bug in the return statement, changing + to -:

    return Date(timeIntervalSinceReferenceDate: delta - epochDelta)

  2. test with a folder on the desktop:

let finder = Finder()
print(try finder.folders["TEMP"].creationDate.get())
  1. perhaps a better name for "delta" might be "secondsSince1904"?
@tobi-mb
Copy link

tobi-mb commented Jun 16, 2023

@ronzo99 @hhas Just stumbled upon this bug, looking for a solution and found your old issue. Thank you for posting! I'd like to add to that that I've noticed yet another bug, related to time zones.

As odd as it may seem, it seems to me that AppleScript returns a timestamp relative to the user's (or processes?) time zone and not in UTC. It feels quite wrong to do the following but maybe this is just a flaw in AppleScript/AppleEvents itself? So what I did is change the return statement to:

return Date(timeIntervalSinceReferenceDate: delta - epochDelta - TimeInterval(TimeZone.current.secondsFromGMT()))

to account for the time zone offset already included in delta.

Isn't it possible for a macOS process to have a different time zone set than the system? If so, this code is going to break and I would have no idea how to convert it back to UTC.

Edit: Just looked up the private implementation of -[NSAppleEventDescriptor dateValue] in Foundation and it converts the timestamp from the descriptor, calling UCConvertLongDateTimeToCFAbsoluteTime which, implemented in CarbonCore uses CFTimeZoneGetSecondsFromGMT(CFTimeZoneCopyDefault() …) and then creates the date object from the resulting timestamp via +[NSDate dateWithTimeIntervalSinceReferenceDate:] 😅. So turns out this is in fact the correct approach!

@ronzo99
Copy link
Author

ronzo99 commented Jun 17, 2023

Great sleuthing! I wonder if @hhas has abandoned this project now, like so many others? Either way, I’ve found his source code very instructive for coding my own AppleScript support.

@tobi-mb
Copy link

tobi-mb commented Jun 17, 2023

@ronzo99 Could you elaborate on why SwiftAutomation didn't meet your requirements and what your own code does better now? I'm considering using it for production code at the moment.

@ronzo99
Copy link
Author

ronzo99 commented Jun 17, 2023

@tobi-mb I was looking at it when I was thinking of converting some ObjC + ScriptingBridge automation code to Swift. I found Swift Automation worked as expected, but eventually decided not to rewrite my code in Swift. Good luck with your project!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants