Mismatch between String Date and NSDate through dateFromString in XCode - ios

I am having an issue with converting a string to NSDate in Xcode: I am trying to get the current date, subtract one day and set the hour to noon. This is how I'm going about it (thw two snippets are in different functions):
let date = NSDate();
let dateFormatter = NSDateFormatter()
//var locale = NSLocale(localeIdentifier: "en_US_POSIX")
//dateFormatter.locale = locale
dateFormatter.dateFormat = "dd/mm/yyyy HH:mm"
dateFormatter.timeZone = NSTimeZone.localTimeZone()
var string = dateFormatter.stringFromDate(date)
var localdate = dateFormatter.dateFromString(string)
var localString = dateFormatter.stringFromDate(localdate!)
var calendar = NSCalendar.currentCalendar()
var components = calendar.components(NSCalendarUnit.HourCalendarUnit | NSCalendarUnit.DayCalendarUnit | NSCalendarUnit.MonthCalendarUnit | NSCalendarUnit.YearCalendarUnit, fromDate: localdate!)
self.dateCriteriaHour = components.hour
self.dateCriteriaDay = components.day
self.dateCriteriaMonth = components.month
self.dateCriteriaYear = components.year
This seems to work: I get the current date's components. Then I do this:
var day = String(self.dateCriteriaDay - 1)
var month = String(currentMonth)
var year = String(self.dateCriteriaYear)
var hour = "12:00"
var date = year + "/" + month + "/" + day + " " + hour
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy/m/dd HH:mm"
var criteriaDate = dateFormatter.dateFromString(date)
println(date)
println(NSDate())
println(criteriaDate)
This is where things get strange. Here is the output to the console:
2015/7/11 12:00
2015-07-12 15:21:42 +0000
Optional(2015-01-11 04:00:00 +0000)
I understand that the device stores time in its selected time zone so I'm not too worried about that. What puzzles me is basically that everything is right except for the month, even though it comes out right in the string.
Any idea as to why this is happening?

Your dateformat is wrong.
dd/mm/yyyy HH:mm
^^ ^^
You use mm two times. A lower case m means minutes, an upper case M means month. So your dateFormat should be dd/MM/yyyy HH:mm

Related

How to compare 2 dates and get how far they are apart from each other

I have this string date value
let stringDate = 2018-06-10T13:57:23.232+0000
the string date format will always be the same and I want to have output similar to one of these
6 year, 3 month, 1 day
or
3 month, 20 days
or
1 day
Basically I'm comparing the stringDate with current date and display how far they are apart from each other.
I'm able to get the date from string using this
let dateFormatter = DateFormatter()
var dateFromString: Date?
dateFormatter.timeZone = NSTimeZone.local
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
if let dateReturn = dateFormatter.date(from: stringDate) {
dateFromString = dateReturn
}
but I'm stuck on how to get the custom input like above. Thank you for helping me

apply DayLightSavingTime to NSDate

I get a NSDate from a UIDatePicker (timePicker) which is converted to the users time zone but it is one hour off because I'm in Summer Time.
So I tried to check if the User is in Summer Time if yes it should add the time to the NSDate/dateInUserTimezone.
How can I achieve this?
func convertTimeZone() ->NSDate {
var date = timePicker.date
print(date)
var formatter = NSDateFormatter()
let timeZone = NSTimeZone(abbreviation: userTimeZone())
formatter.timeZone = timeZone
formatter.dateFormat = "HH:mm:ss"
var isDaylightSavingTime: Bool {
return NSTimeZone.localTimeZone().daylightSavingTime
}
print(isDaylightSavingTime)
var daylightSavingTimeOffset: NSTimeInterval {
return NSTimeZone.localTimeZone().daylightSavingTimeOffset
}
let dateInUserTimezone = formatter.dateFromString(formatter.stringFromDate(date))
return dateInUserTimezone!
}
func userTimeZone() -> String {
return NSTimeZone.localTimeZone().abbreviation ?? ""
}
NSDate is inherently in UTC (it has no timezone). Best to save/transfer your dates in UTC. Then, you can convert this UTC time stamp to any time zone of your preference. Instead of detecting whether the user is DST or not, try converting to your preferred time zone. Here's an example of how you would convert any date to local time zone.
var date = ...
var myTimeZone = NSTimeZone.localTimeZone()
var df = NSDateFormatter()
df.timeZone = myTimeZone
df.dateFormat = "yyyy.MM.dd G 'at' HH:mm:ss zzz"
df.stringFromDate(date)

