使用 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 选项(或类似的选项)。

154091 次浏览

What you are looking for (if I understand the question correctly) is NSCalendarUnit.CalendarUnitWeekday. The corresponding property of NSDateComponents is weekday.

Note also that your date format is wrong (the full specification can be found here: http://unicode.org/reports/tr35/tr35-6.html).

The function can be simplified slightly, using automatic type inference, also you use variables a lot where constants are sufficient. In addition, the function should return an optional which is nil for an invalid input string.

Updated code for Swift 3 and later:

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
}

Example:

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

Original answer for 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
}
}

For Swift4 to get weekday from 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

You can use this table date_formats for converting your date to different formats. My shortest code:

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

In my case I was after a three letter string for each day. I modified @Martin R's function as follows:

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

I ended up needing a few more strings from the date, including date of the week (e.g. "5th") and month of the year (e.g. Aug). Below are all three functions I have created based upon @Martin R's function and modified to return 3 char strings:

//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 3 & 4

Retrieving the day of the week's number is dramatically simplified in Swift 3 because DateComponents is no longer optional. Here it is as an extension:

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

If you were looking for the written, localized version of the day of week:

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

There is an easier way. Just pass your string date to the following function, it will give you the day name :)

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

SWIFT 2.0 code to present the current week starting from monday.

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


}

This code is to find the whole current week. It is written 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
}

The output will be like this:

14March(Monday) 15March(Tuesday) 16March(Wednesday) 17March(Thursday) 18March(Friday) 19March(Saturday) 20March(Sunday)

If you want the full "Sunday", "Monday", "Tuesday", "Wednesday" etc.

EDIT: There's actually a built in format that returns localized day names:

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

My previous solution (for English only):

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

You don't need to unwrap calendar and components, they are guaranteed by the foundation framework.

Usage:

print(myDate.dayOfTheWeek())

Swift 3 : Xcode 8 helper function:

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

The simple answer (swift 3):

Calendar.current.component(.weekday, from: Date())
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)
}
}

usage let weekday = Date().weekdayName

Swift 3 Date extension

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

The practical solution ...

Be aware that results are the integers one through seven.

(Not zero through six.)

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

and then ...

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

There are already a lot of answers here but I think there's another, perhaps better, way of doing this using the correct Calendar APIs.

I'd suggest getting the day of the week using the weekdaySymbols property of Calendar (docs) in an extension to 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]
}
}

This requires initialising a Date first, which I would do using a custom 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
}
}

This can then be called with:

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

Why I prefer this:

  1. dayOfWeek does not have to care about time zones because the user's calendar is used, some of the other solutions here will show the incorrect day because time zones are not considered.
  2. It's very likely that you'll need to use dates in the same format in other places so why not create a reusable DateFormatter and use that instead?
  3. weekdaySymbols is localised for you.
  4. weekDaySymbols can be replaced with other options such as shortWeekdaySymbols for "Mon", "Tues" etc.

Please note: This example DateFormatter also doesn't consider time zones or locales, you'll need to set them for what you need. If the dates are always precise, consider setting the time zone TimeZone(secondsFromGMT: 0).

SWIFT 5 - Day of the week

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

Date extension based on Fattie's answer

SWIFT 5

let MyFormatter = DateFormatter()
MyFormatter.dateFormat = "EE MMM dd"
print(MyFormatter.string(from: Date()))

Output is: Thu Jun 03

One can add to the number of E's or M's to change the format of day or month. YY or YYYY can be added for the year as well.

If you want to take full text use below code:

func dayOfWeek(date: Date()) -> String? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE"
return dateFormatter.string(from: date).capitalized
}




print(Date().dayOfWeek()!) // Monday

Or you want short text, take this code:

func dayOfWeek(date: Date()) -> String? {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE"
return dateFormatter.string(from: date).capitalized
}




print(Date().dayOfWeek()!) // Mon

This version returns a computed property and should be called after setting the locale if needed...

extension Date {
/**
Usage: print(Date().dayOfWeek) \\\ Monday
*/
var dayOfWeek: String {
let formatter = DateFormatter()
formatter.setLocalizedDateFormatFromTemplate("EEEE")
return formatter.string(from: self)
}
}
extension Date {


enum Weekday: CaseIterable {
case sunday
case monday
case tuesday
case wednesday
case thursday
case friday
case saturday
}
    

var isWednesday: Bool { dayOfTheWeek == .wednesday } // 🐸
        

var dayOfTheWeek: Date.Weekday {
let dayNumber = Calendar.current.component(.weekday, from: self)
return Weekday.allCases[dayNumber - 1]
}
}