What time/day format is openweathermap.org list.dt using - swift

I'm using the day forecast api at http://openweathermap.org/forecast16. There is a parameter called list.dt. It gives a value in this format: 1406080800.
What format is that and how would I translate it to some human readable using functionality in Swift?

The date is most likely in unix time (see forecast5, which states that list.dt is the "Time of data forecasted, unix, UTC".
Using Swift, you can use NSDate(timeIntervalSince1970: dt) in order to convert this to a date. Then you can use standard NSDateFormatter to make it human readable.

The dt is for date and time.
The value of dt is in a format known as unix time
Unix time is a system for describing time, which is the number of seconds elapsed since 00:00:00 (UTC), Thursday, 1 January 1970.
The value you have there (1406080800) is equal to Wed, 23 Jul 2014 02:00:00 GMT which is used in there example provided for the link you posted.
To use within Swift try the following:
var date = NSDate(timeIntervalSince1970: timeInterval)
To get a unix timestamp from Swift you can also use:
let timeInterval = NSDate().timeIntervalSince1970

Create a computed property to convert timestamp that you've got into Date. CodingKeys are here just to rename the meaningless dt.
struct Weather: Codable {
private let timestamp: Double
let temp: Float
var date: Date {
Date(timeIntervalSince1970: timestamp)
}
enum CodingKeys: String, CodingKey {
case timestamp = "dt", temp
}
}

Related

how to convert a String to a Date without changing the Format

I'm using Xcode 11.4.1
In my Project I got a String with some data which I need to split up and save the Information in some variables.
now I face a problem if I try this
let dateString = "12-04-2020"
let dateFormatIn = DateFormatter()
dateFormatIn.dateFormat = "dd-MM-yyyy"
let saveDate: Date = dateFormatIn.date(from: dateString)!
print("The date is: \(saveDate)")
the result which I expected is "The date is: 12-04-2019" but what I got is "The date is: 2020-04-11 15:00:00 +0000"
what do I miss, what is this printed Date? it's not the current date ans also not the String!
I need the Date in the same format as I got it in the String.
A Date is a point in time, it doesn't have a format nor a time zone.
print shows the description – a string representation – of the date in the UTC time zone.
Your time zone is obviously UTC +0900, 2020-04-12 00:00:00 +0900 and 2020-04-11 15:00:00 +0000 is the same point in time.
If you want to create the date string independent of the time zone add the line
dateFormatIn.timeZone = TimeZone(secondsFromGMT: 0)
let saveDate: Date = dateFormatIn.date(from: dateString)!
The ": Date" looks like a data type declaration. You're saying, "create a variable called saveDate of type Date, and initialize it from the output of dateFormatIn.date(from: dateString)".
So you're not printing the formatted output. You're converting the formatted output to a new Date object, and then printing that.
Try:
let saveDate = dateFormatIn.date(from: dateString)!
This should save whatever dateFormatIn.date(from: dateString) returns in saveDate.

How do I "combine" an un-zoned date and a time zone?

My question is very similar to Get "time with time zone" from "time without time zone" and the time zone name (I think). I just want to do it in Swift.
Anyway, I am trying to write a function with the following signature:
func combine(_ date: Date, with timeZone: TimeZone) -> Date?
What it does is that it basically takes in a date and returns a "zoned" date. If the date does not exist in the time zone, it returns nil.
To avoid being an XY question, here is a screenshot:
I'm asking the user for a date and a time zone and I want to combine these two into one single Date.
I'll try my best to explain. I will express dates in the format of timeIntervalFrom1970 to make it as clear as possible.
Say I pass in 0 as the date and GMT-1 as the time zone, it'll return 3600. 0 is 1970-1-1 00:00:00. 1970-1-1 00:00:00 in GMT-1 is 1970-1-1 01:00:00 in GMT, which is 3600.
This is how I tried to implement this:
return date.addingTimeInterval(-timeZone.secondsFromGMT(for: date))
This seems to work most but not all of the time. However, I don't think it returns the correct results if DST gets involved and the whole thing becomes messy. It also feels "math-ish". I would prefer an approach without math, using only the Foundation API methods.
So, How can I implement this method?
In your example, the API gives you a Date, but you want to interpret
that as "2017/08/18 8:08" in some given time zone. Assuming that
the eureka forms UI element uses the timezone of the current calendar
for display, you can convert the date to DateComponents, and back
to a Date with a different timezone.
func combine(_ date: Date, with timeZone: TimeZone) -> Date? {
var cal = Calendar.current
let comp = cal.dateComponents([.era, .year, .month, .day, .hour, .minute, .second], from: date)
cal.timeZone = timeZone
return cal.date(from: comp)
}
nil will be returned if the day/time combination does not exist
in the other timezone.

How to get the number of days since NSDate's Reference Date?

I saw in the Apple's documentation about NSDate that Date objects represents an invariant time interval relative to an absolute reference date. How can I get the number of days since that Reference Date?
Edit: I saw solutions for a similar question, but I'm searching for a solution that don't force me to enter specific dates.
You can use calendar method dateComponents from Date to Date and pass only the day component:
let date = Date(timeIntervalSinceReferenceDate: 0) // "2001-01-01 00:00:00 +0000"
let days = Calendar.current.dateComponents([.day], from: date, to: Date()).day // 5971

Timestamp to weekday going wrong

I made this function:
func getDayOfWeek(date: NSDate) -> String? {
let myCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
let myComponents = myCalendar?.components(NSCalendarUnit.CalendarUnitWeekday, fromDate: date)
let weekDay = myComponents?.weekday
println(date)
return weekNumberToWord(weekDay!)
}
To which I give a timestamp as date (1439460000, which is the date of today) and it prints: 2046-08-13 10:00:00 +0000. How is this possible?
This is how I call the function:
var day = getDayOfWeek(NSDate(timeIntervalSinceReferenceDate: timestamp.doubleValue))!
In which getDayOfWeek() is a switch converting all the numbers to day name as string.
You are using the wrong initializer:
init(timeIntervalSinceReferenceDate:)
Returns an NSDate object initialized relative the first instant of 1 January 2001, GMT by a given number of seconds.
You should use init(timeIntervalSince1970 seconds: NSTimeInterval) to initialize a date from a UNIX timestamp (which you are apparently using):
Returns an NSDate object set to the given number of seconds from the first instant of 1 January 1970, GMT.
var day = getDayOfWeek(NSDate(timeIntervalSince1970: timestamp.doubleValue))!

Convert mach absolute timestamp to NSDate

I have a mach absolute timestamp from a sql database, I want to read in my app. I want to display this timestamp, so I want to convert it to NSDate. How is this possible? I have a timestamp like this: 443959550 (result in this case is UTC: 26.01.2015 10:05:50)
443959550 seems to be a time interval since the reference date
1 January 2001, GMT:
let date = NSDate(timeIntervalSinceReferenceDate: 443959550)
println(date) // 2015-01-26 10:05:50 +0000
Take a look at timeIntervalSince1970. There you can set a timestamp as init-parameter.
var timeStamp = 443959550
//NSDate
var date = NSDate(timeIntervalSince1970:443959550)