JavaScript Date / Time - javascript

I have the following input and i can change the source of this data
Input
var strDate = "/Date(1391402871117+0100)/";
I can convert it to a date using eval, but i really dont want to eval
var DateResult1 = eval ("new Date(1391402871117+0100)");
console.log(DateResult1); // Date {Mon Feb 03 2014 05:47:51 GMT+0100 (Romance Standard Time)}
I did try this, sadly do not work:
// Remove /Date( )/
strDate = strDate.replace(/[^\d+]/g,'');
var DateResult3 = new Date(strDate);
console.log(DateResult3); //Date {Invalid Date}
When i write result of strDate i manual with out " it work.
var DateResult2 = new Date(1391402871117+0100);
console.log(DateResult2); // Date {Mon Feb 03 2014 05:47:51 GMT+0100 (Romance Standard Time)}
How can convert the input data into a date with out using eval or any library?

You are very likely not getting a correct result out of this code:
var DateResult2 = new Date(1391402871117+0100);
The problem is the addition: 1391402871117+0100. 0100 is an octal constant, equal to 64 in decimal, which would add 64 milliseconds to the 1391402871117 timestamp. It seems likely to be indended as a time zone instead, but the Date constructor does not support time zones — only UTC and the local time zone of the browser.
Since UNIX timestamps are actually absolute (they are always in UTC), using just the timestamp would result in a Date instance referencing the correct instant in time, but possibly at another time zone. You can disregard the +0100 part, by converting the "1391402871117+0100" into an integer using parseInt:
strDate = strDate.replace(/[^\d+]/g,'');
var DateResult2 = new Date(parseInt(strDate));

If you can change the data source, as you say, why not do this?
Have your data source generate something like this, to add the timezone offset to the timestamp:
// convert timezone offset hours into seconds and add them to the timestamp
return (unixTimestamp + (timezoneOffsetHours * 3600));
Then you can do something like this in your JS:
// Math.floor works faster than parseInt to convert a string to integer :)
var timestamp = Math.floor(result of above timestamp generation);
var DateResult = new Date(timestamp);
The reason:
new Date() can't handle timezones specified in this way (or at all as far as I can Google)

try by parsing string to int:
var strDate = "/Date(1391402871117+0100)/";
strDate = strDate.replace(/[^\d+]/g, '');
var DateResult3 = new Date(parseInt(strDate.split('+')[0]) + parseInt(strDate.split('+')[1]));
console.log(DateResult3);
Here is Demo

Related

How do I save date/time in some other timezone

I need to save a Date: February 16th, 2017 5PM HST.
The database (Parse) only accepts JS Date. And, my system timezone is IST.
JS Date does not have the ability to save in a different timezone.
To overcome this, I save three variables. Date (Calculated, calculation explained below), Timezone Offset, Timezone
Date is converted using moment.tz(DateObject, Timezone).
But, calling the toDate() function, seems to change it back to IST.
On further examination, I found a _d key to the Moment object, which seems to have the converted datetime in IST.
But, I seem to cannot get it to work.
Any hints would be helpful.
What do you mean by "save in a different timezone"? Timezone is a presentation-layer concern. 01:00+00:00 and 02:00-01:00 are the same time, presented differently. The point in time is represented using a large integer (the timestamp), and this timestamp is the thing you should save.
When you load this timestamp and want to use it again: you can present it from the perspective of any zone you choose.
//-- parsing the user input...
// parse HST (Honolulu Standard Time) date-time
var inputTime = moment.tz("February 16th, 2017 5PM", "MMMM Do, YYYY hA", "Pacific/Honolulu");
// in case you want to double-check that it parsed correctly
var inputTimePrettyPrinted = inputTime.format(); // "2017-02-16T17:00:00-10:00"
// grab timestamp
var timestamp = +inputTime;
//-- presenting the stored timestamp in Indian Standard Time...
// install a timezone definition for Indian Standard Time
moment.tz.add("Asia/Calcutta|HMT BURT IST IST|-5R.k -6u -5u -6u|01232|-18LFR.k 1unn.k HB0 7zX0");
moment.tz.link("Asia/Calcutta|Asia/Kolkata");
var timePresentedInIndianTime = moment(timestamp).tz("Asia/Calcutta");
var indianTimePrettyPrinted = timePresentedInIndianTime.format(); // "2017-02-17T08:30:00+05:30"
Try something like this:
var UTC = new Date();
var UTC = UTC.getTime() // Get UTC Timestamp
var IST = new Date(date); // Clone UTC Timestamp
IST.setHours(IST.getHours() + 5); // set Hours to 5 hours later
IST.setMinutes(IST.getMinutes() + 30); // set Minutes to be 30 minutes later
var EST = new Date(date); // Clone date
EST.setHours(EST.getHours() - 4); // set EST to be 4 hour earlier
You can change according to your need.
You need to use moment tz to add to HST
var now = new Date();
moment.tz.add('HST|HST|a0|0|');
console.clear();
var converted = moment(now).tz("HST").format();
console.log(now);
console.log(converted);
Here is the jsfiddle link
Check console.log for the answer.
Fri Feb 17 2017 18:24:49 GMT+0530 (India Standard Time) //IST time
2017-02-17T02:54:49-10:00 // HST Time

