Converting Python time.asctime() to Swift Date using DateFormatter - ios

I am working with a series of string representations of timestamps returned by time.asctime() in Python. The documentation states:
Convert a tuple or struct_time representing a time as returned by gmtime() or localtime() to a string of the following form: 'Sun Jun 20 23:21:05 1993'. The day field is two characters long and is space padded if the day is a single digit, e.g.: 'Wed Jun 9 04:26:40 1993'.
I've referenced Unicode Technical Standards to determine how I can instruct an instance of Swift's DateFormatter how to interpret the string and create a Date.
The UTS is very clear, but my Date object still unwraps to nil:
let dateAsString = measurement[2]
print("Date as string: \(dateAsString)")
let df = DateFormatter()
df.dateFormat = "E MMM dd HH:mm:ss y"
let date = df.date(from: dateAsString)
print("Date: \(String(describing: date))")
Output:
Date as string: Thu Oct 20 17:53:06 2022
Date: nil
Date as string: Thu Oct 20 17:53:06 2022
Date: nil
Date as string: Thu Oct 20 17:53:16 2022
Date: nil

When printing dateAsString to console output, I did not notice that there is a single trailing whitespace after the year. Adjusting the Unicode format string to the following solved the problem:
df.dateFormat = "EEE MMM d HH:mm:ss y " // <- observe the extra space

Related

Formatting a date from a string in swift [duplicate]

This question already has answers here:
How can I parse / create a date time stamp formatted with fractional seconds UTC timezone (ISO 8601, RFC 3339) in Swift?
(13 answers)
Closed 3 years ago.
i have the following date coming from a server 2019-09-05T10:37:49.494Z as a string and i need to parse this and convert it to a format like this Fri September 13,2019 12:36 AM and back to a string again:
i found multiple question links but none of them are working for me Question One
Question Two
it tried doing this:
let dateFormatterGet = DateFormatter()
let dateFormatterPrint = DateFormatter()
var rawDate = "2019-09-05T10:37:49.494Z"
dateFormatterGet.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
dateFormatterPrint.dateFormat = "E, d MMM yyyy HH:mm"
var formattedDate = "Error Formatting date"
if let date = dateFormatterGet.date(from: rawDate) {
formattedDate = dateFormatterPrint.string(from: date)
print("Formatted Date : \(formattedDate)")
}else {
print("There was an error decoding the string")
}
this fails printing the error message, what am i doing wrong and how can i fix it?
You are almost there.
A small tip playing with (NS)DateFormatter put the dateFormat above/under the date string.
yyyy-MM-dd'T'HH:mm:ssZ
2019-09-05T10:37:49.494Z
Then, add "spaces" to align and separate them.
yyyy - MM - dd 'T' HH : mm : ss Z
2019 - 09 - 05 T 10 : 37 : 49 . 494Z
^ ^^^
I highlighted the missing ones. You need to tell the (NS)DateFormatter through the dateFormat how to interpret theses additional characters.
Let's check the documentation.
It's
Fractional Second - truncates (like other time fields) to the count of letters. (example shows display using pattern SSSS for seconds value 12.34567)
So using yyyy-MM-dd'T'HH:mm:ss.SSSZ should interpret them and fix your issue.
That's how you fix your issue. And it explained your error.
But since as pointed by #Zombie it's using a ISO format, use if available the ISO8601DateFormatter if possible (iOS10+)
If in future cases you don't have an ISO something format, you can use theses tips ;)
The format you provided seems like an iso 8601 date for this reason I would suggest using the ISO8601DateFormatter
You can specify the options to match your string
here is an example
let dateString = "2019-09-05T10:37:49.494Z"
let formatter = ISO8601DateFormatter()
formatter.formatOptions = [
.withDashSeparatorInDate,
.withFullDate,
.withFullTime,
.withFractionalSeconds,
.withColonSeparatorInTime
]
// "Sep 5, 2019 at 12:37 PM"
let date = formatter.date(from: dateString) ?? Date()
//"Thursday, September 5, 2019 at 12:37:49 PM"
let formattedDate = DateFormatter.localizedString(
from: date,
dateStyle: .full,
timeStyle: .medium
)
The problem is you don't tell dateFormatterGet how to parse milliseconds. Modify the dateFormat to:
dateFormatterGet.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

Issue in formatting date string Swift 3 [duplicate]

