Ottieni il giorno della settimana utilizzando NSDate


91

Ho creato un metodo che dovrebbe contenere una stringa nel formato "AAAA-MM-GG" e sputare un int che rappresenta la posizione delle date in relazione alla settimana in cui si trova (indipendentemente dal fatto che si sovrapponga tra i mesi). Quindi ad esempio domenica = 1 lunedì = 2 e così via.

Ecco il mio codice:

    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
}

So che NSCalendarUnit.WeekdayOrdinalCalendarè sbagliato, ma ho provato la maggior parte delle combinazioni logiche. E ho anche scherzato con, myComponents.weekdayOrdinalad esempio, usato mycomponents.dayo .weekday.

Ecco le mie opzioni su cosa usare:

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 }

Non mi è chiaro poiché non esiste un'opzione DayOfWeekUnit (o qualcosa di simile).


1
Vedere: Date e orari di formattazione ICU per la formattazione dei caratteri.
Zaph il


1
@Suhaib Se guardi i miei tag si dice che Swift non Objective-C. Inoltre, il codice è in Swift 2.
boidkan

prova il seguente "EEEE" nel tuo dataformatter
Alexandros

Risposte:


121

Quello che stai cercando (se ho capito correttamente la domanda) è NSCalendarUnit.CalendarUnitWeekday. La proprietà corrispondente di NSDateComponentsè weekday.

Nota anche che il formato della tua data è sbagliato (la specifica completa può essere trovata qui: http://unicode.org/reports/tr35/tr35-6.html ).

La funzione può essere leggermente semplificata, utilizzando l'inferenza automatica del tipo, inoltre si utilizzano molto le variabili dove le costanti sono sufficienti. Inoltre, la funzione dovrebbe restituire un opzionale che è nil per una stringa di input non valida.

Codice aggiornato per Swift 3 e versioni successive:

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
}

Esempio:

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

Risposta originale per 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
    }
}

Sì, era il formato che mi stava incasinando. Stavo ottenendo 2 invece di 4 quando ho provato WeekdayCalendarUnit ed ero molto confuso! Grazie per il link, lo leggerò.
boidkan

1
So che non fa parte della domanda originale, ma questo sarebbe un buon posto per restituire un Int opzionale nel caso in cui la data passata non sia nel formato corretto o non valida in qualche modo.
Mike S

1
Non dovrebbe essere func getDayOfWeek(today:String)->Int?. Se forzi a scartare l'opzionale, si blocca ancora, vero?
HA

1
@HAS: Hai perfettamente ragione, grazie! - Non è andato in crash nel mio caso di test perché l'assegnazione opzionale if let ...funziona anche con optionals implicitamente scartate.
Martin R

1
Grazie Marting per questo, per rendere la tua risposta più bella potresti modificarla per rimuovere il codice swift 2 e mantenere il codice swift 3. Quindi aggiungi una nota alla fine dicendo: "Se hai bisogno di codice per swift 2, controlla la modifica precedente" o qualcosa del genere
Suhaib

158

Swift 3 e 4

Il recupero del numero del giorno della settimana è notevolmente semplificato in Swift 3 perché DateComponentsnon è più opzionale. Eccolo come estensione:

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

Se stavi cercando la versione scritta e localizzata del giorno della settimana:

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
Forse sarebbe più chiaro se mettessi aDate.dayOfWeek () sotto Usage.
boidkan

1
Tieni presente che la domanda era come ottenere il giorno della settimana da una stringa nel formato "AAAA-MM-GG". Ovviamente semplifica se hai già un NSDate.
Martin R

4
Probabilmente vale la pena menzionare che se lo usi ad es. vista tabella, potrebbe rallentare lo scorrimento, poiché la creazione di DateFormatter è piuttosto costosa. Se hai intenzione di usarlo molto spesso, è bene ad es. creare un'istanza e fornirla durante il calcolo a tutte le chiamate di funzione.
Vive

Assolutamente. In tal caso, sarebbe utile anche un gestore di array in cui è possibile eseguire la funzione su un array di dati.
brandonscript

1
più semplice sarebbe la risposta di @ david72 di seguito: Calendar.current.component (.weekday, from: Date ())
Adam Smaka

38

Se desideri la versione completa di "domenica", "lunedì", "martedì", "mercoledì" ecc.

EDIT: in realtà esiste un formato integrato che restituisce i nomi dei giorni localizzati:

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

