Swift- reformatting time after reading from JSON - ios

I am trying to reformat the time that I am reading off from a String from a JSON API. It is reading from the JSON fine because it gives me the result- the String "2020-05-12T00:00:00:00.000 How can I convert this string it is giving in to an NSDate because I have looked at previous questions and the solution they are giving me is giving me the error that leads to the string having a value of nil

Try using following as format - "yyyy-MM-dd'T'HH:mm:ss:SS.SSS"
let dateString = "2020-05-12T00:00:00:00.000"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss:SS.SSS"
let date = dateFormatter.date(from: dateString)!
print(date)
// Prints Date object
// 2020-05-12 00:00:00 +0000
The last 00.000 tells us fractional of a second, which is represented by SS.SSS
Refer to this page for more date formatter related queries.
Two things to note about the fractional second. First, it does not round, it just shows the appropriate places (otherwise the 2 digit fractional second would show 7 ms as “01”). Secondly, the Unicode standard lets you use as many as you want, so “SSSSS” is valid. However, DateFormatter will not show anything below milliseconds, it will just show 0s below that. So 123456789 nanoseconds with a “SSSSSSSSS” format string will show up as “123000000”

Related

DateFormatter.date(from: String) vs Locale

I'd like to ask for some help understanding what might cause my DateFormatter to fail...
App receives data from server as string (ex. "2020-12-13 02:54:36 UTC")
App parses string to date
App supports English and Spanish localisations (irrelevant?)
Code:
DateFormatter (all setup):
dateFormat = "yyyy-MM-dd HH:mm:ss zzz"
generally all dates are returned in UTC but using 'zzz' to also cover other time formats like CDT etc.. we had some mix up on sever side at one point...
Problem:
I've received a single log from a user (using Spanish locale) who experienced date parser failure. But i can't reproduce this anyhow... (phone set to EN / ES - dates parse ok for both UTC and CDT time zones).
Server Response:
{ "creation_date":
"2021-05-14 06:07:55 UTC", }
where date(from string:) returns nil for above date(s).
Am I doing this wrong?
Improvements? (i.e. would setting formatter.locale = "en_EN" help? Server date format is fixed.

Why create Date from String only failed On Real iphone?

I'm using following function to create Date from String. It works well on simulator. But it crashed on real iPhone.
String: "Tue May 23 23:19:41 +0800 2017"
The first picture is debugging information on real iPhone. The second one is debugging information on simulator.
func createDate(fromString string: String) -> Date {
let formatter = DateFormatter()
formatter.dateFormat = "EEE MMM dd HH:mm:ss zzz yyyy"
let date = formatter.date(from: string) //fatal error: unexpectedly found nil while unwrapping an Optional value
return date!
}
I even tried it on playground. It's really weird!
Thanks!
this link may solve your problem.....
Swift
formatter.locale = Locale(identifier: "en_US")
I bet it's crashing on the next line, not on the line you've commented. You're force-unwrapping the result. That force-unwrap will crash with the exact error you are reporting if the date conversion fails.
I call the ! operator the "crash if nil" operator. You should not do that. You need to program defensively and return the optional, then write the calling code to handle the case where the conversion fails.
Others have already pointed out that date formatters depend on the locale of the device, and if it's different your conversion could fail. Force the formatter's locale to a known locale if you want to give it literal strings who's format doesn't vary based on country and language.
from the app docs
When working with fixed format dates, such as RFC 3339, you set the
dateFormat property to specify a format string. For most fixed
formats, you should also set the locale property to a POSIX locale
("en_US_POSIX"), and set the timeZone property to UTC.
RFC 3339
In macOS 10.12 and later or iOS 10 and later, use the
ISO8601DateFormatter class when working with ISO 8601 date
representations.
wiki ISO 8601
For proper format, use Date Field Symbol Table
you date format slightly wrong, please use the bellow example dateformat.
let dateString : String = "Tue May 23 23:19:41 +0800 2017"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE MMM dd HH:mm:ss ZZZ yyyy"
dateFormatter.timeZone = TimeZone(identifier: "GMT")
print(dateFormatter.date(from: dateString))

Converting server date with Z format to local nsdate

I need to convert this server date (Given from kinvey request) into local timezone.
I'm using the following code:
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-ddTHH:mm:ss.sTZD"
print(dateFormatter.dateFromString(newValue))
The date format is this:
ect = "2016-08-28T16:30:06.553Z" or
lmt = "2016-08-28T16:30:06.553Z"
When I print the date it is nil, do you know what I'm doing wrong ?. I think it could be the end of the dateFormat
If your app can target only iOS7+, you can use format symbols described in:
Fixed Formats (in Data Formatting Guide)
Unicode Technical Standard #35 version tr35-31
second | S | 1..n | 3456 | Fractional Second - truncates (like other
time fields) to the count of letters. (example shows display using
pattern SSSS for seconds value 12.34567)
zone | X | 1 | -08,+0530,Z | The
ISO8601 basic format with hours field and optional minutes field. The
ISO8601 UTC indicator "Z" is used when local time offset is 0. (The
same as x, plus "Z".)
So, to parse fractional second, use uppercase 'S',
and 'X' for timezone including "Z" as UTC.
Try this:
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSX"
(I escaped 'T' as it may be used as another time formatting symbol in the future.)
PS. Though I couldn't have found a thread describing the date format which interprets "Z" as UTC+0000, ignoring or removing it may not be a bad solution, if some conditions met. Please find your best solution.

why is some strange character in NSDate string

I am using below code to get date time. I will post them to server
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
let strDate = dateFormatter.stringFromDate(NSDate())
In server, I found there several log has strange data. it is encoded as "date": "\u0662\u0660\u0661\u0666-\u0660\u0664-\u0661\u0660 \u0661\u0668:\u0665\u0669:\u0664\u0663"
I found them show as ٢٠١٦-٠٤-١٠ ١٨:٥٩:٤٣ in UTF16, what is the problem, it seems date format is correct, but why year-month-day hour:minitue:seconds become invalid. Thanks~
Just set the locale on the formatter:
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
en_US_POSIX is a standardized locale that will never change (even if the US were to change how it encodes things).
As A-Live notes, these are valid digits and valid dates. They're just not Western Arabic digits (0123456789). They're Eastern Arabic digits (٠١٢٣٤٥٦٧٨٩). stringFromDate() uses the locale from the formatter. If you don't set one, it uses the system locale. If you want a particular one, set it.
See QA1480 for full details.
These are totally valid year, month, day, etc: based on your code we can see that you've decided to accept the values of any locale, including non-arabic digits.

NSDateFormatter fails parsing three letter abbreviation of German month March/June/Jul

I have a number of German dates in the format of "10.Feb.2016", i.e. 2 digits for the day, 3 letters for the month, 4 digits for the year.
I tried to use the date format dd.MMM.yyyy, but that fails for 3 German months:
10.Mär.2016
10.Jun.2016
10.Jul.2016
That's because that's according to the docs, MMM actually stands for "date abbreviation", which does to guarantee or imply exactly three letters.
How can I parse a date with exactly three letters for the month that will work in any language? Is this even possible with NSDateFormatter?
The code below illustrates the problem. It prints:
OK 10.Jan.2016
OK 10.Feb.2016
FAILED parsing: 10.Mär.2016
OK 10.Apr.2016
OK 10.Mai.2016
FAILED parsing: 10.Jun.2016
FAILED parsing: 10.Jul.2016
OK 10.Aug.2016
OK 10.Sep.2016
OK 10.Okt.2016
OK 10.Nov.2016
OK 10.Dez.2016
Here's the code:
let dateFormatter = NSDateFormatter()
dateFormatter.timeZone = NSTimeZone(abbreviation: "UTC")
dateFormatter.dateFormat = "dd.MMM.yyyy"
dateFormatter.locale = NSLocale(localeIdentifier: "de_DE")
let input = [
"10.Jan.2016",
"10.Feb.2016",
"10.Mär.2016",
"10.Apr.2016",
"10.Mai.2016",
"10.Jun.2016",
"10.Jul.2016",
"10.Aug.2016",
"10.Sep.2016",
"10.Okt.2016",
"10.Nov.2016",
"10.Dez.2016",
]
for test in input
{
if let date = dateFormatter.dateFromString(test)
{
print("OK \(test)")
}
else
{
print("FAILED parsing: \(test)")
}
}
Strangely when I tried your code, only "Mai" worked. All others failed.
However after taking a look at that documentation I tried this change:
dateFormatter.dateFormat = "dd.LLL.yyyy"
All of those sample dates worked ("OK" for all). LLL is the "stand-alone" month, which is described as follows:
The most important distinction to make between format and stand-alone forms is a grammatical distinction, for languages that require it. For example, many languages require that a month name without an associated day number be in the basic nominative form, while a month name with an associated day number should be in a different grammatical form: genitive, partitive, etc. Another common type of distinction between format and stand-alone involves capitalization...
I don't know enough about German to say if that should apply, but obviously NSDateFormatter thinks that it does.

Resources