This question already has answers here:
NSDateFormatter doesn't show time zone abbreviation for "Asia/Kolkata" for the "z" or "zzz" specifier, just the GMT offset
(1 answer)
What is the best way to deal with the NSDateFormatter locale "feature"?
(4 answers)
Closed 5 years ago.
I need to convert the following date string in to a Date in Swift 3.
Fri Dec 09 16:18:43 AMST 2016
Here is the code that i have been using, but it's getting cash on this particular date string conversion. (This date was logged on Android using new Date().toString() method.)
static func formatDate(date: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
dateFormatter.dateFormat = "EEE MMM dd HH:mm:ss zzz yyyy"
//Works for "Fri Sep 16 10:55:48 GMT+05:30 2016"
var myDate = dateFormatter.date(from: date)
// My date returns nil on "Fri Dec 09 16:18:43 AMST 2016"
dateFormatter.dateFormat = "dd/MM/yyyy"
return "\(dateFormatter.string(from: myDate!))"
}
There are both type of strings in the database. I tried with various types of Timezone formats (z/zz/zzz/zzzz/zzzzz) but always myDate returns nil.
Any help would be appreciated.
Thanks In Advance.
Apple doc for TimeZone(abbreviation:):
In general, you are discouraged from using abbreviations except for unique instances such as “GMT”. Time Zone abbreviations are not standardized and so a given abbreviation may have multiple meanings.
Does AMST represents "Amazon Summer Time" (UTC-3) or "Armenia Summer Time" (UTC+5)? See: https://www.timeanddate.com/time/zones
That's probably why it can't detect the proper timezone to use.
Solutions I can propose:
If you know which timezone AMST is:
replace AMST by UTC-3 or UTC+5 in the date string
remove AMST from the date string and use dateFormatter.timeZone = TimeZone(secondsFromGMT: -3 or 5 * 3600)
Have your source output a more precise timezone.
Note the following code, where AMST is understood correctly:
let df = DateFormatter()
df.locale = Locale.init(identifier: "pt_BR") // assuming AMST is Amazon Summer Time (UTC -3)
df.dateFormat = "HH:mm:ss z"
print(df.date(from: "16:18:43 AMST")) // Optional(2000-01-01 19:18:43 +0000)
But as soon as you include English day or month names (e.g. Fri or Dec) it will produce nil (because they aren't in Portuguese).

Curious behavior while formatting dates

I'm getting a string representation of a date from a json that looks like the following:
let dateString = "2016-12-31T00:10:00+01:00"
In order to model it as a Date object I'm using a date formatter like so:
let dateForm = DateFormatter()
dateForm.locale = Locale(identifier: "fr_FR")
dateForm.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
dateForm.timeZone = TimeZone.current
When I turn it into a Date, my Playground output is correct:
let date = dateForm.date(from: dateString)
=> Output: "Dec 31, 2016, 12:10 AM"
But if I try to print this exact same object (date) I get the following output:
print(date!)
=> Output: "2016-12-30 23:10:00 +0000\n"
My question is: How can I be sure that I'm dealing with the correct date (by correct I mean with my local time zone (GMT+01)) ?
When you print the date output 2016-12-30 23:10:00 +0000 and your GMT is +00:00
but when you get the string from date it will return string as per your given format And your Locale (fr_FR) output 2016-12-31T00:10:00+01:00 and your GMT is +01:00
if you want to date from string then
date output = your string date - (your GMT)
In your case
2016-12-30 23:10:00 = 2016-12-31 00:10:00 - (+01:00)

Convert two strings to NSDate

i am trying to calculate the time between two dates. One of the dates is today and the other date is somewhere in the future.
The issue is the date in future is separated into two string, the first containing the date and the other containing the time for that date. When i put the two strings together to a single string and try to convert it to a NSDate i get Nil.
I assume there is something wrong with my date variable.
let eventDate: String? = "21 Aug Sun 2016"
let eventTime: String? = "9:00 PM"
let date : String? = "\(eventDate!) \(eventTime!)"
print(date!) // "21 Aug Sun 2016 9:00 PM"
let formatter = NSDateFormatter()
formatter.dateFormat = "dd MMM eee yyyy HH:MM a"
formatter.AMSymbol = "AM"
formatter.PMSymbol = "PM"
if let dateTimeForEvent = formatter.dateFromString(date!) {
print(dateTimeForEvent)
}else {
print("Error")// prints error
}
Two things:
You have the wrong format for the time. It should be h:mm a. HH is for a two-digit, 24-hour hour. You have a 1 or 2 digit, 12-hour hour. And MM is for a 2-digit month. Use mm for a two-digit minute.
If your date and time strings will always be in English, you need to set the formatter's locale to an English locale. If you don't, your code will always return a nil date on any device using a language other than English.
Your primary issue is that you're using HH, which is for 24-hour time, instead of hh, and MM (which is for month) instead of mm. Try this:
import Foundation
let eventDate = "21 Aug Sun 2016"
let eventTime = "9:00 PM"
let eventDateTime = "\(eventDate) \(eventTime)"
print(eventDateTime) // "21 Aug Sun 2016 9:00 PM"
let formatter = NSDateFormatter()
formatter.dateFormat = "dd MMM eee yyyy hh:mm a"
if let date = formatter.dateFromString(eventDateTime) {
print(date) // 2016-08-21 21:00:00 +0000
}
else {
print("Error")// prints error, no shit? why is this comment here?
}
Side notes:
Why is a variable called date, if it's a String??
Why is date an optional, anyway? You assigned it a literal value.
You don't have to set the AMSymbol and the PMSymbol. Those only pertain to printing dates, not parsing them.

EDT not working with NSDateFormatter

In iOS, I am using a NSDateFormatter with the DateFormat EEE, dd MMM yyyy HH:mm:ss z.
The String Sat, 29 Aug 2015 12:34:36 EDT does not work and gives back nil when given to the function .dateFromString(). The exact same string with GMT (Sat, 29 Aug 2015 12:34:36 GMT) gives me the correct date, though.
What am I missing here?
So the problem was that the locale I was using wasn't a usual one. I live in Germany and use English as my system language, so the Locale was one with the identifier en_DE. Both de_DE and en_US work with the usual Time Zones (Like EDT), but the unusual en_DE doesn't work with all of them. So the fix was to use en_US as the locale.
Hopefully this should work, I'm in New Zealand but set locale to "EDT"
let string = "Sat, 29 Aug 2015 12:34:36 EDT"
let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier: "EDT")
formatter.dateFormat = "EEE, dd MMM yyyy hh:mm:ss z"
let localDate = formatter.dateFromString(string)

Resources