How to handle timezones in the Query API?

Posted by Rollbase User on 26-Apr-2012 10:31

Hi - I have a situation with timezones. I wonder if there's a recommended way to handle this. Different parts of the system are returning / expecting the same timestamp value in different timezones. I'm running into this in a Before Create validation trigger. The new record has date/time data that represents a range of time - start, and end. Before allowing creation, I want to query for overlaps. I want to ensure that I never have two records that overlap in time. I use merge tokens to get the date/time values from the new record. The merge tokens seem to give me their values in the current user's time zone: var start = new Date ('{!start_timestamp}'); var end = new Date ('{!end_timestamp}'); Then I run a query using the Query API to count overlaps: var num_overlaps = rbv_api.selectNumber ('SELECT count(1) FROM worked_time WHERE start_timestamp?', end, start); However, the Query API seems to interpret the timestamp data as being in a different timezone. I'm getting false p

All Replies

Posted by Admin on 26-Apr-2012 10:37

I suppose another option, if it were possible, might be to access the timestamp data on the uncreated record via the Query API. If the API returns that data in the timezone it expects back, then I would have it in the right timezone. I could use that to then run the query I'm wanting to run.

Posted by Admin on 26-Apr-2012 12:25

API always uses user's timezone. Hope that explains.

Posted by Admin on 27-Apr-2012 02:06

Hey Pavel,



Thanks for that. Maybe you can explain what I'm seeing. Maybe I'm not understanding what's happening here.



The book says (in chapter 6) that merge tokens for date field values will give you the value in the current user's timezone. Is that right? Above you say that the API always uses the user's timezone. So I think that means if I acquire a date value via the API, I'll get the date value in the timezone of the current user. My expectation therefore would be that if I acquire the same date value via a merge token and the API, I'd get the value in the same timezone from both sources. However, that's not what I'm seeing.



Here's what I'm seeing. If I run a formula that acquires the same date value via a merge token, and then immediately again via the API, I get date values that are an hour apart. My first thought was that I must be getting them in different timezones. But maybe something different is causing that hour difference.



Here's the formula:

// Acquire the date value

var start_vi

Posted by Admin on 27-Apr-2012 11:55

This will be fixed in the next release.

Posted by Admin on 27-Apr-2012 11:58

Thanks very much, Pavel - Nathan

Posted by Admin on 27-Apr-2012 20:59

Following up on Pavel's comment, this was fixed in Friday's release (April 27, 2012)

Posted by Admin on 29-Apr-2012 05:13

That was fast! Thanks very much for that. I see I'm getting date values in the same time zone now.



It doesn't seem to be my user's time zone, though. I have my time zone set to GMT-7, and I'm getting date values from the above formula in GMT-5. I see the account settings have the time zone set to GMT-5.



Does the server give me the account time zone rather than the viewing user's time zone?

Posted by Admin on 29-Apr-2012 09:20

Actually, I just noticed that the time value I get does change when I change the time zone in my user settings.



I'm not really sure what's going on here, but something doesn't seem right.



My user account has MST: (GMT-07:00) MST

The account settings has EST: (GMT -05:00) EST



Merge token date strings give me MDT: Thu Apr 05 2012 04:00:00 (MDT)

Date objects from them are CDT: Thu Apr 05 2012 04:00:00 GMT-0500 (CDT)

Date objects from the API are also CDT: Thu Apr 05 04:00:00 CDT 2012



If I change my time zone (in my user account), the time value I get does change. BUT, the time zone on the date/time string remains at CDT, no matter what I do. I don't know if that time zone label is just a string somewhere, or if it's actually the time zone of the JS Date object.



I think the MDT in the merge token date string is actually correct. I believe Mountain Time is currently in daylight savings time, so it becomes Mountain Daylight Time. I have no idea where the CDT is coming from.



If the JS Date objec

Posted by Admin on 29-Apr-2012 09:22

Here's an updated formula that also outputs the merge token string Before it's converted to a JS date object.



Formula:

// Acquire the merge token string

var start_merge_token_string = '{!worked_time_start}';

rbv_api.println ('Acquired merge token string: start_merge_token_string=' + start_merge_token_string);

// Acquire the date value from both sources

var start_via_merge_token = new Date (start_merge_token_string);

var start_via_api = rbv_api.selectValue ('SELECT worked_time_start FROM worked_time WHERE id=?', {!id});

rbv_api.println ('Acquired date value: start_via_merge_token=' + start_via_merge_token + ', start_via_api=' + start_via_api);

