Android Question How to use timezone?

udg

Expert
Licensed User
Longtime User
Hi all,

after reading a few posts about SetTimeZone and similar functions I still can't understand the way I should use them in my app.

App goal: show a countdown from a date set in the future to today date.
Problem: the date in the future is fixed in code and represents a real event to be held in a specific location, whereby today date (and time) is local to the user of the app.

What functions am I expected to use in order to have the "right" time difference between dates taking in account both locations?

To be clearer:
Event held in Rome, Italy (UTC+1) on 2013-12-31 10:00
App user being in Rome,Italy launching my app on 2013-12-28 09:00
Countdown should shows: 3 days and 1hour left
But a second user launching the app at the same time but in New York, USA (UTC-5) should read the same irrespective of his clock showing 4 AM (i.e. his local time).

Can you help please?
TIA
 

udg

Expert
Licensed User
Longtime User
Hi David,

I'm not sure how to use your suggestion.
So far I found a "working" solution, but since it seems too complex I feel it's somewhat wrong..

Anyway, further reading led me to the following, based on the assumption that DateTime.Now is always computed as of UTC 0.
B4X:
Sub Globals
   DateTime.SetTimeZone(0)     'refer everything to UTC 0/Greenwich from now on
   'Local time for eventdate should be 16:50 (Rome time, UTC+2) but it's written as 14:50 (UTC 0)
   Dim EventDate As Long = DateUtils.SetDateAndTime(2013,10,25,14,50,0) ' Today, October 25th 2013 14:50:00 UTC time
   Dim lblCountDown As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("Layout1")
   dt_now= DateTime.now  'Now as UTC 0 time
   'remaining time before Event; both datetimes are UTC 0 so the difference should be correct
   Dim CountDown As Period = DateUtils.PeriodBetween(EventDate, dt_now)
   lblCountDown.Text = CountDown.Years & CountDown.Months & CountDown.Days & CountDown.Hours & CountDown.Minutes & CountDown.Seconds
  Timer1.Initialize("Timer1", 1000) ' 1000 = 1 second
  Timer1.Enabled = True
End Sub
Am I near to what you suggested?

Umberto
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Please use [ code ] [ /code ] tags (without spaces) when posting code.

Your current code will not work correctly.

1. Don't call DateTime.SetTimeZone in sub globals. It should only be used for variables declarations.
2. You don't need to call DateTime.SetTimeZone at all.
3. Download the latest DateUtils module (v1.05): http://www.b4x.com/android/forum/th...fies-date-and-time-calcuations.26290/#content

You should use DateUtils.SetDateAndTime2. It allows you to set the event time zone.

You can then call PeriodBetween to calculate the difference.
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Hi Erel,
thank you for your advice.
I edited my previous msg so to correctly show the code section as suggested; my apologies for the inconvenience.
As you know I'm knew to B4A, so how am I expected to "upgrade" my 2.71 B4A version of DateUtils (v1.03) with the one provided as a module in the example given? I mean, I open your DateUtils.zip example and find a code module named DateUtils; how do I save/use it in my project?
BTW, why checking the library DateUtils my B4A copy loads version 1.03? Should I upgrade to the already downloaded (but not installed) version 3.0?

A final question about SetDateAndTime2 function usage: have I to set the timezone of the place where the event will take place? So, remaining to my example in msg #3
DateUtils.SetDateAndTime2(2013,10,25,16,50,0,2) ' Rome (ITA), October 25th 2013 16:50:00 Rome local time

and then simply DateUtils.PeriodBetween(EventDate, dt_now) to have a correct countdown all over the world?



Thank again.

Umberto
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Thanks Erel.
Done as instructed, everything is working ok.
So, from now on, when in an app I need to reference a function in DateUtils I don't check the library in the list but simply add the module from the DateUtils example just downloaded. This will stay so until you announce a new version of the library, right?

