Archive for the 'NSDateFormatter' Category

2017/09/22 指定日時以降に作成されたファイルをSpotlight検索 v2

指定フォルダ(Desktop)以下のファイルで、指定日時以降に作成されたものをSpotlight検索するAppleScriptです。

本ルーチンの原型は、電子書籍を作成する際にMarkdown書類(MacDown)とPages書類をまとめてPDFに出力して1つのPDFに連結するAppleScriptで使っていたものです(こういう武器がないと、電子書籍を執筆からレイアウトから何から何までひとりで行うことなんてできません)。

bookfiles2.png
Pagesはともかく、MacDownからは指定フォルダにPDFを書き出すという機能は(MacDownのAppleScript用語辞書に機能が用意されていないため)AppleScriptからは利用できませんでした。そこで、GUI Scriptingで強引にデスクトップにPDF書き出しすることに。

デスクトップに書き出させたのは、保存ダイアログ上でCommand-Dのキーボードショートカットで一意に指定できる数少ないフォルダだからです(このあたり、生活の知恵)。

GUI Scriptingでファイル保存やファイル書き出しを行う場合、保存ダイアログがどこのフォルダを指し示すかはアプリケーション側まかせなので、保存/書き出し先フォルダをデスクトップに強引に指定する処理はたいへん重要です。GUI Scriptingはたいへんに弱点が多く不確実な手段ですが、不確実さを地道につぶしてあげることで、信頼性のある処理フローを構築できます。

PDF書き出し開始時のタイムスタンプを変数に記憶させておき、その時刻以降でデスクトップに生成されたPDFをすべて取得し、ファイル名でソート(ファイル名の先頭にソート用の仮想ノンブルをつけて管理)し、(末尾に生じていた意図しない空白ページ自動削除しつつ)1つのPDFに合成していました。

そのため、日時を指定して指定フォルダに存在するファイルをSpotlight検索する本ルーチンの重要度はとても高かったわけです。

当初は日付情報をJan 1 2001 00:00:00 GMTからの相対秒(Absolute Time)で指定していたのですが、OSのバージョンアップにともないこの書き方が使えなくなったため、仕方なく対処。

本ルーチンでは指定年月日でdateオブジェクトを生成したあと、ISO8601形式の日付文字列に変換し、それをもとにShane StanleyのMetadata LibでSpotlight検索を行なっています。実行のさいには、Metadata Libを~/Library/Script Libraries/フォルダに入れておく必要があります。

AppleScript名:指定日時以降に作成されたファイルをSpotlight検索 v2
– Created 2017-09-21 by Takaaki Naganoya
– 2017 Piyomaru Software
use AppleScript version “2.5″
use framework “Foundation”
use scripting additions
use mdLib : script “Metadata Lib” version “1.0.0″
–http://piyocast.com/as/archives/4838

property NSTimeZone : a reference to current application’s NSTimeZone
property NSCalendar : a reference to current application’s NSCalendar
property NSDateFormatter : a reference to current application’s NSDateFormatter

set aDate to getDateInternationalYMDhms(2017, 9, 21, 23, 2, 0) of me
–>  date “2017年9月21日木曜日 23:02:00″

set bStr to retISO8601DateTimeString(aDate) as string
–>  ”2017-09-21T14:02:00Z”

set thePath to POSIX path of (path to desktop)

