1

Does anyone have an answer to why I am getting -8 hours instead of -7 (my timezone) hours difference upon converting time from GMT to local i using the formula below:

print("TIMEZONE IN HOURS: \(timeZone/3600)")
        
let interval = Date(timeIntervalSinceReferenceDate: 93866.4142533315)
print("GMT TIME: \(interval)")
        
let intervalDateComponents = calendar.dateComponents([.hour, .minute, .second], from: interval)
let mHour = intervalDateComponents.hour ?? 0
let mMinute = intervalDateComponents.minute ?? 0
print("INTERVAL DATE COMPONENT: \(intervalDateComponents)")
    
let formatter = DateFormatter()
        
formatter.timeZone = TimeZone.current
        
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        
let intervalDateString = formatter.string(from: interval)
        
print("DATE STRING FORMAT: \(intervalDateString)")
        

prints out the following: (please pay attention to date)

TIMEZONE IN HOURS: -7
GMT TIME: 2001-01-02 02:04:26 +0000 (January 2)
INTERVAL DATE COMPONENT: hour: 18 minute: 4 second: 26 isLeapMonth: false 
DATE STRING FORMAT: 2001-01-01 18:04:26 (January 1)
interval HOURS: 18

edit/update:

let mDateString = formatter.string(from: interval) 
print("DATE STRING FORMAT: (mDateString)")
let mdate = formatter.date(from: mDateString) 
print("MDATE: (mdate)")
let mDateComponents = calendar.dateComponents([.hour, .minute, .second], from: mdate!)
print("M DATE COMPONENT: (mDateComponents)")

prints out:

DATE STRING FORMAT: 2001-01-01 19:01:27 -0700 
MDATE: Optional(2001-01-02 02:01:27 +0000)
M DATE COMPONENT: hour: 18 minute: 1 second: 27 isLeapMonth: false 

If you notice above in the code my intention is to extract the local time component to trigger alarm at a later time daily. So I fed the string that shows

2001-01-01 19:01:27 -0700

I converted the string to mdate in order to get time components that I need to use for the alarm to work on time so I got (hour: 18) rather than hour: 19 which I used to generate the mdate string.

Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
AA Kanj
  • 13
  • 4

1 Answers1

0

The problem there is that you are getting the timezone offset for today. You need to get the timezone offset for the same date you are using:

let timeZone = TimeZone.current.secondsFromGMT(for: interval)
print("TIMEZONE IN HOURS: \(timeZone/3600)")
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • To leoWould you be able to tell me how to handle daylight savings? I looked at so many answers and every one say different things. I understand the general concept though not sure about application as how to compensate for the 1 hour difference – AA Kanj Oct 06 '20 at 17:07
  • What do you mean by handle daylight savings? What are you trying to accomplish? Usually you just need to avoid using midnight for calendrical calculations. – Leo Dabus Oct 06 '20 at 17:11
  • this the heart of the problem: – AA Kanj Oct 06 '20 at 18:28
  • For a time insensitive calendrical calculations just use noon (12pm) – Leo Dabus Oct 06 '20 at 18:38
  • this might help as well https://stackoverflow.com/a/62590112/2303865 – Leo Dabus Oct 06 '20 at 18:48
  • let mDateString = formatter.string(from: interval) print("DATE STRING FORMAT: \(mDateString)") let mdate = formatter.date(from: mDateString) print("MDATE: \(mdate)") let mDateComponents = calendar.dateComponents([.hour, .minute, .second], from: mdate!) print("M DATE COMPONENT: \(mDateComponents)") – AA Kanj Oct 06 '20 at 18:53
  • prints out: DATE STRING FORMAT: 2001-01-01 19:01:27 -0700 MDATE: Optional(2001-01-02 02:01:27 +0000) M DATE COMPONENT: hour: 18 minute: 1 second: 27 isLeapMonth: false if you notice above in the code my intention is to extract the local time component to trigger alarm at a later time daily. so I fed the string that shows 2001-01-01 19:01:27 -0700 – AA Kanj Oct 06 '20 at 18:54
  • I converted the string to mdate in order to get time components that I need to use for the alarm to work on time so I got (hour: 18) rather than hour:19 which I used to generate the mdate string. I hope you got my point now – AA Kanj Oct 06 '20 at 18:54
  • Do you mind editing your question and posting your code there? It is very hard to read the code in comments – Leo Dabus Oct 06 '20 at 18:57
  • is it not clear? yes, you can edit whatever I posted so far – AA Kanj Oct 06 '20 at 19:03
  • @AAKanj no it is not clear why are you using a date in 2001. Can you show why are you using `"Jan 2, 2001 at 12:04 AM"`? How do you come up with `93866.4142533315` and why? – Leo Dabus Oct 06 '20 at 19:21
  • Btw if your intent is to get the next date (7pm) after now you can use `Calendar` method `nextDate(after:)` and pass the desired DateComponent `let next19pm = Calendar.current.nextDate(after: Date(), matching: .init(hour: 19), matchingPolicy: .nextTime)!` – Leo Dabus Oct 06 '20 at 19:26
  • Leo, I was able to get the right hour: 19 using your recommended formula below by adjusting the timeZone to formatter.timeZone from:mdate) as follows: let hourInAEST = Calendar.current.dateComponents(in: formatter.timeZone, from: mdate).hour! THANKS FOR YOUR HELP MR. DABUS – AA Kanj Oct 06 '20 at 22:34
  • you are welcome. Please don't forget to accept the answer as correct by clicking on the checkmark below the votes counter – Leo Dabus Oct 06 '20 at 22:36
  • I am new to this group, I looked but could not find the check mark!! I went under activity, there votes but no checkmark flag there. Please more details ! – AA Kanj Oct 07 '20 at 03:15
  • https://www.dropbox.com/s/c9exrnw3xmsfe1m/F2281226-6982-48C5-884C-3A5165EA34EF.png?dl=1 – Leo Dabus Oct 07 '20 at 11:34
  • Leo, I am not able to find the CheckMark you are indicatin!!! – AA Kanj Oct 11 '20 at 06:53
  • until today I was able to see the checkMark you are talking about. Sorry for the delay!! – AA Kanj Dec 02 '20 at 03:43
  • @AAKanj no problem. Glad to help – Leo Dabus Dec 02 '20 at 03:48