Will you show me examples of changing time zones with datetime?

I am currently working with data that comes in GMT. I want to get averages of when an event began and ended in local time (which is pacific standard time, a difference of 7 or 8 hours depending on the time of year). I don't want to just subtract 7 or 8, because datetime keeps track of daylight savings time, which is super helpful.
I change my time with the following code:
dateHourlyTZ = datetime(dateHourlyLocal, 'TimeZone','America/Los_Angeles','Format','d-MMM-y HH:mm:ss Z');
And as a result, I get dates that look like the following:
'1-Dec-1994 15:00:00 -0800'
'1-Dec-1994 16:00:00 -0800'
'1-Dec-1994 17:00:00 -0800'
'1-Dec-1994 18:00:00 -0800'
'2-Dec-1994 11:00:00 -0800'
'2-Dec-1994 15:00:00 -0800'
'5-Dec-1994 15:00:00 -0800'
'5-Dec-1994 16:00:00 -0800'
'18-Dec-1994 16:00:00 -0800'
'18-Dec-1994 17:00:00 -0800'
'23-Dec-1994 15:00:00 -0800'
'23-Dec-1994 16:00:00 -0800'
'23-Dec-1994 17:00:00 -0800'
'27-Dec-1994 15:00:00 -0800'
This is great except for the fact that it doesn't actually subtract the 8 hour time difference from the time. I considered maybe converting it to datestring and then manually subtracting the difference (whether it's 7 or 8 hours for the time of year), but when I convert it to datestring, I lose the -0800 or -0700.
The truth is I think I just don't understand all of what I can do with datetime or how the timezone change is applied. I've read all the Mathworks's info on datetime, but if you have any examples of how to manipulate timezones better or have any additional insight, that would be great. I'm not finding useful examples right now online!
Thanks a lot! -- Ellyn

 채택된 답변

Walter Roberson
Walter Roberson 2016년 10월 24일

2 개 추천

If you have not set the TimeZone on a datetime before, then it does not assume UTC to be converted. Setting the TimeZone for such an object does not change the associated time: it leaves the time alone and fills in the TimeZone field.
For an object that has a TimeZone filled out, changing the TimeZone will changed the displayed time.

댓글 수: 10