// Convert to milliseconds

var start_via_merge_token_ms = start_via_merge_token.getTime ();

var start_via_api_ms = start_via_api.getTime ();

rbv_api.println ('Converted to milliseconds: start_via_merge_token_ms=' + start_via_merge_token_ms + ', start_via_api_ms=' + start_via_api_ms);

// Compare for equality

rbv_api.println ('Equality comparison

Posted by Admin on 29-Apr-2012 10:05

Here's an example of what happens when I change my user time zone. I'm acquiring the same date value from the same record, with nothing but my user time zone changed:



With my time zone as MST (GMT -07:00):

Via merge token: Thu Apr 05 2012 04:00:00 GMT-0500 (CDT)

Via API: Thu Apr 05 04:00:00 CDT 2012



With my time zone as CST (GMT -06:00):

Via merge token: Thu Apr 05 2012 05:00:00 GMT-0500 (CDT)

Via API: Thu Apr 05 05:00:00 CDT 2012



With my time zone as EST (GMT -05:00):

Via merge token: Thu Apr 05 2012 06:00:00 GMT-0500 (CDT)

Via API: Thu Apr 05 06:00:00 CDT 2012

Posted by Admin on 29-Apr-2012 11:19

So it seems to be working fine now.

Posted by Admin on 29-Apr-2012 12:49

Thanks for looking at this, Pavel. It seems to me that something is a bit off.



Here's a test I ran. I queried the same date value from the same field on the same record multiple times. Between queries, I changed one thing: my user timezone setting. When I check the UTC time for the Date objects I get, it's different every time.



My expectation here would be that the UTC time for the same date value is the same every time I query it, regardless of the timezone of the current user. I would expect the timezone of the object to change, but not the underlying, absolute UTC time value.



For interest, when my user timezone setting is GMT, the standard UI displays the date value I'm querying as:

2012-04-05 11:00



With timezone GMT:

start.toUTCString=Thu, 05 Apr 2012 16:00:00 GMT



With timezone IST (GMT+05:30, India time):

start.toUTCString=Thu, 05 Apr 2012 20:30:00 GMT



With timezone JST (GMT+09:00, Japan time):

start.toUTCString=Fri, 06 Apr 2012 00:00:00 GMT



With timezone

Posted by Admin on 29-Apr-2012 12:54

Here's the same set of queries again, this time displaying the results of the getTime() method. This method returns the milliseconds-since-epoch for a time value. I think the milliseconds value is intended to represent an absolute point in time, independent of timezone.



Again, my expectation here would be that the milliseconds value is the same every time I query the same date value, regardless of the timezone setting of the current user.



With timezone GMT:

start.getTime=1333641600000



With timezone IST (GMT+05:30, India time):

start.getTime=1333657800000



With timezone JST (GMT+09:00, Japan time):

start.getTime=1333670400000



With timezone MST (GMT-07:00, Mountain Time):

start.getTime=1333616400000



With timezone CST (GMT-06:00, Central Time):

start.getTime=1333620000000



With timezone EST (GMT-05:00, Eastern Time):

start.getTime=1333623600000




Here's the formula I used to generate the above output:

var start = new Date ('{!worked_time_start}');

rb

Posted by Admin on 29-Apr-2012 13:01

This seems to be affecting date comparisons. I can't seem to run a comparison successfully.



If I pull a date value from an existing record, then immediately query the database for any records matching that date value, I get zero matches. My expectation here would be that if I query for the value of an existing record, I would get a match on at least that record.



Here's a formula that pulls a date value via the API, then immediately queries for it:

var start = rbv_api.selectValue ('SELECT worked_time_start FROM worked_time WHERE id=?', {!id});

var num_matches = rbv_api.selectNumber ('SELECT COUNT(1) FROM worked_time WHERE worked_time_start=?', start);

rbv_api.println ('num_matches=' + num_matches);




The output is:

num_matches=0



And here it is pulling the same date value via a merge token, then querying for it:

var start = new Date ('{!worked_time_start}');

var num_matches = rbv_api.selectNumber ('SELECT COUNT(1) FROM worked_time WHERE worked_time

Posted by Admin on 30-Apr-2012 12:55

This type of queries will not work since in DB date/time is always stored in server's time zone. I can try to fix this.

Posted by Admin on 30-Apr-2012 13:01

Thanks, Pavel. It would be helpful to me if I could run queries like that.

This thread is closed