120
-(NSDate *)beginningOfDay:(NSDate *)date
{
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *components = [cal components:( NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];
    
    [components setHour:0];
    [components setMinute:0];
    [components setSecond:0];
    
    return [cal dateFromComponents:components];
    
}

-(NSDate *)endOfDay:(NSDate *)date
{
    NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *components = [cal components:(  NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];
    
    [components setHour:23];
    [components setMinute:59];
    [components setSecond:59];
    
    return [cal dateFromComponents:components];

}

私が電話するとき:[self endOfDay:[NSDate date]]; 私は月の最初を取得します...それはなぜですか?最初の日付の最初の秒(beginningOfDay:date1)から2番目の日付の最後の秒(endOfDay:Date2)までの間隔が必要なため、この2つのメソッドを使用します...

4

25 に答える 25

255

一日の始まり/一日の終わり— Swift 4

  // Extension

extension Date {
    var startOfDay: Date {
        return Calendar.current.startOfDay(for: self)
    }

    var endOfDay: Date {
        var components = DateComponents()
        components.day = 1
        components.second = -1
        return Calendar.current.date(byAdding: components, to: startOfDay)!
    }

    var startOfMonth: Date {
        let components = Calendar.current.dateComponents([.year, .month], from: startOfDay)
        return Calendar.current.date(from: components)!
    }

    var endOfMonth: Date {
        var components = DateComponents()
        components.month = 1
        components.second = -1
        return Calendar.current.date(byAdding: components, to: startOfMonth)!
    }
}

// End of day = Start of tomorrow minus 1 second
// End of month = Start of next month minus 1 second
于 2013-11-23T05:29:21.817 に答える
38

Swift5 シンプルでより正確な答え。

開始時間:00:00:00

終了時間:23:59:59.5

let date = Date() // current date or replace with a specific date
let calendar = Calendar.current
let startTime = calendar.startOfDay(for: date)
let endTime = calendar.date(bySettingHour: 23, minute: 59, second: 59, of: date)

追加

let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: noon)!
let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: noon)!
let specificDate = Date("2020-01-01")

extension Date {
    init(_ dateString:String) {
        let dateStringFormatter = DateFormatter()
        dateStringFormatter.dateFormat = "yyyy-MM-dd"
        dateStringFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale
        let date = dateStringFormatter.date(from: dateString)!
        self.init(timeInterval:0, since:date)
    }
}
于 2018-02-08T22:39:53.187 に答える
35

あなたは行方不明NSDayCalendarUnitです

NSDateComponents *components = [cal components:( NSMonthCalendarUnit | NSYearCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:date];
于 2012-11-10T18:15:26.243 に答える
28

iOS 8以降では、これは本当に便利です。できるよ:

let startOfDay: Date = Calendar.current.startOfDay(for: Date())

1日の終わりを取得するには、1日の終わりをどのように定義するかに応じて、23時間、59分、59秒のCalendarメソッドを使用します。

// Swift 5.0
let components = DateComponents(hour: 23, minute: 59, second: 59)
let endOfDay = Calendar.current.date(byAdding: components, to: startOfDay)

日付数学

AppleiOSNSCalendarドキュメント。(セクション:カレンダー計算を参照)

NSHipsterによって議論されたNSCalendarメソッド

于 2015-08-18T04:41:47.183 に答える
17

NSDateのSwift拡張機能:

スイフト1.2

extension NSDate {

    func beginningOfDay() -> NSDate {
        var calendar = NSCalendar.currentCalendar()
        var components = calendar.components(.CalendarUnitYear | .CalendarUnitMonth | .CalendarUnitDay, fromDate: self)
        return calendar.dateFromComponents(components)!
    }

    func endOfDay() -> NSDate {
        var components = NSDateComponents()
        components.day = 1
        var date = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: self.beginningOfDay(), options: .allZeros)!
        date = date.dateByAddingTimeInterval(-1)!
        return date
    }
}

Swift 2.0

extension NSDate {

    func beginningOfDay() -> NSDate {
        let calendar = NSCalendar.currentCalendar()
        let components = calendar.components([.Year, .Month, .Day], fromDate: self)
        return calendar.dateFromComponents(components)!
    }

