Получить день недели с помощью NSDate

90

Я создал метод, который должен принимать строку в форме «ГГГГ-ММ-ДД» и выдавать int, который представляет позицию даты по отношению к неделе, в которой она находится (независимо от того, перекрывается ли она между месяцами). Так, например, воскресенье = 1, понедельник = 2 и так далее.

Вот мой код:

    func getDayOfWeek(today:String)->Int{

    var formatter:NSDateFormatter = NSDateFormatter()
    formatter.dateFormat = "YYYY-MM-DD"
    var todayDate:NSDate = formatter.dateFromString(today)!
    var myCalendar:NSCalendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)
    var myComponents = myCalendar.components(NSCalendarUnit.WeekdayOrdinalCalendarUnit, fromDate: todayDate)
    var weekDay = myComponents.weekdayOrdinal
    return weekDay
}

Я знаю, что NSCalendarUnit.WeekdayOrdinalCalendarэто неправильно, но я пробовал, думаю, наиболее логичные комбинации. И также возились, myComponents.weekdayOrdinalнапример, с использованием mycomponents.dayили .weekday.

Вот мои варианты того, что использовать:

static var EraCalendarUnit: NSCalendarUnit { get }
static var YearCalendarUnit: NSCalendarUnit { get }
static var MonthCalendarUnit: NSCalendarUnit { get }
static var DayCalendarUnit: NSCalendarUnit { get }
static var HourCalendarUnit: NSCalendarUnit { get }
static var MinuteCalendarUnit: NSCalendarUnit { get }
static var SecondCalendarUnit: NSCalendarUnit { get }
static var WeekCalendarUnit: NSCalendarUnit { get }
static var WeekdayCalendarUnit: NSCalendarUnit { get }
static var WeekdayOrdinalCalendarUnit: NSCalendarUnit { get }
static var QuarterCalendarUnit: NSCalendarUnit { get }
static var WeekOfMonthCalendarUnit: NSCalendarUnit { get }
static var WeekOfYearCalendarUnit: NSCalendarUnit { get }
static var YearForWeekOfYearCalendarUnit: NSCalendarUnit { get }
static var CalendarCalendarUnit: NSCalendarUnit { get }
static var TimeZoneCalendarUnit: NSCalendarUnit { get }

Мне это непонятно, поскольку нет опции DayOfWeekUnit (или чего-то подобного).

Бойдкан
источник
1
См .: Даты и время форматирования ICU для форматирования символов.
zaph
Возможный дубликат Как узнать день недели с Cocoa Touch?
Suhaib 05
1
@Suhaib Если вы посмотрите на мои теги, там написано Swift, а не Objective-C. Кроме того, код находится в Swift 2.
boidkan 05
попробуйте следующий "EEEE" в вашем формате даты
Александрос

Ответы:

118

То, что вы ищете (если я правильно понял вопрос), есть NSCalendarUnit.CalendarUnitWeekday. Соответствующее свойство NSDateComponentsесть weekday.

