Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

json and Utc datetime

I'm storing Utc datetime on the server and requesting data via json to display on client. The problem is that the server returns the time by its timezone which is different to a client. How could I get the local dateTime to display on client without hardcoding the offset?

I'm using asp.net mvc and stroring date and time in SQL Server 2008 database as 'datetime'. DateTime format in database is 2013-03-29 08:00:00.000.

like image 254
agri Avatar asked Mar 31 '13 00:03

agri


1 Answers

You don't say how the UTC time is represented. It's common to use a UNIX time value that is seconds since 1970-01-01T00:00:00Z. If that is what you are using, you can create a date object on the client by multiplying by 1,000 and giving it to the Date constructor:

var unixTimeValue = '1364694508';
var clientDateObject = new Date(unixTimeValue * 1000);

If you are using say .NET, the value may already be in milliseconds so you don't need to multiply by 1,000. You need to check with the source to see what value is passed and what epoch is used if it's a time value.

Javascript date objects are based on a time value that is the same epoch as UNIX, but uses milliseconds. The standard Date methods (getFullYear, getMonth, getDate, etc.) will return values in the local timezone based on system settings. The UTC methods (getUTCFullYear, getUTCMonth, getUTCDate, etc.) return UTC values for the same time.

So if you are passing a time value, use it to create a date object on the client and read the values using standard methods and you have local equivalents of the UTC time value.

If you are passing a datetime string like 2013-03-31T14:32:22Z, you can convert that to a date object using Date.UTC to convert the string to a time value, then give that to the date constructor:

function dateFromUTCString(s) {
    s = s.split(/[-T:Z]/ig);
    return new Date(Date.UTC(s[0], --s[1], s[2], s[3], s[4], s[5]));
}

var s = '2013-03-31T14:32:22Z';
alert(dateFromUTCString(s));  // Mon Apr 01 2013 00:32:22 GMT+1000 (EST)

If your input string is a different format, you may need to adjust the split pattern and order of parameters passed to Date.UTC.

Edit

If the string format is 2013-03-29 08:00:00.000 (assuming UTC), you can use:

function dateFromUTCString(s) {
    s = s.split(/[\D]/ig);
    return new Date(Date.UTC(s[0], --s[1], s[2], s[3], s[4], s[5], s[6]||0));
}

var s = '2013-03-29 08:00:00.000';
alert(dateFromUTCString(s));  // Fri Mar 29 2013 18:00:00 GMT+1000 (EST)

But be careful of additional spaces. You might want to trim any leading or trailing spaces and ensure there is only one separating the date and time components.

Edit 2

Don't use Date.parse. Until ES5 it was completely implementation dependent. Now it's partially standardised if the string complies with the ISO8601–like format specified by ES5. But that isn't supported by all browsers in use, so not reliable and is otherwise still implementation dependent. The best solution (i.e. one that will work everywhere) is to manually parse the value you are given.

If the format is like: "1364835180000-0700", then you can fairly easily deal with that using a function that subtracts the offset to get UTC time value, the gives that to the date constructor. I'm assuming that -0700 means 7hrs west of Greenwich (javascript timezone offsets have an opposite sense, west of Greenwich is +ve).

Edit 3

Sorry, must have posted the wrong snipped, rushing to a meeting.

// Where s is a time value with offset
function toDate(s) {

  // Include factor to convert mins to ms in sign
  var sign = s.indexOf('-') > -1? 6e4 : -6e4;
  s = s.split(/[\+\-]/);
  var l = s[1].length;

  // Convert offset in milliseconds
  var offset = sign*s[1].substring(l-2,l) + sign*s[1].substring(l-4, l-2)*60;

  // Add offset to time value to get UTC and create date object 
  return new Date(+s[0] + offset);
}

var s = "1364835180000-0700"
alert(toDate(s)); // Tue Apr 02 2013 09:53:00 GMT+1000 (EST)
like image 167
RobG Avatar answered Sep 25 '22 21:09

RobG