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


Я создал метод, который должен принимать строку в форме" YYYY-MM-DD " и выплевывать 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 (или что-то подобное).

16 54

16 ответов:

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

обратите внимание также, что ваш формат даты неверен (the полную спецификацию можно найти здесь: 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
    }
}

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

Если вы хотите полную "среду", "воскресенье" и т. д.

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",
            "Satudrday,"
        ]

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

вам не нужно разворачивать календарь и компоненты, они гарантированы рамками foundation.

использование:

print(myDate.dayOfTheWeek())

простой ответ (swift 3):

Calendar.current.component(.weekday, from: Date())

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

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);
    }

в моем случае я был после трех букв строки на каждый день. Я изменил функцию @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
    }
}

Swift 3 продление даты

extension Date {
    var weekdayOrdinal: Int {
        return Calendar.current.component(.weekday, from: self)
    }
}

вы можете использовать эту таблицу 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

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

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

(не равно нулю шесть.)

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] )
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)
}
}

использование пусть будний день = дата().weekdayName

Мне понадобилось еще несколько строк с даты, включая дату недели (например, "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
    }
}

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)

}

этот код должен найти всю текущую неделю. Это написано в 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
}

вывод будет выглядеть так:

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

func getDayOfWeek(today:String)->Int {

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

let weekday = getDayOfWeek("2014-08-27")
print(weekday) // 4

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
    }
}

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

я бы предложил получить день недели с помощью 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]
    }
}

для этого требуется инициализация a 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).