Также обратите внимание, что ваш формат даты неверен (полную спецификацию можно найти здесь: http://unicode.org/reports/tr35/tr35-6.html ).

Функцию можно немного упростить, используя автоматический вывод типа, также вы часто используете переменные там, где достаточно констант. Кроме того, функция должна возвращать необязательный параметр, предназначенный nil для недопустимой входной строки.

Обновленный код для Swift 3 и новее:

func getDayOfWeek(_ today:String) -> Int? {
    let formatter  = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    guard let todayDate = formatter.date(from: today) else { return nil }
    let myCalendar = Calendar(identifier: .gregorian)
    let weekDay = myCalendar.component(.weekday, from: todayDate)
    return weekDay
}

Пример:

if let weekday = getDayOfWeek("2014-08-27") {
    print(weekday)
} else {
    print("bad input")
}

Оригинальный ответ для Swift 2:

func getDayOfWeek(today:String)->Int? {

    let formatter  = NSDateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    if let todayDate = formatter.dateFromString(today) {
        let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
        let myComponents = myCalendar.components(.Weekday, fromDate: todayDate)
        let weekDay = myComponents.weekday
        return weekDay
    } else {
        return nil
    }
}
Мартин Р
источник
Да, именно формат меня испортил. Когда я попробовал WeekdayCalendarUnit, я получил 2 вместо 4 и был очень сбит с толку! Спасибо за ссылку, буду читать дальше.
boidkan
1
Я знаю, что это не часть исходного вопроса, но это было бы хорошим местом для возврата необязательного Int в случае, если переданная дата не в правильном формате или некорректна.
Mike S
1
Не должно быть func getDayOfWeek(today:String)->Int?. Если вы принудительно развернете необязательный компонент, он все равно выйдет из строя, не так ли?
ИМЕЕТ
1
@HAS: Вы совершенно правы, спасибо! - В моем тестовом примере не произошло сбоя, потому что необязательное присваивание if let ...работает также с неявно развернутыми необязательными параметрами.
Martin R
1
Спасибо, Мартинг. За это, чтобы сделать свой ответ более красивым, вы можете отредактировать его, чтобы удалить код swift 2 и сохранить код swift 3. Затем добавьте в конце примечание: «Если вам нужен код для Swift 2, проверьте предыдущее изменение» или что-то в этом
роде
155

Swift 3 и 4

Получение номера дня недели в Swift 3 значительно упрощено, поскольку DateComponentsбольше не является необязательным. Вот как расширение:

extension Date {
    func dayNumberOfWeek() -> Int? {
        return Calendar.current.dateComponents([.weekday], from: self).weekday 
    }
}

// returns an integer from 1 - 7, with 1 being Sunday and 7 being Saturday
print(Date().dayNumberOfWeek()!) // 4

Если вы искали письменную локализованную версию дня недели:

extension Date {
    func dayOfWeek() -> String? {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "EEEE"
        return dateFormatter.string(from: self).capitalized 
        // or use capitalized(with: locale) if you want
    }
}

print(Date().dayOfWeek()!) // Wednesday
брендонскрипт
источник
1
Может быть, будет более понятно, если вы поместите aDate.dayOfWeek () в Usage.
boidkan
1
Обратите внимание, что вопрос заключался в том, как получить день недели из строки в форме «ГГГГ-ММ-ДД». Конечно, это упрощается, если у вас уже есть NSDate.
Martin R
4
Вероятно, стоит упомянуть, что если вы используете его, например. в виде таблицы, это может замедлить прокрутку, так как создание DateFormatter довольно затратно. Если вы собираетесь использовать его очень часто, хорошо, например. создать один экземпляр и предоставить его во время расчета для всех вызовов функций.
Vive
Абсолютно. В этом случае было бы полезно иметь даже обработчик массива, в котором вы могли бы запускать функцию для массива данных.
brandonscript
1
проще было бы просто ответить @ david72 ниже: Calendar.current.component (.weekday, from: Date ())
Адам Смака
37

Если вы хотите полное «воскресенье», «понедельник», «вторник», «среда» и т. Д.

EDIT: на самом деле есть встроенный формат, который возвращает локализованные названия дней:

extension NSDate {
    func dayOfTheWeek() -> String? {        
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "EEEE"
        return dateFormatter.stringFromDate(self)
    }
}

Мое предыдущее решение (только для английского):

extension NSDate {

    func dayOfTheWeek() -> String? {
        let weekdays = [
            "Sunday",
            "Monday",
            "Tuesday",
            "Wednesday",
            "Thursday",
            "Friday",
            "Saturday"
        ]

        let calendar: NSCalendar = NSCalendar.currentCalendar()
        let components: NSDateComponents = calendar.components(.Weekday, fromDate: self)
        return weekdays[components.weekday - 1]
    }
}

Вам не нужно разворачивать календарь и компоненты, они гарантируются базовой структурой.

Применение:

print(myDate.dayOfTheWeek())
Матян
источник
5
EEEEE и EEEEEE дает вам краткие формы дней, например, среда,
четверг, пятница
1
Или используйте свойство shortWeekdaySymbols в Calendar, чтобы вообще не создавать DateFormatter.
mikepj
22

Простой ответ (быстрый 3):

Calendar.current.component(.weekday, from: Date())
david72
источник
11

В моем случае я искал трехбуквенную строку на каждый день. Я изменил функцию @Martin R следующим образом:

func getDayOfWeekString(today:String)->String? {
    let formatter  = NSDateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    if let todayDate = formatter.dateFromString(today) {
        let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
        let myComponents = myCalendar.components(.Weekday, fromDate: todayDate)
        let weekDay = myComponents.weekday
        switch weekDay {
        case 1:
            return "Sun"
        case 2:
            return "Mon"
        case 3:
            return "Tue"
        case 4:
            return "Wed"
        case 5:
            return "Thu"
        case 6:
            return "Fri"
        case 7:
            return "Sat"
        default:
            print("Error fetching days")
            return "Day"
        }
    } else {
        return nil
    }
}
Tr0yJ
источник
2
Вы можете использовать EEE какdateFormat
mrvincenzo 01
10

Есть способ попроще. Просто передайте строковую дату следующей функции, она даст вам название дня :)

