13

I'm working on date formatter, I got a response of date from server in string type, which I convert into date format but what I want to do is to convert a date and then manage according to local time.

For example, if 12/06/2017, 06:48:03 is a date from server and i'm from Pakistan so it gives me a date and time according to GMT+5 which is 12/06/2017, 11:48:03

Same as from India it gives me a date and time according to GMT+5:30 which is 12/06/2017, 12:18:03

Here is a source code

public class func converServerTimeStampToDate (_ timeStamp: String) -> Date {

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MM/dd/yyyy, hh:mm:ss a"
        dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
        let localDate = dateFormatter.date(from: timeStamp)
        dateFormatter.timeZone = TimeZone.current
        dateFormatter.dateFormat = "MM/dd/yyyy, hh:mm:ss a"

       // return dateFormatter.string(from: localDate!)
        return dateFormatter.date(from:dateFormatter.string(from: 
       localDate!))!

    }

Any help would be appreciated !!

pckill
  • 3,709
  • 36
  • 48
Nasir Javed
  • 315
  • 2
  • 3
  • 13

2 Answers2

10

If you want the result to be a Date object just use the first part of @Intellij-Shivam's answer:

func serverToLocal(date:String) -> Date? {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
    let localDate = dateFormatter.date(from: date)

    return localDate
}

(note that DateFormatter.date(from:) returns an optional, which is correct because the input date string might not be in the correct format.)

There is no such thing as a Date in your local time zone. Dates don't have a time zone. They record an instant in time all over the planet.

To display a date in your local time zone you can use the DateFormatter class method localizedString():

let dateString = DateFormatter.localizedString(
  inputDate, 
  dateStyle: .medium, 
  timeStyle: .medium)
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • 2
    (I Think you should accept @Intellij-Shivam's answer. The code above is his, with only minor changes.) – Duncan C Dec 28 '17 at 11:54
  • 1
    Note that if you're going to make more than occasional use of this code, you should refactor it to create a date formatter once and re-use it. It's fairly expensive to keep creating them and disposing of them. I'd make the above an instance method, and have it use a lazy instance variable for the date formatter. – Duncan C Jan 17 '20 at 19:13
3

I hope this will work for your problem

func serverToLocal(date:String) -> Date {
 let dateFormatter = DateFormatter()
 dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss"
 dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
 let date = dateFormatter.date(from: date)
 dateFormatter.timeZone = TimeZone.current
 let timeStamp = dateFormatter.string(from: date!)

 return date
}
cpt. Sparrow
  • 415
  • 8
  • 22
  • you can change the `dateFormat` according to the format that you are getting the date and time – cpt. Sparrow Dec 28 '17 at 10:54
  • 1
    Force unwrapping the output of a dateformatter is a bad idea in a function which accepts the date format as an input argument. Either make your function throwable or return nil if either format is wrong. – AshvinGudaliya Dec 28 '17 at 10:56
  • i know for random dateFormat it is not good idea but if the know the dateFormat which we are going to get, i don't think there is no harm in it to forceWrap the return value, if we know the exact date format that we are going to get. – cpt. Sparrow Dec 28 '17 at 10:59
  • @Intellij-Shivam yeah its working but i want to return a Date not String – Nasir Javed Dec 28 '17 at 11:05
  • this will convert you local time zone Date String to Date format @NasirJaved – cpt. Sparrow Dec 28 '17 at 11:12
  • You said you wanted a date in your local time zone. A Date object does not have ANY Time zone. If you just change Intellij's function above so that it returns localDate that will give you the server date, but if you try to display it it will be displayed in UTC. You will need to use a local date formatter to display the date in your time zone. – Duncan C Dec 28 '17 at 11:12
  • you can change the format of the date accordingly i have take the standard date format – cpt. Sparrow Dec 28 '17 at 11:13
  • error Occur in local date "Cannot convert value of type 'Date?' to expected argument type" – Nasir Javed Dec 28 '17 at 11:16
  • its because of the format that you are giving is wrong.. and @DuncanC is right you need to use a local date formatter to display the date in your time zone.. this is what i have done in new edii – cpt. Sparrow Dec 28 '17 at 11:20
  • @Intellij-Shivam i m posting the code – Nasir Javed Dec 28 '17 at 11:26
  • @Intellij-Shivam check the code still its not working – Nasir Javed Dec 28 '17 at 11:30
  • 1
    As we said, just use localDate. See my answer. – Duncan C Dec 28 '17 at 11:50
  • yes its Working Thanks Alot – Nasir Javed Dec 28 '17 at 11:53
  • please accept the answer and upvote it @NasirJaved – cpt. Sparrow Dec 28 '17 at 11:53
  • (Sorry Intellij. He ended up accepting my answer instead, even though it was based on your code and I credited you for it. I didn't mean to steal your thunder.) I up-voted your answer though, since it converted the date "into local time" as the OP asked. – Duncan C Dec 28 '17 at 17:58
  • no problem sir I really appreciate that happy to help @DuncanC – cpt. Sparrow Dec 28 '17 at 18:43
  • WHy does DateFormatter only accept a string? Why not a date object as param? – chitgoks Oct 01 '22 at 02:31