File Exchange

image thumbnail

Convert between world time zones with daylight saving times

version 1.1 (5.38 KB) by

This is a very simple yet powerful function to convert a datenum from one timezone to another.

4.125
8 Ratings

5 Downloads

Updated

View License

Update (2014-12-16): I now greatly recommend to use the Joda Time library instead of this function:
http://joda-time.sourceforge.net/
I have been using the C# port Noda Time lately and it is perfectly suited for this kind of tasks.
-----------------
As I could find no built-in function nor reliable contribution to achieve that, I had no choice but to write my own, leveraging the GregorianCalendar Java class.
Usage is quite simple:
    targetDST = TimezoneConvert( dn, fromTimezone, toTimezone )
The datenum dn corresponds to the datetime you want to convert. Just specify from which timezone it comes and the target timezone, and you should get the expected result, that takes into account daylight saving time.

Feel free to let me know if I can extend it to support more situations (like Julian Calendar, obviously ;-).

You can get the name of the available timezones using this command:
    TimeZone.getAvailableIDs
after importing the relevant java packages.
    import java.lang.String
    import java.util.* java.awt.*
    import java.util.Enumeration

Comments and Ratings (22)

Matt Fifer

I incorrectly added one to the milliseconds below, they need to be rounded instead:

t1.set(Calendar.MILLISECOND, round((S - fix(S)) * 1000));

Matt Fifer

Thanks for providing this function, Erwin! One quick thing: the set function used does not support milliseconds, so those have to be set manually. To fix this issue (and keeping the Financial Toolbox dependency fix from Scott below), the t1.set... line in the current code has to be replaced with the following lines:

[Y, M, D, H, MN, S] = datevec(dn);
t1.set(Y, M-1, D, H, MN, S);
t1.set(Calendar.MILLISECOND, (S - fix(S)) * 1000 + 1);

otherwise, it seems like milliseconds get set to a random number.

Alex

Alex (view profile)

Thanks

Ricardo

Here's a suggestion for a vectorized version of this function:

function time = convertTZone(time, TZoneOld, TZoneNew)

OffSet = now - TimezoneConvert(now, TZoneOld, TZoneNew);
time = time - OffSet;

end

@Scott, I applied your 'fix', but do not observe your issue.

t1 = datestr(TimezoneConvert(datenum('31-Mar-2013 00:59:59'),'UTC','Europe/Berlin'))
t2 = datestr(TimezoneConvert(datenum('31-Mar-2013 01:00:00'),'UTC','Europe/Berlin'))

Results in:
t1 =
31-Mar-2013 01:59:59
t2 =
31-Mar-2013 03:00:00

as expected.
So I think your fix is ok.

Justinas

Hi, currently the function supports only one date conversion, due to Calendar.set method limitations.
How could I modify it to make fast conversions for multiple dates? i.e.if dn would be a vector.

janez

janez (view profile)

Great tool. A word of warning though: as noticed by Matt Aldrich it doesn't accept multidimensional arrays. But if you loop sequentially over all array elements (datenumbers) it works like a charm.

Erwin Mayer

Hello Scott, I would be happy to help more, unfortunately I don't have Matlab installed right now, and I would greatly suggest to use the Joda Time library instead, to perform the same task as in my original script:
http://joda-time.sourceforge.net/
I have been using the C# port Noda Time lately and it is perfectly suited for this kind of tasks.

@Benjamin, this library would also be more reliable to avoid the kind of rounding errors you have observed.

Hi Erwin, thanks for the reply.

I tried to remove the dependency on the financial toolbox and this almost worked: for Germany, the transition from/to daylight savings times happens at midnight, which isn't correct:
   http://www.timeanddate.com/worldclock/timezone.html?n=37

But since I'm not totally certain about what the dependency-causing financial toolbox functions do, the problem might lie with my hacks. Here's the change I made to TimezoneConvert.m:

% Remove dependence on financial toolbox
% t1.set(year(dn), month(dn)-1, day(dn), hour(dn), minute(dn), second(dn))

[Y, M, D, H, MN, S] = datevec(dn);
t1.set(Y, M-1, D, H, MN, S);

Does this hack give the same answer as when using the FT functions?

Erwin Mayer

Scott: Yes, it requires the financial toolbox.

When I run it, I get the error:

??? Undefined function or method 'year' for input arguments of type 'double'.

Error in ==> TimezoneConvert at 11
    t1.set(year(dn), month(dn)-1, day(dn), hour(dn), minute(dn), second(dn))

Does this require the financial toolbox?

Benjamin

Sorry, I did not finish the comment but the Matlab comment already got submitted.

Using the same code if we ignored the seconds difference the time conversion is incorrect as well for historical daylight savings:

nDates1 = datenum([2012 6 21 6 0 0]);
tDates1 = TimezoneConvert(nDates1, 'EST', 'Hongkong');

datevec(tDates1)

ans = 2012 06 21 19 0 0.34

6am EST on June 21 does not equate to 7pm China Standard Time on June 21st (as there is no daylight savings then).

Benjamin

There seems to be a rounding error. Using following code generates 0.34 seconds difference. I believe you need to floor some of the calculations when performing this calculation as the precision isn't correct.

nDates1 = datenum([2012 6 21 6 0 0]);
tDates1 = TimezoneConvert(nDates1, 'EST', 'Hongkong');

datevec(tDates1)

ans =

   1.0e+03 *

    2.0120 0.0060 0.0210 0.0190 0 0.0003

Matt Aldrich

What about vectorized support?

Yuxiao Qin

Thank you so much for the file... I was always working on APIs, which cannot display historical DST... Never thought matlab itself can do the job... Much appreciation!

David

David (view profile)

thank you!

Erwin Mayer

Hi Justinas, it should adjust historical time for the DST, that was the purpose. At least provided the functions from the Java package support them (probably not for dates very far away) Let me know if it does not work with a special case.

Justinas

This function does not seem to adjust historical time for the DST, does it?

"Feel free to let me know if I can extend it to support more situations"

Well, since K E wasn't explicit: can you make it Financial-Toolbox-free (i.e., not dependent on having that)?

K E

K E (view profile)

OK, that's why - I don't have the Financial Toolbox.
Thanks, KE

Erwin Mayer

Hi K E, from what I could see these functions are normally part of the Financial Toolbox. Aren't they enabled by default?

K E

K E (view profile)

Seems to crash because the following mfiles are not included:
year
month
day
hour
minute
second
Or have I misunderstood how to run this?
t1 = TimezoneConvert(now, 'UTC', 'US/Eastern')

Updates

1.1

Update (2014-12-16): I now greatly recommend to use the Joda Time library instead of this function:
http://joda-time.sourceforge.net/
I have been using the C# port Noda Time lately and it is perfectly suited for this kind of tasks.

MATLAB Release
MATLAB 7.4 (R2007a)

Download apps, toolboxes, and other File Exchange content using Add-On Explorer in MATLAB.

» Watch video