Date string to NSDate swift

i'm having an array fill with date string, which i would like to go through and check whether the date is today or yesterday. The date string could look like following:
2015-04-10 22:07:00
So far i've tried just to convert it using dateFormatter, but it keeps returning nil
var dateString = arrayNews[0][0].date as NSString
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"
var date = dateFormatter.dateFromString(dateString as String)
println(date)
the sudo code i would like to look something like this
if dateString == currentDate
date = "Today, hh:mm"
else if dateString == currentDate(-1)
date = "Yesterday, hh:mm
else
date = dd. MM, hh:mm
in the else statement the date could be 1. April, 12:00
How can i achieve such a logic?
Without the logic
func getDate(dateStr:String, format:String = "yyyy-MM-dd HH:mm:ss") -> NSString {
var dateFmt = NSDateFormatter()
dateFmt.timeZone = NSTimeZone.defaultTimeZone()
dateFmt.dateFormat = format
let newsDate = dateFmt.dateFromString(dateStr)!
let date = NSDate();
let dateFormatter = NSDateFormatter()
dateFormatter.timeZone = NSTimeZone()
let localDate = dateFormatter.stringFromDate(date)
return ""
}
You have to use yyyy-MM-dd HH:mm:ss instead of yyyy-MM-dd hh:mm:ss
HH: 24h format
hh: 12h format (with AM/PM)
Pay attention with dateFormatter, by default, it use localtime zone.
println() shows the value for GMT time, which is hold by NSDate.
It means, without specifying timezone, when you convert your string 2015-04-10 22:07:00 to NSDatetime, it return a data which is the time at your local time zone is 2015-04-10 22:07:00. As NSDate holds date time in GMT, you will see a different value when you show the value of that NSDate with println().
If your timezone is GMT+2 (2h earlier than GMT), when it's 22h:07 in your place, the GMT time is 20h:07. When you call println() on that NSDate, you see 2015-04-10 20:07:00
To compare 2 NSDate:
let calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
let compareResult = calendar?.compareDate(date, toDate: date2, toUnitGranularity: NSCalendarUnit.CalendarUnitDay)
if (compareResult == NSComparisonResult.OrderedSame) {
println("yes")
} else {
println("no")
}
//to get yesterday, using NSCalendar:
let yesterday = calendar?.dateByAddingUnit(NSCalendarUnit.CalendarUnitDay, value: -1, toDate: date, options: NSCalendarOptions.MatchStrictly)

NSDateFormatter dateFromString returning wrong date

Quick question.
I have a string date: example var dateString = "17-02-2015"
I use:
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"
var newDate = dateFormatter.dateFromString(dateString)
And I get the output: 2015-01-16 23:02:00 +0000
Why am I missing a day? Is it because of the time zone? (I am at +1, and in the date the timezone is 0?).
I also tryed setting the time zone:
dateFormatter.locale = NSLocale.currentLocale()
dateFormatter.timeZone = NSTimeZone.systemTimeZone()
But no success.
What am I missing?
Thats the UTC time and it is correct considering the fact that your LocalTime is 1+
var dateString = "17-02-2015"
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"
var newDate = dateFormatter.dateFromString(dateString)!
println(newDate.descriptionWithLocale(NSLocale.currentLocale())!)

Hijri (islamic) calendar in swift التاريخ الهجري

