How to get only time from the date with am/pm. Below is my code what I have tried so far:
func changeFormat(str:String) -> String {
let dateFormatter = DateFormatter()
let newDateFormatter = DateFormatter()
// step 1
dateFormatter.dateFormat = "MM/dd/yyyy HH:mm aa" // input format
newDateFormatter.dateFormat = "HH:mm aa" // output format
let date = dateFormatter.date(from: str)!
// step 2
let string = newDateFormatter.string(from: date)
return string
}
Usage:
let strTimeFromDate = changeFormat(str: self.response?.Data[indexPath.row].ADateTime ?? "")
input date:
06/22/2021 2:00 PM
output:
12:45 PM
Getting wrong time return after formatting. Please guide what's wrong with above code
As mentioned by #JoakimDanielson in the comment, you are mixing HH (24 hours format) with hh (12 hours format). Using hh for the dateFormatter (given your input has 02:00 PM) should fix your issue (as long as this input value was captured in the same time zone in which you intend to convert).
In case you are still seeing that the output is not expected, then it is the issue with missing timeZone info in your input. You are trying to convert String > Date > String without specifying an input timeZone & output timeZone. You can try printing these values in your implementation.
print("dateFormatter.timeZone.secondsFromGMT() : \(dateFormatter.timeZone.secondsFromGMT())")
let date = dateFormatter.date(from: str)!
print("parsed date : \(date)")
print("\n ------------------------ \n")
// step 2
print("newDateFormatter.timeZone.secondsFromGMT() : \(newDateFormatter.timeZone.secondsFromGMT())")
let string = newDateFormatter.string(from: date)
print("parsed string : \(string)")
For me it prints following. 19800 / (60 * 60) = 5.5 (+05:30)
dateFormatter.timeZone.secondsFromGMT() : 19800
parsed date : 2021-06-22 06:30:00 +0000
------------------------
newDateFormatter.timeZone.secondsFromGMT() : 19800
parsed string : 12:00 PM
The issue is - for these two conversions to happen correctly - you must specify an appropriate time zone.
String to Date
Date to String
Here's what that implementation could look like. Assuming input is "06/22/2021 2:00 PM +0530"
func changeFormat(str: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: Int(5.5*60*60)) // +05:30
let newDateFormatter = DateFormatter()
newDateFormatter.timeZone = TimeZone(secondsFromGMT: Int(5.5*60*60)) // +05:30
dateFormatter.dateFormat = "MM/dd/yyyy hh:mm aa Z"
newDateFormatter.dateFormat = "hh:mm aa"
let date = dateFormatter.date(from: str)!
let string = newDateFormatter.string(from: date)
return string
}
When you are consuming this date string from your backend server, you should consider using appropriate time zone for it. An example, assuming input is "06/22/2021 2:00 PM +0000" -
func changeFormat(str: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0) // Server timeZone (UTC)
let newDateFormatter = DateFormatter()
newDateFormatter.timeZone = TimeZone.current // User's timeZone
dateFormatter.dateFormat = "MM/dd/yyyy hh:mm aa Z"
newDateFormatter.dateFormat = "hh:mm aa"
let date = dateFormatter.date(from: str)!
let string = newDateFormatter.string(from: date)
return string
}
"HH" is for 24h format and "aa" is for 12h format so you can't mix them, so you should use "hh:mm a" instead for both DateTimeFormatter's
Related
I'm working on an iOS project in swift 5. In one of my API, the date is coming in the format, "yyyy-MM-dd HH:mm:ss.m". And from this date, I need to fetch the time. But the issue is, suppose the date I'm getting from API is "1900-01-01 08:30:00.000000", and when I convert this date format to YYYY-MM-dd HH:mm:ss, the result is coming as "1900-01-01 08:00:00", the time before conversion is 08:30:00.000000 but after conversion 08:00:00. Why it is happening? Please help me.
I will add my code here,
let dateTime = "1900-01-01 08:30:00.000000"
let outFormatter = DateFormatter()
outFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.m"
if let date = outFormatter.date(from: dateTime) {
//here value od date is 1900-01-01 04:18:48 +0000
outFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
outFormatter.locale = tempLocale
let exactDate = outFormatter.string(from: date)
//here the value of exactDate is 1900-01-01 08:00:00
}
m is minutes and S is milliseconds so the format must be "yyyy-MM-dd HH:mm:ss.S".
Further for fixed date formats it's highly recommended to set the locale to en_US_POSIX
let dateTime = "1900-01-01 08:30:00.000000"
let outFormatter = DateFormatter()
outFormatter.locale = Locale(identifier: "en_US_POSIX")
outFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss.S"
if let date = outFormatter.date(from: dateTime) {
//here value od date is 1900-01-01 04:18:48 +0000
outFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let exactDate = outFormatter.string(from: date)
//here the value of exactDate is 1900-01-01 08:00:00
}
But if you only want to strip the milliseconds from the date string there is a simpler solution
let dateTime = "1900-01-01 08:30:00.000000"
let exactDate = dateTime.replacingOccurrences(of: "\\.\\d+", with: "", options: .regularExpression)
It removes the dot and any digit behind
i am passing "01/12/2017" in the fromDate.text(textfield), but receiving unexpected output.
let formatter = DateFormatter.init()
formatter.dateFormat = "dd/mm/yyyy"
startDate = formatter.date(from: fromDate.text!)
print("startDate = \(startDate)")
output is : 31/12/2016
The format of date should be dd/MM/yyyy not dd/mm/yyyy. The mm indicates the minutes and MM indicates the month.
And also add the below line in your code
formatter.timeZone = TimeZone(abbreviation: "GMT+0:00")
This line of code set time zone. If you not, then you get 30/11/2017 in output.
The reason behind this is when string date not contain time then formatter assume that it is midnight and you also not given the timezone so it will take current timezone.
It has to be dd/MM/yyyy dateformat. MM in capital.
func convertToString(of dateTo: Date) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy" //Your New Date format as per requirement change it own
let newDate: String = dateFormatter.string(from: dateTo) //pass Date here
print(newDate) //New formatted Date string
return newDate
}
I am parsing date from server into a custom format :-
This is the date :- "8/9/2017 3:58:00 AM" but it is not parsing into Date object using this format "MM/dd/yyyy hh:mm:ss a" because obviously the month, day and hour is single digit
As per my knowledge it should parse automatically because Android's DateFormat parses the same date.
This is the code snippet i am using :-
func getDateString(_ dateString:String) -> String{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "M/dd/yyyy hh:mm:ss a"
let date = dateFormatter.date(from: dateString)
dateFormatter.dateFormat = "dd MMM yyyy"
return dateFormatter.string(from: date!)
}
This function is returning null
Your code should work, although you should also add some error-checking.
Try this (it will run in a Playground):
// returns an empty string "" if the date format is invalid
func getDateString(_ dateString:String) -> String {
var strResult = ""
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "M/dd/yyyy hh:mm:ss a"
if let date = dateFormatter.date(from: dateString) {
dateFormatter.dateFormat = "dd MMM yyyy"
strResult = dateFormatter.string(from: date)
}
return strResult
}
let dateString = getDateString("8/9/2017 3:58:00 AM")
print(dateString) // prints "09 Aug 2017"
If you change your "source" string to an invalid date/time - such as changing the month from 8 to 18 or the hour from 3 to 13 - you will see the returned value is an empty string.
**
GET GMT DATE STRING
**
func getGMTString(dateAsDate:NSDate) -> String
{
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss zzz"//this your string date format
// dateFormatter.locale = NSLocale.currentLocale()
// dateFormatter.timeZone = NSTimeZone(name: "GMT")
let date = dateFormatter.stringFromDate(dateAsDate)
return date
}
OUTPUT
startDate---2016-06-29 00:00:00 GMT+5:30
endDate----2016-06-30 03:57:39 GMT+5:30
NOW TRYING to get GMT Date object from output string
func getGMTDate(string:String) -> NSDate {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss zzz"//this your string date format
// dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT")!
// dateFormatter.locale = NSLocale.currentLocale()
let date = dateFormatter.dateFromString(string)
return date!
}
PROBLEM: OUTPUT DATE OBJECT MESS
startDateOBJECT---2016-06-28 18:30:00 +0000 endDateOBJECT----2016-06-30 17:30:00 +0000
Unable to figure what is going wrong
I don't understand your step 3. I looks like you're using NSLog or a Swift print to display the resulting date. That is ALWAYS done in UTC.
If you want to view your date in a different format, or with your local time zone, you need a second date formatter to convert the NSDate to an output date string.
Here's the flow:
input date string -> input date formatter -> NSDate
NSDate -> output date formatter -> display date in local time zone
I want to get a date that is represented in a String with a time zone GMT+1 and display it on screen with the local time zone GMT+10.
I have 2 methods, one is for create a date from a String (with GMT+1 timeZone), the other one is to format the date into a String (with localTimeZone GMT+10):
func dateFromString(dateString: String) -> NSDate? {
let dateFormatter = NSDateFormatter()
dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT+1")
dateFormatter.dateFormat = "M/d/yyyy hh:mma"
return dateFormatter.dateFromString(dateString)
}
func stringFromDate(date: NSDate) -> String {
let dateFormatter = NSDateFormatter()
dateFormatter.timeZone = NSTimeZone.localTimeZone()
dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
return dateFormatter.stringFromDate(date)
}
In the playground, when I do this:
let date = dateFromString("4/8/2015 1:29am")!
println(date)
println(stringFromDate(date))
I get the following output on the right side:
"Apr 8, 2015, 1:29 AM"
"2015-04-07 15:29:00 +0000"
"1:29 AM"
I don't understand why I don't get what I am expecting and looking for:
"Apr 8, 2015, 1:29 AM"
"2015-04-08 10:29:00 +0000"
"10:29 AM"
What's wrong?
Input formatters need the time zone in their string. Like so:
func dateFromString(dateString: String) -> NSDate? {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "M/d/yyyy hh:mma z"
return dateFormatter.dateFromString(dateString)
}
let date = dateFromString("4/8/2015 1:29am GMT+01")!
Also note that NSTimeZone names have a two digit offset. Compare in the playground
var oops = NSTimeZone(abbreviation: "GMT+1")
var righteous = NSTimeZone(abbreviation: "GMT+01")
The first is nil, the second is not.
I wouldn't trust the formatting of a time stamp that the debugger prints. In my experience dates are always in UTC regardless of the time zone you set according to the log. Try adding the date as a string to a label on the project and see if it's right.
The reasoning behind this as far as I know is that when you print to the log, all it's doing is calling -description. In the case of NSDate this will return in UTC by definition.