MySql TimeStamp and JavaScript Time - javascript

I have a time stamp in a MySQL database in GMT time [2013-07-19 10:12:56].
I know it should be in the DB as a DateTime and UTC but unfortunately this is the way it is.
I need to extract the timestamp and pass into JavaScript [HighCharts].
$time = strtotime('2013-07-19 10:12:56');
echo("Converting to UNIX Time: ");echo $time;
echo("Converting to JS Time: ");echo ($time*1000);
As JavaScript takes time in milliseconds hence the multiply buy 1000
Output: Converting to UNIX Time: 1374253976
Output: Converting to JS :Time: 1374253976000
The question I have is why does it come up in HighCharts as 17.12
When I put 1374253976000 into http://www.epochconverter.com I get:
GMT: Fri, 19 Jul 2013 17:12:56 GMT which is incorrect. The time should come up as displayed in the database as 10:12:56.
Any ideas why it would be 7h out ?

Epochtimeconverter says that Fri, 19 Jul 2013 10:12:56 GMT has following epoch times
Epoch timestamp: 1374228776
Timestamp in milliseconds: 1374228776000
Human time (GMT): Fri, 19 Jul 2013 10:12:56 GMT
Human time (your time zone): Friday, July 19, 2013 3:42:56 PM
Note, it's NOT 1374253976 as you are getting. So that is the problem, the conversion from epochtime to highcharts, etc. is correct. It's your epochtime that is coming to be wrong
PHP will treat the string to be in server's timezone, unless mentioned otherwise.
Give this a try, specify the timezone explicitly as GMT as follows
$time = strtotime('2013-07-19 10:12:56' . ' GMT');
echo("Converting to UNIX Time: ");echo $time;
echo("Converting to JS Time: ");echo ($time*1000);
The 7h difference that you were observing may be because your server is located in a the timezone -7 ?