    func endOfDay() -> NSDate {
        let components = NSDateComponents()
        components.day = 1
        var date = NSCalendar.currentCalendar().dateByAddingComponents(components, toDate: self.beginningOfDay(), options: [])!
        date = date.dateByAddingTimeInterval(-1)
        return date
    }
}
于 2015-04-01T07:02:15.697 に答える
15

Swift 5.1-XCode 11の代わりに、およびの代わりにクラスDateを使用NSDateCalenderNSCalender

extension Date {

    var startOfDay : Date {
        let calendar = Calendar.current
        let unitFlags = Set<Calendar.Component>([.year, .month, .day])
        let components = calendar.dateComponents(unitFlags, from: self)
        return calendar.date(from: components)!
   }

    var endOfDay : Date {
        var components = DateComponents()
        components.day = 1
        let date = Calendar.current.date(byAdding: components, to: self.startOfDay)
        return (date?.addingTimeInterval(-1))!
    }
}

使用法:

    let myDate = Date()
    let startOfDate = myDate.startOfDay
    let endOfDate = myDate.endOfDay
于 2016-10-22T13:36:10.213 に答える
9

Swiftでこれを行う最も簡潔な方法は次のとおりです。

extension Date {
    func startOfDay() -> Date {
        return Calendar.current.startOfDay(for: self)
    }
    func endOfDay() -> Date {
        return Calendar.current.date(bySettingHour: 23, minute: 59, second: 59, of: self) ?? self
    }
}
于 2020-04-26T14:28:39.923 に答える
6

Swift3以降の場合

extension Date {
    var startOfDayDate: Date {
        return Calendar.current.startOfDay(for: self)
    }

    var endOfDayDate: Date {
        let nextDayDate = Calendar.current.date(byAdding: .day, value: 1, to: self.startOfDayDate)!
        return nextDayDate.addingTimeInterval(-1)
    }
}

使用法:

var currentDayStart = Date().startOfDayDate
var currentDayEnd = Date().endOfDayDate
于 2019-07-24T08:24:09.387 に答える
4

コンポーネントをゼロに設定する必要はありません。無視してください。

-(NSDate *)beginningOfDay:(NSDate *)date
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:date];
    return [calendar dateFromComponents:components];
}
于 2014-01-02T13:01:18.113 に答える
4

私にとって、ここやスタックオーバーフローが機能した場所での答えはありませんでした。今日のスタートを切るために私はこれをしました。

NSCalendar * gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 
[gregorian setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];    
NSDateComponents *components = [gregorian components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:[NSDate date]]; 
[components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]]; 
NSDate *beginningOfToday = [gregorian dateFromComponents:components];

