Archive for the '日付、カレンダー関連(calendar)' Category

02/25 自然言語による相対日付指定v13

自然言語による相対日付の指定を処理するためのAppleScriptです。

すべてAppleScriptで記述した人工知能インタフェース「Newt On」(10年以上前に開発)のカレンダー処理モジュール(Calendar Scripting)用に作成しておいたものです。「来週の水曜日」「先々週の金曜日」といった自然言語による相対的な日付計算を行うためのプログラムです。

 「日」ベースの相対パラメータ「今日」「昨日」「一昨日」「一昨々日」/「明日」「明後日」「明々後日」
 「週」ベースの相対パラメータ「今週」「先週」「先々週」/「来週」「再来週」
 汎用相対パラメータ「次」「前」「今度」「こんど」

などを受け付けます。日本語処理を前提としているため、日本語に多い「同義語」に対処すべく{”次”, “今度”, “こんど”, “つぎ”}などのように柔軟に対処できるようデータ部分を定義してあります。

ただし、このバージョンでは「月」「年」単位での処理、および日本の祝日やイベント日などについては処理を行っていません(作り直している途中だったので)。

 set aDate to calcDate(”来週”, “金曜”) of me

などのようにパラメータを与えて呼び出すと、実際の日付情報を計算して返してくれるので便利です。Mac OS X 10.2とか10.3の頃に作成しておいたものなので、久しぶりに引っ張り出してきて十分に動作チェックを行っていない状態。思わぬ動作をする可能性があります。何か、不具合があればお知らせください。

スクリプト名:自然言語による相対日付指定v13
–The Calendar Scripting Module

global d3List –3か月カレンダーの格納変数
global d4List –3か月カレンダーBの格納変数(当月の情報しか日付は入っていないカレンダー)
global weekCounter – 今日が3か月カレンダーの何週目にあたるか

set aDate to calcDate(“今日”, “”) of me
display dialog aDate as text

set aDate to calcDate(“先々週”, “水曜日”) of me
display dialog aDate as text

set aDate to calcDate(“来週”, “金曜”) of me
display dialog aDate as text

on calcDate(param1, param2)
  
  
–相対日付指定パラメータテーブル
  
–data sample: {{”今日”, “きょう”}, 0, “date”}
  
–data format:{{”keyword_1″, “keyword_2″….”keyword_n”}, vector, “class_of_this_keyword”}
  
  
–Vector量をその場で算出する必要がある場合には「999」を設定しておく
  
  
set dDat to {{{“来年”}, 1, “year”}, {{“今年”}, 0, “year”}, {{“去年”}, -1, “year”}, {{“再来年”}, 2, “year”}, {{“今週”}, 0, “week”}, {{“先週”}, -1, “week”}, {{“先々週”}, -2, “week”}, {{“来週”}, 1, “week”}, {{“再来週”}, 2, “week”}, {{“今日”, “きょう”}, 0, “date”}, {{“明日”, “あした”}, 1, “date”}, {{“明後日”, “あさって”}, 2, “date”}, {{“明々後日”, “しあさって”}, 3, “date”}, {{“昨日”, “きのう”}, -1, “date”}, {{“一昨日”, “おととい”}, -2, “date”}, {{“一昨々日”, “さきおととい”}, -3, “date”}, {{“次”, “今度”, “こんど”, “つぎ”}, 1, “variable”}, {{“前”}, -1, “variable”}}
  
  
–曜日指定パラメータ
  
set wDat to {“日曜日”, “月曜日”, “火曜日”, “水曜日”, “木曜日”, “金曜日”, “土曜日”, “日曜”, “月曜”, “火曜”, “水曜”, “木曜”, “金曜”, “土曜”, “にちようび”, “げつようび”, “かようび”, “すいようび”, “もくようび”, “きんようび”, “どようび”, “にちよう”, “げつよう”, “かよう”, “すいよう”, “もくよう”, “きんよう”, “どよう”}
  
  
–3か月カレンダーを作成
  
makeCalendar() of me
  
  
–今日の日付を保持
  
set todayDate to current date
  
–指定週の計算用ワーク変数
  
set targetWeek to 0
  
–指定月の計算用ワーク変数
  
set targetMonth to month of todayDate as number
  
set targetYear to year of todayDate
  
set targetDate to day of todayDate
  
  
set aItem to “”
  
repeat with i in dDat
    if param1 is in item 1 of i then
      copy i to aItem
      
log i
      
exit repeat
    end if
  end repeat
  
  
if (item 3 of aItem) is “date” then
    log “Hit date class parameter”
    
–dateレベルのパラメータの場合
    
set retDate to todayDate + (item 2 of aItem) * days
    
set ret2Date to date “0:0:0″ of retDate
    
return ret2Date
    
–「時刻を問わない」ことを示す表現として、00時を指定してdate型を返す
    
  else if item 3 of aItem is “week” then
    log “hit week class parameter”
    
    
–weekレベルのパラメータの場合
    
set targetWeek to weekCounter + (item 2 of aItem)
    
if param2 is in wDat then
      
      
–パラメータが「何曜日か?」を得る
      
set tmpD to 1
      
repeat with j in wDat
        if param2 is contents of j then exit repeat
        
set tmpD to tmpD + 1
      end repeat
      
      
if tmpD > 7 then
        set tmpD to tmpD mod 7
      end if
      
      
–set tmp_Week to targetWeek * 7 + tmpD - 1
      
      
      
–今月か?
      
if item tmpD of item targetWeek of d4List is 0 then
        –今月ではない場合
        
set tmp2 to item tmpD of item targetWeek of d3List
        
–set tmp3 to day of todayDate
        
if ((item 2 of aItem) < 0) then
          –今月ではなく、パラメータがマイナスの週計算を行う場合
          
–先月に入ったので月を減らす
          
set targetMonth to targetMonth - 1
          
set tmp4 to (targetYear & “/” & targetMonth & “/” & tmp2) as string
          
set ret2Date to date “0:0:0″ of (date tmp4)
          
return ret2Date
        else
          –来月として処理
          
set targetMonth to targetMonth + 1
          
set tmp4 to (targetYear & “/” & targetMonth & “/” & tmp2) as string
          
set ret2Date to date “0:0:0″ of (date tmp4)
          
return ret2Date
        end if
      else
        –今月の場合の処理
        
set tmp2 to item tmpD of item targetWeek of d3List
        
set tmp3 to day of todayDate
        
        
–set targetMonth to targetMonth + 1
        
set tmp4 to (targetYear & “/” & targetMonth & “/” & tmp2) as string
        
set ret2Date to date “0:0:0″ of date tmp4
        