date object returns different date when parsing using D3.time.format

var startDate = new Date('2013-05-13');
var date_format = d3.time.format("%m/%d");
if I do
startDate = date_format(startDate);
I get "05/12" instead of "05/13". Anyone has a clue why is this happening?
Don’t use the Date(string) constructor to parse dates; it varies from browser to browser. The most likely (but not guaranteed) interpretation of "2013-05-13" is as an ISO8601 string in UTC time. Thus, if you run your statement in the JavaScript console, you will see:
> new Date("2013-05-13")
Sun May 12 2013 17:00:00 GMT-0700 (PDT)
The string is interpreted in UTC time by the Date construct, while the returned Date object is in local time. May 13, midnight UTC is May 12 5PM PDT, so when you format it in local time using d3.time.format, you get back May 12.
You could switch to using d3.time.format.utc("%m/%d") to format your date, but then you’re still dependent on the ambiguous behavior of the Date(string) constructor. So, instead…
As #minikomi suggested, you could create a d3.time.format to parse a date string: d3.time.format("%Y-%m-%d"), then format.parse("2013-05-13"). Or you could use the multi-argument Date constructor: new Date(2013, 4, 13), but note that months start at zero rather than the usual one.
You might get more consistent results using a d3.time.format to parse your string as well:
var startDate = '2013-05-13';
var parser = d3.time.format("%Y-%m-%d");
var formatter = d3.time.format("%m/%d");
var startDateString = formatter(parser.parse(startDate));

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.
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)
Return the DateTime as UTC and convert it on the client using .toLocaleString():
#ViewBag.Time = Model.Time.ToUniversalTime().Ticks / TimeSpan.TicksPerMillisecond
<script>
var time = new Date(#ViewBag.Time);
var localTimeString = time.toLocaleString();
alert(localTimeString);
</script>

How to assume local time zone when parsing ISO 8601 date string?

I have a ISO date string as below
var startTimeISOString = "2013-03-10T02:00:00Z";
when I convert it to date object in javascript using below code, it returns
var startTimeDate = new Date(startTimeISOString);
output is
Date {Sun Mar 10 2013 07:30:00 GMT+0530 (India Standard Time)}
It sure converts the ISOString to date but it converts to local time since new Date() is client dependent. How to just convert iso date time string to date and time but not to local date-time..?
Thanks
According to MDN:
Differences in assumed time zone
Given a date string of "March 7, 2014", parse() assumes a local time
zone, but given an ISO format such as "2014-03-07" it will assume a
time zone of UTC. Therefore Date objects produced using those strings
will represent different moments in time unless the system is set with
a local time zone of UTC. This means that two date strings that appear
equivalent may result in two different values depending on the format
of the string that is being converted (this behavior is changed in
ECMAScript ed 6 so that both will be treated as local).
I have done like this and am now getting the exact time which is inside the ISO date string instead of the local time
var startTimeISOString = "2013-03-10T02:00:00Z";
var startTime = new Date(startTimeISOString );
startTime = new Date( startTime.getTime() + ( startTime.getTimezoneOffset() * 60000 ) );
This will give the same date time inside iso date string , the output here is
o/p
Date {Sun Mar 10 2013 02:00:00 GMT+0530 (India Standard Time)}
To sum up the conversation from tracevipin's post:
All Date objects are based on a time value that is milliseconds since 1970-01-01T00:00:00Z so they are UTC at their core. This is different to UNIX, which uses a value that is represents seconds since the same epoch.
The Date.prototype.toString method returns an implementation dependent string that represents the time based on the system settings and timezone offset of the client (aka local time).
If a UTC ISO8601 time string is required, the Date.prototype.toISOString method can be used. It's quite easy to write a "shim" for this methods if required.
Lastly, do not trust Date.parse to parse a string. Support for an ISO8601 format UTC string is specified in ES5, however it's not consistently implemented across browsers in use. It is much better to parse the string manually (it's not hard, there are examples on SO of how to do it) if wide browser support is required (e.g. typical web application).
Simple ISO8601 UTC time stamp parser:
function dateObjectFromUTC(s) {
s = s.split(/\D/);
return new Date(Date.UTC(+s[0], --s[1], +s[2], +s[3], +s[4], +s[5], 0));
}
and here's a shim for toISOString:
if (typeof Date.prototype.toISOString != 'function') {
Date.prototype.toISOString = (function() {
function z(n){return (n<10? '0' : '') + n;}
function p(n){
n = n < 10? z(n) : n;
return n < 100? z(n) : n;
}
return function() {
return this.getUTCFullYear() + '-' +
z(this.getUTCMonth() + 1) + '-' +
z(this.getUTCDate()) + 'T' +
z(this.getUTCHours()) + ':' +
z(this.getUTCMinutes()) + ':' +
z(this.getUTCSeconds()) + '.' +
p(this.getUTCMilliseconds()) + 'Z';
}
}());
}
This happens because date is printed using toString method which by default returns the date and time in local timezone. The method toUTCString will give you the string you need.
Date actually keeps the date as unix time in milliseconds and provides methods to manipulate it.
In vanilla javascript there isn't a way to create a date that assumes the local time of the ISO formatted string you give it. Here's what happens when you pass an ISO 8601 formatted string to javascript. I'm going to use a non UTC time as it illustrates the problem better than using an ISO formatted string:
var startTime = new Date("2013-03-10T02:00:00+06:00"). Note this could also be 2013-03-10T02:00:00Z or any other ISO-formatted string.
read the time, apply the offset and calculate milliseconds since 1970-01-01T00:00:00Z
You now have only milliseconds - you have lost all timezone info. In this case 1362859200000
All functions, apart from the ones that give you a UTC representation of that number, will use the timezone of the computer running the code to interpret that number as a time.
To do what the original poster wants, you need to.
parse the ISO string, interpret the offset ('Z' or '+06:00') as the timezone offset
store the timezone offset
calculate and store the ms since epoch, using the offset timezone offset
hold that offset
whenever attempting to make a calculation or print the date, apply the timezone offset.
This isn't trivial, and requires a complete interpretation of the 8601 spec. Way too much code to put here.
This is exactly what moment.js is designed to do. I strongly recommend using it. Using moment.js:
moment("2013-03-10T02:00:00Z").format()
"2013-03-10T02:00:00Z"
this will result in printing the ISO time of the original string, preserving the offset.
you can try moment js library https://momentjs.com
For my case, I had 2022-10-17T01:00:00 on my database. SO I need to format it to the 01:00:00 AM.
So here was my solution.
var date = "2022-10-17T01:00:00"
var timeFormat = moment(date ).format('HH:mm A');
output: 01:00:00 AM
it will return ISOdate
var getDate = () => {
var dt = new Date();
var off = dt.getTimezoneOffset() * 60000
var newdt = new Date(dt - off).toISOString()
return newdt.slice(0, 19)
}
Output