これ[gregorian setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];とに注意してください[components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

カレンダーが作成されると、現在のタイムゾーンで初期化され、日付がそのコンポーネントから抽出されると、NSDateにはタイムゾーンがないため、現在のタイムゾーンからの日付はUTCタイムゾーンと見なされます。したがって、コンポーネントを抽出する前と、後でこれらのコンポーネントから日付を抽出するときにタイムゾーンを設定する必要があります。

于 2015-07-07T19:57:39.610 に答える
4

スウィフト3

  class func today() -> NSDate {
        return NSDate()
    }

    class func dayStart() -> NSDate {
          return NSCalendar.current.startOfDay(for: NSDate() as Date) as NSDate
    }

    class func dayEnd() -> NSDate {
        let components = NSDateComponents()
        components.day = 1
        components.second = -1
        return NSCalendar.current.date(byAdding: components as DateComponents, to: self.dayStart() as Date)
    }
于 2016-10-10T06:03:49.693 に答える
4

Swift3 * XCode8の使用
Appleは、にスワップアウトできるNSように、クラス名からを削除しています。それらをキャストしようとすると、常に失敗するというコンパイラの警告が表示される場合がありますが、プレイグラウンドで実行すると正常に動作します。NSDateDate

NSDate生成されたコアデータモデルをに置き換えましたが、Date引き続き機能します。

extension Date {
  func startTime() -> Date {
    return Calendar.current.startOfDay(for: self)
  }

  func endTime() -> Date {
    var components = DateComponents()
    components.day = 1
    components.second = -1
    return Calendar.current.date(byAdding: components, to: startTime())!
  }
}
于 2016-10-23T08:51:09.403 に答える
3

Objective-C

NSCalendar * calendar = [NSCalendar currentCalendar];
NSDate * startDate = [calendar startOfDayForDate:[NSDate date]];
NSLog(@"start date is %@", startDate);
于 2018-02-27T08:55:27.333 に答える
2

コンポーネントが不足NSDayCalendarUnitしています。

于 2012-11-10T18:17:50.293 に答える
2

結果を得るもう1つの方法:

NSDate *date = [NSDate date];

NSDateComponents *components = [[NSDateComponents alloc] init];
components.day = [[NSCalendar currentCalendar] ordinalityOfUnit:(NSCalendarUnitDay) inUnit:(NSCalendarUnitEra) forDate:date];
NSDate *dayBegin = [[NSCalendar currentCalendar] dateFromComponents:components];

components.day += 1;
NSDate *dayEnd = [[NSCalendar currentCalendar] dateFromComponents:components];
于 2015-05-29T22:03:50.203 に答える
2

迅速な4の場合

    var calendar = Calendar.current
    calendar.timeZone = NSTimeZone(abbreviation: "UTC")! as TimeZone
    let dateAtMidnight = calendar.startOfDay(for: Date())

    //For End Date
    var components = DateComponents()
    components.day = 1
    components.second = -1

    let dateAtEnd = calendar.date(byAdding: components, to: dateAtMidnight)

    print("dateAtMidnight :: \(dateAtMidnight)")
    print("dateAtEnd :: \(dateAtEnd!)")
于 2018-10-09T16:00:57.907 に答える
2

Swift 5.3では、Calendar.current.startOfDay()とCalendar.current.date(bySettingHour:、minute:、second:、of:)の両方がタイムゾーン固有です。タイムゾーンに関係なく同じ時刻に日付を正規化する場合は、このようにGMT時刻を使用する必要があります。

// Normalize time of aDate to 12:00 GMT
let aDate = Date()
let twelveGMT = 12 + TimeZone.current.secondsFromGMT() / 3600
let normalizedDate = Calendar.current.date(bySettingHour: twelveGMT, minute: 0, second: 0, of: aDate)
于 2020-11-29T05:11:30.520 に答える
1

と専用のdateInterval(of:start:interval:for:)DateInterval構造体を使用する別の方法Calendar

帰りstartDateには、その日の始まりとその日intervalの秒数が含まれます。

func dateInterval(of date : Date) -> DateInterval {
    var startDate = Date()
    var interval : TimeInterval = 0.0
    Calendar.current.dateInterval(of: .day, start: &startDate, interval: &interval, for: date)
    return DateInterval(start: startDate, duration: interval-1)
}

let interval = dateInterval(of: Date())
print(interval.start, interval.end)
于 2016-09-12T13:07:11.647 に答える
1

iOS 8.0+ / macOS 10.12+ / tvOS 10.0+ / watchOS 3.0+Foundationには組み込みの関数があるので、箱から出してすぐに使用できます。独自の機能を実装する必要はありません。

public func startOfDay(for date: Date) -> Date

したがって、次のように使用できます。

let midnightDate = Calendar(identifier: .gregorian).startOfDay(for: Date())

これはデバイスのタイムゾーンを考慮に入れていることを覚えておく価値があります。たとえばUTCゾーンが必要な場合は.timeZone、オンに設定できます。calendar

Appleリファレンスページへのリンク:https ://developer.apple.com/reference/foundation/nscalendar/1417161-startofday 。

于 2016-12-01T07:40:21.280 に答える
1

これは私がSwift4.2に使用するものです。

    let calendar = Calendar.current
    let fromDate = calendar.startOfDay(for: Date())
    let endDate = calendar.date(bySettingHour: 23, minute: 59, second: 59, of: Date())

私にとっては魅力のように機能します。の開始日と終了日の拡張機能にこれを追加できますが、拡張機能をDate追加するとコンパイル時間が長くなることに注意してください(クラスと同じファイルにある場合を除く)。したがって、1つの場所または1つのクラスでのみ必要な場合。 ..拡張子を使用しないでください。

于 2019-03-05T08:11:35.480 に答える
1

カレンダーを取得するために@Zelkoの回答を更新します。

extension Date {

    func startOfDay(in calendar: Calendar = .current) -> Date {
        calendar.startOfDay(for: self)
    }

    func endOfDay(in calendar: Calendar = .current) -> Date {
        var components = DateComponents()
        components.day = 1
        components.second = -1
        return calendar.date(byAdding: components, to: startOfDay(in: calendar))!
    }

    func startOfMonth(in calendar: Calendar = .current) -> Date {
        let components = calendar.dateComponents([.year, .month], from: startOfDay(in: calendar))
        return calendar.date(from: components)!
    }

    func endOfMonth(in calendar: Calendar = .current) -> Date {
        var components = DateComponents()
        components.month = 1
        components.second = -1
        return calendar.date(byAdding: components, to: startOfMonth(in: calendar))!
    }
}

ノート:

アプリがより多くの地域をサポートする場合は、正しいカレンダーを使用することが非常に重要です

于 2022-01-26T10:36:22.500 に答える
0
extension Date {
    func stringFrom(dateFormat: String) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = dateFormat
        return formatter.string(from: self)
    }

    func firstSecondInDay() -> Date {
        let dayStr = self.stringFrom(dateFormat: "yyyy-MM-dd")
        let firstSecondStr = "\(dayStr) 00:00:00"
        let format = DateFormatter()
        format.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return format.date(from: firstSecondStr)!
    }

    func lastSecondInDay() -> Date {
        let dayStr = self.stringFrom(dateFormat: "yyyy-MM-dd")
        let laseSecondStr = "\(dayStr) 23:59:59"
        let format = DateFormatter()
        format.dateFormat = "yyyy-MM-dd HH:mm:ss"
        return format.date(from: laseSecondStr)!
    }
}
于 2017-11-03T07:52:03.643 に答える
0