return ret2Date
        
      end if
      
    else
      –ここはエラーを返すべし(”来週”,”")といったパターンになるので
      
—-あるいは、「○○日」といったダイレクトパラメータの処理を行う
      
      
–日付ダイレクトパラメータの処理
      
      
      
error “日付を特定するためのパラメータがありません”
      
(*
      ただし、このように決め打ちでエラーメッセージを返すような実装は暫定仕様。
      何が欠けているかをGUIフィードバックするのが最終的な実装
      *)

    end if
  else if item 3 of aItem is “month” then
    –monthレベルのパラメータの場合
    
log “Hit month class parameter”
    
  else if item 3 of aItem is “year” then
    –yearレベルのパラメータの場合
    
log “Hit year class parameter”
    
  end if
  
  
return “no hit”
end calcDate

–相対日付計算用の3か月カレンダーを作成する
on makeCalendar()
  
  
set aToday to current date
  
  
–とりあえず、当月の情報を収集する
  
set y1 to getYear(aToday) of me
  
set m1 to getMonth(aToday) of me
  
set d1 to getDate(aToday) of me
  
set dy1 to getDay(aToday) of me
  
set mlen1 to getMlen(y1, m1) of me
  
  
set mXDay to getDay(aToday) of me –今日の曜日
  
  
  
–前月の情報を組み立てる
  
if m1 is not equal to 1 then
    –2〜12月の場合
    
set y0 to y1
    
set m0 to m1 - 1
  else
    –1月の場合
    
set yo to y1 - 1
    
set m0 to 12
  end if
  
–前月の月の長さ
  
set mLen0 to getMlen(y0, m0) of me
  
  
–前月のみ開始日の曜日を求めておく必要がある(3か月カレンダーを作るため)
  
set m0Date to (y0 & “/” & m0 & “/1″) as text
  
set m0Date to date m0Date
  
set m0Day to getDay(m0Date) of me –1日の曜日
  
  
  
–翌月の情報を組み立てる
  
if m1 is not equal to 12 then
    –1〜11月の場合
    
set y2 to y1
    
set m2 to m1 + 1
  else
    –12月の場合
    
set y2 to y1 + 1
    
set m2 to 1
  end if
  
–翌月の月の長さ
  
set mLen2 to getMlen(y2, m2) of me
  
  
–3か月カレンダーの格納変数
  
set d3List to {}
  
–3か月カレンダーBの格納変数(当月の情報しか日付は入っていないカレンダー)
  
set d4List to {}
  
  
  
set gapList to {0, 0, 0, 0, 0, 0, 0}
  
set w1temp to items 1 thru (m0Day) of gapList
  
set w2temp to items 1 thru (m0Day) of gapList
  
  
(*
  set w1temp to items 1 thru (m0Day - 1) of gapList
  set w2temp to items 1 thru (m0Day - 1) of gapList
  *)

  
  
set dayCounter to 1
  
  
–最初の1週目の要素を組み立てる
  
repeat with i from m0Day to 7
    set the end of w1temp to dayCounter
    
set the end of w2temp to 0
    
set dayCounter to dayCounter + 1
  end repeat
  
set the end of d3List to w1temp
  
set the end of d4List to w2temp
  
  
set w1temp to {}
  
set w2temp to {}
  
  
  
–前月の通常処理
  
repeat
    repeat with i from 1 to 7
      set the end of w1temp to dayCounter
      
set the end of w2temp to 0
      
      
set dayCounter to dayCounter + 1
      
if dayCounter > mLen0 then exit repeat
    end repeat
    
if dayCounter > mLen0 then exit repeat
    
set the end of d3List to w1temp
    
set the end of d4List to w2temp
    
    
set w1temp to {}
    
set w2temp to {}
    
  end repeat
  
  
–ここから当月処理
  
  
–1週目
  
if i = 7 then
    set ii to 1
    
set the end of d3List to w1temp
    
set the end of d4List to w2temp
    
set w1temp to {}
    
set w2temp to {}
    
  else
    set ii to i + 1
  end if
  
  
set dayCounter to 1 –日付カウンタの初期化
  
repeat with j from ii to 7
    set the end of w1temp to dayCounter
    
set the end of w2temp to dayCounter
    
    
set dayCounter to dayCounter + 1
  end repeat
  
  
set the end of d3List to w1temp
  
set the end of d4List to w2temp
  
  
set w1temp to {}
  
set w2temp to {}
  
  
–当月の2週目以降
  
repeat
    repeat with j from 1 to 7
      set the end of w1temp to dayCounter
      
set the end of w2temp to dayCounter
      
      
set dayCounter to dayCounter + 1
      
if dayCounter > mlen1 then exit repeat
    end repeat
    
if dayCounter > mlen1 then exit repeat
    
set the end of d3List to w1temp
    
set the end of d4List to w2temp
    
    
set w1temp to {}
    
set w2temp to {}
    
  end repeat
  
  
–ここから翌月処理
  
  
–1週目
  
if j = 7 then
    set iii to 1
    
set the end of d3List to w1temp
    
set the end of d4List to w2temp
    
    
set w1temp to {}
    
set w2temp to {}
    
  else
    set iii to j + 1
  end if
  
  
set dayCounter to 1 –日付カウンタの初期化
  
repeat with j from iii to 7
    set the end of w1temp to dayCounter
    
set the end of w2temp to 0
    
    
set dayCounter to dayCounter + 1
  end repeat
  
  
set the end of d3List to w1temp
  
set the end of d4List to w2temp
  
  
set w1temp to {}
  
set w2temp to {}
  
  
–翌月の2週目以降
  
repeat
    repeat with k from 1 to 7
      set the end of w1temp to dayCounter
      
set the end of w2temp to 0
      
      
set dayCounter to dayCounter + 1
      
if dayCounter > mlen1 then exit repeat
    end repeat
    
if dayCounter > mlen1 then exit repeat
    
set the end of d3List to w1temp
    
set the end of d4List to w2temp
    
    
set w1temp to {}
    
set w2temp to {}
    
  end repeat
  
  
if length of w1temp is not equal to 0 then
    set the end of d3List to w1temp
    
set the end of d4List to w2temp
    
  end if
  
  
  
–ここまで3か月カレンダーの生成
  
  
  
–3か月カレンダーにおいて今日が何週目かを算出
  
set weekCounter to 1
  
  
repeat with aWeek in d4List –裏リストで操作を行う
    –ただし、該当曜日しかチェックしないので全チェックに比べて速度7倍
    
set aDay to (item mXDay of aWeek) as number
    
if aDay = (d1 as number) then
      exit repeat
    end if
    
set weekCounter to weekCounter + 1
  end repeat
end makeCalendar

–現在日時から曜日を取得を返す
on getDay(aDate)
  
  
–パラメータ判定部分
  
if aDate is “” then
    –ヌルの場合には本日の日付を指定
    
set aDate to current date
  else if class of aDate is not date then
    try
      –パラメータがDate型でなければ、castする
      
set aDate to date aDate
    on error number errNo
      –型変換に失敗した場合にはエラーを返す
      
error errNo
    end try
  end if
  
  
set b to weekday of aDate as number
  
  
return b
  
end getDay

–指定日の月のみ返す
on getMonth(aDat)
  –引数がDate型でなかった場合にキャスト
  
if class of aDat is not equal to date then
    try
      set aDat to date aDat
    on error
      –日付フォーマットでなかった場合には「0」を返す
      
return 0
    end try
  end if
  
–Mac OS X 10.3.5以降のみOK
  
set bDate to month of aDat as number
  
  
return bDate as number
end getMonth

–指定日の日付のみ返す
on getDate(aDat)
  –引数がDate型でなかった場合にキャスト
  
if class of aDat is not equal to date then
    try
      set aDat to date aDat
    on error
      –日付フォーマットでなかった場合には「0」を返す
      
return 0
    end try
  end if
  
  
set bDate to day of aDat
  
return bDate as number
end getDate

–指定日の年のみ返す
on getYear(aDat)
  –引数がDate型でなかった場合にキャスト
  
if class of aDat is not equal to date then
    try
      set aDat to date aDat
    on error
      –日付フォーマットでなかった場合には「0」を返す
      
return 0
    end try
  end if
  
set bDate to year of aDat
  
return bDate as number
end getYear

–指定月の長さを得る(日数)
on getMlen(aYear, aMonth)
  
  
(*
  Parameter
    set aYear to 2004–Year
    set aMonth to 7–Month
*)
  set aDat to (aYear as text) & “/” & (aMonth as text) & “/1″
  
if aMonth is not equal to 12 then
    set eDat to ((aYear as text) & “/” & (aMonth + 1) as text) & “/1″
  else
    set eDat to ((aYear + 1) as text) & “/” & (1 as text) & “/1″
  end if
  
  
–set sDat to date aDat
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
  
end getMlen

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

02/21 「m月d日」の文字列を「m/d」に変換して返す

「m月d日」のフォーマットの文字列を「m/d」に変換して返すAppleScriptです。

Mac OS X 10.6上で作成してあとから10.4.11上でも動くように対応したものです。まー、この手の簡単なテキスト整形サブルーチンは大量に生々しいものがゴロゴロしていますが、このぐらいのあたりさわりのないものしか出せないような気が、、、、

スクリプト名:「m月d日」の文字列を「m/d」に変換して返す
set aStr to "11月1日"
set aRes to retMonthSlashDateStr(aStr) of me
–> "11/1"

–「m月d日」の文字列を「m/d」に変換して返す
on retMonthSlashDateStr(aStr)
  set {mStr, dStr} to retMonthStrAndDateStr(aStr, {"月", "日"}, 2) of me
  
set resStr to mStr & "/" & dStr
  
return resStr
end retMonthSlashDateStr

–指定リストを指定デリミタでparseして日付文字列をリストにして、先頭から指定アイテムまで取り出して返す
–ただし、日付など「月」「日」が必ず存在しているという前提条件が成立するものだけが処理対象
on retMonthStrAndDateStr(aStr, delimiterList, lastItem)
  set osVer to system attribute "sys2"
  
  
if osVer 5 then
    –Mac OS X 10.5以上の場合
    
set curDelim to AppleScript’s text item delimiters
    
set AppleScript’s text item delimiters to delimiterList
    
set aList to text items of aStr
    
set AppleScript’s text item delimiters to curDelim
    
set bList to items 1 thru lastItem of aList
    
return bList
    
  else
    –Mac OS X 10.4以下の場合
    
set resList to {}
    
    
repeat with i in delimiterList
      set curDelim to AppleScript’s text item delimiters
      
set AppleScript’s text item delimiters to i –10.4ではデリミタをリストで指定できないので1つずつ指定
      
set aList to text items of aStr
      
set AppleScript’s text item delimiters to curDelim
      
      
set the end of resList to item 1 of aList
      
      
try
        set aStr to contents of (item 2 of aList) –ここ、あんまりよくないな〜。実害はないけど、美しくない
      end try
      
    end repeat
    
    
return resList
  end if
  
end retMonthStrAndDateStr

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

02/06 指定年のすべての日付をdateオブジェクトで取得する

指定年のすべての日付をdateオブジェクトで取得するAppleScriptです。

こういう基礎的なプログラムは、誰が組んでもあんまり差が出ないので、あえてゼロから組む必要性がなく……こうした基礎的な部品を組み合わせてどれだけ高度な処理を組み上げられるか、というところに頭を使いたいところです。

スクリプト名:指定年のすべての日付をdateオブジェクトで取得する
set thisYear to 2020
set dList to {}

repeat with i from 1 to 12
  set mLen to getMlen(thisYear, i) of me
  
repeat with ii from 1 to mLen
    set dStr to (thisYear as string) & "/" & (i as string) & "/" & (ii as string)
    
set the end of dList to date dStr
  end repeat
end repeat

dList

–指定月の長さを得る(日数)
on getMlen(aYear, aMonth)
  
  
set aDat to (aYear as text) & "/" & (aMonth as text) & "/1"
  
if aMonth is not equal to 12 then
    set eDat to ((aYear as text) & "/" & (aMonth + 1) as text) & "/1"
  else
    set eDat to ((aYear + 1) as text) & "/" & (1 as text) & "/1"
  end if
  
  
–set sDat to date aDat
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
  
end getMlen

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

01/12 与えられたリストに、値がヌルの要素が入っているか判定し、フラグ、ブランク開始終了位置を返す v2

与えられたリストに、値がヌルの要素が入っているか判定し、ヌルが入っているかをフラグで返し、前方にブランクがあるか後方にブランクがあるかのフラグ、ブランク開始位置、ブランク終了位置を返すAppleScriptです。

何らかの数字をO、ブランクをXとすると……

後方にブランクが存在するリスト {O, O, O, O, O, X, X}
前方にブランクが存在するリスト {X, X, O, O, O, O, O}

というタイプの「前方か後方にブランクが存在するリスト」を処理対象にしています。途中にブランクが登場するようなもの(例:{O, X, O, O, X, O, O})は前提にしていません。

はっきり言えば、カレンダーの日付の存在箇所と存在しない箇所をピックアップするために作成したものなので、そういう用途に使いました。

スクリプト名:与えられたリストに、値がヌルの要素が入っているか判定し、フラグ、ブランク開始終了位置を返す v2
set aList to {“1″, “2″, “3″, “4″, “5″, “6″, “7″} –すべての要素がヌルではないリスト
set {aFlag, pFlag, bStart, bEnd} to detectBlankItemFromList(aList) of me
log {aFlag, pFlag, bStart, bEnd}
–> (*true, , 0, 0*)

set aList to {“1″, “2″, “3″, “”, “”, “”, “”} –後ろにヌルが入っているリスト
set {aFlag, pFlag, bStart, bEnd} to detectBlankItemFromList(aList) of me
log {aFlag, pFlag, bStart, bEnd}
–> (*false, after, 4, 7*)

set aList to {“”, “”, “”, “4″, “5″, “6″, “7″} –先頭にヌルが入っているリスト
set {aFlag, pFlag, bStart, bEnd} to detectBlankItemFromList(aList) of me
log {aFlag, pFlag, bStart, bEnd}
–> (*false, before, 1, 3*)

–与えられたリストに、値がヌルの要素が入っているか判定し、フラグ、前がブランクか後がブランクか、ブランク開始・終了位置を返す
on detectBlankItemFromList(aList)
  set aCount to 1
  
set retF to true
  
set aLen to length of aList
  
  
set directionF to “”
  
  
set blankStart to 1
  
set blankEnd to aLen
  
  
  
if contents of item 1 of aList = “” then
    –頭の方にブランクがある場合
    
set rList to reverse of aList –リストを逆順に
    
repeat with i in rList
      if contents of i is equal to “” then
        set retF to false –Blank Itemが入っている場合
        
exit repeat
      end if
      
set aCount to aCount + 1
    end repeat
    
    
set blankStart to 1
    
set blankEnd to (aLen - aCount + 1)
    
    
set directionF to “before”
    
  else if contents of last item of aList = “” then
    –末尾の方にブランクがある場合
    
repeat with i in aList
      if contents of i is equal to “” then
        set retF to false –Blank Itemが入っている場合
        
exit repeat
      end if
      
set aCount to aCount + 1
    end repeat
    
    
set blankStart to aCount
    
set blankEnd to aLen
    
    
set directionF to “after”
    
  else
    –先頭にも末尾にもブランクがない場合
    
set blankStart to 0
    
set blankEnd to 0
    
set retF to true
    
  end if
  
  
return {retF, directionF, blankStart, blankEnd}
  
end detectBlankItemFromList

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

01/12 指定日がその月の中で何週目かを求めて、週リストを取得する

指定日がその月の中で何週目かを求め、その該当週のdateオブジェクトが入ったリストを取得するAppleScriptです。

スクリプト名:指定日がその月の中で何週目かを求めて、週リストを取得する
set tDate to "2011/1/3"
set tDateObj to date tDate

set aWeek to retTheNumberOfWeekInTheMonth(tDateObj) of me
–> 2

set aList to retTheListOfWeekInTheMonth(tDateObj, aWeek) of me
–> {date "2011年1月2日日曜日 0:00:00", date "2011年1月3日月曜日 0:00:00", date "2011年1月4日火曜日 0:00:00", date "2011年1月5日水曜日 0:00:00", date "2011年1月6日木曜日 0:00:00", date "2011年1月7日金曜日 0:00:00", date "2011年1月8日土曜日 0:00:00"}

–指定日が所属する月の中の指定週のリストを求める
on retTheListOfWeekInTheMonth(tDateObj, theWeek)
  –引数から年と月を求める
  
set theYear to year of tDateObj
  
set theMonth to month of tDateObj as number
  
set theDate to day of tDateObj
  
  
–指定月のリストを作成
  
set mList to makeMonthList(theYear, theMonth) of me
  
  
–得られた週リストから、指定週のリストを返す
  
set wList to contents of item theWeek of mList
  
return wList
  
end retTheListOfWeekInTheMonth

–指定日がその月の中で何週目かを求める
on retTheNumberOfWeekInTheMonth(tDateObj)
  –引数から年と月を求める
  
set theYear to year of tDateObj
  
set theMonth to month of tDateObj as number
  
set theDate to day of tDateObj
  
  
–指定月のリストを作成
  
set mList to makeMonthList(theYear, theMonth) of me
  
  
set wNum to getWeekNumInTheMonth(mList, tDateObj) of me
  
  
return wNum
  
end retTheNumberOfWeekInTheMonth

–指定のカレンダーから、指定日が何週目かを求める
on getWeekNumInTheMonth(yList, aDate)
  set weekCount to 1
  
  
repeat with i in yList
    repeat with ii in i
      set jj to contents of ii
      
if jj is equal to aDate then
        return weekCount
      end if
    end repeat
    
set weekCount to weekCount + 1
  end repeat
  
return 0
end getWeekNumInTheMonth

–指定の月を1月分リスト化
on makeMonthList(theYear, theMonth)
  
  
set yList to {}
  
set curList to {}
  
  
set curList to {"", "", "", "", "", "", ""}
  
  
–1か月分の日をリスト化
  
set aLen to getMlen(theYear, theMonth) of me
  
  
repeat with ii from 1 to aLen
    set aDateStr to (((theYear as string) & "/" & theMonth as string) & "/" & ii as string)
    
set aDate to date aDateStr
    
set aWD to weekday of aDate as number
    
set item aWD of curList to aDate
    
if aWD = 7 then
      set the end of yList to curList
      
set curList to {"", "", "", "", "", "", ""}
    end if
  end repeat
  
  
if curList is not equal to {"", "", "", "", "", "", ""} then
    set the end of yList to curList
  end if
  
  
return yList
  
end makeMonthList

–指定月の長さを得る(日数)
on getMlen(aYear, aMonth)
  
  
set aDat to (aYear as text) & "/" & (aMonth as text) & "/1"
  
if aMonth is not equal to 12 then
    set eDat to ((aYear as text) & "/" & (aMonth + 1) as text) & "/1"
  else
    set eDat to ((aYear + 1) as text) & "/" & (1 as text) & "/1"
  end if
  
  
–set sDat to date aDat
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
  
end getMlen

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

01/12 指定日がその月の中で何週目かを求める

指定日がその月の何週目かを求めるAppleScriptです。

スクリプト名:指定日がその月の中で何週目かを求める

set tDate to "2011/1/3"
set tDateObj to date tDate

set a to retTheNumberOfWeekInTheMonth(tDateObj) of me
–> 2

–指定日がその月の中で何週目かを求める
on retTheNumberOfWeekInTheMonth(tDateObj)
  –引数から年と月を求める
  
set theYear to year of tDateObj
  
set theMonth to month of tDateObj as number
  
set theDate to day of tDateObj
  
  
–指定月のリストを作成
  
set mList to makeMonthList(theYear, theMonth) of me
  
  
set wNum to getWeekNumInTheMonth(mList, tDateObj) of me
  
  
return wNum
  
end retTheNumberOfWeekInTheMonth

–指定のカレンダーから、指定日が何週目かを求める
on getWeekNumInTheMonth(yList, aDate)
  set weekCount to 1
  
  
repeat with i in yList
    repeat with ii in i
      set jj to contents of ii
      
if jj is equal to aDate then
        return weekCount
      end if
    end repeat
    
set weekCount to weekCount + 1
  end repeat
  
return 0
end getWeekNumInTheMonth

–指定の月を1月分リスト化
on makeMonthList(theYear, theMonth)
  
  
set yList to {}
  
set curList to {}
  
  
set curList to {"", "", "", "", "", "", ""}
  
  
–1か月分の日をリスト化
  
set aLen to getMlen(theYear, theMonth) of me
  
  
repeat with ii from 1 to aLen
    set aDateStr to (((theYear as string) & "/" & theMonth as string) & "/" & ii as string)
    
set aDate to date aDateStr
    
set aWD to weekday of aDate as number
    
set item aWD of curList to aDate
    
if aWD = 7 then
      set the end of yList to curList
      
set curList to {"", "", "", "", "", "", ""}
    end if
  end repeat
  
  
if curList is not equal to {"", "", "", "", "", "", ""} then
    set the end of yList to curList
  end if
  
  
return yList
  
end makeMonthList

–指定月の長さを得る(日数)
on getMlen(aYear, aMonth)
  
  
set aDat to (aYear as text) & "/" & (aMonth as text) & "/1"
  
if aMonth is not equal to 12 then
    set eDat to ((aYear as text) & "/" & (aMonth + 1) as text) & "/1"
  else
    set eDat to ((aYear + 1) as text) & "/" & (1 as text) & "/1"
  end if
  
  
–set sDat to date aDat
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
  
end getMlen

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

01/12 指定の月を1月分リスト化

指定日の属している月の日付を1か月分リスト化するAppleScriptです。

7日ペアになったリスト(1週分)を入れ子にしたリストを返します。

スクリプト名:指定の月を1月分リスト化
set tDate to "2011/1/3"
set tDateObj to date tDate

set theYear to year of tDateObj
set theMonth to month of tDateObj as number

set aList to makeMonthList(theYear, theMonth) of me
–> {{"", "", "", "", "", "", date "2011年1月1日土曜日 0:00:00"}, {date "2011年1月2日日曜日 0:00:00", date "2011年1月3日月曜日 0:00:00", date "2011年1月4日火曜日 0:00:00", date "2011年1月5日水曜日 0:00:00", date "2011年1月6日木曜日 0:00:00", date "2011年1月7日金曜日 0:00:00", date "2011年1月8日土曜日 0:00:00"}, {date "2011年1月9日日曜日 0:00:00", date "2011年1月10日月曜日 0:00:00", date "2011年1月11日火曜日 0:00:00", date "2011年1月12日水曜日 0:00:00", date "2011年1月13日木曜日 0:00:00", date "2011年1月14日金曜日 0:00:00", date "2011年1月15日土曜日 0:00:00"}, {date "2011年1月16日日曜日 0:00:00", date "2011年1月17日月曜日 0:00:00", date "2011年1月18日火曜日 0:00:00", date "2011年1月19日水曜日 0:00:00", date "2011年1月20日木曜日 0:00:00", date "2011年1月21日金曜日 0:00:00", date "2011年1月22日土曜日 0:00:00"}, {date "2011年1月23日日曜日 0:00:00", date "2011年1月24日月曜日 0:00:00", date "2011年1月25日火曜日 0:00:00", date "2011年1月26日水曜日 0:00:00", date "2011年1月27日木曜日 0:00:00", date "2011年1月28日金曜日 0:00:00", date "2011年1月29日土曜日 0:00:00"}, {date "2011年1月30日日曜日 0:00:00", date "2011年1月31日月曜日 0:00:00", "", "", "", "", ""}}

–指定の月を1月分リスト化
on makeMonthList(theYear, theMonth)
  
  
set yList to {}
  
set curList to {}
  
  
set curList to {"", "", "", "", "", "", ""}
  
  
–1か月分の日をリスト化
  
set aLen to getMlen(theYear, theMonth) of me
  
  
repeat with ii from 1 to aLen
    set aDateStr to (((theYear as string) & "/" & theMonth as string) & "/" & ii as string)
    
set aDate to date aDateStr
    
set aWD to weekday of aDate as number
    
set item aWD of curList to aDate
    
if aWD = 7 then
      set the end of yList to curList
      
set curList to {"", "", "", "", "", "", ""}
    end if
  end repeat
  
  
if curList is not equal to {"", "", "", "", "", "", ""} then
    set the end of yList to curList
  end if
  
  
return yList
  
end makeMonthList

–指定月の長さを得る(日数)
on getMlen(aYear, aMonth)
  
  
set aDat to (aYear as text) & "/" & (aMonth as text) & "/1"
  
if aMonth is not equal to 12 then
    set eDat to ((aYear as text) & "/" & (aMonth + 1) as text) & "/1"
  else
    set eDat to ((aYear + 1) as text) & "/" & (1 as text) & "/1"
  end if
  
  
–set sDat to date aDat
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
  
end getMlen

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

01/11 日本の月呼称を返す

数値で月を与えると、日本語の月呼称の文字列を返すAppleScriptです。

スクリプト名:日本の月呼称を返す
repeat with i from 1 to 15
  set aStr to retJapaneseMonthName(i) of me
  
log {i, aStr}
end repeat

–>
(*1, 睦月*)
(*2, 如月*)
(*3, 弥生*)
(*4, 卯月*)
(*5, 皐月*)
(*6, 水無月*)
(*7, 文月*)
(*8, 葉月*)
(*9, 長月*)
(*10, 神無月*)
(*11, 霜月*)
(*12, 師走*)
(*13, *)
(*14, *)
(*15, *)

–日本の月呼称を返す
on retJapaneseMonthName(aMonthNum)
  if aMonthNum < 1 or aMonthNum > 12 then return "" –エラーチェック
  
  
set aMonthNum to aMonthNum as integer
  
set mStrList to {"睦月", "如月", "弥生", "卯月", "皐月", "水無月", "文月", "葉月", "長月", "神無月", "霜月", "師走"}
  
return contents of item aMonthNum of mStrList
end retJapaneseMonthName

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

09/12 dateに対してincMonthNumか月足した結果の年、月を取得する

dateに対して指定の月を足した結果の年、月を取得するAppleScriptです。

足す月の分だけinctementMonthルーチンをただループさせるだけですが、意外とこの手のルーチンが転がっていないために安直な方法ではありますが、作っておきました。

ただ、それほど登場頻度は高くなさそうです。

スクリプト名:dateに対してincMonthNumか月足した結果の年、月を取得する
set aDate to "2011/4/1"
set aDateObj to date aDate

set incMonthNum to 6

set dRes to addMonth(aDateObj, incMonthNum) of me

–dateに対してincMonthNumか月足した結果の年、月を取得する
on addMonth(aDateObj, incMonthNum)
  set aYear to year of aDateObj
  
set aMonth to month of aDateObj as number
  
  
repeat incMonthNum times
    set {aYear, aMonth} to incrementMonth(aYear, aMonth) of me
  end repeat
  
  
return {yearnum:aYear, monthNum:aMonth}
  
end addMonth

–カレンダー(年と月のペア)をインクリメント(+1)
on incrementMonth(aYear, aMonth)
  if aMonth < 12 then
    –1から11月の場合
    
set nMonth to aMonth + 1
    
return {aYear, nMonth}
    
  else if aMonth = 12 then
    –12月の場合
    
set nYear to aYear + 1
    
set nMonth to 1
    
return {nYear, nMonth}
    
  else
    –月パラメータが1から12の範囲になかった
    
return {false, false}
  end if
end incrementMonth

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

09/12 2つのdateの差を月単位で取得する。パラメータはdateオブジェクトではなくリストで

2つの日付の差を月単位で取得するAppleScriptです。

年と月をそれぞれリストで渡すと、結果がリストで返ってきます。

スクリプト名:2つのdateの差を月単位で取得する。パラメータはdateオブジェクトではなくリストで
set aDateList to {2001, 9, 1}

set bDateList to {2010, 8, 1}

set dRes to monthDiffByList(aDateList, bDateList) of me
–> {yearDiff:8, monthDiff:11}

–2つのdateの差を月単位で取得する。パラメータはdateオブジェクトではなくリストで
on monthDiffByList(aDateList, bDateList)
  set aYear to contents of item 1 of aDateList
  
set aMonth to contents of item 2 of aDateList
  
  
set bYear to contents of item 1 of bDateList
  
set bMonth to contents of item 2 of bDateList
  
  
if aMonth > bMonth then
    set dMonth to (12 - aMonth) + bMonth
    
set dYear to bYear - aYear - 1
  else
    set dMonth to (bMonth - aMonth)
    
set dYear to bYear - aYear
  end if
  
  
return {yearDiff:dYear, monthDiff:dMonth}
  
end monthDiffByList

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

09/08 数字で指定した月の英語名称を返す

数字で指定した月の英語名称を返すAppleScriptです。

当初、このサブルーチン内では日(day)を指定していませんでした。すると、あら不思議。日によって2月が「March」と返ってくるではありませんか!!

……あとになって、その理由を分析してびっくり。○月30日に実行(current dateを取得)してあとから月を2月に指定すると、「2月30日」を設定したことになり、繰り上がって3月になっていたのでした。

かなりマヌケなバグを作ってしまいましたが、いまとなってはいい思い出です(たぶん)。

スクリプト名:数字で指定した月の英語名称を返す
set m to getEnglishMonthName(11) of me
–> "November"

–数字で指定した月の英語名称を返す
on getEnglishMonthName(aMonth)
  set aDate to current date
  
set day of aDate to 1 –ここ、すごく重要
  
set month of aDate to aMonth
  
set mRes to month of aDate as string
  
return mRes
end getEnglishMonthName

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

08/29 2つのdateの差を月単位で取得する

2つのdateオブジェクトの差を年および月単位で取得するAppleScriptです。

aDateObj < bDateObj が前提条件です。

スクリプト名:2つのdateの差を月単位で取得する
set aDate to “2001/9/1″
set aDateObj to date aDate

set bDate to “2010/8/1″
set bDateObj to date bDate

set dRes to monthDiff(aDateObj, bDateObj) of me
–> {yearDiff:8, monthDiff:11}

–2つのdateの差を月単位で取得する
on monthDiff(aDateObj, bDateObj)
  set aYear to year of aDateObj
  
set aMonth to month of aDateObj as number
  
  
set bYear to year of bDateObj
  
set bMonth to month of bDateObj as number
  
  
if aMonth > bMonth then
    set dMonth to (12 - aMonth) + bMonth
    
set dYear to bYear - aYear - 1
  else
    set dMonth to (bMonth - aMonth)
    
set dYear to bYear - aYear
  end if
  
  
return {yearDiff:dYear, monthDiff:dMonth}
  
end monthDiff

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

08/24 与えられた日付の「月」が異なるかどうかチェック

与えられた2つの日付の「月」(month)が異なるかどうかチェックするAppleScriptです。

スクリプト名:与えられた日付の「月」が異なるかどうかチェック
set date1 to "2011/1/27"
set date2 to "2011/2/5"

set d1Obj to date date1
set d2Obj to date date2

set dRes to getDifferenceOfMonth(d1Obj, d2Obj) of me
–> false

–与えられた日付の「月」が異なるかどうかチェック
on getDifferenceOfMonth(d1Obj, d2Obj)
  set m1 to month of d1Obj as number
  
set m2 to month of d2Obj as number
  
return (m1 = m2)
end getDifferenceOfMonth

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

08/24 指定年月の最後のx曜日を返す

指定年月の最後の○曜日(日曜日=1、土曜日=7)を返すAppleScriptです。

スクリプト名:指定年月の最後のx曜日を返す
–2011年の12月の最後の月曜日
set lastDay to retLastWeekday_X(2011, 12, 2) of lastXdayKit
–> 26

script lastXdayKit
  –指定年月の最後のx曜日を返す
  
on retLastWeekday_X(aYear, aMonth, aWeekDayNum)
    set aLen to getMlen(aYear, aMonth) of me
    
    
set xDayList to {}
    
repeat with i from 1 to aLen
      set dStr to (aYear as string) & "/" & (aMonth as string) & "/" & (i as string)
      
set aDate to date dStr
      
set theWeekdayN to weekday of aDate as number
      
if theWeekdayN = aWeekDayNum then
        set the end of xDayList to i
      end if
    end repeat
    
    
return contents of last item of xDayList
    
  end retLastWeekday_X
  
  
  
–指定月の日数を返す
  
on getMlen(aYear, aMonth)
    set aYear to aYear as number
    
set aMonth to aMonth as number
    
    
set aDat to (aYear as text) & "/" & (aMonth as text) & "/1"
    
    
if aMonth is 12 then
      set eDat to ((aYear + 1) as text) & "/" & (1 as text) & "/1"
    else
      set eDat to ((aYear as text) & "/" & (aMonth + 1) as text) & "/1"
    end if
    
    
set eDat to date eDat
    
set eDat to eDat - 1
    
    
set mLen to day of eDat
    
return mLen
  end getMlen
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

08/24 指定年月の最初のx曜日を返す

指定年月の最初の○曜日(日曜日=1、土曜日=7)を取得するAppleScriptです。

スクリプト名:指定年月の最初のx曜日を返す
—2011年1月の最初の月曜日(=2)を求める
set fRes to retFirstWeekday_X(2011, 1, 2) of firstXdayKit
–> 3
–つまり、2011/1/3が最初の月曜日

script firstXdayKit
  –指定年月の最初のx曜日を返す
  
on retFirstWeekday_X(aYear, aMonth, aWeekDayNum)
    set aLen to getMlen(aYear, aMonth) of me
    
    
repeat with i from 1 to aLen
      set dStr to (aYear as string) & "/" & (aMonth as string) & "/" & (i as string)
      
set aDate to date dStr
      
set theWeekdayN to weekday of aDate as number
      
if theWeekdayN = aWeekDayNum then
        return i
      end if
    end repeat
    
  end retFirstWeekday_X
  
  
–指定月の日数を返す
  
on getMlen(aYear, aMonth)
    set aYear to aYear as number
    
set aMonth to aMonth as number
    
    
set aDat to (aYear as text) & "/" & (aMonth as text) & "/1"
    
    
if aMonth is 12 then
      set eDat to ((aYear + 1) as text) & "/" & (1 as text) & "/1"
    else
      set eDat to ((aYear as text) & "/" & (aMonth + 1) as text) & "/1"
    end if
    
    
set eDat to date eDat
    
set eDat to eDat - 1
    
    
set mLen to day of eDat
    
return mLen
  end getMlen
end script

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

08/24 指定日がその年の何日目かを取得する

任意の指定日(どの日でも好きな日を指定)が、その年の何日目かを取得するAppleScriptです。

スクリプト名:指定日がその年の何日目かを取得する
set aYear to 2011
set tDate to "2011/1/3"
set tDateObj to date tDate

set a to retTheNumberOfDays(tDateObj) of me
–> 3

–指定日がその年の何日目かを取得する
on retTheNumberOfDays(aDate)
  set aYear to year of aDate
  
  
set sDate to (aYear as string) & "/1/1"
  
set dDiff to (aDate - (date sDate)) div days + 1 –divは整数除算
  
  
return dDiff
end retTheNumberOfDays

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

08/22 指定年_月の初日(1日)がその年の何日目かを取得する

指定年&月の初日(●月1日)がその年の何日目かを取得するAppleScriptです。

カレンダーを作成する際に、支給されたイベントのデータを実際に週カレンダーや月カレンダーに入れたりするわけですが、その際のデータの頭出し用に作成したものです。

2011年12月1日が2011年の何日目か分かれば、listに入れておいたイベントデータの何アイテム目にアクセスすればよいか簡単に分かります。

スクリプト名:指定年_月の初日(1日)がその年の何日目かを取得する
set aYear to 2011
set aMonth to 12

set a to retDayNumUntillTheFirstDayOfTheMonth(aYear, aMonth) of me
–> 335

–指定年/月の初日(1日)がその年の何日目かを取得する
on retDayNumUntillTheFirstDayOfTheMonth(aYear, aMonth)
  set fD to (aYear as string) & "/1/1"
  
set fDobj to date fD
  
  
set tD to ((aYear as string) & "/" & aMonth as string) & "/1"
  
set tDobj to date tD
  
  
set diffD to ((tDobj - fDobj) / days) + 1
  
  
return diffD as integer
end retDayNumUntillTheFirstDayOfTheMonth

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

08/22 指定年&月の初日が何曜日かを数値で取得する

指定の年&月の初日が何曜日かを数値で取得するAppleScriptです。

たとえば、2011年1月を指定すると7(土曜日)が返ってきます。

2011cal.jpg

スクリプト名:指定年&月の初日が何曜日かを数値で取得する
set aYear to 2011
set aMonth to 1

getWeekdayNumOfFirstDay(aYear, aMonth) of me
–> 7

–指定年&月の初日が何曜日かを数値で取得する
on getWeekdayNumOfFirstDay(aYear, aMonth)
  set fD to ((aYear as string) & "/" & aMonth as string) & "/1"
  
set fDobj to date fD
  
set fNum to weekday of fDobj as number
  
return fNum
end getWeekdayNumOfFirstDay

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

08/10 時刻文字列の差を数値で返す

時刻文字列(例:09:30)の差を数値で返すAppleScriptです。

開始時刻(例:09:30)、終了時刻(例:12:00)を渡すと、その差を数値で返します。数値で返す際には、60を1.0、30を0.5で表現して返します。2時間30分は2.5、1時間15分は1.25となります。

スクリプト名:時刻文字列の差を数値で返す
set aRes to getTimeDiffNum("09:30", "12:00") of me
–> 2.5

–文字列で与えられた時刻(時:分)の「差」を数値で返す(30分=0.5、15分=0.25)
on getTimeDiffNum(startTImestr, endTimeStr)
  
  
set {sH, sM} to parseByDelim(startTImestr, ":") of me
  
set sDate to current date
  
set hours of sDate to (sH as number)
  
set minutes of sDate to (sM as number)
  
set seconds of sDate to 0
  
  
set {eH, eM} to parseByDelim(endTimeStr, ":") of me
  
set eDate to current date
  
set hours of eDate to (eH as number)
  
set minutes of eDate to (eM as number)
  
set seconds of eDate to 0
  
  
set d to eDate - sDate
  
set h to d div 3600
  
set m to d mod 3600
  
set m2 to m / 3600
  
set m3 to h + m2
  
  
return m3
  
end getTimeDiffNum

on parseByDelim(aData, aDelim)
  set curDelim to AppleScript’s text item delimiters
  
set AppleScript’s text item delimiters to aDelim
  
set dList to text items of aData
  
set AppleScript’s text item delimiters to curDelim
  
return dList
end parseByDelim

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/25 指定フォルダ以下のファイル作成日付をファイル修正日にコピーする

指定フォルダ以下のすべてのファイルの作成日付の情報を取得し、最終修正日の情報にコピーするAppleScriptです。

10数年前に撮影したQuickTake 100のデジタル写真データをPICTからJPEGにコンバートしたのはよかったのですが、iPhotoにインポートしたときに作成日が反映されなかったので、ためしに作ってみました。

なお、実行のためには、Developper Toolsがインストールしてある必要があります。

これでダメなら、本当にEXIFのデータをいじくる必要が(汗)

スクリプト名:指定フォルダ以下のファイル作成日付をファイル修正日にコピーする
set aFol to choose folder
set fList to {}
set f_r to a reference to fList

–外付けHDDをSpotlightの処理対象外に指定していたので、mdfindコマンドを使わなかった
tell application “Finder”
  set fList to entire contents of aFol as alias list
end tell

–メインループ
repeat with i in f_r
  set j to contents of i
  
try
    set aInfo to info for j
    
set aF to folder of aInfo
  on error
    set aF to false
  end try
  
  
if aF = false then
    changeModDateToCreationDate(j) of me
  end if
end repeat

–作成日付の情報を修正情報にコピーする
on changeModDateToCreationDate(aFile)
  tell application “Finder”
    set aInfo to info for aFile
    
set creDate to creation date of aInfo
  end tell
  
set aDateStr to makeMMDDYYYYhhmmssStr(creDate) of me
  
  
set aP to POSIX path of aFile
  
  
try
    do shell script “/usr/bin/SetFile -m “ & quoted form of aDateStr & ” “ & quoted form of aP –修正日
  end try
end changeModDateToCreationDate

–DateオブジェクトからMM/DD/YYYY hh:mm:ssの形式の文字列を返す
on makeMMDDYYYYhhmmssStr(aDate)
  –Dateオブジェクトから各要素を取り出す
  
set yStr to (year of aDate) as string
  
set mStr to (month of aDate as number) as string
  
set dStr to (day of aDate) as string
  
set hhStr to (hours of aDate) as string
  
set mmStr to (minutes of aDate) as string
  
set ssStr to (seconds of aDate) as string
  
  
–桁数を合わせる
  
set y2Str to retZeroPaddingText(yStr, 4) of me
  
set m2Str to retZeroPaddingText(mStr, 2) of me
  
set d2Str to retZeroPaddingText(dStr, 2) of me
  
set hh2Str to retZeroPaddingText(hhStr, 2) of me
  
set mm2Str to retZeroPaddingText(mmStr, 2) of me
  
set ss2Str to retZeroPaddingText(ssStr, 2) of me
  
  
return (m2Str & “/” & d2Str & “/” & y2Str & ” “ & hh2Str & “:” & mm2Str & “:” & ss2Str)
end makeMMDDYYYYhhmmssStr

–数値にゼロパディングしたテキストを返す
on retZeroPaddingText(aNum, aLen)
  set tText to (“0000000000″ & aNum as text)
  
set tCount to length of tText
  
set resText to text (tCount - aLen + 1) thru tCount of tText
  
return resText
end retZeroPaddingText

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/10 DateオブジェクトからYYYY-MM-DD-hh-mm-ssの形式の文字列を返す

DateオブジェクトからYYYY-MM-DD-hh-mm-ss形式の文字列を取得するAppleScriptです。

Dateオブジェクトから特定形式の文字列を取り出す処理は、ひじょうによくあるものですが、よくある割に短く書けないので……少々苦労させられてしまうところです。

スクリプト名:DateオブジェクトからYYYY-MM-DD-hh-mm-ssの形式の文字列を返す
set aDate to current date
set aStr to makeYYYYMMDDhhmmssStr(aDate) of me
–> "2010-07-10-09-54-40"

–DateオブジェクトからYYYY-MM-DD-hh-mm-ssの形式の文字列を返す
on makeYYYYMMDDhhmmssStr(aDate)
  –Dateオブジェクトから各要素を取り出す
  
set yStr to (year of aDate) as string
  
set mStr to (month of aDate as number) as string
  
set dStr to (day of aDate) as string
  
set hhStr to ((time of (aDate)) div 3600) as string
  
set mmStr to ((time of (aDate)) mod 3600 div 60) as string
  
set ssStr to ((time of (aDate)) mod 3600 mod 60) as string
  
  
–桁数を合わせる
  
set y2Str to retZeroPaddingText(yStr, 4) of me
  
set m2Str to retZeroPaddingText(mStr, 2) of me
  
set d2Str to retZeroPaddingText(dStr, 2) of me
  
set hh2Str to retZeroPaddingText(hhStr, 2) of me
  
set mm2Str to retZeroPaddingText(mmStr, 2) of me
  
set ss2Str to retZeroPaddingText(ssStr, 2) of me
  
  
return (y2Str & "-" & m2Str & "-" & d2Str & "-" & hh2Str & "-" & mm2Str & "-" & ss2Str)
  
end makeYYYYMMDDhhmmssStr

–数値にゼロパディングしたテキストを返す
on retZeroPaddingText(aNum, aLen)
  set tText to ("0000000000" & aNum as text)
  
set tCount to length of tText
  
set resText to text (tCount - aLen + 1) thru tCount of tText
  
return resText
end retZeroPaddingText

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

01/22 元号変換v31

以前作成したものに(派手な)バグが見つかったので、修正しました。Wikipediaで確認していたつもりだったのですが、元号の切れ目の日付を間違えてしまいました。

指摘してくれたのが中国から日本に来ているプログラマーの女性で(汗)、ひたすら感謝です。

スクリプト名:元号変換v31
set a to "1989/1/18"
set a to parseDate(a) of me
set {aGengoStr, aGengoNum} to retJapaneseGengo(a) of me
–> {"平成", 1}

on retJapaneseGengo(aDate)
  
  
set aYear to year of aDate
  
set aMonth to month of aDate as number
  
set aDay to day of aDate
  
  
set aStr to retZeroPaddingText(aYear, 4) of me & retZeroPaddingText(aMonth, 2) of me & retZeroPaddingText(aDay, 2) of me
  
  
set aGengo to ""
  
–if aStr "19890118" then–間違ってた!!!
  
if aStr "19890108" then
    set aGengo to "平成"
    
set aGengoNum to aYear - 1989 + 1
  else if aStr "19261225" then
    set aGengo to "昭和"
    
set aGengoNum to aYear - 1926 + 1
  else if aStr "19120730" then
    set aGengo to "大正"
    
set aGengoNum to aYear - 1912 + 1
    
–else if aStr "18681125" then–間違ってた!!!
  else if aStr "18680125" then
    set aGengo to "明治"
    
set aGengoNum to aYear - 1868 + 1
  end if
  
  
return {aGengo, aGengoNum}
  
end retJapaneseGengo

–数値にゼロパディングしたテキストを返す
on retZeroPaddingText(aNum, aLen)
  set tText to ("0000000000" & aNum as text)
  
set tCount to length of tText
  
set resText to text (tCount - aLen + 1) thru tCount of tText
  
return resText
end retZeroPaddingText

on parseDate(inStr)
  set aClass to class of inStr
  
if aClass = string then
    try
      set aDate to date inStr
    on error
      return false
    end try
  else if aClass = date then
    set aDate to inStr
    
  end if
  
  
return aDate
  
end parseDate

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

12/25 元号変換v3

日付から元号および年を返すAppleScriptです。→ 2010/1/22 本バージョンにはバグが見つかったので、修正版を使うようにしてください。

元号の切り換えについては、年単位ではなく日単位で計算しています。

stringをdateオブジェクトにする部分は、普通に1行で組める程度の内容ですが……将来的に、文字パラメータから月や日が省略されていた場合に補う処理を入れようと考えていたものです。たとえば、2009という文字が渡されたら、それに月と日を補ってdateオブジェクトに変換する下準備を行おう、ぐらいの考えです。

日が省略されていた場合には末日を、月+日が省略されていた場合には「12/31」を補えば、世間一般で期待しているような処理になるだろうか……と考えています。

スクリプト名:元号変換v3
set a to “1989/1/18″
set a to parseDate(a) of me
set {aGengoStr, aGengoNum} to retJapaneseGengo(a) of me
–> {”平成”, 1}

on retJapaneseGengo(aDate)
  
  
set aYear to year of aDate
  
set aMonth to month of aDate as number
  
set aDay to day of aDate
  
  
set aStr to retZeroPaddingText(aYear, 4) of me & retZeroPaddingText(aMonth, 2) of me & retZeroPaddingText(aDay, 2) of me
  
  
set aGengo to “”
  
if aStr “19890118″ then
    set aGengo to “平成”
    
set aGengoNum to aYear - 1989 + 1
  else if aStr “19261225″ then
    set aGengo to “昭和”
    
set aGengoNum to aYear - 1926 + 1
  else if aStr “19120730″ then
    set aGengo to “大正”
    
set aGengoNum to aYear - 1912 + 1
  else if aStr “18681125″ then
    set aGengo to “明治”
    
set aGengoNum to aYear - 1868 + 1
  end if
  
  
return {aGengo, aGengoNum}
  
end retJapaneseGengo

–数値にゼロパディングしたテキストを返す
on retZeroPaddingText(aNum, aLen)
  set tText to (“0000000000″ & aNum as text)
  
set tCount to length of tText
  
set resText to text (tCount - aLen + 1) thru tCount of tText
  
return resText
end retZeroPaddingText

on parseDate(inStr)
  set aClass to class of inStr
  
if aClass = string then
    try
      set aDate to date inStr
    on error
      return false
    end try
  else if aClass = date then
    set aDate to inStr
    
  end if
  
  
return aDate
  
end parseDate

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/30 指定年の各月の開始日と終了日を算出する

指定年の各月の開始日と終了日を算出するAppleScriptです。

この手のカレンダー演算によく登場するgetMLenがまたもや登場。開始日は1日なので決め打ちで、終了日はgetMLenを用いて計算で算出。

指定期間内の祝日を取得するとか、指定期間内のiCalのイベントを取り出すといった場合、このように範囲をdateオブジェクトで用意しておく必要が出てきたりします。実につまらない機能のプログラムですが、こういうものを地道に揃えていくと、割とおっかない内容の処理ができるようになったりします。

スクリプト名:指定年の各月の開始日と終了日を算出する
set dList to {}
set aYear to 2010

repeat with i from 1 to 12
  set sDateStr to ((aYear as string) & / & i as string) & / & 1
  
set eDateStr to ((aYear as string) & / & i as string) & / & getMlen(aYear, i) of me as string
  
set the end of dList to {sDateStr, eDateStr}
end repeat

dList
> {{”2010/1/1″, “2010/1/31″}, {”2010/2/1″, “2010/2/28″}, {”2010/3/1″, “2010/3/31″}, {”2010/4/1″, “2010/4/30″}, {”2010/5/1″, “2010/5/31″}, {”2010/6/1″, “2010/6/30″}, {”2010/7/1″, “2010/7/31″}, {”2010/8/1″, “2010/8/31″}, {”2010/9/1″, “2010/9/30″}, {”2010/10/1″, “2010/10/31″}, {”2010/11/1″, “2010/11/30″}, {”2010/12/1″, “2010/12/31″}}

指定月の日数を返す
on getMlen(aYear, aMonth)
  set aYear to aYear as number
  
set aMonth to aMonth as number
  
  
set aDat to (aYear as text) & / & (aMonth as text) & /1
  
if aMonth is 12 then
    set eDat to ((aYear + 1) as text) & / & (1 as text) & /1
  else
    set eDat to ((aYear as text) & / & (aMonth + 1) as text) & /1
  end if
  
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
end getMlen

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/28 月曜日はじまりのカレンダーで指定月が何週分あるか行数を数える

月曜日はじまりのカレンダーで、指定月が何週分あるか計算するAppleScriptです。

カレンダーは月によって何週あるかが変わってくるため、一定の週数よりも多い場合にはレイアウト時に例外処理を行わなくてはならない場合もあります。そういうケースに備えて作成したものです。

月曜日はじまりのカレンダーに対応できるように、曜日(weekday)のテーブルを介して変換を行っています。この調子でいけば、どの曜日ではじまるようにでも対応できるような変換テーブルを作っておいてもよさそうです。

スクリプト名:月曜日はじまりのカレンダーで指定月が何週分あるか行数を数える
set thisYear to 2010
set wList to {}

repeat with i from 1 to 12
  set wRes to detectWeekNumMondayStart(thisYear, i) of me
  
set the end of wList to wRes
end repeat

wList
> {5, 4, 5, 5, 6, 5, 5, 6, 5, 5, 5, 5}

月曜日はじまりのカレンダーで指定月が何週分あるか行数を数える
on detectWeekNumMondayStart(thisYear, thisMonth)
  set wConList to {7, 1, 2, 3, 4, 5, 6}
  
  
set mLen to getMlen(thisYear, thisMonth) of me
  
set sDate to ((thisYear as string) & / & thisMonth as string) & /1
  
set eDate to ((thisYear as string) & / & thisMonth as string) & / & mLen as string
  
set sDate to date sDate
  
set eDate to date eDate
  
set sWeekDay to contents of item (weekday of sDate as number) of wConList
  
set eWeekDay to contents of item (weekday of eDate as number) of wConList
  
  
set mPos to sWeekDay + mLen - 1
  
  
set mP1 to mPos div 7
  
set mp2 to mPos mod 7
  
  
if mp2 = 0 then
    set mpRes to mP1
  else
    set mpRes to mP1 + 1
  end if
  
  
return mpRes
  
end detectWeekNumMondayStart

指定月の日数を返す
on getMlen(aYear, aMonth)
  set aYear to aYear as number
  
set aMonth to aMonth as number
  
  
set aDat to (aYear as text) & / & (aMonth as text) & /1
  
if aMonth is 12 then
    set eDat to ((aYear + 1) as text) & / & (1 as text) & /1
  else
    set eDat to ((aYear as text) & / & (aMonth + 1) as text) & /1
  end if
  
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
end getMlen

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/28 日曜日はじまりのカレンダーで指定月が何週分あるか行数を数える

日曜日はじまりのカレンダーで、指定月が何週分あるか計算するAppleScriptです。

カレンダーは月によって何週あるかが変わってくるため、一定の週数よりも多い場合にはレイアウト時に例外処理を行わなくてはならない場合もあります。そういうケースに備えて作成したものです。

スクリプト名:日曜日はじまりのカレンダーで指定月が何週分あるか行数を数える
set thisYear to 2010
set wList to {}

repeat with i from 1 to 12
  set wRes to detectWeekNum(thisYear, i) of me
  
set the end of wList to wRes
end repeat

wList
> {6, 5, 5, 5, 6, 5, 5, 5, 5, 6, 5, 5}

日曜日はじまりのカレンダーで指定月が何週分あるか行数を数える
on detectWeekNum(thisYear, thisMonth)
  set mLen to getMlen(thisYear, thisMonth) of me
  
set sDate to ((thisYear as string) & / & thisMonth as string) & /1
  
set eDate to ((thisYear as string) & / & thisMonth as string) & / & mLen as string
  
set sDate to date sDate
  
set eDate to date eDate
  
set sWeekDay to weekday of sDate as number
  
set eWeekDay to weekday of eDate as number
  
  
set mPos to sWeekDay + mLen - 1
  
  
set mP1 to mPos div 7
  
set mp2 to mPos mod 7
  
  
if mp2 = 0 then
    set mpRes to mP1
  else
    set mpRes to mP1 + 1
  end if
  
  
return mpRes
  
end detectWeekNum

指定月の日数を返す
on getMlen(aYear, aMonth)
  set aYear to aYear as number
  
set aMonth to aMonth as number
  
  
set aDat to (aYear as text) & / & (aMonth as text) & /1
  
if aMonth is 12 then
    set eDat to ((aYear + 1) as text) & / & (1 as text) & /1
  else
    set eDat to ((aYear as text) & / & (aMonth + 1) as text) & /1
  end if
  
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
end getMlen

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/22 1年間の各週の開始日と終了日を求める(月曜日はじまりカレンダー)

1年間の各週の開始日と終了日を求めるAppleScriptです。ただし、通常の日曜日はじまりのカレンダーではなく月曜日はじまりのカレンダーを対象としています。

スクリプト名:1年間の各週の開始日と終了日を求める(月曜日はじまりカレンダー)
set wList to “”
set sDate to 2010/1/1
set sDate to date sDate
set sDateW to weekday of sDate as number
> 6

起点となる月曜日の原点日を決める(元日からのオフセット値)
set wOffset to 0
if sDateW < 2 then
  月曜日より小さい場合
  
set wOffset to 2 - sDateW
else if sDateW = 2 then
  月曜日の場合
  
set wOffset to 0
else
  それ以外
  
set wOffset to 7 - sDateW + 2
end if

最初の月曜日を求める
set sDateM to sDate + (wOffset * days)

メインループ
repeat with i from 0 to 52
  set fMonday to sDateM + (i * 7 * days)
  
set fSunday to sDateM + ((6 + (i * 7)) * days)
  
  
set wList to wList & date string of fMonday & tab & date string of fSunday & return
end repeat
wList

>

(*
“2010年1月4日月曜日  2010年1月10日日曜日
2010年1月11日月曜日  2010年1月17日日曜日
2010年1月18日月曜日  2010年1月24日日曜日
2010年1月25日月曜日  2010年1月31日日曜日
2010年2月1日月曜日  2010年2月7日日曜日
2010年2月8日月曜日  2010年2月14日日曜日
2010年2月15日月曜日  2010年2月21日日曜日
2010年2月22日月曜日  2010年2月28日日曜日
2010年3月1日月曜日  2010年3月7日日曜日
2010年3月8日月曜日  2010年3月14日日曜日
2010年3月15日月曜日  2010年3月21日日曜日
2010年3月22日月曜日  2010年3月28日日曜日
2010年3月29日月曜日  2010年4月4日日曜日
2010年4月5日月曜日  2010年4月11日日曜日
2010年4月12日月曜日  2010年4月18日日曜日
2010年4月19日月曜日  2010年4月25日日曜日
2010年4月26日月曜日  2010年5月2日日曜日
2010年5月3日月曜日  2010年5月9日日曜日
2010年5月10日月曜日  2010年5月16日日曜日
2010年5月17日月曜日  2010年5月23日日曜日
2010年5月24日月曜日  2010年5月30日日曜日
2010年5月31日月曜日  2010年6月6日日曜日
2010年6月7日月曜日  2010年6月13日日曜日
2010年6月14日月曜日  2010年6月20日日曜日
2010年6月21日月曜日  2010年6月27日日曜日
2010年6月28日月曜日  2010年7月4日日曜日
2010年7月5日月曜日  2010年7月11日日曜日
2010年7月12日月曜日  2010年7月18日日曜日
2010年7月19日月曜日  2010年7月25日日曜日
2010年7月26日月曜日  2010年8月1日日曜日
2010年8月2日月曜日  2010年8月8日日曜日
2010年8月9日月曜日  2010年8月15日日曜日
2010年8月16日月曜日  2010年8月22日日曜日
2010年8月23日月曜日  2010年8月29日日曜日
2010年8月30日月曜日  2010年9月5日日曜日
2010年9月6日月曜日  2010年9月12日日曜日
2010年9月13日月曜日  2010年9月19日日曜日
2010年9月20日月曜日  2010年9月26日日曜日
2010年9月27日月曜日  2010年10月3日日曜日
2010年10月4日月曜日  2010年10月10日日曜日
2010年10月11日月曜日  2010年10月17日日曜日
2010年10月18日月曜日  2010年10月24日日曜日
2010年10月25日月曜日  2010年10月31日日曜日
2010年11月1日月曜日  2010年11月7日日曜日
2010年11月8日月曜日  2010年11月14日日曜日
2010年11月15日月曜日  2010年11月21日日曜日
2010年11月22日月曜日  2010年11月28日日曜日
2010年11月29日月曜日  2010年12月5日日曜日
2010年12月6日月曜日  2010年12月12日日曜日
2010年12月13日月曜日  2010年12月19日日曜日
2010年12月20日月曜日  2010年12月26日日曜日
2010年12月27日月曜日  2011年1月2日日曜日
2011年1月3日月曜日  2011年1月9日日曜日

*)

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/22 指定月のうち、日曜日に該当するものを日付だけ返す

指定月のうち、日曜日に該当する日付だけを数値のリストで返すAppleScriptです。

最初はどう書いたものかと途方に暮れていましたが、書き出したらそれほどたいした長さにはなりませんでした。

1か月の長さを求めて、ループで1か月分のdateオブジェクトを生成し、曜日を確認して日曜日に該当したら出力用リストに追加……という処理を行うだけです。

スクリプト名:指定月のうち、日曜日に該当するものを日付だけ返す
set aList to retSundayDateNum(2009, 7) of me
> {5, 12, 19, 26}

指定月のうち、日曜日に該当するものを日付だけ返す
on retSundayDateNum(aYear, aMonth)
  set myMonthLen to getMlen(aYear, aMonth) of me
  
set sundayList to {}
  
repeat with i from 1 to myMonthLen
    set aDateStr to (((aYear as string) & / & aMonth as string) & / & i as string)
    
set aDate to date aDateStr
    
if (weekday of aDate as number) = 1 then 日曜日
      set the end of sundayList to i
    end if
  end repeat
  
  
return sundayList
end retSundayDateNum

指定年の指定月の日数を求める
on getMlen(aYear, aMonth)
  set aYear to aYear as number
  
set aMonth to aMonth as number
  
  
set aDat to (aYear as text) & / & (aMonth as text) & /1
  
if aMonth is 12 then
    set eDat to ((aYear + 1) as text) & / & (1 as text) & /1
  else
    set eDat to ((aYear as text) & / & (aMonth + 1) as text) & /1
  end if
  
  
set eDat to date eDat
  
set eDat to eDat - 1
  
  
set mLen to day of eDat
  
return mLen
end getMlen

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/22 もんのすごいざっくりな元号計算ルーチン

西暦から元号名および年を算出するAppleScriptです。

ほぼ、西暦から平成に変換することだけを目的として作ったので、もう……目を覆わんばかりの雑なサブルーチンです。西暦→和暦の変換ルーチンが見つからなかったので、ひらすらやっつけで書いたものですが……納得できません。

本来、元号は1年の途中で切り替わるものなので……日付まで考慮して計算すべきものであり、そのあたりに不満が残ります。

スクリプト名:もんのすごいざっくりな元号計算ルーチン
set gRes to retGngoAndYear(2010) of me
log gRes
>   (*aGengo:平成, aYear:22*)

set gengoText to aGengo of gRes
set jYearNum to aYear of gRes

もんのすごいざっくりな元号計算ルーチン
作るのがダルすぎる、、、、
on retGngoAndYear(aYear)
  set gengoText to “”
  
if aYear > 1989 then
    set jYear to aYear - 1989 + 1
    
set gengoText to 平成
    
  else if aYear > 1926 then
    set jYear to aYear - 1926 + 1
    
set gengoText to 昭和
    
  else if aYear > 1912 then
    set jYear to aYear - 1912 + 1
    
set gengoText to 大正
    
  else if aYear > 1868 then
    set jYear to aYear - 1868 + 1
    
set gengoText to 明治
  end if
  
  
return {aGengo:gengoText, aYear:jYear}
end retGngoAndYear

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

07/22 国民の祝日を求め__指定期間に該当するものを返す

指定期間内の国民の祝日および振替休日をリストで返すAppleScriptです。

あまりに巨大化したのと、どこにでも登場するようなサブルーチンの塊だったりするので、他のサブルーチンと衝突しないようにscript文で論理分割してみました。script文で囲まれた範囲は「別のScript」として扱われるため、サブルーチン名などで他と重複するものがあっても、「別のScript上にある別のサブルーチン」として扱われるため、名前の衝突を回避することができます。

呼び出すには、

set hList to retHolidaysWithinDates(sDate, eDate) of calendarKit

のようにof meではなくof Script名となります。さらに、この呼び出し部分がいずれかのサブルーチン内にある場合には、

set hList to retHolidaysWithinDates(sDate, eDate) of calendarKit of me

のようになります。
(more…)