前提・実現したいこと
実現したいこととしては"第2月曜日"・"第3木曜日"などの
"第○□曜日"のフォーマットの文字列から、今日を基準にして次にくる"第○□曜日"の
日付をDate型で求めたいのですが、実現方法がわかりませんでした。
前提として"第○□曜日"のフォーマットから
正規表現を使って○と□の部分を抽出してからInt型に変換するところまでは出来ています。
例:
第2月曜日 → ○ = 2 , □ = 1
第3木曜日 → ○ = 3 , □ = 5
今日が2018/10/30なので
次にくる第2月曜日は2018/11/12
次にくる第1木曜日は2018/11/1
と言った具合でこれらをDate型で求めたいです。
宜しくお願い致します。
該当のソースコード
let day = "第2月曜日"
if day.pregMatche(pattern: "第([1-5])(.曜日)"){
let pattern = "第([1-5])(.)曜日"
let capture = day.capture(pattern:pattern, group: [1, 2])
if !capture.isEmpty{
//第何週目何曜日か取得
let ordinal = capture[0]
let week = capture[1]
if let weekValue = getWeekValue(week){
print("\(ordinal),\(week)")
//解決後の追記コード
let date = Date()
let calendar = Calendar(identifier: .gregorian)
var dateComponents = DateComponents()
dateComponents.weekday = Int(week)
dateComponents.weekdayOrdinal = Int(ordinal)
let nextDate = calendar.nextDate(after: date, matching: dateComponents, matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: .forward)!
}
}else{
fatalError()
}
}
func getWeekValue(week:String)->Int?{
switch week {
case "日":
return 1
case "月":
return 2
case "火":
return 3
case "水":
return 4
case "木":
return 5
case "金":
return 6
case "土":
return 7
default:
return nil
}
}
extension String {
/// 正規表現でキャプチャした文字列を抽出する
///
/// - Parameters:
/// - pattern: 正規表現
/// - group: 抽出するグループ番号(>=1)
/// - Returns: 抽出した文字列
func capture(pattern: String, group: Int) -> String? {
let result = capture(pattern: pattern, group: [group])
return result.isEmpty ? nil : result[0]
}
/// 正規表現でキャプチャした文字列を抽出する
///
/// - Parameters:
/// - pattern: 正規表現
/// - group: 抽出するグループ番号(>=1)の配列
/// - Returns: 抽出した文字列の配列
func capture(pattern: String, group: [Int]) -> [String] {
guard let regex = try? NSRegularExpression(pattern: pattern) else {
return []
}
guard let matched = regex.firstMatch(in: self, range: NSRange(location: 0, length: self.count)) else {
return []
}
return group.map { group -> String in
return (self as NSString).substring(with: matched.range(at: group))
}
}
//正規表現の検索をします
func pregMatche(pattern: String, options: NSRegularExpression.Options = []) -> Bool {
guard let regex = try? NSRegularExpression(pattern: pattern, options: options) else {
return false
}
let matches = regex.matches(in: self, options: [], range: NSMakeRange(0, self.count))
return matches.count > 0
}
}
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+2
Calendarを使うとよろしいかと思います。
qiitaをご覧になると参考になるかと思います。(swift3なのでswift4の場合差分があるかもしれません)
注意点としては、最初の週が何曜日から始まるかを確認して、それに応じて処理をすることでしょうか。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
checkベストアンサー
+1
Calendarの、
nextDate(after:matching:matchingPolicy:repeatedTimePolicy:direction:)
enumerateDates(startingAfter:matching:matchingPolicy:repeatedTimePolicy:direction:using:)
あたりでお手軽に取れそうな気がします。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.32%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
fuzzball
2018/10/31 10:14 編集
まだコード(Swift)は関係なくて、アルゴリズムの問題ではないのですか?
sgyeta
2018/10/31 10:22
レスポンス頂きありがとうございます。SwiftのDate及びCalendarクラスを使っての実装という意味合いでSwiftのタグを付けて質問させて頂きましたが、確かに話の内容はアルゴリズムに関してのものですね・・・。不慣れなもので判断しかねるのですが、タグの変更をした方が宜しいのでしょうか?
fuzzball
2018/10/31 10:30
もうCalendarを使うところまで回答が付いている(解決が近い)ので、今回はこのままでいいような気がします。
sgyeta
2018/10/31 10:34
今後質問させて頂くときは気に掛けるよう心掛けます。ご教示頂きありがとうございます!