Obtenha o dia da semana usando NSDate

91

Eu criei um método que deveria pegar uma string no formato "AAAA-MM-DD" e cuspir um int que representa a posição das datas em relação à semana em que está (independentemente se ela se sobrepõe entre os meses). Então, por exemplo, domingo = 1 segunda-feira = 2 e assim por diante.

Aqui está o meu 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
}

Eu sei que isso NSCalendarUnit.WeekdayOrdinalCalendarestá errado, mas eu tentei combinações mais lógicas. E também mexeu com, myComponents.weekdayOrdinalpor exemplo, usado mycomponents.dayou .weekday.

Aqui estão minhas opções sobre o que 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 }

Não está claro para mim, já que não há opção DayOfWeekUnit (ou algo semelhante).

Boidkan
fonte
1
Consulte: Datas e horários de formatação de ICU para formatar caracteres.
zaph
Possível duplicata de Como obtenho o dia da semana com Cocoa Touch?
Suhaib
1
@Suhaib Se você olhar minhas tags diz Swift, não Objective-C. Além disso, o código está em Swift 2.
boidkan
tente o seguinte "EEEE" em seu formatador de data
Alexandros

Respostas:

121

O que você está procurando (se bem entendi a pergunta) é NSCalendarUnit.CalendarUnitWeekday. A propriedade correspondente de NSDateComponentséweekday .

Observe também que o formato da data está incorreto (a especificação completa pode ser encontrada aqui: http://unicode.org/reports/tr35/tr35-6.html ).

A função pode ser um pouco simplificada, usando inferência automática de tipo, você também usa muitas variáveis ​​onde as constantes são suficientes. Além disso, a função deve retornar um opcional que énil para uma string de entrada inválida.

Código atualizado para Swift 3 e 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
}

Exemplo:

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

Resposta 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
    }
}
Martin R
fonte
Sim, era o formato que estava me atrapalhando. Eu estava recebendo 2 em vez de 4 quando tentei WeekdayCalendarUnit e estava muito confuso! Obrigado pelo link, vou ler sobre ele.
boidkan
1
Eu sei que não faz parte da pergunta original, mas este seria um bom lugar para retornar um Int opcional caso a data passada não esteja no formato correto ou seja inválida de alguma forma.
Mike S
1
Não deveria ser func getDayOfWeek(today:String)->Int?. Se você forçar o desembrulhar o opcional, ele ainda travará, não é?
TEM
1
@HAS: Você está completamente certo, obrigado! - Não travou em meu caso de teste porque a atribuição opcional if let ...também funciona com opcionais não embalados implicitamente.
Martin R
1
Obrigado Marting por isso, para tornar sua resposta mais bonita, você pode editá-la para remover o código do swift 2 e manter o código do swift 3. Em seguida, adicione uma nota no final dizendo: "Se você precisar de código para swift 2, verifique a edição anterior" ou algo parecido
Suhaib
158

Swift 3 e 4

Recuperar o número do dia da semana é dramaticamente simplificado no Swift 3 porque DateComponentsnão é mais opcional. Aqui está como uma extensão:

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 você estava procurando a versão escrita e localizada do dia da 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
fonte
1
Talvez fique mais claro se você colocar aDate.dayOfWeek () em Uso.
boidkan
1
Observe que a questão era como obter o dia da semana de uma string no formato "AAAA-MM-DD". Claro, isso simplifica se você já tiver um NSDate.
Martin R de
4
Provavelmente, vale a pena mencionar que, se você estiver usando, por exemplo, visualização de tabela, pode retardar a rolagem, pois a criação de DateFormatter é bastante cara. Se você for usá-lo com frequência, é bom, por exemplo. crie uma instância e a forneça durante o cálculo para todas as chamadas de função.
Vive
Absolutamente. Nesse caso, até mesmo ter um manipulador de array onde você pudesse executar a função em um array de dados seria útil.
brandonscript
1
mais simples seria apenas a resposta de @ david72 abaixo: Calendar.current.component (.weekday, from: Date ())
Adam Smaka
38

Se você quiser o "domingo" completo, "segunda-feira", "terça", "quarta-feira" etc.

EDIT: Na verdade, existe um formato embutido que retorna nomes de dias localizados:

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