can someone help me please
I'm trying to create an IOS app using Swift language and I need to use Hijri (islamic) calendar
I tried many time but I failed :(
this is my try
let datenow = NSDate()
let calendar = NSCalendar.currentCalendar()
let components = calendar.components(NSCalendarUnit(UInt.max), fromDate: datenow)
var gregorian = NSCalendar(identifier:NSIslamicCivilCalendar)
var date = gregorian.dateFromComponents(components)
println(date)
and the output is wrong
2576-04-25 09:05:08 +0000
We are in year 1434 in hijri not 2576 !
You're mixing up the calendars, dates & components:
let datenow = NSDate()
// This is a point in time, independent of calendars
let calendar = NSCalendar.currentCalendar()
// System calendar, likely Gregorian
let components = calendar.components(NSCalendarUnit(UInt.max), fromDate: datenow)
// Gregorian components
println("\(components.year)") // "2014"
var islamic = NSCalendar(identifier:NSIslamicCivilCalendar)! // Changed the variable name
// *** Note also NSCalendar(identifier:) now returns now returns an optional ***
var date = islamic.dateFromComponents(components)
// so you have asked to initialise the date as AH 2014
println(date)
// This is a point in time again, sometime in AH 2014, or AD 2576
What you need to do is simply:
let datenow = NSDate()
let islamic = NSCalendar(identifier:NSIslamicCivilCalendar)!
let components = islamic.components(NSCalendarUnit(UInt.max), fromDate: datenow)
println("Date in system calendar:\(datenow), in Hijri:\(components.year)-\(components.month)-\(components.day)")
//"Date in system calendar:2014-09-25 09:53:00 +0000, in Hijri:1435-11-30"
To get a formatted string, rather than just the integer components, you need to use NSDateFormatter, which will allow you to specify the calendar & date as well as the format. See here.
Update
To simply transliterate the numerals to (Eastern) Arabic numerals (as 0...9 are referred to as (Western) Arabic numerals to distinguish them from, say, Roman numerals), as requested, you could use:
let sWesternArabic = "\(components.day)-\(components.month)-\(components.year)"
let substituteEasternArabic = ["0":"٠", "1":"١", "2":"٢", "3":"٣", "4":"٤", "5":"٥", "6":"٦", "7":"٧", "8":"٨", "9":"٩"]
var sEasternArabic = ""
for i in sWesternArabic {
if let subs = substituteEasternArabic[String(i)] { // String(i) needed as i is a character
sEasternArabic += subs
} else {
sEasternArabic += String(i)
}
}
println("Western Arabic numerals = \(sWesternArabic), Eastern Arabic numerals = \(sEasternArabic)")
Get Hajri Date:
Swift :
let dateFor = DateFormatter()
let hijriCalendar = Calendar.init(identifier: Calendar.Identifier.islamicCivil)
dateFor.locale = Locale.init(identifier: "ar") // or "en" as you want to show numbers
dateFor.calendar = hijriCalendar
dateFor.dateFormat = "dd/MM/yyyy"
print(dateFor.string(from: Date()))
Obj-C :
NSCalendar *hijriCalendar2 = [[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierIslamicCivil];
NSDateFormatter * lastDate = [[NSDateFormatter alloc]init];
lastDate.calendar = hijriCalendar2;
[lastDate setDateFormat:#"dd/MM/yyyy HH:mm:ss"];
NSString * dateString = [lastDate stringFromDate:[NSDate date]];
thank you #Grimxn and I also find a great way to show arabic numbers
let formatter = NSNumberFormatter()
formatter.locale = NSLocale(localeIdentifier: "ar_SA")
var date:String = "\(formatter.stringFromNumber(components.year))-\(formatter.stringFromNumber(components.month))-\(formatter.stringFromNumber(components.day))"
it will print ١-١١-١٤٣٤
Swift 3 & 4
let dateNow = DateFormatter()
let islamicCalendar = Calendar.init(identifier: Calendar.Identifier.islamicCivil)
dateNow.calendar = islamicCalendar
dateNow.locale = Locale.init(identifier: "ar_SA") // This is used to show numbers, day and month in arabic letters
dateNow.dateFormat = "EEE dd MMM yyyy"
print("\(dateNow.string(from: Date()))")
find out and place date format from:
http://userguide.icu-project.org/formatparse/datetime
Swift 5:
let hijriCalendar = Calendar(identifier: .islamicCivil)
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "ar")
formatter.calendar = hijriCalendar
formatter.dateFormat = "dd/MM/yyyy"
print(formatter.string(from: Date()))

Resources