質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

476閲覧

文字列から条件に合致するDate型の値を求めたい

sgyeta

総合スコア23

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/10/30 08:42

編集2018/10/31 02:22

前提・実現したいこと

実現したいこととしては"第2月曜日"・"第3木曜日"などの
"第○□曜日"のフォーマットの文字列から、今日を基準にして次にくる"第○□曜日"の
日付をDate型で求めたいのですが、実現方法がわかりませんでした。

前提として"第○□曜日"のフォーマットから
正規表現を使って○と□の部分を抽出してからInt型に変換するところまでは出来ています。

例:
第2月曜日 → ○ = 2 , □ = 1
第3木曜日 → ○ = 3 , □ = 5

今日が2018/10/30なので
次にくる第2月曜日は2018/11/12
次にくる第1木曜日は2018/11/1
と言った具合でこれらをDate型で求めたいです。

宜しくお願い致します。

該当のソースコード

Swift

1let day = "第2月曜日" 2 3if day.pregMatche(pattern: "第([1-5])(.曜日)"){ 4 let pattern = "第([1-5])(.)曜日" 5 let capture = day.capture(pattern:pattern, group: [1, 2]) 6 7 if !capture.isEmpty{ 8 //第何週目何曜日か取得 9 let ordinal = capture[0] 10 let week = capture[1] 11 12 if let weekValue = getWeekValue(week){ 13 print("(ordinal),(week)") 14 15 //解決後の追記コード 16 let date = Date() 17 let calendar = Calendar(identifier: .gregorian) 18 var dateComponents = DateComponents() 19 dateComponents.weekday = Int(week) 20 dateComponents.weekdayOrdinal = Int(ordinal) 21 22 let nextDate = calendar.nextDate(after: date, matching: dateComponents, matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: .forward)! 23 } 24 }else{ 25 fatalError() 26 } 27} 28 29func getWeekValue(week:String)->Int?{ 30 switch week { 31 case "日": 32 return 1 33 case "月": 34 return 2 35 case "火": 36 return 3 37 case "水": 38 return 4 39 case "木": 40 return 5 41 case "金": 42 return 6 43 case "土": 44 return 7 45 default: 46 return nil 47 } 48}
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 } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2018/10/31 01:14 編集

まだコード(Swift)は関係なくて、アルゴリズムの問題ではないのですか?
sgyeta

2018/10/31 01:22

レスポンス頂きありがとうございます。SwiftのDate及びCalendarクラスを使っての実装という意味合いでSwiftのタグを付けて質問させて頂きましたが、確かに話の内容はアルゴリズムに関してのものですね・・・。不慣れなもので判断しかねるのですが、タグの変更をした方が宜しいのでしょうか?
fuzzball

2018/10/31 01:30

もうCalendarを使うところまで回答が付いている(解決が近い)ので、今回はこのままでいいような気がします。
sgyeta

2018/10/31 01:34

今後質問させて頂くときは気に掛けるよう心掛けます。ご教示頂きありがとうございます!
guest

回答2

0

Calendarを使うとよろしいかと思います。

qiitaをご覧になると参考になるかと思います。(swift3なのでswift4の場合差分があるかもしれません)

注意点としては、最初の週が何曜日から始まるかを確認して、それに応じて処理をすることでしょうか。

投稿2018/10/30 10:02

t_obara

総合スコア5488

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sgyeta

2018/10/30 15:28

ご回答頂きありがとうございます。 リンク先は何度も目にしたことがあるのですが 自分の理解が乏しくもう少しヒントを頂きたいです。 calendar.date(bySetting: .weekday, value: weekValue, of: date) これで次の抽出部分が取れそうです。また以下を参考にして DateComponentsに変換して.weekdayを使えば第◯の部分はわかりそうですが Calendarを使うに当たってどんなアプローチをしていけば宜しいでしょうか。 https://fussan-blog.com/swift-date/
t_obara

2018/10/31 02:26

Calendar自体はDateオブジェクトを指定・返却されるので、Dateオブジェクトを操作するツールと お考えになればよろしいのではないでしょうか。 あとはアルゴリズムの問題ですので、色々なアプローチがあると思います。
sgyeta

2018/10/31 02:29

Swiftと言うよりアルゴリズムの質問でしたね失礼しました・・・。 無事解決しました。 この度はありがとうございました!
guest

0

ベストアンサー

投稿2018/10/31 01:34

fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sgyeta

2018/10/31 02:26 編集

ご回答頂きありがとうございます。 質問に挙げたコードにnextDateを使って実装した部分を追記しました。 取り急ぎで手荒な部分はありますが、やりたいことが無事実現出来ました。 この度はありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問