DateFormatter returns unexpected date for Timezone
In
let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "HHmmss"
timeFormatter.timeZone = TimeZone(identifier: "UTC")
let time = timeFormatter.date(from: "131006")
only a time is provided, but no day/month/year. In this case the date formatter uses a default date of Jan 1, 2001, as you can verify with
print(time!) // 2000-01-01 13:10:06 +0000
Daylight saving time was not active on that day, therefore
your local time for that point in time is 14:10
, not 15:10
.
To solve the issue, you can either combine the date and time strings
sent from the server and parse that, or convert the date string
first and set it as default date when converting the time string:
timeFormatter.defaultDate = ...
DateFormatter gives weird timezone for very old dates
In the past, each local area kept their own local mean time by observing the times of sun sets and sun rises. This meant that the local time at each town/city not be a nice whole number offset from Greenwich, like +17 minutes for example. This wasn't that big of a problem until people invented trains, which had schedules. At around the 19th century, countries around the world standardised their local times, and that is why we have nice whole number offsets like +1 hour (most of the time).
So in the year 1000, your timezone, Europe/Brussels
was really 17 minutes ahead of Greenwich as far as the history we know. This bit of history got recorded in the IANA tz
database, which is what TimeZone
queries. That is why you got +00:17
.
Interestingly, when I ask the TimeZone
how many seconds it is from GMT at around the 1000s, it says 0:
let date = Date(timeIntervalSinceNow: 86400 * 365 * -1000)
// this is 0
TimeZone(identifier: "Europe/Brussels")!.secondsFromGMT(for: date)
It might have rounded the actual number of seconds down. Java can tell you the actual answer though:
// prints +00:17:30
System.out.println(ZoneId.of("Europe/Brussels")
.getRules().getOffset(LocalDate.of(1000, 1, 1).atStartOfDay()));
DateFormatter is Giving a Day before date
You are mixing a Date
- which is a point in time - with a formatted Date string, which is something you can see on a watch or on a calendar.Date
is always referencing UTC (f.k.a. Greenwich Mean Time), so the output of print(date)
will not print a calendar date but the UTC date and time.
If you convert that date to a "calendar entry" (by specifing a time zone etc.), you then will get the value that is displayed on your local watch, when in UTC its midnight on the 8th of March, 2021.
If you are living west of Greenwich, this will be the day before, because you are still on the 7th of March, waiting for the new day to arrive.
Unexpected result after formating string to date
Set the locale and timezone to avoid invalid results. The return value of the extension should be Date?
since the string may not be a valid date.
And since dateFormat
is not optional, it should be a valid date format, see here for more details.
import UIKit
extension String {
func toDate(dateFormat: String, locale : Locale? = nil, timezone: TimeZone? = nil) -> Date? { //locale and timezone are optional with a default nil value
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = dateFormat
dateFormatter.locale = locale
dateFormatter.timeZone = timezone
return dateFormatter.date(from: self)
}
}
You can use it like so:
let string = "01/24/2018 09:59:24"
let myLocale = Locale(identifier: "en_US_POSIX")
let myTimeZone = TimeZone(abbreviation: "PCT")
print(string.toDate(dateFormat: "MM/dd/yyyy HH:mm:ss",
locale: myLocale,
timezone: myTimeZone))
String to date with UTC timezone
The Date
object does not have any inherent locale / time zone. It just represents a moment in time. If you want to see that Date
as a string in a specific locale/time zone you have to use a date formatter. Or there's descriptionWithLocale
. If you use print
it will print a debug description of the Date
instance in UTC.
Related Topics
How to Store Push Notification Alert Message in Userdefault
iPhone iOS Will Not Display Box-Shadow Properly
Which Is the Best Way to Estimate Measure of Photographed Things
Email Validation on Textfield in iOS
Swift: How to Get Substring from Start to Last Index of Character
Get the Current View Controller from the App Delegate
Nsinteger and Nsuinteger in a Mixed 64Bit/32Bit Environment
How to Asynchronously Load an Image in an Uiimageview
How to Detect Whether I Have iPhone 2G,3G,3Gs
Facebook Sdk 3.1 for iOS - Runs on iOS6, But Crashes on iOS 5.X
iOS 9 Orientation Auto-Rotation Animation Not Working, But Always on Main Thread
Mobile Safari Position:Fixed Z-Index Glitch When Scrolling
Xcode 8.3/Xcode 9.0 Refresh Provisioning Profile Devices
Xcode 6 with Swift Super Slow Typing and Autocompletion
Swift Merge Audio and Video Files into One Video
How to Do Programmatically Gradient Border Color Uibutton with Swift
How Can an iOS 7 App Make Itself Transparent to See a User's Home Screen Image