Oh so what I actually have is the following:
dateHourlyLocal = datetime(dateHourlyReal, 'TimeZone','local','Format','d-MMM-y HH:mm:ss Z');
dateHourlyLocal.TimeZone='Etc/UTC';
dateHourlyTZ = datetime(dateHourlyLocal, 'TimeZone','America/Los_Angeles','Format','d-MMM-y HH:mm:ss Z');
I thought that was correctly telling it that it was UTC, but I'm actually not sure. I guess I assumed since it said -0800 that it knew
Seems to work for me:
dateHourlyReal = datevec(now)
dateHourlyReal =
Columns 1 through 5
2016 10 24 19 39
Column 6
50.915399999998
>> dateHourlyLocal = datetime(dateHourlyReal, 'TimeZone','local','Format','d-MMM-y HH:mm:ss Z');
dateHourlyLocal.TimeZone='Etc/UTC';
dateHourlyTZ = datetime(dateHourlyLocal, 'TimeZone','America/Los_Angeles','Format','d-MMM-y HH:mm:ss Z');
>> dateHourlyTZ
dateHourlyTZ =
datetime
24-Oct-2016 17:39:50 -0700
That is, my local timezone is -0500 and the time does indeed get changed by 2 hours.
But I would just use the shorter
dateHourlyLocal = datetime(dateHourlyReal, 'TimeZone','local','Format','d-MMM-y HH:mm:ss Z');
dateHourlyTZ = dateHourlyLocal;
dateHourlyTZ.TimeZone = 'America/Los_Angeles'
The output I get when doing this is the same as what I have before:
'1-Dec-1994 15:00:00 -0800'
'1-Dec-1994 16:00:00 -0800'
'1-Dec-1994 17:00:00 -0800'
'1-Dec-1994 18:00:00 -0800'
'2-Dec-1994 11:00:00 -0800'
'2-Dec-1994 15:00:00 -0800'
'5-Dec-1994 15:00:00 -0800'
'5-Dec-1994 16:00:00 -0800'
'18-Dec-1994 16:00:00 -0800'
'18-Dec-1994 17:00:00 -0800'
'23-Dec-1994 15:00:00 -0800'
'23-Dec-1994 16:00:00 -0800'
'23-Dec-1994 17:00:00 -0800'
'27-Dec-1994 15:00:00 -0800'
How do I actually get timezone to be applied to the hour itself more like
'1-Dec-1994 7:00:00'
'1-Dec-1994 8:00:00'
'1-Dec-1994 9:00:00'
And so on ... It's great that it indicates the time is different, but that was already happening before as well
Are you sure you are working with datetime objects? They would not have the '' when they were displayed.
dh = {'1-Dec-1994 15:00:00 -0800'
'1-Dec-1994 16:00:00 -0800'
'1-Dec-1994 17:00:00 -0800'
'1-Dec-1994 18:00:00 -0800'
'2-Dec-1994 11:00:00 -0800'
'2-Dec-1994 15:00:00 -0800'
'5-Dec-1994 15:00:00 -0800'
'5-Dec-1994 16:00:00 -0800'
'18-Dec-1994 16:00:00 -0800'
'18-Dec-1994 17:00:00 -0800'
'23-Dec-1994 15:00:00 -0800'
'23-Dec-1994 16:00:00 -0800'
'23-Dec-1994 17:00:00 -0800'
'27-Dec-1994 15:00:00 -0800'};
datetime(dh, 'TimeZone','local','Format','d-MMM-y HH:mm:ss Z')
ans =
14×1 datetime array
1-Dec-1994 17:00:00 -0600
1-Dec-1994 18:00:00 -0600
1-Dec-1994 19:00:00 -0600
1-Dec-1994 20:00:00 -0600
2-Dec-1994 13:00:00 -0600
2-Dec-1994 17:00:00 -0600
5-Dec-1994 17:00:00 -0600
5-Dec-1994 18:00:00 -0600
18-Dec-1994 18:00:00 -0600
18-Dec-1994 19:00:00 -0600
23-Dec-1994 17:00:00 -0600
23-Dec-1994 18:00:00 -0600
23-Dec-1994 19:00:00 -0600
27-Dec-1994 17:00:00 -0600
ans.Format = 'd-MMM-y HH:mm:ss'
ans =
14×1 datetime array
1-Dec-1994 17:00:00
1-Dec-1994 18:00:00
1-Dec-1994 19:00:00
1-Dec-1994 20:00:00
2-Dec-1994 13:00:00
2-Dec-1994 17:00:00
5-Dec-1994 17:00:00
5-Dec-1994 18:00:00
18-Dec-1994 18:00:00
18-Dec-1994 19:00:00
23-Dec-1994 17:00:00
23-Dec-1994 18:00:00
23-Dec-1994 19:00:00
27-Dec-1994 17:00:00
I was thrown off for a moment about the -06:00 when I had been seeing -05:00 locally, but I realized that the -05:00 I had been seeing is because I am currently in Daylight Savings Time, and that the times in those strings would be after the switch back to Standard Time, at which point I switch to -06:00
Hmm yeah, mine is a datetime object. I've attached the screenshot. I'm not sure why the quotation marks are there when I copy and paste it.
So in your example above where the time difference is -0600, is there anyway to get the date to read 1-Dec-1994 11:00:00, as a reflection of the local time, instead of 1-Dec-1994 17:00:00 -0600.
I ask because I am trying to perform
>> mean(hour(dateDecLowVis))
ans =
15.6429
But I need it to give me the mean in local time (either -0700 or -0800 depending on the year), rather than the GMT mean. I had already performed the same TimeZone changes you guys have been helping me with, but I can't get them to stick when I'm trying to find the mean.
"So in your example above where the time difference is -0600, is there anyway to get the date to read 1-Dec-1994 11:00:00, as a reflection of the local time, instead of 1-Dec-1994 17:00:00 -0600."
You are misreading. 1-Dec-1994 17:00:00 -0600 is 1-Dec-1994 23:00:00 UTC which is 1-Dec-1994 15:00:00 -0800 . 1-Dec-1994 11:00:00 would be -12:00 (twice -06:00) .
If you yourself are not in Pacific time, then:
%using the dh from above
aaa = datetime(dh, 'TimeZone','America/Los_Angeles','Format','d-MMM-y HH:mm:ss Z');
mean(hour(aaa))
This is a pretty long thread and I'm coming in at the end, but I think all of what Walter has said is correct: setting the timezone of an unzoned datetime leaves the timestamp unchanged, while changing the timezone of a datetime that already has a timezone changes the "appearance" of the timestamp but actually leaves the absolute point in time that the datetime represents unchanged.
Just to summarize how this works in your case:
If you are starting from text that represents UTC timestamps ...
>> s = '26-Oct-2016 09:44:52'
s =
'26-Oct-2016 09:44:52'
... then create a datetime with UTC as the time zone ...
>> d = datetime(s,'TimeZone','UTC')
d =
26-Oct-2016 09:44:52
>> d.Format = [d.Format ' z']
d =
26-Oct-2016 09:44:52 UTC
... and then change to your local time zone.
>> d.TimeZone = 'America/Los_Angeles'
d =
26-Oct-2016 02:44:52 PDT
You don't need to do any arithmetic, it's all done for you. I don't know what your original strings look like, so you may need to tweak things having to do with that, but you get the general idea.
If your strings had represented timestamps in your local time, you would not have had to take the extra step, you'd just do this:
>> d = datetime(s,'TimeZone','America/Los_Angeles')
d =
26-Oct-2016 09:44:52
Thank you so much for breaking it down like that! I finally understand where I was going wrong. I'm so grateful for your help and glad I asked this question or else my dates would have been all messed up! All the best!
This worked example is very helpful. Where do I go to suggest a similar example gets added to the online datetime documentation?
K E, I'll make a note to have that added. Thanks for the suggestion.

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Marc Jakobi
Marc Jakobi 2016년 10월 24일
편집: Marc Jakobi 2016년 10월 24일
Setting the TimeZone property doesn't change the time of a datetime vector, it just tells Matlab which time zone the datetime object is in. So setting
dateHourlyLocal, 'TimeZone','America/Los_Angeles')
will only change the property (and maybe the dates at which daylight savings occurs), but not the time itself. The TimeZone property is especially useful if you have two datetime vectors from two different time zones. For example, subtracting two datetimes with the same value - one in New York, one in Berlin - will result in 06:00:00 (the time difference between the two time zones).
So if you would like to convert the time, you could do something like
dt = datetime(dateHourlyLocal, 'TimeZone','America/Los_Angeles') - dateHourlyLocal;
dateHourlyTZ = datetime(dateHourlyLocal, 'TimeZone','America/Los_Angeles') - dt;
Or the other way round (depending on whether you would like to add or subtract time). You may have to experiment with this a bit.

