Wrong Date is Display from DateComponets - swift

let dateString = "2017-10-08T00:12:00.000Z"
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
let date = formatter.date(from: dateString)!
let components = Calendar.current.dateComponents(in: TimeZone(identifier: "America/New_York")!, from: date)
print("Day - \(components.day!)")
print("Month - \(components.month!)")
print("Year - \(components.year!)")
print("Hour - \(components.hour!)")
print("Min - \(components.minute!)")
print("Second - \(components.second!)")
print("Final Date - \(components.date!)")
By running the above code i got the output
Day - 7
Month - 10
Year - 2017
Hour - 20
Min - 12
Second - 0
Final Date - 2017-10-08 00:12:00 +0000
But my Expected Date should be
Final Date - 2017-10-07 20:12:00 +0000

I GOT SOLUTION AS #Leo Dabus say issue with Timezone so
let dateString = "2017-10-08T00:12:00.000Z"
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
let date = formatter.date(from: dateString)!
let components = Calendar.current.dateComponents(in: TimeZone(identifier: "America/New_York")!, from: date)
//Converting part
let gregorian = Calendar(identifier: .gregorian)
var dateComponents = components
dateComponents.timeZone = TimeZone.init(identifier: "UTC") //Here is the logic
let myDate = gregorian.date(from: dateComponents)!
print(myDate)
Now i get the converted date as output.
2017-10-07 20:12:00 +0000

Related

Wrong Day From date