set theFiles to mdLib’s searchFolders:{thePath} searchString:(“kMDItemFSCreationDate >= ’$time.iso(\”" & bStr & “\”)’”) searchArgs:{}
–> returns POSIX path list

–NSDate -> ISO8601 Date & Time String
on retISO8601DateTimeString(targDate)
  set theNSDateFormatter to NSDateFormatter’s alloc()’s init()
  
theNSDateFormatter’s setDateFormat:“yyyy-MM-dd’T’HH:mm:ss’Z’”
  
theNSDateFormatter’s setTimeZone:(NSTimeZone’s alloc()’s initWithName:“UTC”)
  
return (theNSDateFormatter’s stringFromDate:targDate) as text
end retISO8601DateTimeString

–現在のカレンダーで指定年月のdate objectを返す(年、月、日、時、分、秒)
on getDateInternationalYMDhms(aYear, aMonth, aDay, anHour, aMinute, aSecond)
  set theNSCalendar to NSCalendar’s currentCalendar()
  
set theDate to theNSCalendar’s dateWithEra:1 |year|:aYear |month|:aMonth |day|:aDay hour:anHour minute:aMinute |second|:aSecond nanosecond:0
  
return theDate as date
end getDateInternationalYMDhms

★Click Here to Open This Script 

2016/04/13 ISO8601日付文字列を生成

NSDateからISO8601日付文字列を生成するAppleScriptです。

昨日のGHKitによるISO8601日付文字列ではいまひとつDropbox側と仕様が合わず、ちょっと困ってしまいました。

いくつものXcode Projectをgithub上で探してビルドしては捨て、捨ててはビルドしての繰り返しをしていました。ソースが古いとARC対応していなかったりして、かなり書き換える必要が生じてしまいます。

が、そもそも別にそんなたいしたものでもないので(^ー^;; 「自分で書いた方が簡単なんじゃないの?」と気付き、さらっと書きました。

これで、REST API経由でAppleScriptからDropboxを小突きまわして、ファイル共有期限の日時指定を行えます。

AppleScript名:ISO8601日付文字列を生成
– Created 2016-04-13 by Takaaki Naganoya
– 2016 Piyomaru Software
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use BridgePlust : script “BridgePlus” –for OS X 10.10.x

set aDate to (current date) + 3 * days
set bDate to Cocoaify aDate
set bStr to retISO8601DateTimeString(aDate) as string
–> “2016-04-16T09:23:11Z”

–NSDate -> ISO8601 Date & Time String for Dropbox
on retISO8601DateTimeString(targDate)
  set theNSDateFormatter to current application’s NSDateFormatter’s alloc()’s init()
  
theNSDateFormatter’s setDateFormat:“yyyy-MM-dd’T’HH:mm:ss’Z’”
  
theNSDateFormatter’s setTimeZone:(current application’s NSTimeZone’s alloc()’s initWithName:“UTC”)
  
return (theNSDateFormatter’s stringFromDate:targDate) as text
end retISO8601DateTimeString

★Click Here to Open This Script 

2015/02/25 Conversion between UTCTime String and NSDate

Conversion ASOC script between UTCTime String (with milli-seconds) and NSDate.

In US Apple’s AppleScript Users ML, I saw the thread “UTC time with milliseconds”.

They talk about only current date -> UTCTime string (with milli-seconds) . And there is no care of each time zone.

So, I added time zone consideration and reverse conversion handler.

Reverse conversion (UTCTime string -> NSDate) does not need to get users time zone, I think.

Ole Begemann’s Working with Date and Time in Cocoa was very useful and helpful for me.

Shane Stanley taught me this is not right. Oh! my Buddha! (something like God..)

I misunderstood the definition of the word “UTCTime”. I meant it as a time string. So, I’ll fix this later. Hmm..I don’t need to get “UTCTime” string….Is there any need to get it?

AppleScript名:UTCTime StringとNSDateの相互変換
– Created 2015-02-24 by Shane Stanley
– Changed 2015-02-25 By Takaaki Naganoya
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”

set aStr to retUTCTimeString()
–>   “2015-02-25T13:49:55.713″

set aNSDate to retNSDateFromUTCString(aStr)
–>  (NSDate) 2015-02-25 13:49:55 +0000 –ASObjC Explorer
–> «class ocid» id «data optr0000000030F7400000600000» –Apple’s Script Editor

–Current Date -> UTCTime String
on retUTCTimeString()
  –There is need to get Current Calendar in my Time Zone
  
set aCalendar to current application’s NSCalendar’s currentCalendar()
  
set aTimeZone to (aCalendar’s timeZone)
  
set tDiff to (aTimeZone’s secondsFromGMT())
  
  
set theNSDateFormatter to current application’s NSDateFormatter’s alloc()’s init()
  
  
theNSDateFormatter’s setDateFormat:“yyyy-MM-dd’T’HH:mm:ss.SSS”
  
theNSDateFormatter’s setTimeZone:(current application’s NSTimeZone’s timeZoneForSecondsFromGMT:tDiff)
  
  
return (theNSDateFormatter’s stringFromDate:(current application’s NSDate’s |date|())) as text
end retUTCTimeString

–UTCTime String -> NSDate
on retNSDateFromUTCString(aText)
  set aStr to current application’s NSString’s stringWithString:aText
  
  
set theNSDateFormatter to current application’s NSDateFormatter’s alloc()’s init()
  
theNSDateFormatter’s setDateFormat:“yyyy-MM-dd’T’HH:mm:ss.SSS”
  
theNSDateFormatter’s setTimeZone:(current application’s NSTimeZone’s timeZoneForSecondsFromGMT:0)
  
  
return theNSDateFormatter’s dateFromString:aStr
end retNSDateFromUTCString

★Click Here to Open This Script 

2014/12/16 指定ロケールの月名、曜日名を取得する

指定ロケールの月名、曜日名を取得するAppleScriptです。

曜日名などはローカライズされた呼称がけっこう言語ごとに異なるので、重要です。香港のクライアントと仕事をしたときに、1週間の開始曜日が月曜日だったのと、曜日が中国語の(漢字なのに)異なる表記で驚かされました。

OS X自体がサポートしている言語の数だけ月および曜日呼称を取得できるはずですが、話者人口が少ない言語だと英語表記がそのまま表示されるかもしれません。

AppleScript名:指定ロケールの月名、曜日名を取得する
– Created 2014-01-26 Shane Stanley
use AppleScript version “2.4″
use scripting additions
use framework “Foundation”
use framework “ASObjCExtras”

set mList to monthNames(“ja”) –Japanese
–> {”1月”, “2月”, “3月”, “4月”, “5月”, “6月”, “7月”, “8月”, “9月”, “10月”, “11月”, “12月”}

set mList to monthNames(“zh_CN”) –Chinese
–> {”一月”, “二月”, “三月”, “四月”, “五月”, “六月”, “七月”, “八月”, “九月”, “十月”, “十一月”, “十二月”}

set mList to monthNames(“us”) –US English
–> {”January”, “February”, “March”, “April”, “May”, “June”, “July”, “August”, “September”, “October”, “November”, “December”}

set mList to monthNames(“fr”) –French
–> {”janvier”, “février”, “mars”, “avril”, “mai”, “juin”, “juillet”, “août”, “septembre”, “octobre”, “novembre”, “décembre”}

set mList to monthNames(“ru”) –Russian
–> {”января”, “февраля”, “марта”, “апреля”, “мая”, “июня”, “июля”, “августа”, “сентября”, “октября”, “ноября”, “декабря”}

set dList to dayNames(“ja”) –Japanese
–> {”日曜日”, “月曜日”, “火曜日”, “水曜日”, “木曜日”, “金曜日”, “土曜日”}

set dList to dayNames(“zh_CN”) –Chinese
–> {”星期日”, “星期一”, “星期二”, “星期三”, “星期四”, “星期五”, “星期六”}

set dList to dayNames(“us”) –US English
–> {”Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”}

set dList to dayNames(“fr”) –French
–> {”dimanche”, “lundi”, “mardi”, “mercredi”, “jeudi”, “vendredi”, “samedi”}

set dList to dayNames(“ru”) –Russian
–> {”воскресенье”, “понедельник”, “вторник”, “среда”, “четверг”, “пятница”, “суббота”}

on monthNames(aLocStr as string)
  set fm to current application’s NSDateFormatter’s new()
  
fm’s setLocale:(current application’s NSLocale’s localeWithLocaleIdentifier:aLocStr)
  
return fm’s monthSymbols() as list
end monthNames

on dayNames(aLocStr as string)
  set fm to current application’s NSDateFormatter’s new()
  
fm’s setLocale:(current application’s NSLocale’s localeWithLocaleIdentifier:aLocStr)
  
return fm’s weekdaySymbols() as list
end dayNames

★Click Here to Open This Script