Adjusting for Timezone

J

Jim Davis

I'm (still) working on an ISO 8601 date parser. I want to convert at least
the formats described here:

http://www.w3.org/TR/NOTE-datetime

Well.. I've got most of it working (via RegEx's) good enough for me but I'm
having a brain block when it comes to TimeZone.

The datetime may come with an optional timezone offset (from GMT) as here
(the offset is +1 hour from GMT):

1997-07-16T19:20:30+01:00

So... that's the current time there... but my spec is that timezone
information, if present, should be used to convert the given time to local
time. For me, for example, this would be -5:00 from GMT.

I've already split the Timezone information: I've got indiviual access to
the sign (plus or minus), the hour offset and the minute offset.

So I'm sure there's a nice, simple formula for this... but it eludes me. Or
I'm lazy... I can't decide which.

Any pointers?

Thanks in advance,

Jim Davis
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Tue, 30 Aug 2005
11:58:36, seen in Jim Davis
I'm (still) working on an ISO 8601 date parser.

Please do not start a new thread to continue an existing discussion. As
a thread develops, it is taken for granted that some progress may be
made.

The datetime may come with an optional timezone offset (from GMT) as here
(the offset is +1 hour from GMT):

1997-07-16T19:20:30+01:00

So... that's the current time there... but my spec is that timezone
information, if present, should be used to convert the given time to local
time. For me, for example, this would be -5:00 from GMT.

I've already split the Timezone information: I've got indiviual access to
the sign (plus or minus), the hour offset and the minute offset.

There are 60 minutes in each hour; I see no other possible difficulty.
In fact, you do not even need to know that. Perhaps you should explain
your problem more clearly.

Remember that you should not use new Date(Y, M, D, h, m, s, ms) as
that muddles the situation with your local zone. Use new
Date(Date.UTC(,,,,,,)) .

Read the FAQ; see below. Use extant resources before reinventing
wheels.

Consider
new Date(Date.UTC(Y, M, D, h+oh, m+om, s, c))
where oh, om are the offsets and maybe + should be - ; that's not
explicit in the cited resource but should be obvious after reading it.

Consider whether the input should be validated; perhaps not, if your
data source is reliable.
 
J

Jim Davis

Dr John Stockton said:
JRS: In article <[email protected]>, dated Tue, 30 Aug 2005
11:58:36, seen in Jim Davis


Please do not start a new thread to continue an existing discussion. As
a thread develops, it is taken for granted that some progress may be
made.

New topic... new thread. Seems simple to me.

While this topic may be related to another it has both greater specificity
and broader appeal (for adjusting timezones is only one small part of
converting iso8601 dates and applicable to much more than iso8601 dates).
Any answers may inform the other but are not part of the same discussion.

Honestly it seems like you're being rather pendantic about this (or in
general I don't you so perhaps it's that). For archiving purposes
specific,searchable subjects are generally respected on Usenet.
There are 60 minutes in each hour; I see no other possible difficulty.
In fact, you do not even need to know that. Perhaps you should explain
your problem more clearly.

In other words actually obtaining the offset is not the problem (I do not
need help in extracting it). My question concerned the conversion of one
timezone to another.
Remember that you should not use new Date(Y, M, D, h, m, s, ms) as
that muddles the situation with your local zone. Use new
Date(Date.UTC(,,,,,,)) .

Well... only if I want UTC time. ;^)

My spec is clear that, if timezone information provided, it should be used
to convert the time to local time.
Read the FAQ; see below. Use extant resources before reinventing
wheels.

Perhaps I'm missing it. I see nothing in the FAQ that concerns this. A
rather extensive search didn't produce the answer I needed.

I'm neither too proud or too stupid to existing code when I can find it and
when it's appropriately licensed.
Consider
new Date(Date.UTC(Y, M, D, h+oh, m+om, s, c))
where oh, om are the offsets and maybe + should be - ; that's not
explicit in the cited resource but should be obvious after reading it.

That does not convert a date... it provides the UTC date.
Consider whether the input should be validated; perhaps not, if your
data source is reliable.

Not an issue for puposes of discussion.


I thank you for your effort, however. I've since solved the problem and
will shortly post a resolution.

It really should have have clearer, but I was having a mental block on
this... once I got a nap in it became much clearer.

Jim Davis
 
J

Jim Davis

Well, I took a nap and then was able to figure it out.

There are two general methods for doing this. I'll be used the term
"source" in relation to the given time and "target" in relation to the local
time zone (so the problem becomes "how to convert a source timezone to a
target timezone):

1) A two stage conversion. Step one uses the source timezone offset to
generate a UTC datetime. We then use the target offset to generate the
local time.

This works just fine... but it's rather inelegant in my opinion (needing the
middle-man irks me).

2) Do the basic math (never a personal strong point). Subtracting the
target from the source gives us our answer. For example:

Source offset is +1:00, target is -4:00: (+1 - -4) = 5
Source offset is -5:00, target is -5:00: (-5 - -5) = 0
Source offset is -7:00, target is 2:00: (-7 - +2) = -9

