Obtener el día de la semana con NSDate

90

Creé un método que se supone debe tomar una cadena en forma "AAAA-MM-DD" y escupir un int que representa la posición de las fechas en relación con la semana en la que se encuentra (independientemente de si se superpone entre meses). Por ejemplo, domingo = 1 lunes = 2 y así sucesivamente.

Aquí está mi código:

    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
}

Sé que NSCalendarUnit.WeekdayOrdinalCalendarestá mal pero lo he intentado creo que la mayoría de combinaciones lógicas. Y también me he metido con, myComponents.weekdayOrdinalpor ejemplo, usado mycomponents.dayo .weekday.

Aquí están mis opciones sobre qué usar:

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 }

No me queda claro ya que no existe la opción DayOfWeekUnit (o algo similar).

boidkan
fuente
1
Consulte: Fechas y horas de formato de la UCI para conocer el formato de caracteres.
zaph
1
@Suhaib Si miras mis etiquetas, dice Swift, no Objective-C. Además, el código está en Swift 2.
boidkan
pruebe el siguiente "EEEE" en su formato de fecha
Alexandros

Respuestas:

118

Lo que está buscando (si entiendo la pregunta correctamente) es NSCalendarUnit.CalendarUnitWeekday. La propiedad correspondiente de NSDateComponentses weekday.

Tenga en cuenta también que su formato de fecha es incorrecto (la especificación completa se puede encontrar aquí: http://unicode.org/reports/tr35/tr35-6.html ).

La función se puede simplificar un poco, usando la inferencia de tipo automática, también se usan muchas variables donde las constantes son suficientes. Además, la función debe devolver un opcional que es nil para una cadena de entrada no válida.

Código actualizado para Swift 3 y posterior:

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
}

Ejemplo:

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

Respuesta original para 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
    }
}
Martín R
fuente
Sí, era el formato lo que me estaba arruinando. Estaba obteniendo 2 en lugar de 4 cuando probé WeekdayCalendarUnit y estaba muy confundido. Gracias por el enlace, lo leeré.
boidkan
1
Sé que no es parte de la pregunta original, pero este sería un buen lugar para devolver un Int opcional en el caso de que la fecha pasada no esté en el formato correcto o no sea válida de alguna manera.
Mike S
1
¿No debería ser así func getDayOfWeek(today:String)->Int?? Si fuerza a desenvolver el opcional, todavía se bloquea, ¿no es así?
TIENE el
1
@HAS: ¡Tienes toda la razón, gracias! - No se bloqueó en mi caso de prueba porque la asignación opcional if let ...también funciona con opcionales sin envolver implícitamente.
Martin R
1
Gracias Marting Por esto, para que su respuesta sea más hermosa, puede editarla para eliminar el código swift 2 y mantener el código swift 3. Luego agregue una nota al final que diga: "Si necesita un código para Swift 2, verifique la edición anterior" o algo por el estilo
Suhaib
155

Swift 3 y 4

La recuperación del número del día de la semana se simplifica drásticamente en Swift 3 porque DateComponentsya no es opcional. Aquí está como una extensión:

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

Si estaba buscando la versión escrita y localizada del día de la semana:

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
brandonscript
fuente
1
Quizás sería más claro si pones aDate.dayOfWeek () en Usage.
boidkan
1
Tenga en cuenta que la pregunta era cómo obtener el día de la semana a partir de una cadena con el formato "AAAA-MM-DD". Por supuesto, se simplifica si ya tiene un NSDate.
Martin R
4
Probablemente valga la pena mencionar que si lo está usando, por ejemplo. vista de tabla, puede ralentizar el desplazamiento, ya que crear DateFormatter es bastante caro. Si lo va a usar con mucha frecuencia, es bueno, por ejemplo. crear una instancia y proporcionarla durante el cálculo a todas las llamadas a funciones.
Vive el
Absolutamente. En ese caso, incluso sería útil tener un controlador de matriz en el que pudiera ejecutar la función en una matriz de datos.
brandonscript
1
más simple sería la respuesta de @ david72 a continuación: Calendar.current.component (.weekday, from: Date ())
Adam Smaka
37

Si desea el "domingo", "lunes", "martes", "miércoles" completo, etc.

EDITAR: En realidad, hay un formato integrado que devuelve nombres de días localizados:

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

Mi solución anterior (solo para inglés):

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

No necesita desenvolver el calendario y los componentes, están garantizados por el marco de la base.