Formatting a date in javascript till the millisecond

We are using the following js lib from Microsoft
https://ajax.aspnetcdn.com/ajax/4.0/1/MicrosoftAjax.js
var datetimehigh = new Date(2011,01,12,14,45,55,596);
var sDate = datetimehigh.format("dd/MM/yyyy HH:mm:ss sss");
I cannot get the millisecond part to work.Note that format comes from Microsoft's Mvc Ajax lib.
If you are using the native Date javascript object, you can simply use .toISOString method to get a formatted string with milliseconds:
const date = new Date();
const dateString = date.toISOString(); // "2020-01-06T19:57:12.146Z"
Note that using .toString won't give you milliseconds precision.
It's indicated by an f:
"dd/MM/yyyy HH:mm:ss fff"
Use 'S' for milliseconds formatting:
"dd/MM/yyyy HH:mm:ss:SSS"
Using the date format library, it should be something like this:
var nowMilliseconds = new Date().format("yyyy-mm-dd HH:MM:ss l");
http://blog.stevenlevithan.com/archives/date-time-format
L for milliseconds with two digits
l (minus) for milliseconds with three digits
Here's how I do it:
function date_to_string_with_milliseconds(date){
let date_str = date.toString()
let date_without_milliseconds = new Date(date_str) // truncated date since milliseconds are not included
let milliseconds_delta = date - date_without_milliseconds
let date_str_with_milliseconds = date_str.replace(/(^.*:\d\d:\d\d)(.*$)/, `$1:${milliseconds_delta}$2`)
return date_str_with_milliseconds
}
Usage:
date_to_string_with_milliseconds(new Date(Date.now())).toString()
// outputs 'Wed Nov 30 2022 16:40:42:991 GMT+0530 (India Standard Time)'
Doing it this way has a couple of advantages:
The date string that you get as output can be converted back to a
Date object.
This doesn't change the original date object in any
way since you only need a string representation.

Categories