And so forth. The resulting number is the offset between the source date
and the target date: modify the target by the result and the conversion is
complete.

I hope this helps somebody else. ;^)

Jim Davis
 
R

RobG

Jim said:
I'm (still) working on an ISO 8601 date parser. I want to convert at least
the formats described here:

http://www.w3.org/TR/NOTE-datetime

Well.. I've got most of it working (via RegEx's) good enough for me but I'm
having a brain block when it comes to TimeZone.

The datetime may come with an optional timezone offset (from GMT) as here
(the offset is +1 hour from GMT):

1997-07-16T19:20:30+01:00

So... that's the current time there... but my spec is that timezone
information, if present, should be used to convert the given time to local
time. For me, for example, this would be -5:00 from GMT.

I've already split the Timezone information: I've got indiviual access to
the sign (plus or minus), the hour offset and the minute offset.

So I'm sure there's a nice, simple formula for this... but it eludes me. Or
I'm lazy... I can't decide which.

Any pointers?

The sample below converts a timestamp to local time. If a zone is
present, it is used to create a local time based on the offset.

Each component must be a proper 'bit' of the datetime in the format
you've specified, i.e. the date must be yyyy-m-d, the time must be
Thh:mm:ss and the zone must be +/-hh:mm. It will tolerate not having
leading zeros.

How you handle not having some parts of the date can done elsewhere,
e.g. if you get '2005' you can decide if you want to make it 2005-01-01
or 2005-currentMonth-currentDate, it's up to you. Same with the time.
If no timezone offset is specified, it will be the local one.

Decimal seconds in the input time are removed.

The input date separator can be '-' or '/' as hyphens are converted to
slashes.

<form action="">
<input type="text" name="time" value="1997-07-16T19:20:30.45+01:00"
size="50">
<input type="button" value="Convert" onclick="

var x, tz, tStr = this.form.time.value;

// Get timezone
tz = tStr.match(/[\+\-]\d{1,2}:\d{1,2}$/);

// Remove timezone
tStr = tStr.replace( tz, '');

// Split date and time
tStr = tStr.split('T');

// Format date string
x = tStr[0].replace(/-/g,'/');

// If there's a time
// Remove decimal seconds and append it to the date string
if ( tStr[1] ) x += ' ' + tStr[1].match(/^[^\.]+/);

// Add timezone offset if there is one
if ( tz ) x += ' ' + tz;

// Generate a date object using the string
var localTime = new Date( x );

// Show the world what we've done
var msg = document.getElementById('zz')
msg.innerHTML = 'Datetime string: ' + x;
msg.innerHTML += '<br>Timezone: ' + (tz || '<i>No timezone</i>');
msg.innerHTML += '<br>Local time: ' + localTime.toString();

">
<br>
<input type="reset">
</form>
<p id="zz"></p>
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Tue, 30
Aug 2005 23:59:45, seen in Dr John Stockton
Update : omit "maybe", and in the same line "not" -> "now".

function TryISO(F) { var OK, S
S = F.ISO.value
OK = /^(\d{4})?-?(\d\d)?-?(\d\d)?T?(\d\d)?:?(\d\d)?:?(\d\d)?([+-])?(\d\d)?:?(\d\d)?$/.test(S)
with (RegExp) F.DT.value = !OK ? "BAD" : new Date(Date.UTC(
$1||77, $2-1, $3, $4 - ($7+$8), $5 - ($7+$9)||0, $6
)).UTCstr() }

F is a form. Those who don't have .UTCstr() can omit it. 77 is arbitrary!

One day, I may learn what's preferred to such use of $1..$9.
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Tue, 30 Aug 2005
21:47:48, seen in Jim Davis
Honestly it seems like you're being rather pendantic about this (or in
general I don't you so perhaps it's that).

Please read what you write before expecting others to do so. You can
then adjust it to be potentially comprehensible.


That seems strange. A datum such as 1111-11-11 22:22:22 is in local
time, but there remains the question of which locality. The processer's
local offset is not necessarily the offset at the location of the data.

Timezone information enables conversion to UTC. Conversion to own local
is a further, albeit trivial in javascript, step.

Well... only if I want UTC time. ;^)

No; if the computer's timezone is not the data's timezone. First
determine the meaning of the data, then consider the presentation.
My spec is clear that, if timezone information provided, it should be used
to convert the time to local time.

If that's so, you go beyond ISO 8601.

Perhaps I'm missing it. I see nothing in the FAQ that concerns this. A
rather extensive search didn't produce the answer I needed.

I'm neither too proud or too stupid to existing code when I can find it and
when it's appropriately licensed.

As above.

That does not convert a date... it provides the UTC date.

"Consider" is a recommendation that you read and think about it. It
does not mean that you can use it directly. That statement in fact
gives a Date Object which holds the instant given by the arguments
interpreted as UTC, but default conversion to string uses your local
timezone.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top