WeatherKit or SwiftUI date formatting issues

Hello! Hope you had an amazing Dub Dub week.

I am currently integrating widgets into my weather app. The widgets use WeatherKit to get the hourly forecast. I have issues formatting or displaying dates for the locations. When I display the date for 2 or more locations with different timezones, the hours displayed are local for the phone, not the location I'm grabbing the weather for.

This is how I display the date. hour is the Forecast<HourlyWeather> item from WeatherKit.

Text(hour.date.formatted(date: .omitted, time: .shortened))

Example:

Neither of the locations' time is 9:00. They are in different time zones with 10 hours difference, one should be different from the other.

Accepted Reply

Get the time zone of the location and use that:

import Foundation

let sanFrancisco = TimeZone(identifier: "PST")
let time = Date.now

let timeFormatter = DateFormatter()
timeFormatter.dateStyle = .none
timeFormatter.timeStyle = .short
timeFormatter.timeZone = sanFrancisco
timeFormatter.locale = .current

let timeStr = timeFormatter.string(from: time)
print("\(timeStr)")
// For me, prints 2.08, local time was 12.08.

And, if starting from a coordinate, rather than a timezone identifier:

import Foundation
import CoreLocation

let sanFrancisco = CLLocation(latitude: 37.77493, longitude:  -122.41942)
let geoCoder = CLGeocoder()

do {
	let placemarks = try await geoCoder.reverseGeocodeLocation(sanFrancisco)

	if !placemarks.isEmpty {
		if let placemark = placemarks.first {

			let time = Date.now
			let timeFormatter = DateFormatter()

			timeFormatter.dateStyle = .none
			timeFormatter.timeStyle = .short
			timeFormatter.timeZone = placemark.timeZone
			timeFormatter.locale = .current

			let timeStr = timeFormatter.string(from: time)
			print("\(timeStr)")
		} else {
			print("No placemark for the coordinate")
		}
	}
} catch {
	print("Failed to geolocate coordinate: \(error.localizedDescription)")
}

Replies

Get the time zone of the location and use that:

import Foundation

let sanFrancisco = TimeZone(identifier: "PST")
let time = Date.now

let timeFormatter = DateFormatter()
timeFormatter.dateStyle = .none
timeFormatter.timeStyle = .short
timeFormatter.timeZone = sanFrancisco
timeFormatter.locale = .current

let timeStr = timeFormatter.string(from: time)
print("\(timeStr)")
// For me, prints 2.08, local time was 12.08.

And, if starting from a coordinate, rather than a timezone identifier:

import Foundation
import CoreLocation

let sanFrancisco = CLLocation(latitude: 37.77493, longitude:  -122.41942)
let geoCoder = CLGeocoder()

do {
	let placemarks = try await geoCoder.reverseGeocodeLocation(sanFrancisco)

	if !placemarks.isEmpty {
		if let placemark = placemarks.first {

			let time = Date.now
			let timeFormatter = DateFormatter()

			timeFormatter.dateStyle = .none
			timeFormatter.timeStyle = .short
			timeFormatter.timeZone = placemark.timeZone
			timeFormatter.locale = .current

			let timeStr = timeFormatter.string(from: time)
			print("\(timeStr)")
		} else {
			print("No placemark for the coordinate")
		}
	}
} catch {
	print("Failed to geolocate coordinate: \(error.localizedDescription)")
}