댓글 수: 1

Hi Marc,
Thanks for your thoughts. Your method gives me the same output I had above. I should have mentioned that I am telling Matlab which time zone the data is set in with the following code:
dateHourlyLocal = datetime(dateHourlyReal, 'TimeZone','local','Format','d-MMM-y HH:mm:ss Z');
dateHourlyLocal.TimeZone='Etc/UTC';
dateHourlyTZ = datetime(dateHourlyLocal, 'TimeZone','America/Los_Angeles','Format','d-MMM-y HH:mm:ss Z');
The challenge I've had both in applying your idea here (subtracting dt) as well as my own objective (trying to find the mean), is that datetime doesn't seem to retain this TimeZone change when doing arithmetic. Thus when I tried to do
dt = datetime(dateHourlyLocal, 'TimeZone','America/Los_Angeles') - dateHourlyLocal;
(which would be the correct subtraction) ... it said that the solution was 0 for all entries.
Currently my dateHourlyTZ looks the same as it does using your code:
1-Dec-1994 15:00:00 -0800
1-Dec-1994 16:00:00 -0800
1-Dec-1994 17:00:00 -0800
but I would prefer it look like this:
1-Dec-1994 07:00:00
1-Dec-1994 08:00:00
1-Dec-1994 09:00:00
so that when I calculated a mean for each month, it would calculate it in the correct time and applying the correct daylight savings change.
If you have any ideas, let me know!

댓글을 달려면 로그인하십시오.

Al in St. Louis
Al in St. Louis 2018년 5월 23일

0 개 추천

So, I have to tell MATLAB that the timezone is London if I have UTC times. That's not very intuitive.

댓글 수: 3

London's time zone is not UTC. London goes on BST during the summer months. A time zone is not an offset from UTC, it's a set of rules for what offset to apply at what time of year, and how that was done historically.
If you have timestamps that you know are from London, and you want to tag them with London's time zone (which you do not have to), and you have a computer that's set up for the UK, then 'TimeZone','local' will do it.
In the OP's question, he had text time stamps with no explicit indication of what time zone they were collected in. It's fine (and simplest) to create "unzoned" datetimes if you are willing to keep track of what time zone they are in yourself, but when dealing with timestamps from multiple time zones, that become rather error prone. So you can adjust them all to one common TZ (and perhaps leave them unzoned), or tag them with their time zones.
This doesn't help me as I have times that are UTC, but I have not figured out how to tell MATLAB that.
Natick, MA (the location of MathWorks HQ) is in the America/New_York time zone, as I can see by comparing a datetime created by specifying the 'local' time zone with one in America/New_York.
tLocal = datetime('now', 'TimeZone', 'local');
tNY = datetime('now', 'TimeZone', 'America/New_York');
If I view the information from the list of time zones for the UTC offset for America/New_York it's -5. We're not in Daylight Savings Time right now, so I can ignore the DSTOffset.
tz = timezones;
tz(tz.Name == "America/New_York", :)
So if I convert tNY to UTC, or create a new datetime in the UTC time zone, the time should be five hours different. I can do this using the 'Etc/UTC' time zone.
tUTC = datetime('now', 'TimeZone', 'Etc/UTC');
tNYToUTC = tNY; tNYToUTC.TimeZone = 'Etc/UTC';
If you display these datetime values tLocal and tNY should have (very close to, modulo how long it takes you to type the command) the same time, and tUTC and tNYToUTC should have a time that's (very close to) five hours different.
tLocal, tNY, tUTC, tNYToUTC

댓글을 달려면 로그인하십시오.

질문:

2016년 10월 24일

댓글:

2019년 12월 4일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by