Problem #1
The primary problem is in your conversion step using strtotime. PHP tries to guess the relationship of the time string to the time zone (probably using your time zone), but in your situation it needs to know more to guess properly. You can do that by explicitly telling PHP that the time string is represented as GMT (Greenwich Mean Time).
Since your database only has the form of YYYY-MM-DD HH:MM:SS, you can concatenate the necessary GMT identifier onto it during your strtotime invocation.
$time = strtotime('2013-07-19 10:12:56' . ' GMT');
For example:
<pre>
<?php
$time = strtotime('2013-07-19 10:12:56' . ' GMT');
echo("Converting to UNIX Time: $time\n");
echo("Converting to JS Time: ");
echo ($time*1000);
?>
</pre>
Converting to UNIX Time: 1374228776
Converting to JS Time: 1374228776000
Pasting the resulting UNIX Time into Epoch Converter results correctly in GMT: Fri, 19 Jul 2013 10:12:56 GMT
Problem #2
Changing your PHP code as above is necessary, but since it is not fully working for you, I can see that you have one more problem going on. (Sebastian tried to help you with this.)
What I would add to Sebastian's comments is that global settings need to be configured BEFORE you create any charts or chart objects in your JavaScript. Otherwise they will have no effect on the output of those charts. So you need to make sure that the following configuration is applied before any chart objects exist in your code.
Highcharts.setOptions({
global: {
useUTC: false
}
});
(If you don't use this configuration, your charts will still work fine, but dates and times will show relative to Greenwich Mean Time instead of the local time zone for each user viewing the charts.)
Discussion (placed afterwards for those who hate discussion don't have to read it):
I verified that if you are following the above suggested modification to your PHP code, then you now have the correct UTC/GMT numeric epoch time passed to JavaScript. You can confirm this 100% for sure with the following code:
Date.UTC(2013, 6, 19, 10, 12, 56)
1374228776000
new Date(1374228776000).toUTCString()
"Mon, 19 Aug 2013 10:12:56 GMT"
The second problem you are apparently facing is two-fold: making Highcharts properly interpret this as a UTC/GMT value rather than a value from some other (such as local) timezone, AND telling Highcharts to properly output the timezone in your desired format.
Making Highcharts properly interpret your time numbers: By default Highcharts assumes numeric time data like these are in UTC [[1331028000000, 5], [1331031600000, 6], [1331035200000, 4]]. Unless there is something strange lurking in your JavaScript and altering how the time data is processed, you should be good in that regard.
Making Highcharts display the correct time in the human-readable dates on your charts: this is where you should play close attention to the API here: http://api.highcharts.com/highcharts#global.useUTC
By the way, Sebastian Bochan is a member of the Highcharts support team, so you can certainly trust his comments.

You have a timezone issue. At GMT the time-stamp 2013-07-19 10:12:56 translates to 1374228776 seconds after epoch: http://jsfiddle.net/hsvtE/
Your PHP script however returns the incorrect unix time:
Output: Converting to UNIX Time: 1374253976
As you can see the difference between the two timestamps is:
1374253976 (incorrect)
-1374228776 (correct)
-----------
25200 seconds
The time your PHP script returns is 25200 seconds (or seven hours) ahead of GMT time. The reason PHP returns the wrong time is because of the way the strtotime function works.
If no timezone is specified in the time-stamp then strtotime assumes that the time-stamp belongs to the default timezone.
There are two methods to solve this problem:
Method 1: Set the default timezone to GMT
You can get and set the default timezone in PHP using the functions date_default_timezone_get and date_default_timezone_set. Using these two functions you could set the correct timezone for your timestamp as follows:
function get_time($timestamp, $timezone = 'GMT') {
$default_timezone = date_default_timezone_get(); // get current timezone
date_default_timezone_set($timezone); // set correct timezone
$time = strtotime($timestamp); // get correct time
date_default_timezone_set($default_timezone); // reset original timezone
return $time; // return correct time
}
Now you may safely get the correct time at GMT by simply calling get_time instead of strtotime:
$time = get_time('2013-07-19 10:12:56');
I recommend you use this method because if the time-stamp already specifies a timezone then strtotime simply ignores the default timezone and uses the specified timezone instead.
Method 2: Specify the timezone in the time-stamp itself
The second method is much shorter:
function get_time($timestamp, $timezone = 'GMT') {
return strtotime($timestamp . ' ' . $timezone);
}
$time = get_time('2013-07-19 10:12:56');
However I would recommend that you use the first method instead because it's safer. For example if you provided the timestamp 2013-07-19 10:12:56 EST then the above function would call strtotime with a string with two timezones - 2013-07-19 10:12:56 EST GMT.
Conclusion
This simple change should solve your problems. If you want the time in milliseconds then simply multiply the time by 1000:
$time = 1000 * get_time('2013-07-19 10:12:56');
I'm assuming that your client side code is correct. Hence if you still have problems then you should take a look at your JavaScript.

In fact it is not a JS problem. The trick resides in PHP and how "strtotime" does its conversion with regard to default timezone.
In your example, the timestamp is calculated as if you were in "America/Los_Angeles" timezone, so you you get 1374253976 seconds instead of 1374228776 with timezone "GMT". Since you're converting timestamp relatively to GMT timezone on epochconverter, a "mismatch" appears.
The data you store in MySQL is in GMT, the timezone of your PHP installation is "America/Los_Angeles". When you "strtotime", you interprete the data into MYSQL as not being GMT but America/Los_Angeles. That's why there are 7 hours between the two.
Here is a little script to better explain this :
date_default_timezone_set('GMT');
echo strtotime('2013-07-19 10:12:56', time() - 10) . "\n";
date_default_timezone_set('America/Los_Angeles');
echo strtotime('2013-07-19 10:12:56', time() - 10) . "\n";
will display :
1374228776 // from epochconverter : Fri, 19 Jul 2013 10:12:56 GMT
1374253976 // from epochconverter : Fri, 19 Jul 2013 17:12:56 GMT
Notice how the sequence "287" is replaced by the sequence "539".
In PHP, almost every function manipulating time will do so based on the currently defined timezone.
Look at this for more informations :
PHP Default TimeZone

Related

Converting UTC to local time doesn't work in javascript

My datetimes are stored in the DB as UTC. When they are sent to the client I want to convert them to local time.
Javascript receives a given datetime as a string that looks like this:
2016-09-29T19:13:40
If I run new Date('2016-09-29T19:13:40') on the string I get this output:
Thu Sep 29 2016 19:13:40 GMT-0400 (Eastern Daylight Time)
While the -0400 offset is present, it's not changing the time. Since UTC offsets aren't displayed to the user, it just looks like the timestamp is off by 4 hours.
Conversely if I do this:
new Date('2016-09-29T19:13:40').toISOString();
The output is:
2016-09-29T23:13:40.000Z
As you can see it actually adjusts the hours by 4 and eliminates the offset.
How come when I feed javascript a UTC datetime to convert to local all it does is add an offset, but when I feed it what it thinks is a local datetime it and ask it to convert to UTC it actually adjusts the time?
How can I get it to adjust a UTC datetime to local the way it adjusts local to UTC?
EDIT
Here's a fiddle: https://jsfiddle.net/qjmfLu67/1/
I'm getting different behavior between IE11 and Chrome. IE11 doesn't convert UTC to local. Chrome does convert UTC to local and if it recognizes a date as UTC, when you run toISOString on it, it doesn't adjust anything.
Working with date is not easy, especially if you do TZ conversions. I'd suggest to use momentjs (http://momentjs.com/docs/) for it, like I do.
// create a utc-zone moment
var x = moment.utc('2016-09-29T19:13:40')
x.format()
// output is "2016-09-29T19:13:40Z"
// adjust offset for the initial moment x by the local offset we get from moment created against local tz
x.utcOffset(moment().utcOffset());
x.format()
// output is "2016-09-29T22:13:40+03:00"
Looks like for IE11, you'll have to pass the date string in full javascript format for it to work properly.
new Date("Thu Sep 29 2015 19:13 GMT")
new Date('2016-09-29T19:13:40')
This is missing milliseconds and "Z" which are needed for a correct conversion from UTC to Local.
new Date('2016-09-29T19:13:40.000Z') should give you the correct time relative to your machine.

Date in PHP and Javascript are not match

As title, although I set with only value.
In Javascript:
var n = (new Date("2015 Oct 17")).getTime()/1000;
console.log(n);
// result: 1445014800
And PHP:
$unix = date('d-m-Y', 1445014800);
echo $unix;
// result: 16-10-2015
Please leave some explanations.
Thanks a lot!
In your JavaScript:
var n = (new Date("2015 Oct 17")).getTime()/1000;
console.log(n);
// result: 1445014800
The operation /1000 is coercing your value to a numeric type, so the answer is correct!
In javascript, parsing of a string like "2015 Oct 17" is entirely implementation dependant. If it works at all, it is likely to be converted to a Date object representing the date at 00:00:00 at the start of the day in the time zone of the host system.
For a system whose time zone offset is, say, UTC+1000, and that parses the string as a local time, the time value in seconds will be 1445004000.
However, such a system might decide that the string is a bit like an ISO 8601 string, and it might decide that since such strings without a time zone were treated as UTC in ES5, that it will treat it as a UTC time. In that case, the time value in seconds will be 1445040000 (i.e. equivalent to 2015-10-17T00:00:00Z).
To reliably transfer dates between systems, it is often considered best to transfer time values in either seconds or milliseconds since the UNIX (and ECMAScript) epoch of 1070-01-01T00:00:00Z.
To create such a time value for 2015-Oct-17 you can use:
var timeValue = Date.UTC(2015, 9, 17);
To convert the UNIX time value 1445014800 to an ECMAScript date, you can do (noting that UNIX time values are in seconds and ECMAScript in milliseconds):
console.log(new Date(1445014800*1000).toISOString()); // 2015-10-16T17:00:00.000Z
So I'll assume that the PHP host is in a timezone that is UTC-05:00 and that 2015-Oct-17 has been treated as UTC.
I have checked it, and this JS function returns
1445036400
which in 'human time' is
Fri, 16 Oct 2015 23:00:00 GMT
https://jsbin.com/wuvawupede/edit?js,console,output
http://www.epochconverter.com/

Get unix timestamp of only date in node js

I have a problem in getting unix timestamp on only date(Without time) in node js. I tried with moment js
I have tried this,
moment.unix();// which gives,1446090606
If i use the same i php,
echo date("Y-m-d H:i:s", 1446090606);// echoes 2015-10-29 04:50:06
But actual time stamp of today's date is 1446073200
echo date("Y-m-d H:i:s", 1446073200);// echoes 2015-10-29 00:00:00
I even tried with Date() in javascript,
I referred this, this but no use.
EDIT
I even tried like this,
console.log(moment("2015-10-29 00:00:00").unix());// which gives 1446057000
echo date("Y-m-d H:i:s", 1446057000);// echoes 2015-10-28 19:30:00
It echoes yesterday's date
To summarize what i want is, timestamp of only date without time.
Thank you.
So first you need to ask yourself what you are looking for ultimately. It's really in your best interest to keep all your timestamps in standard UTC format and, if you are storing strings, use the ISO8601 standard. For fun: XKCD on ISO8601
It will make your life so much easier to pass around dates in only one format (UTC timezone / ISO8601 format if a string) until just before you display them to a user.
Only then should you format the date as a user would expect it to be formatted to represent the local time, and you should write a date formatter to ensure this conversion is always done consistently.
On the client side, convert the date to this standardized format the moment it is captured by the user and before it is sent to the server (effectively a reverse of the formatter described above).
All of your server date logic beyond that will typically be calculating time differences without needing to worry about timezone conversions. /rant
Now to discuss your question in a bit more detail and why you are facing issues.
According to moment.js docs:
By default, moment parses and displays in local time.
So when you do this:
moment.unix();
Know that this is relative to the local time. Also unix time is the number of seconds relative to one singular point in time, an epoch which happens to be January 1st, 1970 00:00:00 (when put into the UTC timezone).
To make this hit home. Use your PHP date function and input "0" as the unix timestamp. What do you get? It will depend on the default timezone set in your PHP environment.
For me, the output of the online PHP sandbox I used:
<?php echo date('Y-m-d H:i:s', 0); ?>
// 1969-12-31 16:00:00
Uh oh. What's going on here? That's before epoch time, and I definitely just put a big fat ZERO there.
So this is the importance of keeping your date formats consistent across the board. It will make your life a lot easier.
Here is what you need to do and why:
1. Get the local date's midnight. This is the first piece of information you need to capture in a moment variable because it represents what you are interested in. Once you have that, the rest is just understanding how to format that date how you want.
var lastLocalMidnight = moment().startOf('day')
var lastUTCMidnight = moment.utc().startOf('day')
For the sake of argument and your understanding, I have included another variable which captures and converts "now" into the UTC timezone before getting "midnight".
So what's the difference here? Read the moment.js docs on UTC further:
Any moment created with moment.utc() will be in UTC mode, and any moment created with moment() will not.
To switch from UTC to local time, you can use moment#utc or
moment#local.
moment.js variables have timezone information self-contained within them when you perform other operations on them. It is important to distinguish the difference between this and the standard PHP Date behavior which treats dates the same (unless you explicitly say otherwise).
The timezone being used in every case needs to be known or set. Not understanding these two behaviors completely is most likely the source of your confusion.
A "date is a date is a date". A moment in time, hence the library name "moment.js". It needs to be stated or set what timezone that date is in. There are different formats to capture this information, but just understand that "2015-10-29 04:50:06" doesn't tell you anything until you know the timezone. It's basically the same as how 12:00 doesn't tell you anything until you know AM or PM (assuming you are not using military time).
2. Now that you have a midnight representation (whichever you deem is the correct one for your purposes), you can convert that to a UNIX timestamp because it is relative to a timezone you know you are interested in and represents the exact moment you want.
console.log(lastLocalMidnight.format());
// e.g. - 2015-10-28T00:00:00-06:00
console.log(lastUTCMidnight.format());
// e.g. - 2015-10-29T00:00:00+00:00
console.log(lastLocalMidnight.unix());
// e.g. - 1446012000
console.log(lastUTCMidnight.unix());
// e.g. - 1446076800
$timezoneBeforeSet = date_default_timezone_get();
echo $timezoneBeforeSet."\n";
Notice how moment.js's format() function displays the UTC offset by default. So even printing in that way looks like the midnight you want, but you know it wouldn't end in 00:00:00 if you formatted it to be in UTC (or any timezone other than the one you requested the date in originally).
For the moment converted to UTC ahead of time, there is no offset. If you later formatted that one in your local timezone, it would not be at 00:00:00, and the output of moment.js format() would indicate a timezone offset based on the timezone you set (-06:00, for example).
3. On the PHP side of things, you have a default environmental timezone set, as we demonstrated by seeing what PHP thought of the unix timestamp "0". So, knowing a little more about what they represent now, let's take the unix timestamps we obtained from moment.js and try to format them with PHP's date.
// Timestamps obtained from moment.js
$unixTimestampLocalMidnight = 1446012000;
$unixTimestampUTCMidnight = 1446076800;
// Relative to untampered timezone set in your PHP environment
$phpLocalMidnightUnchangedTZ = date('Y-m-d H:i:s', $unixTimestampLocalMidnight);
echo $phpLocalMidnightUnchangedTZ."\n";
// 2015-10-27 23:00:00
$phpUTCMidnightUnchangedTZ = date('Y-m-d H:i:s', $unixTimestampUTCMidnight);
echo $phpUTCMidnightUnchangedTZ."\n";
// 2015-10-28 17:00:00
So yeah. Those are totally not what we were wanting, right? Actually they are. It's 23:00:00 somewhere and 17:00:00 somewhere when it's midnight somewhere else, right?
We need to be sure where PHP thinks we are right now. We could output that timezone information using Date, but we don't care to see it in our final output (understandable). So how do we find out, otherwise? Glad you asked:
$timezoneBeforeSet = date_default_timezone_get();
echo $timezoneBeforeSet."\n";
// US/Pacific
I'm in Colorado which is US/Mountain, so what's the deal? Well, this must mean the online PHP sandbox I was using is hosted over in California or something. Makes sense. Know where your code is running.
But don't get too caught up worrying about that. This is why we capture and convert to a consistent format upfront and worry about formatting only at which point we really need it. That way, if you did your conversion wrong, you only need to change it in one or two places at most.
For a complete reference to PHP timezones, click here.
4. If you have any control of your PHP environment, you should be setting the default timezone to UTC (one of the very first things you do in your project bootstrapping or in your PHP environmental config file).
// Explicitly set PHP default timezone to UTC
date_default_timezone_set('UTC');
$timezoneAfterSet = date_default_timezone_get();
echo $timezoneAfterSet."\n";
// UTC
$phpLocalMidnight = date('Y-m-d H:i:s', $unixTimestampLocalMidnight);
echo $phpLocalMidnight."\n";
// 2015-10-28 06:00:00
$phpUTCMidnight = date('Y-m-d H:i:s', $unixTimestampUTCMidnight);
echo $phpUTCMidnight."\n";
// 2015-10-29 00:00:00
So this makes sense. We are showing a time relative to UTC now. If I had originally captured a midnight in US/Mountain time, I would expect to see a time of day that corresponds to that over in Greenwich, England.
When you know a date is formatted with a timezone, think of reading that date-time in the place the timezone indicates. We know PHP is spitting out UTC stuff, so I can imagine I'm in Greenwich, England when I see the output.
If it's 06:00 in the morning and I am in Greenwich, it should be 6 hours earlier in Colorado (-6:00) <-- remember that useful timezone suffix moment.js outputs with .format()? The sun hasn't quite risen yet in Colorado because the sun rises in the East and sets in the West. So what time is 6 hours before 6AM? Midnight!
And of course the date we explicitly converted to UTC upfront comes back out looking like an actual midnight. Why? Because PHP is set to format dates in UTC. Also notice it's a day ahead. You should know enough now to explain that yourself =)
Make sense?
You have to create the date without the hour part first, something like this:
var moment = require("moment");
var unixTime = moment().startOf('day').unix(); //last midnight in local time
console.log("Your timestamp: " + unixTime + " And your date: " + day);
Now, let's see your examples.
Yo said that this unix timestamp 1446073200 but, you when you check here, you can see that this is the date that represents:
UTC: Wednesday 28th October 2015 11:00:00 PM
And also gives you another date with your local time, which in my case:
In your local time zone: Wednesday 28th October 2015 05:00:00 PM
So, my guess is that you are getting that unix timestamps in a place with timezone UTC + 1 and that's why you believe that this unix timestamp 1446073200 has no the hour part.
In my previous example you will get a unix timestamp in your local time, which in my case is: 1446098400, but you will probably want the UTC time, so you should change the code a little bit, like this:
var moment = require("moment");
var unixTime = moment.utc().startOf('day').unix(); //last midnight in UTC time
console.log("Your timestamp: " + unixTime + " And your date: " + day);
That will give you this unix timestamp: 1446076800which is the one you need. You can check it here.
UTC: Thursday 29th October 2015 12:00:00 AM
I simplified my code using #forgo answer.
This is how I do in pure Javascript:
var today = new Date()
today.setUTCHours(0, 0, 0, 0)
var today_timestamp = Math.floor(today.getTime() / 1000)
If you want to get the value for the current timezone, use setHours instead.

Why is the ColdFusion epoch time one hour behind the javascript epoch time?

I am writing an application where I need to get the epoch time on the server side using ColdFusion 8 running on Windows Server 2008 and client side using javascript (testing in Google Chrome). The problem is that the epoch time generated by ColdFusion is one hour behind the one generated by javascript. I have verified that the date/time settings are correct both client side and server side.
This is how I am setting the time stamp with ColdFusion:
<cfset cfEpoch = DateDiff("s", "January 1 1970 00:00", DateConvert("Local2utc", now()))>
And this is how I'm setting it with javascript:
var jsEpoch = Math.round(new Date().getTime()/1000.0);
The javascript epoch matches the one on this website (http://www.epochconverter.com/) which makes sense because they're using the same method I'm using. The ColdFusion epoch is one hour behind. Here's what I've run to try to sort this out:
<cfset localDate = now()>
<cfset utcDate = DateConvert("Local2utc", localDate)>
<cfset epoch = DateDiff("s", "January 1 1970 00:00", utcDate)>
<cfoutput>
Local Date: #localDate# <br>
UTC Date: #utcDate# <br>
Epoch: #epoch#
</cfoutput>
That code outputs:
Local Date: {ts '2013-04-30 17:44:56'}
UTC Date: {ts '2013-04-30 21:44:56'}
Epoch: 1367354696
So I'm at a loss. Both the local date and UTC date values are correct. It appears that the only explanation is that the DateDiff() function isn't working properly, but I've tested it with other dates and it seems to work fine. I suppose I can just add 3600 to the epoch value it generates but I'd rather not do that without knowing why I'm getting an incorrect value in the first place. Does anyone see what I'm missing here?
Writing a little script you might notice something very strange.
This is what it output for me.
1367360584 - Javascript time
1367360594 - Epoch seconds (convert Epoch to local time)
1367356994 - Epoch seconds (convert local time to UTC)
So converting epoch to local time is spot on, but the other way around isn't.
This is running on CF8 too, so if you convert Epoch to local time, it seems to do it right.
Try it out.
<script>
var jsEpoch = Math.round(new Date().getTime()/1000.0);
document.write(jsEpoch + ' - Javascript time <br>');
</script>
<cfset TheDate = now()>
<cfoutput>
#DateDiff("s",DateConvert("utc2Local", "January 1 1970 00:00"), TheDate)# - Epoch seconds (convert Epoch to local time)<br>
#DateDiff("s", "January 1 1970 00:00", DateConvert("Local2utc", TheDate))# - Epoch seconds (convert local time to UTC)
</cfoutput>
ColdFusion 8 is pretty old, so you should check your JVM version. You may be running an outdated version that doesn't account for the new DST rules. See this Adobe forum for more:
"The US day light savings rules changed since that Version of
ColdFusion and it's underlining JRE where released. You need to
update the JRE to at least 1.6.12 to get the new rules."
UPDATED:
After further testing, the JVM is not the issue. I get the same results as above on CF9, and we're already past the time frame where the old rules and new rules would return different results.
However, here are a couple ways you could get the correct result (thanks to Gavin's answer):
function getEpoch(date localDate=now()){
return dateDiff('s', dateConvert('utc2Local', createDateTime(1970, 1, 1, 0, 0, 0)), localDate);
}
Or, you can access the underlying Java method (wrap the result in int() to drop the decimal):
int(createObject('java', 'java.lang.System').currentTimeMillis()/1000);
This is timezone hell. Unix time should be seconds from 1970 in UTC time. But they way Coldfusion and railo do it you need to add seconds from Server time not utc. Convert 1970 to "localServer time" then add seconds then convert back to UTC. It seems that when converting to UTC it just shifts the hour and does not apply UTC DST rules. This is correct:
UTC from UNIX:
CreateODBCDateTime(DateConvert("local2Utc", DateAdd("s", #UNIXTIME#, DateConvert("utc2Local", "January 1 1970 00:00"))) )
UNIX FROM no server local time:
DateDiff("s",DateConvert("utc2Local", "January 1 1970 00:00"), dateAdd('h',-timezone_hours_local_to_server, #LOCALTIME#))

What format is this timestamp, and how can I format it in its own time

I have a problem converting a timestamp in javascript.
I have this timestamp:
2011-10-26T12:00:00-04:00
I have been trying to format it to be readable. So far, it converts this using the local time of my system instead of the GMT offset in the timestamp. I know the timezone that this was created in is EST. I'm in PST, so the times are being offset by 3 hours.
Instead of this showing as:
Wednesday October 26, 2011 12:00 pm
It shows as:
Wednesday October 26, 2011 9:00 am
I have tried a few different solutions, but the latest one is found here: http://blog.stevenlevithan.com/archives/date-time-format
I am less concerned with the formatting part as I am with figuring out how to handle the GMT offsets. Would appreciate any help and insight anyone can provide.
Date objects are created in the local zone. If the date string was created in a different time zone, then you need to adjust the date object to allow for the difference.
The abbreviations PST and EST are ambiguous on the web, there is no standard for time zone abbreviations and some represent two or zones. You should express your zone only in terms of +/- UTC or GMT (which are the same thing, more or less).
You can get the local time zone offset using Date.prototype.getTimezoneOffset, which returns the offset in minutes that must be added to a local time to get UTC. Calculate the offset for where the time string was created and apply it to the created date object (simply add or subtract the difference in minutes as appropriate).
If your time zone is -3hrs, getTimezoneOffset will return +180 for a date object created in that zone. If the string is from a zone -4hrs, its offset is +240. So you can do:
var localDate = new Date('2011-10-26T12:00:00') // date from string;
var originOffset = 240;
var localOffset = localDate.getTimezoneOffset();
localDate.setMinutes( localDate.getMinutes() + originOffset - localOffset );
Adding the origin offset sets it to UTC, subracting the local offset sets it to local time.
It would be much easier if the time string that was sent by the server was in UTC, that way you just apply the local offset.
Edit
IE will not parse a time string with an offset, and Chrome thinks that the above time string is UTC and adjusts for local offset. So don't let Date parse the string, do it manually.
It doesn't matter what time zone you are- the time stamp will result in a different local time for every different time-zone, but they all will be correct, and anyone checking the UTC time of the date will get the same time-stamp:
new Date('2011-10-26T12:00:00-04:00').toUTCString()
returns
Wed, 26 Oct 2011 16:00:00 GMT
and getTime() anywhere returns the same milliseconds universal timestamp:1319644800000

Categories