DATA MANAGEMENT Crossing Time Zones With ASE Solving the Time Zone Translation Problem Working with timestamped data in ASE can be challenging as there is little information and few coded solutions for translating data from one time zone to another. In this article, I will explain how to implement time translations across multiple time zones. By Mark Gearhart I f you find yourself juggling time zones, you are not alone. I am currently in contact with clients in UTC -4, +1, +8, +3, and -5 (i.e. New York, London, Hong Kong, Moscow, and Houston), although it varies with the projects I’m working on at any given time. If you add daylight savings time to the mix, it gets even more interesting. A frequent exercise usually involves computing the difference in time, between, say Hong Kong and New York in order to schedule a time for a conference call. Another common scenario is figuring out what time it is in Sydney when the markets close on Friday at 4PM in New York. The result is, not surprisingly, a decision to let my colleague sleep at 6AM Saturday morning rather then wake him for a question. Mark Gearhart is an independent Systems Engineer, currently based in Research Triangle Park, North Carolina. He develops databases and rich internet applications for temporal and realtime systems. His background encompasses the energy and financial industries with a special interest in data storage architectures and fast user interfaces. He is currently working on projects with Dobler Consulting and can be reached at www.mgearhart.com. 50 ISUG TECHNICAL JOURNAL The Problem If you are writing applications which likewise deal with times around the globe, there is little information and very few coded solutions for translating data from one time zone to another. In Sybase ASE, the bigdatetime, datetime and smalldatetime data types do not store time zone information and the products are entirely unaware of the concepts of time zones and daylight savings time. Sybase Servers only recognize and store the date and time portions of the values provided by the operating system, which are based on the time zone configured at the operating system level. Therefore, if you work with timestamped data in ASE, you must solve time translation problems yourself. Coordinated Universal Time If we start by thinking about Coordinated Universal Time (UTC) time as a common point of reference, then times can be compared. For example, in a scheduling application, when a user in New York enters a time for a conference call with a colleague in Hong Kong, he types 2011-0519 09:00 EDT. The application converts this to UTC time and stores 2011-05-19 14:00 UTC in the database. On the other side of the world, the user in Hong Kong checks the time of the meeting. The application reads the time from the database. It still represents 2011-05-19 14:00 UTC, but based on Hong Kong’s time zone, the time is returned as 2011-05-19 21:00 HKT. Therefore, knowing that time is stored as UTC turns the entire problem into a simple calculation from New York time (UTC-5 hours) to UTC and then from UTC to Hong Kong time CROSSING TIME ZONES WITH ASE (UTC+8 hours). Based on this general approach, a user in Frankfurt knows that he can join the same call at his local time of 2011-05-19 14:00 CEST. UTC time is the key to translating time zones. UTC time represents the physical world; therefore, time neither reverses nor does it skip as in the case of local time, which can have 23, 24, or 25 hours days. There are no daylight savings adjustments, and therefore data stored in UTC time guarantees uniqueness. In UTC time, there are always 24 hours in a day. For any location in the world, the local time can be calculated by adding or subtracting a certain number of minutes which may vary from one day to the next depending on the daylight savings time adjustment. The Solution So, how do we implement time translation so we can convert between local and UTC time? Do we extend the datetime data type to include a time zone? Do we write some kind of layered API? Do we invent a database solution using time translation tables which supply offsets to UTC time? I have found that the last option presents a viable and simple solution, and is well worth trying. For this option, we can begin by constructing two static lookup tables as follows: cre at e t abl e T i meZon e ( Z o n e s m al l i n t not nu ll, Nam e v arc h ar ( 50 ) not nu ll) UTCStart UTCStop DST Offset Abbr 4 2010-11-07 08:00:00.000 2011-03-13 06:59:59.997 ““ -300 EST 4 2011-03-13 07:00:00.000 2011-11-06 06:59:59.997 ““ -240 EDT 4 2011-11-06 07:00:00.000 2011-11-06 07:59:59.997 “2“ -300 EST 4 2011-11-06 07:00:00.000 2012-03-11 06:59:59.997 ““ -300 EST Table 2: TimeTran UTC-to-local time translations are performed according to the interval and offset configured for the time in question. For the U.S. Eastern time zone, which encompasses America/New_York, the time translation for the spring and fall daylight savings time intervals would proceed as shown in Table 3. For this UTC Time Add this offset To produce this local time And this DST And this Zone 2011-03-13 05:00 -300 2011-03-13 00:00 ““ EST 2011-03-13 06:00 -300 2011-03-13 01:00 ““ EST 2011-03-13 07:00 -240 2011-03-13 03:00 ““ EDT 2011-03-13 08:00 -240 2011-03-13 04:00 ““ EDT 2011-11-06 04:00 -240 2011-11-06 00:00 ““ EDT 2011-11-06 05:00 -240 2011-11-06 01:00 ““ EDT 2011-11-06 06:00 -240 2011-11-06 02:00 ““ EDT 2011-11-06 07:00 -300 2011-11-06 02:00 “2” EST 2011-11-06 08:00 -300 2011-11-06 03:00 ““ EST Table 3: UTC-to-Local Time Translation cre at e t abl e T i meT r a n ( Z o n e s m al l i n t not nu ll, U TCS t art dat etim e n ot nu ll, U TCS t o p d at e t im e n ot nu ll, D S T c h ar(1 ) n o t nu ll, Of f s e t s m al l i n t not nu ll, A bbr c h ar(5 ) not nu ll) The TimeZone table (see Table 1) contains a list of time zones. We will concentrate on just one time zone, called America/ New_York as it is known from the public domain TZ (or Olson) data source. Zone Zone Name 0 UTC 1 Europe/London 3 Europe/Moscow 4 America/New_York 8 Australia/Sydney Table 1: TimeZone The TimeTran table (see Table 2) contains the offsets from UTC time for each time zone listed in the TimeZone table. The TimeTran table has a row for every resetting of the clock. For America/New_York, this gives us a table with 4 rows per year. Westward Expansion As time zones move westward to increase UTC time, the offset also increases. This preserves the relative time of the data with respect to the time at which it was stored in the database. Once the offset has been configured, data may be selected by converting the UTC time stored with the data into a local time. To automate things a bit, we can create functions which convert from UTC time to local time and visa versa. The utctoloc function takes UTC time as input and returns the corresponding local time and DST indicator as output. The loctoutc function is the reverse of utctoloc. It takes the local time and DST indicator as input and returns the corresponding UTC time as output. For the spring daylight savings time interval in the U.S., we consider the local 2 AM hour as being non-existent. Therefore if this hour is passed in, the UTC time is returned as null: cr ea t e funct ion ut ct oloc(@U t c d a t et me, @Z one sma llint ) r et ur ns d a t et ime a s beg in r et ur n (select d a t ea d d (mi,O ffset ,@U t c) fr om T imeT r a n w her e @U t c >= U T CS t a r t APRIL - JUNE 2011 51 CROSSING TIME ZONES WITH ASE an d @ U t c < = U T C Stop an d Z o n e = @Zon e) en d cre at e f un c t i o n l octou tc( @ L oc d a tetm e, @ Ds t cha r (1 ), @Z o n e s m al l i n t ) r etu r n s d a tetim e a s begin re t u rn (s e l e c t d a tea d d ( m i, - O ffs et, @ L oc) f ro m T i m e Tra n w h e re UT CS t a r t < d a tea d d ( m i, - O ffs et, @ L oc) an d U TCS t o p > = d a tea d d ( m i, - O ffs et, @ L oc) an d D S T = @ D s t an d Z o n e = @Zon e) en d Using these functions, we can perform time arithmetic between local times in different time zones. For example, the query below will show that, on May 19th, 2011, there are 14 hours between Sydney and New York (for other dates there may be a 13 or 15 hour difference depending on daylight savings time): se l e c t Ho urs = d a ted iff( hh, (s e l e c t dbo .l o c tou tc( “ 20 1 1 - 05 - 19 ” , ” “ , Zon e) f ro m Ti m e Z o ne wher e N a m e = “ A u s tr a lia / Syd ney”), (s e l e c t dbo .l o c tou tc( “ 20 1 1 - 05 - 19 ” , ” “ , Zon e) f ro m Ti m e Z o ne wher e N a m e = “ A m er ica / N ew _ Y or k”)) We can also use local time as a search argument to translate data stored in UTC time into any desired local time. For example,the following query will select a day’s worth of data for the America/ New_York time zone. Since November 7th, 2011 crosses the fall daylight savings time interval, the query automatically returns 25 hours of data: se l e c t U TCTi m e = d .U T C T im e, L o c Ti m e = d at ea d d ( m i, O ffs et, d . U T C T im e) , HE = ri g h t (“ 0 ” + conv er t( v a r cha r ( 2 ) , d a tep a r t(hh, dat e add(m s, - 2 , d a tea d d ( m i, t. O ffs et, d . U T CT ime))) + 1 , 2 ), D S T = t .D S T , A bbr = t .A bbr, V al u e = d.V al u e fro m D at a d, Ti meT r a n t, T im eZone z w h e re d.UT CTi me > = t. U T C Sta r t an d d.UT CTi m e < = t. U T C Stop an d t .Z o n e = z.Zone an d d.UT CTi m e > d b o. loctou tc( “ 20 1 1 - 11 - 06 ” , ” “,z. Z one) an d d.UT CTm e < = d b o. loctou tc( “ 20 1 1 - 11 - 07 ” ,” “,z. Z one) an d z.N am e = “ Am er ica / N ew_ Y or k ” ) o rd e r by d.UT CTim e 52 ISUG TECHNICAL JOURNAL The output of this query (see Table 4) demonstrates that we have: • Converted local to UTC time in the search arguments in order to locate data which is stored in UTC time. • Converted the returned data to the appropriate local time. • Displayed a repeated 2 AM hour. • Displayed the correct EDT/EST time zone for each hour. • Displayed a nice hour-ending time from 1 through 24. UTCTime LocTime HE DST Abbr Value 2011-11-06 05:00 2011-11-06 01:00 2011-11-06 06:00 2011-11-06 02:00 01 EDT 456 02 EDT 684 2011-11-06 07:00 2011-11-06 02:00 02 EST 123 2011-11-06 08:00 2011-11-06 03:00 03 EST 234 2011-11-06 09:00 2011-11-06 04:00 04 EST 768 2011-11-06 10:00 2011-11-06 05:00 05 EST 345 2011-11-06 11:00 2011-11-06 06:00 06 EST 456 2011-11-06 12:00 2011-11-06 07:00 07 EST 546 2011-11-06 13:00 2011-11-06 08:00 08 EST 234 2011-11-06 14:00 2011-11-06 09:00 09 EST 345 2011-11-06 15:00 2011-11-06 10:00 10 EST 838 2011-11-06 16:00 2011-11-06 11:00 11 EST 155 2011-11-06 17:00 2011-11-06 12:00 12 EST 947 2011-11-06 18:00 2011-11-06 13:00 13 EST 258 2011-11-06 19:00 2011-11-06 14:00 14 EST 783 2011-11-06 20:00 2011-11-06 15:00 15 EST 145 2011-11-06 21:00 2011-11-06 16:00 16 EST 555 2011-11-06 22:00 2011-11-06 17:00 17 EST 456 2011-11-06 23:00 2011-11-06 18:00 18 EST 754 2011-11-07 00:00 2011-11-06 19:00 19 EST 174 2011-11-07 01:00 2011-11-06 20:00 20 EST 358 2011-11-07 02:00 2011-11-06 21:00 21 EST 678 2011-11-07 03:00 2011-11-06 22:00 22 EST 264 2011-11-07 04:00 2011-11-06 23:00 23 EST 457 2011-11-07 05:00 2011-11-07 00:00 24 EST 256 2 Table 4: Query Output Conclusion With this, the data engineer can appreciate the fact that time zone configurations have been placed into a very manageable spot inside the database to be used with all the other data. New entries can be added for historic or future data, and with a small amount SQL code, both time zone arithmetic and time translation across time zones can be implemented when the opportunity arises.
© Copyright 2026 Paperzz