Minha solução anterior (apenas 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]
    }
}

Você não precisa desembrulhar calendário e componentes, eles são garantidos pela estrutura de base.

Uso:

print(myDate.dayOfTheWeek())
Matjan
fonte
6
EEEEE e EEEEEE fornecem formas curtas dos dias, por exemplo, Qua, Qui, Fr
Matjan
1
Ou use a propriedade shortWeekdaySymbols de Calendar para evitar a criação de um DateFormatter completamente.
mikepj de
23

A resposta simples (swift 3):

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

No meu caso, eu estava atrás de uma seqüência de três letras para cada dia. Modifiquei a função de @Martin R da seguinte maneira:

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
fonte
2
Você pode usar EEE comodateFormat
mrvincenzo
10

Existe uma maneira mais fácil. Basta passar a data da string para a seguinte função, ela lhe dará o nome do dia :)

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
fonte
2
estava procurando por "EEE". obrigado
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 dayday = Date (). weekdayName

Akash Shindhe
fonte
8

Extensão de data Swift 3

extension Date {
    var weekdayOrdinal: Int {
        return Calendar.current.component(.weekday, from: self)
    }
}
quemeful
fonte
Eu adicionei um ponto importante à sua resposta, que é a resposta atualizada aqui. Obviamente, sinta-se à vontade para relaxar se não gostar! :) Saúde
Fattie
a pergunta feita por um inteiro
quemeful
6

Você pode usar esta tabela date_formats para converter sua data em diferentes formatos. Meu código mais curto:

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
fonte
Muito obrigado Isso é o que eu estava procurando formatter.dateFormat = "eeee" // "eeee" -> Sexta
Mohammed Abunada
4

SWIFT 5 - Dia da 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"]
        }
     }

Extensão de data com base na resposta de Fattie

Dili
fonte
3

A solução prática ...

Esteja ciente de que os resultados são inteiros de um a sete.

(Diferente de zero a seis.)

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

e depois ...

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

Já existem muitas respostas aqui, mas acho que há outra, talvez melhor, maneira de fazer isso usando a Calendar APIs .

Sugiro obter o dia da semana usando a weekdaySymbolspropriedade de Calendar( docs ) em uma extensão 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]
    }
}

Isso requer inicializar um Dateprimeiro, o que eu faria usando um 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
    }
}

Isso pode ser chamado com:

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

Por que eu prefiro isso:

  1. dayOfWeek não precisa se preocupar com os fusos horários porque o calendário do usuário é usado, algumas das outras soluções aqui mostrarão o dia incorreto porque os fusos horários não são considerados.
  2. É muito provável que você precise usar datas no mesmo formato em outros lugares, então por que não criar um reutilizável DateFormattere usá-lo?
  3. weekdaySymbols está localizado para você.
  4. weekDaySymbolspode ser substituído por outras opções, como shortWeekdaySymbols"Seg", "Ter" etc.

Observação: este exemplo DateFormattertambém não considera fusos horários ou localidades; você precisará defini-los de acordo com suas necessidades. Se as datas forem sempre precisas, considere definir o fuso horário TimeZone(secondsFromGMT: 0).

Leon
fonte
1
É surpreendente que esta seja a única resposta que menciona weekdaySymbols, obrigado
Fattie
1

Acabei precisando de mais algumas strings da data, incluindo a data da semana (por exemplo, "5") e o mês do ano (por exemplo, agosto). Abaixo estão todas as três funções que criei com base na função de @Martin R e modifiquei para retornar 3 strings 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
fonte
1

Código SWIFT 2.0 para apresentar a semana atual a partir de segunda-feira.

@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)

}
Himanshu
fonte
1

Este código é para encontrar toda a semana atual. Está escrito em 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
}

A saída será assim:

14 de março (segunda-feira) 15 de março (terça-feira) 16 de março (quarta-feira) 17 de março (quinta-feira) 18 de março (sexta-feira) 19 de março (sábado) 20 de março (domingo)

Anurag Mehta
fonte
1

Swift 3: função auxiliar do 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
fonte
1
Isso não é localizado.
Alexander
0

Para o Swift4 obter o dia da semana da string

   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
fonte
Como isso é diferente do primeiro método em stackoverflow.com/a/25533357/1187415 ?
Martin R