As for my code, Rome is GMT +1 but due to DST it could be +2 on specific event dates.
So this leaves me to check beforehand whether any specific event_date needs a +1 or +2 offset.
I thought about the DateTime.GetTimeZoneOffsetAt() function but I guess its response is based on the knowledge of where the device is located when it's called so it seems to be no way to calculate the GMT offset of a given location on a specific future date.
No problem for the task at hand (I checked the event date on timeanddate.com and read there the offset needed) but as a general method it could be nice to have a function
GMTOffset(Location,Date)
returning the offset from GMT 0 to be taken account for on date Date for location Location.
Example
GMTOffset(Rome, '2013-10-25') --> +2
GMTOffset(Rome, '2013-10-27') --> +1

If you find it useful, just add it to the wishlist. Thank you.

Umberto
 
Upvote 0

Theera

Well-Known Member
Licensed User
Longtime User
Hi all,
I don't understand that Udg's post#1 ,The time is started at "App user being in Rome,Italy launching my app on 2013-12-28 09:00(UTC+1)" Why do Erel guide set the time zone in Rome is GMT +2? (I think that UTC+1=GMT+1) in post #6 and the line in post #7 at GMTOffset(Rome, '2013-10-25') --> +2,why don't be GMTOffset(Rome, '2013-10-26')-->+2?
(if it compare with Time at2013-10-28)

Thank you in advance.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
So, from now on, when in an app I need to reference a function in DateUtils I don't check the library in the list but simply add the module from the DateUtils example just downloaded. This will stay so until you announce a new version of the library, right?
Yes. Or you can compile DateUtils library yourself. It is very simple to compile a library.

Why do Erel guide set the time zone in Rome is GMT +2?
I haven't checked the the timezone (I wrote that I assumed that it is GMT + 2).
 
Upvote 0

Theera

Well-Known Member
Licensed User
Longtime User
Another question has no answer.
the line in post #7 at GMTOffset(Rome, '2013-10-25') --> +2,why don't be GMTOffset(Rome, '2013-10-26')-->+2?
(if it compare with Time at2013-10-28)
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Hi Erel,
thank you so much for your attention.

Theera: Rome, Italy is indeed settled at GMT+1 but due to DTS (daylight saving time) from approximately March-end- to October-end it should be set at GMT+2.
In year 2013 DST ended on October 27th, 3 A.M. so the offset went from +2 to +1 at that moment and will stay so until 2014 March 30th, 2 A.M. local time.
It coud be useful for you to have a look on http://www.timeanddate.com/worldclock/ to verify by yourself which is the right GMT to apply to any town in the world at a specific date.
In the end, as Erel wrote in msg #11 the function GMTOffset is just on my wishing list.

Umberto
 
Upvote 0

Theera

Well-Known Member
Licensed User
Longtime User
Thank you for your informations ,Umberto My Coding is right? (Due to not understanding English well)
B4X:
Sub Globals
  'refer everything to UTC 0/Greenwich from now on
  'Rome, Italy is indeed settled at GMT+1 but due to DST (daylight saving time) from approximately
  ' March-end- to October-end it  should be set at GMT+2.
  'Therefore, The local time for eventdate should be 10:00 (Rome time, UTC+2)

  Dim dt_now,EventDate As Long
  Dim lblCountDown As Label
End Sub
Sub Activity_Create(FirstTime As Boolean)
  Activity.LoadLayout("Layout1")
  dt_now= DateTime.now  'The current Time at 2013-12-28 09.00 in Rome,Italy Or The current Time at 2013-12-28 04.00 in New York,USA
  'Using DateUtils Code Module version 1.05 up
  EventDate=DateUtils.SetDateAndTime2(2013,10,31,10,0,0,2)
  'remaining time before Event; both datetimes are UTC+0 so the difference should be correct
  Dim CountDown As Period = DateUtils.PeriodBetween(EventDate, dt_now)
  lblCountDown.Text = CountDown.Years & CountDown.Months & CountDown.Days & CountDown.Hours & CountDown.Minutes & CountDown.Seconds
  Timer1.Initialize("Timer1", 1000) ' 1000 = 1 second
  Timer1.Enabled = True
End Sub
 
Last edited:
Upvote 0

udg