func getDayNameBy(stringDate: String) -> String
    {
        let df  = NSDateFormatter()
        df.dateFormat = "YYYY-MM-dd"
        let date = df.dateFromString(stringDate)!
        df.dateFormat = "EEEE"
        return df.stringFromDate(date);
    }
Хамид
источник
2
искал "EEE". спасибо
anoo_radha
9
extension Date {

var weekdayName: String {
    let formatter = DateFormatter(); formatter.dateFormat = "E"
    return formatter.string(from: self as Date)
}

var weekdayNameFull: String {
    let formatter = DateFormatter(); formatter.dateFormat = "EEEE"
    return formatter.string(from: self as Date)
}
var monthName: String {
    let formatter = DateFormatter(); formatter.dateFormat = "MMM"
    return formatter.string(from: self as Date)
}
var OnlyYear: String {
    let formatter = DateFormatter(); formatter.dateFormat = "YYYY"
    return formatter.string(from: self as Date)
}
var period: String {
    let formatter = DateFormatter(); formatter.dateFormat = "a"
    return formatter.string(from: self as Date)
}
var timeOnly: String {
    let formatter = DateFormatter(); formatter.dateFormat = "hh : mm"
    return formatter.string(from: self as Date)
}
var timeWithPeriod: String {
    let formatter = DateFormatter(); formatter.dateFormat = "hh : mm a"
    return formatter.string(from: self as Date)
}

var DatewithMonth: String {
    let formatter = DateFormatter(); formatter.dateStyle = .medium ;        return formatter.string(from: self as Date)
}
}

использование let weekday = Date (). weekdayName

Акаш Шиндхе
источник
8

Swift 3 Date extension

extension Date {
    var weekdayOrdinal: Int {
        return Calendar.current.component(.weekday, from: self)
    }
}
неприятный
источник
Я добавил к вашему ответу важный момент, который является актуальным ответом здесь. Очевидно, не стесняйтесь расслабиться, если вам не нравится! :) Cheers
Fattie
вопрос задан для целого числа
quemeful
6

Вы можете использовать эту таблицу date_formats для преобразования даты в разные форматы. Мой самый короткий код:

func getDayOfWeek(today: String) -> Int{
    let formatter:NSDateFormatter = NSDateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    let todayDate = formatter.dateFromString(today)
    formatter.dateFormat = "e" // "eeee" -> Friday
    let weekDay = formatter.stringFromDate(todayDate!)
    return Int(weekDay)!
}
getDayOfWeek("2015-12-18") // 6
qwerty-reloader
источник
Большое вам спасибо. Это то, что я искал formatter.dateFormat = "eeee" // "eeee" -> Пятница
Мохаммед Абунада
4

SWIFT 5 - День недели

    extension Date {

        var dayofTheWeek: String {
             let dayNumber = Calendar.current.component(.weekday, from: self)
             // day number starts from 1 but array count from 0
             return daysOfTheWeek[dayNumber - 1]
        }

        private var daysOfTheWeek: [String] {
             return  ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
        }
     }

Продление даты на основе ответа Фатти

Дили
источник
3

Практическое решение ...

Имейте в виду, что результаты - это целые числа от одного до семи.

(Не с нуля до шести.)

let trivialDayStringsORDINAL = ["", "SUN","MON","TUE","WED","THU","FRI","SAT"]
// note that zero is not used

а потом ...

let dow = Calendar.current.component(.weekday, from: someDate)
print( trivialDayStringsORDINAL[dow] )
Толстяк
источник
3

Здесь уже есть много ответов, но я думаю, что есть другой, возможно, лучший способ сделать это с использованием правильных CalendarAPI.

Я бы предложил получить день недели, используя weekdaySymbolsсвойство Calendar( docs ) в расширении для Date:

extension Date {

    /// Returns the day of the week as a `String`, e.g. "Monday"
    var dayOfWeek: String {
        let calendar = Calendar.autoupdatingCurrent
        return calendar.weekdaySymbols[calendar.component(.weekday, from: self) - 1]
    }
}

Для этого требуется Dateсначала инициализировать , что я бы сделал, используя обычай DateFormatter:

extension DateFormatter {

    /// returns a `DateFormatter` with the format "yyyy-MM-dd".
    static var standardDate: DateFormatter {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        return formatter
    }
}

Затем это можно вызвать с помощью:

DateFormatter.standardDate.date(from: "2018-09-18")!.dayOfWeek