La mia soluzione precedente (solo per l'inglese):

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

Non è necessario scartare calendario e componenti, sono garantiti dalla struttura di base.

Utilizzo:

print(myDate.dayOfTheWeek())

6
EEEEE e EEEEEE ti danno brevi forme dei giorni, ad es. Mercoledì,
giovedì

1
Oppure usa la proprietà shortWeekdaySymbols di Calendar per evitare di creare del tutto un DateFormatter.
mikepj

23

La risposta semplice (swift 3):

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

11

Nel mio caso cercavo una stringa di tre lettere per ogni giorno. Ho modificato la funzione di @Martin R come segue:

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

2
Potresti usare EEE comedateFormat
mrvincenzo

10

C'è un modo più semplice. Basta passare la data della stringa alla seguente funzione, ti darà il nome del giorno :)

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
stava cercando "EEE". grazie
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)
}
}

utilizzo lasciare giorno della settimana = Data (). nome della settimana


8

Estensione della data di Swift 3

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

Ho aggiunto un punto importante alla tua risposta, che è la risposta aggiornata qui. Ovviamente sentiti libero di rilassarti se non ti piace! :) Saluti
Fattie

la domanda chiedeva un numero intero
quemeful

6

Puoi utilizzare questa tabella date_formats per convertire la tua data in diversi formati. Il mio codice più breve:

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

Grazie mille Questo è quello che stavo cercando formatter.dateFormat = "eeee" // "eeee" -> Venerdì
Mohammed Abunada

4

SWIFT 5 - Giorno della settimana

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

Estensione della data basata sulla risposta di Fattie


3

La soluzione pratica ...

Tieni presente che i risultati sono i numeri interi da uno a sette.

(Non da zero a sei.)

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

e poi ...

let dow = Calendar.current.component(.weekday, from: someDate)
print( trivialDayStringsORDINAL[dow] )

3

Ci sono già molte risposte qui, ma penso che ci sia un altro modo, forse migliore, per farlo utilizzando le CalendarAPI corrette .

Suggerirei di ottenere il giorno della settimana utilizzando la weekdaySymbolsproprietà di Calendar( docs ) in un'estensione a 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]
    }
}

Ciò richiede l'inizializzazione di un Dateprimo, cosa che farei usando un'usanza 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
    }
}

Questo può quindi essere chiamato con:

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

Perché preferisco questo:

  1. dayOfWeek non deve preoccuparsi dei fusi orari perché viene utilizzato il calendario dell'utente, alcune delle altre soluzioni qui mostreranno il giorno errato perché i fusi orari non vengono considerati.
  2. È molto probabile che dovrai usare le date nello stesso formato in altri posti, quindi perché non creare un riutilizzabile DateFormattere usarlo invece?
  3. weekdaySymbols è localizzato per te.
  4. weekDaySymbols può essere sostituito con altre opzioni come shortWeekdaySymbols "Lun", "Mar" ecc.

Nota: anche questo esempio DateFormatternon considera i fusi orari o le impostazioni locali, dovrai impostarli per ciò che ti serve. Se le date sono sempre precise, valuta la possibilità di impostare il fuso orario TimeZone(secondsFromGMT: 0).


1
È sorprendente che questa sia l'unica risposta che menziona weekdaySymbols, grazie
Fattie

1

Ho finito per aver bisogno di qualche stringa in più dalla data, inclusa la data della settimana (ad esempio "5") e il mese dell'anno (ad esempio, agosto). Di seguito sono riportate tutte e tre le funzioni che ho creato in base alla funzione di @Martin R e modificate per restituire 3 stringhe di caratteri:

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

1

Codice SWIFT 2.0 per presentare la settimana in corso a partire dal lunedì.

@IBAction func show (sender: 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

Questo codice serve per trovare l'intera settimana corrente. È scritto in 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
}

L'output sarà così:

14 marzo (lunedì) 15 marzo (martedì) 16 marzo (mercoledì) 17 marzo (giovedì) 18 marzo (venerdì) 19 marzo (sabato) 20 marzo (domenica)


1

Swift 3: funzione di supporto 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
    }
}

1
Questo non è localizzato.
Alexander

0

Per Swift4 per ottenere il giorno della settimana dalla stringa

   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

In che modo è diverso dal primo metodo in stackoverflow.com/a/25533357/1187415 ?
Martin R
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.