I get wrong Day from a Date.
I put in for example formatter.date(from: "14.03.2019") which is a Thursday and later in formatter.weekSymbols I get printed the day after it (Friday)
why is that happening? Here's my code
`
func returnFormattedDate() -> String {
let formattedDay = String(format: "%02d.%02d", day, month)
return "\(formattedDay).2019"
}
func returnWeekDay() -> String? {
let formatter = DateFormatter()
formatter.dateFormat = "dd.MM.yyyy"
formatter.locale = Locale(identifier: "de_DE")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
print(returnFormattedDate())
guard let todayDate = formatter.date(from: returnFormattedDate()) else { return nil }
print(todayDate) // prints 2019-03-14 00:00:00 +0000
let nameOfDay = formatter.weekdaySymbols[Calendar(identifier: .gregorian).component(.weekday, from: todayDate)]
print(nameOfDay) // prints 'Friday' instead of thursday
return nameOfDay
}
Two mistakes in your code.
You have to set time zone
weekday values are 1...7 (1 = Sunday, 7 = Saturday) but the array of weekdaySymbols obviously starts with index 0 (weekdaySymbols[0] = Sunday, weekdaySymbols[6] = Saturday). So let's just subtract 1.
let dateString = "14.3.2019"
let formatter = DateFormatter()
formatter.dateFormat = "dd.MM.yyyy"
formatter.locale = Locale(identifier: "de_DE")
// ERROR 1
// you have to set timezone. Since we don't care about time, let's just use UTC.
formatter.timeZone = TimeZone(secondsFromGMT: 0)
let todayDate = formatter.date(from: dateString)!
print(todayDate)
var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(secondsFromGMT: 0)!
// ERROR 2: you are indexing incorrectly
let nameOfDay = formatter.weekdaySymbols[calendar.component(.weekday, from: todayDate) - 1]
print(nameOfDay)

How to compare AM PM in swift

I hardly try but can't find how to compare am and pm.
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "h:mm a"
formatter.amSymbol = "AM"
formatter.pmSymbol = "PM"
dateString = formatter.string(from: Date())
// date Format
dateFormatter.timeStyle = DateFormatter.Style.none;
dateFormatter.dateStyle = DateFormatter.Style.medium;
currentDate = dateFormatter.string(from: now);
if self.dateString >= "09:00 AM" { return true }
In iOS, Apple provide compare function to compare to Date objects.
Please find the below code to compare time
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "h:mm a"
formatter.amSymbol = "AM"
formatter.pmSymbol = "PM"
let timeString = formatter.string(from: Date())
let firstTime = formatter.date(from: "09:00 AM")
let secondTime = formatter.date(from: dateString)
if firstTime?.compare(secondTime!) == .orderedAscending {
print("First Time is smaller then Second Time")
}

Convert time string to Unix time date of the same day

how to convert a string hour to millisecond of the day?
for exemple:
let strDate = "06:00 PM"
Or:
let strDate = "09:00 AM"
my code:
let dateString = "06:00 PM"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
guard let date = dateFormatter.date(from: dateString)
else { fatalError() }
print(date)
for example my string is: 06:00 PM, so I want to have the date in millisecond of today Thursday 20 September 2018 at 06:00 PM
You can set your DateFormatter default date to startOfDay for today, set the formatter locale locale to "en_US_POSIX" when parsing your time then you can simply get your resulting date timeIntervalSince1970 and multiply by 1000:
let strTime = "06:00 PM"
let formatter = DateFormatter()
formatter.defaultDate = Calendar.current.startOfDay(for: Date())
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "hh:mm a"
if let date = formatter.date(from: strTime) {
let milliseconds = date.timeIntervalSince1970 * 1000
print(milliseconds) // 1537477200000
let date2 = Date(timeIntervalSince1970: milliseconds/1000)
print(date2.description(with: .current)) // Thursday, September 20, 2018 at 6:00:00 PM Brasilia Standard Time
}
First, you need to parse the date string:
let dateString = "06:00 PM"
let formatter = DateFormatter()
formatter.defaultDate = Date()
formatter.dateFormat = "hh:mm a"
formatter.locale = Locale(identifier: "en_US_POSIX")
let date = formatter.date(from: dateString)
Then, you need to get the start of day:
let calendar = Calendar.current
let start = calendar.startOfDay(for: date)
After that, get the time interval between date and start:
let timeInterval = date.timeIntervalSince(start)
let milliseconds = timeInterval * 1000.0

milliseconds to full date returns wrong day in my time zone

I have developed an app which must show the current date and time not reading from device but from a http-get service
I read a long integer from server and I should converted to current year month day and time
I'm using this method but returns a wrong day and time.
func setDay(day:Double) {
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .persian)
formatter.locale = Locale(identifier: "fa_IR")
var date = Date(timeIntervalSince1970: (day / 1000.0))
// day
formatter.dateFormat = "dd"
//time=formatter.string(from: date)
self.day = formatter.string(from: date)
print(self.day) //wrong day
}
for example the long integer is : 1532928652552.0
and the day of this month in my country is 11 but returns 8
func convertEpochToStringDate(epoch: Int) -> String {
let dbl = TimeInterval(epoch)
let date = Date(timeIntervalSince1970: dbl)
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .persian)
formatter.locale = Locale(identifier: "fa_IR")
formatter.dateFormat = "dd"
formatter.timeZone = TimeZone(identifier: "IRST")
return formater.string(from: date)
}
Let's test it:
let time = convertEpochToStringDate(epoch: 1532928652552 / 1000)
print(time)
Out put: ۰۸

How to convert a string UTC date to NSDate in Swift

I'm getting UTC string dates that look like this "2015-10-17T00:00:00.000Z" and want to convert them to an NSDate in this format "October 12th 2015 11:19:12 am"
This is the route that I'm trying but I can't seem to get the right dateFormat.
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = //can't seem to get this right
dateFormatter.timeZone = NSTimeZone(name: "UTC")
let date = dateFormatter.dateFromString("2015-10-17T00:00:00.000Z")
I think this should work
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let localDate = formatter.date(from: date)
This works for Swift 3.0 and latest Xcode [April 2017]
let dateString = "2017-Jan-01 12:00:00.250"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-M-dd HH:mm:ss.SSS"
dateFormatter.locale = Locale.init(identifier: "en_GB")
let dateObj = dateFormatter.date(from: dateString)
let date = dateObj
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSXXXXX"
let currentDateTime = formatter.string(from: date!)
Swift 4 code
let dateString = "2015-10-17T00:00:00.000Z"
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
let date = formatter.date(from: dateString)
You can find useful info about date formats here
This question is a few years old but let's answer it literally.
First of all DateFormatter doesn't provide a format specifier for an ordinal suffix so we have to write a function
func ordinalSuffix(for day : String) -> String {
switch day {
case "1", "11", "21", "31": return "st"
case "2", "12", "22": return "nd"
case "3", "13", "23": return "rd"
default: return "th"
}
}
To convert the iso8601 string to date create a DateFormatter, set its calendar to an iso8601 calendar and convert the string to Date. As the time zone is specified in the string you don't need to set it explicitly
let dateString = "2015-10-17T00:00:00.000Z"
let formatter = DateFormatter()
formatter.calendar = Calendar(identifier: .iso8601)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
guard let date = formatter.date(from: dateString) else {
// replace that with a proper error handling
fatalError("Could not convert date string")
}
To convert the date back to string you have to set the Locale to a fixed value, set the am/pm symbols to the lowercase versions, extract the day component first for the ordinal suffix calculation and then take advantage of String(format to insert the ordinal suffix.
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.amSymbol = "am"
formatter.pmSymbol = "pm"
formatter.dateFormat = "dd"
let day = formatter.string(from: date)
formatter.dateFormat = "MMMM dd'%#' yyyy h:mm:ss a"
let output = String(format: formatter.string(from: date), ordinalSuffix(for: day))
print(output)