Почему я предпочитаю это:

  1. dayOfWeek не нужно заботиться о часовых поясах, потому что используется календарь пользователя, некоторые из других решений здесь будут показывать неправильный день, потому что часовые пояса не учитываются.
  2. Весьма вероятно, что вам нужно будет использовать даты в том же формате в других местах, так почему бы не создать многоразовый формат DateFormatterи не использовать его вместо этого?
  3. weekdaySymbols локализован для вас.
  4. weekDaySymbolsможно заменить другими вариантами, такими как shortWeekdaySymbols«Пн», «Вт» и т. д.

Обратите внимание: в этом примере DateFormatterтакже не учитываются часовые пояса или языковые стандарты, вам нужно установить их в соответствии с вашими потребностями. Если даты всегда точны, рассмотрите возможность установки часового пояса TimeZone(secondsFromGMT: 0).

Леон
источник
1
Удивительно, что это единственный ответ, в котором упоминается weekdaySymbols, спасибо
Толстяк
1

В итоге мне понадобилось еще несколько строк с датой, включая дату недели (например, «5-е») и месяц года (например, август). Ниже приведены все три функции, которые я создал на основе функции @Martin R и модифицировал так, чтобы возвращать 3 строки символов:

//Date String Helper Functions
func getDayOfWeek(today:String)->String? {
    let formatter  = NSDateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    if let todayDate = formatter.dateFromString(today) {
        let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
        let myComponents = myCalendar.components(.Weekday, fromDate: todayDate)
        let weekDay = myComponents.weekday
        switch weekDay {
        case 1:
            return "Sun"
        case 2:
            return "Mon"
        case 3:
            return "Tue"
        case 4:
            return "Wed"
        case 5:
            return "Thu"
        case 6:
            return "Fri"
        case 7:
            return "Sat"
        default:
            print("Error fetching days")
            return "Day"
        }
    } else {
        return nil
    }
}

func getDateOfMonth(today:String)->String? {
    let formatter  = NSDateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    if let todayDate = formatter.dateFromString(today) {
        let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
        let myComponents = myCalendar.components(.Day, fromDate: todayDate)
        let weekDay = myComponents.day
        switch weekDay {
        case 1:
            return "1st"
        case 2:
            return "2nd"
        case 3:
            return "3rd"
        case 4:
            return "4th"
        case 5:
            return "5th"
        case 6:
            return "6th"
        case 7:
            return "7th"
        case 8:
            return "8th"
        case 9:
            return "9th"
        case 10:
            return "10th"
        case 11:
            return "11th"
        case 12:
            return "12th"
        case 13:
            return "13th"
        case 14:
            return "14th"
        case 15:
            return "15th"
        case 16:
            return "16th"
        case 17:
            return "17th"
        case 18:
            return "18th"
        case 19:
            return "19th"
        case 20:
            return "20th"
        case 21:
            return "21st"
        case 22:
            return "22nd"
        case 23:
            return "23rd"
        case 24:
            return "24th"
        case 25:
            return "25th"
        case 26:
            return "26th"
        case 27:
            return "27th"
        case 28:
            return "28th"
        case 29:
            return "29th"
        case 30:
            return "30th"
        case 31:
            return "31st"
        default:
            print("Error fetching Date Of Month")
            return "Day"
        }
    } else {
        return nil
    }
}

func getMonthOfYear(today:String)->String? {
    let formatter  = NSDateFormatter()
    formatter.dateFormat = "yyyy-MM-dd"
    if let todayDate = formatter.dateFromString(today) {
        let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
        let myComponents = myCalendar.components(.Month, fromDate: todayDate)
        let month = myComponents.month
        switch month {
        case 1:
            return "Jan"
        case 2:
            return "Feb"
        case 3:
            return "Mar"
        case 4:
            return "Apr"
        case 5:
            return "May"
        case 6:
            return "Jun"
        case 7:
            return "Jul"
        case 8:
            return "Aug"
        case 9:
            return "Sep"
        case 10:
            return "Oct"
        case 11:
            return "Nov"
        case 12:
            return "Dec"
        default:
            print("Error fetching months")
            return "Month"
        }
    } else {
        return nil
    }
}
Tr0yJ
источник
1

Код SWIFT 2.0 для представления текущей недели, начиная с понедельника.

@IBAction func show (отправитель: AnyObject) {

   // Getting Days of week corresponding to their dateFormat

    let calendar = NSCalendar.currentCalendar()
    let dayInt: Int!
    var weekDate: [String] = []
    var i = 2

    print("Dates corresponding to days are")
    while((dayInt - dayInt) + i < 9)
    {
        let weekFirstDate = calendar.dateByAddingUnit(.Day, value: (-dayInt+i), toDate: NSDate(), options: [])
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "EEEE dd MMMM"
        let dayOfWeekString = dateFormatter.stringFromDate(weekFirstDate!)
        weekDate.append(dayOfWeekString)
        i++
    }
    for i in weekDate
    {
        print(i) //Printing the day stored in array
    }
}