参考までに、Swift4で1日の開始と終了を設定する簡単な方法

var comp: DateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: Date())
comp.hour = 0
comp.minute = 0
comp.second = 0
comp.timeZone = TimeZone(abbreviation: "UTC")!


//Set Start of Day
let startDate : Date = Calendar.current.date(from: comp)!
print(“Day of Start : \(startDate)")


//Set End of Day
comp.hour = 23
comp.minute = 59
comp.second = 59

let endDate : Date = Calendar.current.date(from:comp)!
print("Day of End : \(endDate)")
于 2018-12-18T05:11:38.130 に答える
0

Calendar構造体にはが含まれているので、メソッドを内ではなく拡張内startOfDay(for:)にカプセル化するのが最善だと思います。endOfDay(for:)CalendarDate

次のコードは、すばやく実行できるようにPlaygroundファイル内に配置できます。

import Foundation

extension Calendar {

    func endOfDay(for date: Date) -> Date {

        // Get the start of the date argument.
        let dayStart = self.startOfDay(for: date)

        // Add one day to the start of the day 
        // in order to get the start of the following day.            
        guard let nextDayStart = self.date(byAdding: .day, value: 1, to: dayStart) else {
            preconditionFailure("Expected start of next day")
        }

        // Create date components that will subtract a single
        // second from the start of the next day. This will
        // allow you to get the last hour, last minute, and last
        // second of the previous day, which is the day for the 
        // date argument that was passed to this method.
        var components = DateComponents()
        components.second = -1

        // Add the date components to the date for the next 
        // day, which will perform the subtraction of the single
        // second. This will return the end of the day for the date
        // that was passed into this method.
        guard let dayEnd = self.date(byAdding: components, to: nextDayStart) else {
            preconditionFailure("Expected end of day")
        }

        // Simply return the date value.
        return dayEnd
    }

}

フォーマットされた日付を表示するには、を作成しDateFormatterて出力を印刷します。

let formatter = DateFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .long
Calendar.current.endOfDay(for: Date()) // "Dec 31, 2020 at 11:59 PM"
于 2020-12-31T15:12:38.937 に答える
-1

カレンダーの単位は間隔と考える必要があります。iOS 10の時点で、これにCalendarはいくつかの優れた方法があります

let day = Calendar.autoupdatingCurrent.dateInterval(of: .day, for: Date())
day?.start
day?.end.addingTimeInterval(-1)

同じ方法を使用して、任意のカレンダーコンポーネントの開始/終了(週/月/年など)を取得できます

ここでの注意点は、終了として定義できる単一の時点がないことです(開始がある場合)。上記は一日の終わり(23:59:59)の1秒前に与えられます。

于 2019-04-21T16:21:00.220 に答える