Uso:

print(myDate.dayOfTheWeek())
Matjan
fuente
5
EEEEE y EEEEEE le brindan formas breves de los días, por ejemplo, miércoles,
jueves
1
O use la propiedad shortWeekdaySymbols de Calendar para evitar crear un DateFormatter por completo.
mikepj
22

La respuesta simple (rápido 3):

Calendar.current.component(.weekday, from: Date())
david72
fuente
11

En mi caso, buscaba una cadena de tres letras para cada día. Modifiqué la función de @Martin R de la siguiente manera:

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
fuente
2
Puede usar EEE comodateFormat
mrvincenzo
10

Hay una manera más fácil. Simplemente pase la fecha de su cadena a la siguiente función, le dará el nombre del día :)

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);
    }
Hamid
fuente
2
estaba buscando "EEE". gracias
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)
}
}

uso let weekday = Date (). weekdayName

Akash Shindhe
fuente
8

Extensión Swift 3 Date

extension Date {
    var weekdayOrdinal: Int {
        return Calendar.current.component(.weekday, from: self)
    }
}
quemeful
fuente
Agregué un punto importante a su respuesta, que es la respuesta actualizada aquí. ¡Obviamente siéntete libre de relajarte si no te gusta! :) Saludos
Fattie
la pregunta se hizo para un número entero
quemeful
6

Puede utilizar esta tabla date_formats para convertir su fecha a diferentes formatos. Mi código más corto:

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
fuente
Muchas gracias. Esto es lo que estaba buscando formatter.dateFormat = "eeee" // "eeee" -> Viernes
Mohammed Abunada
4

SWIFT 5 - Día de la semana

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

Extensión de fecha basada en la respuesta de Fattie

Dili
fuente
3

La solución práctica ...

Tenga en cuenta que los resultados son los números enteros del uno al siete.

(No de cero a seis).

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

y entonces ...

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

Ya hay muchas respuestas aquí, pero creo que hay otra forma, quizás mejor, de hacerlo usando el Calendar API .

Sugeriría obtener el día de la semana usando la weekdaySymbolspropiedad de Calendar( docs ) en una extensión para 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]
    }
}

Esto requiere inicializar un Dateprimero, lo que haría usando un personalizado 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
    }
}

Esto luego se puede llamar con:

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

Por qué prefiero esto:

  1. dayOfWeek no tiene que preocuparse por las zonas horarias porque se usa el calendario del usuario, algunas de las otras soluciones aquí mostrarán el día incorrecto porque no se consideran las zonas horarias.
  2. Es muy probable que necesites usar fechas en el mismo formato en otros lugares, así que ¿por qué no crear un reutilizable DateFormattery usarlo en su lugar?
  3. weekdaySymbols está localizado para usted.
  4. weekDaySymbolsse puede reemplazar con otras opciones como shortWeekdaySymbols"Lun", "Mar", etc.

Tenga en cuenta: este ejemplo DateFormattertampoco considera las zonas horarias o las configuraciones regionales, deberá configurarlas para lo que necesite. Si las fechas son siempre precisas, considere establecer la zona horaria TimeZone(secondsFromGMT: 0).

León
fuente
1
Es asombroso que esta sea la única respuesta que menciona weekdaySymbols, gracias
Fattie
1

Terminé necesitando algunas cadenas más de la fecha, incluida la fecha de la semana (por ejemplo, "5") y el mes del año (por ejemplo, agosto). A continuación se muestran las tres funciones que he creado según la función de @Martin R y modificadas para devolver 3 cadenas de caracteres:

//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
fuente
1

Código SWIFT 2.0 para presentar la semana actual a partir del lunes.

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

}
Himanshu
fuente
1

Este código sirve para encontrar toda la semana actual. Está escrito en 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
}

La salida será así:

14 de marzo (lunes) 15 de marzo (martes) 16 de marzo (miércoles) 17 de marzo (jueves) 18 de marzo (viernes) 19 de marzo (sábado) 20 de marzo (domingo)

Anurag Mehta
fuente
1

Swift 3: función auxiliar de 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
fuente
1
Esto no está localizado.
Alexander - Reincorpora a Monica
0

Para que Swift4 obtenga el día de la semana de la cadena

   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
Sébastien REMY
fuente
¿En qué se diferencia del primer método en stackoverflow.com/a/25533357/1187415 ?
Martin R