// function to get week day
func getDayOfWeek(today:String)->Int {

    let formatter  = NSDateFormatter()
    formatter.dateFormat = "MMM-dd-yyyy"
    let todayDate = formatter.dateFromString(today)!
    let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
    let myComponents = myCalendar.components(.Weekday, fromDate: todayDate)
    let weekDay = myComponents.weekday
    return weekDay
}


@IBAction func DateTitle(sender: AnyObject) {


    // Getting currentDate and weekDay corresponding to it
    let currentDate = NSDate()
    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "MMM-dd-yyyy"
    let dayOfWeekStrings = dateFormatter.stringFromDate(currentDate)
    dayInt = getDayOfWeek(dayOfWeekStrings)

}
Химаншу
источник
1

Этот код позволяет найти всю текущую неделю. Написано в Swift 2.0:

var i = 2
var weekday: [String] = []
var weekdate: [String] = []
var weekmonth: [String] = []

@IBAction func buttonaction(sender: AnyObject) {

    let currentDate = NSDate()
    let dateFormatter = NSDateFormatter()
    dateFormatter.dateFormat = "MMM-dd-yyyy"
    let dayOfWeekStrings = dateFormatter.stringFromDate(currentDate)
    let weekdays = getDayOfWeek(dayOfWeekStrings)
    let calendar = NSCalendar.currentCalendar()

    while((weekdays - weekdays) + i < 9)
    {
        let weekFirstDate = calendar.dateByAddingUnit(.Day, value: (-weekdays+i), toDate: NSDate(), options: [])

        let dayFormatter = NSDateFormatter()
        dayFormatter.dateFormat = "EEEE"
        let dayOfWeekString = dayFormatter.stringFromDate(weekFirstDate!)
        weekday.append(dayOfWeekString)

        let dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "dd"
        let dateOfWeekString = dateFormatter.stringFromDate(weekFirstDate!)
        weekdate.append(dateOfWeekString)

        let monthFormatter = NSDateFormatter()
        monthFormatter.dateFormat = "MMMM"
        let monthOfWeekString = monthFormatter.stringFromDate(weekFirstDate!)
        weekmonth.append(monthOfWeekString)

        i++
    }

    for(var j = 0; j<7 ; j++)
    {
    let day = weekday[j]
    let date = weekdate[j]
    let month = weekmonth[j]
    var wholeweek = date + "-" + month + "(" + day + ")"
    print(wholeweek)
    }

}

func getDayOfWeek(today:String)->Int {
    let formatter  = NSDateFormatter()
    formatter.dateFormat = "MMM-dd-yyyy"
    let todayDate = formatter.dateFromString(today)!
    let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
    let myComponents = myCalendar.components(.Weekday, fromDate: todayDate)
    let daynumber = myComponents.weekday
    return daynumber
}

Результат будет таким:

14 марта (понедельник) 15 марта (вторник) 16 марта (среда) 17 марта (четверг) 18 марта (пятница) 19 марта (суббота) 20 марта (воскресенье)

Анураг Мехта
источник
1

Swift 3: вспомогательная функция Xcode 8:

func getDayOfWeek(fromDate date: Date) -> String? {
    let cal = Calendar(identifier: .gregorian)
    let dayOfWeek = cal.component(.weekday, from: date)
    switch dayOfWeek {
     case 1:
        return "Sunday"
    case 2:
        return "Monday"
    case 3:
        return "Tuesday"
    case 4:
        return "Wednesday"
    case 5:
        return "Thursday"
    case 6:
        return "Friday"
    case 7:
        return "Saturday"
    default:
        return nil
    }
}
aBikis
источник
1
Это не локализовано.
Александр - Восстановите Монику
0

Чтобы Swift4 получил день недели из строки

   func getDayOfWeek(today:String)->Int {
        let formatter  = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd"
        let todayDate = formatter.date(from: today)!
        let myCalendar = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)!
        let myComponents = myCalendar.components(NSCalendar.Unit.weekday, from: todayDate)
        let weekDay = myComponents.weekday
        return weekDay!
    }

let weekday = getDayOfWeek(today: "2018-10-10")
print(weekday) // 4
Себастьен Реми
источник
Чем это отличается от первого метода в stackoverflow.com/a/25533357/1187415 ?
Martin R