Expert
Licensed User
Longtime User
Hi Theera,
in your code I see two points in need of a clarification:
dt_now = DateTime.Now ; this returns today date/time as if your device was in a GMT 0 country
EventDate=DateUtils.SetDateAndTime2(2013,10,31,10,0,0,2) is wrong if referred to Rome, Italy because on 2013-10-31 Rome will be at GMT+1

My original post asked how to set a countdown for an event to be held on a specific date/time in a specific location, where the countdown was required to be valid all over the world.
The solution found so far is:

1. Look for the event location, date and time on timeandtable.com site to learn the right GMT offset (and eventual DST)
2. Use offset found on step 1 to fill last parameter of SetAndTime2() function where all the other parameters should stay with the real, local date and time of the event (in the example 2013-10-31 10:00 Rome time)
3. Read DateTime.Now
4. Use Periodbetween(EventDate, dt_now) to fill a period type variable containing all the data needed

As I understand, the "magic" is done in SetAndTime2() function where your real, local date/time is converted to its equivalent on GMT 0 and that makes it rigth to compare with result of Now function (already expressed in GMT 0).

Umberto
 
Upvote 0

Theera

Well-Known Member
Licensed User
Longtime User
Hi Umberto,
If I assumed dt_now = DateTime.Now return the current Time at 2013-12-28 09.00 in Rome,Italy,Why don't we set
EventDate=DateUtils.SetDateAndTime2(2013,10,31,10,0,0,2) whenever, you gave this message belows
'Rome, Italy is indeed settled at GMT+1 but due to DST (daylight saving time) from approximately' March-end- to October-end it should be set at GMT+2.'Therefore, The local time for eventdate should be 10:00 (Rome time, UTC+2)
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Hi Theera,

let's try to figure out together the whole process.

1. Event location: Rome, Italy
2. Event Date: 2013-10-31
3. Event time: 10:00 local time in Rome
4. Check the timeanddate.com site to read the correct UTC offset; here we learn that for Rome in year 2013 DST ended on October 27th, 3 A.M. so the offset went from +2 to +1 at that moment and will stay so until 2014 March 30th, 2 A.M. local time.
This means that for our Event date (4 days after offset change) the right UTC offset should be +1.
5. So now we can set our variable EventDate=DateUtils.SetDateAndTime2(2013,10,31,10,0,0,1). The effect of this function is to compute the given event date/time as if it was shifted to Greenwich (or any other UTC 0 zone), making it comparable with result from function Now().
6. Reading dt_now= DateTime.Now it gives us current date/time (again, as it is referring to UTC 0)
7. Finally, DateUtils.PeriodBetween(EventDate, dt_now) computes the difference between those two date/time moments and since they are both expressed as UTC0-based this comparision works and is right.

As an exercise on a real event, the following code shows how to start a countdown to next Olympic Games grand opening (arbitrarly set by me at 18:00, local time). What we know is the location (Rio de Janeiro, Brazil), the date (2016-08-05) and an arbitrary local time (I set it at 18:00).
From timeanddate.com site we learn that the offset at the time of the event will be UTC-3.
So we have:

B4X:
Sub Globals
  
Dim EventDate AsLong = DateUtils.SetDateAndTime2(2016,8,5,18,0,0,-3) ' Olympics opening on August 5th 2016 18:00:00
  
Dim lblCountDown AsLabel

End Sub


Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("Layout1")
   dt_now= DateTime.now  'This exact moment, expressed as UTC 0 time
   'remaining time before Event; both datetimes are expressed as UTC 0, so the difference should be correct
   Dim CountDown As Period = DateUtils.PeriodBetween(EventDate, dt_now)
   lblCountDown.Text = CountDown.Years & CountDown.Months & CountDown.Days & CountDown.Hours & CountDown.Minutes & CountDown.Seconds
   Timer1.Initialize("Timer1", 1000) ' 1000 = 1 second
   Timer1.Enabled = True
End Sub

Hope this will be of any help.

Umberto
 
Upvote 0

Theera

Well-Known Member
Licensed User
Longtime User
Thank you,Umberto I 'm understand Now. I'm still stupid in English.Specifically,they are the long sentences.
 
Last edited:
Upvote 0
Top