Timestamp conversion clarification - javascript

I created a jsfiddle here
e.onclick=timeConverter('2014-05-02 22:03:34'); //IF I PASS THIS STRING AS DATE, I GOT THIS: 2,May 2014 22:3:34
e.onclick=timeConverter('2014-05-02T22:03:34.890Z'); //IF I PASS THIS STRING AS DATE, I GOT THIS: 3,May 2014 6:3:34
Does "T" or "Z" in the string matters? If someone can enlighten me, thank you.
HTML:
<input type="button" id="format" value="Format Date">
Javascript:
function timeConverter(UNIX_timestamp){
var s = new Date(UNIX_timestamp).getTime()/1000;
var a = new Date(s*1000);
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
var year = a.getFullYear();
var month = months[a.getMonth()];
var date = a.getDate();
var hour = a.getHours();
var min = a.getMinutes();
var sec = a.getSeconds();
var time = date+','+month+' '+year+' '+hour+':'+min+':'+sec ;
//var time = date+','+month+' '+year+' '+hour+':'+min+':'+sec ;
alert(time);
}
var e = document.getElementById('format');
e.onclick=timeConverter('2014-05-02 22:03:34');
//e.onclick=timeConverter('2014-05-02T22:03:34.890Z');

Check this document here which is a extract of ISO 8601.
'T' is just meant as separator between Time and Date.
'Z' is a special indicator for UTC (+00:00) as time zone
The Problem is, '2014-05-02 22:03:34' is kinda chrome specific formatting as far as i know, which treats this time as your local time. So the difference of exactly 8 hours appear.
So to be on the safe side, always remember to put the Separator in and keep in mind what timezone you are referring to.

see this wiki-article , the Z in your string means that you are using the
local timezone, so thats the reason for the differnce in your alert

According to ECMA-262, accepted datetime format is:
[+YY]YYYY[-MM[-DD]][THH:mm[:ss[.sss]]]Z
Where Z is either Z or + , - followed by HH:mm. If you specify Z at the end of your timestamp, it means the time is in UTC. Since you are living in GMT+8, your browser adds 8 hours to convert it to local time. Therefore, you get 3,May 2014 6:3:34 instead of 2,May 2014 22:3:34.

Related

Date calculation - Daylight saving time (DST) and Timezone issue - Turkey

Date calculation issue in JavaScript on Browser. There are 3 parameters -
From Date, No. of days & To Date
From Date selected using calendar component in JavaScript = 30/10/2016
No. of days entered = 2
Based on no. of days entered "To Date" should be calculated, so as per above input of From date & No. of days calculated "To Date" value should be 01/11/2016 but due to some wrong calculation it's showing 31/10/2016.
Time Zone - Istanbul, Turkey
Please refer below image for code snipped -
As it is clear from code snipped that prototype JavaScript library being used.
dateUtil.prototype.addDays=function(date,noofDays)
{
var _dateData=date.split("/");
var _date=eval(_dateData[0]);
var _month=eval(_dateData[1]);
var _year=eval(_dateData[2]);
var newFormatedDate = new Date(""+_month+"/"+_date+"/"+_year);
var newAddedDate=newFormatedDate.getTime() + noofDays*24*60*60*1000;
var theDate = new Date(newAddedDate);
var dd = theDate.getDate();
var mm = theDate.getMonth()+1; // 0 based
if(mm<10)
mm="0"+mm;
var yy = theDate.getYear();
if (yy < 1000)
yy +=1900; // Y2K fix
var addedDate=""+dd+"/"+mm+"/"+yy;
return addedDate;
}
It seems noofDays*24*60*60*1000 logic is problem where DST is not being considered.
There are 2 timezone showing with the same code but with different date format.
Please could you advise any guidance or read-up on this.
Edit :
JavaScript code added.
Probably not worth posting the code since it has some fundamental errors that should not have survived the new millennium.
var _date = eval(_dateDate[0]);
Don't use eval. There are a small number of cases where it is appropriate, but in general, just don't use it. Ever. The above is the same as:
var _date = _dateDate[0];
Then there is:
var newFormatedDate = new Date('' + _month + '/' + _date + '/' + _year)
You started on the right track by avoiding parsing strings with the Date constructor by splitting the date string into it's parts. But then you undid that good work by creating a new string and parsing it with Date. Just use parts directly:
var newFormatedDate = new Date(_year, _month-1, _date)
which removes all the vagaries of Date parsing and is less to type as well. Also, Date objects don't have a format, so a name like date is fine.
To add n days, just add them to the date:
var date = new Date(_year, _month-1, _date)
date.setDate(date.getDate() + 2);
So your function can be:
function dateUtil(){}
/* Add days to a date
** #param {string} date - date string in dd/mm/yyyy format
** #param {number} noofDays - number of days to add
** #returns {Date}
*/
dateUtil.prototype.addDays = function(date, noofDays) {
var dateData = date.split('/');
var date = new Date(dateData[2], dateData[1] - 1, dateData[0]);
date.setDate(date.getDate() + +noofDays);
return date;
}
var d = new dateUtil();
console.log(d.addDays('23/09/2016',3).toLocaleString());
I've use +noofDays to ensure it's a number. Also, the SO console seems to always write dates as ISO 8601 strings in Z time zone so I've used toLocaleString to keep it in the host time zone.

How do show my javascript date object in users local time, across various browsers?

I have a project where Im reading JSON data and it contains a date string that Im getting in the following syntax:
2015-09-16T10:00:00
I need to take that string and make it a date object and have it be in the format MM/DD/YYYY hh:mm:ss and make sure its in the viewing users timezone automatically
I have the following function so far, but the issues I see are that
1.) I have to add the 'T' between the date and time in my string or firefox and IE9 tells me NaN and the date object I'm creating ISN'T A VALID DATE. (not sure why, but OK, I can live with adding the 'T')
2.) The bigger issue/problem: Firefox currently has this working and it shows the correct time for my time zone (10:00:00)... but in IE9, chrome and safari, it shows 6:00:00.
Question: How do I get the final output date string to ALWAYS be in the correct time (based on users time zone) across browsers without need of an external library?
Heres the function in its current state:
function cleanDateTime(thisdt) {
var d = new Date(thisdt) // CONVERT THE PASSED STRING TO A DATE OBJECT
var cleanedDate = '';
// GET ALL THE DATE PARTS...
var MM = (d.getMonth()+1).toString();
var DD = d.getDate().toString();
var YYYY = d.getFullYear().toString();
var hh = d.getHours().toString();
var mm = (d.getMinutes()<10?'0':'').toString() + d.getMinutes().toString();
var ss = (d.getSeconds()<10?'0':'').toString() + d.getSeconds().toString();
// BUILD THE FINAL DATE STRING FROM THOSE PARTS...
var cleanedDate = ( MM + '/' + DD + '/' + YYYY + ' ' + hh + ':' + mm + ':' + ss )
return cleanedDate;
};
and I call this function like so...
console.log ( cleanDateTime('2015-09-16T10:00:00') );
** UPDATE / PROBLEM SOLVED ( Thanks achan )...
As suggested, Im now using moment.js and I call the function like so to have it show correct time across browsers:
console.log ( cleanDateTime(moment("2015-09-16T10:00:00")) );
You will have to manually split the datestring and pass the individual parts of the date to the Date constructor and make any timezone adjustments in the process, again, manually. Or use moment.js as achan suggested in the comments.
var ds = '2015-09-16T10:00:00';
var dsSplit = ds.split('T');
var dateArr = dsSplit[0].split('-');
var timeArr = dsSplit[1].split(':');
var yr = dateArr[0], mon = dateArr[1], day = dateArr[2];
var hr = timeArr[0], min = timeArr[1], sec = timeArr[2];
var date = new Date(yr, mon, day, hr, min, sec);
There are a number of issues here. Firstly, never pass strings to the Date constructor because its parsing of strings is unreliable to day the least. The string "2015-09-16T10:00:00" is treated as follows:
In ECMA-262 ed 3 parsing is entirely implementation dependent, early versions of IE will not parse ISO 8601 format dates
In ES5, it will be treated as UTC
In ECMAScript 2015, it will be treated as local (which is also consistent with ISO 8601)
So unless you want to leave it to chance, always manually parse date strings.
Given that you can be sure that the string is a valid date, parsing it per ECMAScript 2015 only requires a couple of lines of code. The following functions create a Date based on either UTC or local time, depending on which you want. Of course it's pretty easy to make them one function with a toggle that looks for a trailing Z and uses UTC.
/** #param {string} s - date string in ISO 8601 format
** #returns {Date} - Date from parsing string as a local date time
**/
function parseISODateLocal(s) {
var b = s.split(/\D/);
return new Date(b[0], b[1]-1, b[2], b[3], b[4], b[5]);
}
document.write(parseISODateLocal('2015-09-16T10:00:00') + '<br>');
/** #param {string} s - date string in ISO 8601 format
** #returns {Date} - Date from parsing string as a UTC date time
**/
function parseISODateUTC(s) {
var b = s.split(/\D/);
return new Date(Date.UTC(b[0], b[1]-1, b[2], b[3], b[4], b[5]));
}
document.write(parseISODateUTC('2015-09-16T10:00:00'));
Presenting a date as 9/6/2015 10:00:00 on the web is likely to be very confusing for many since the vast majority of the world's population will expect the order to be day, month, year. Far better to use an unambiguous format using the month name like September 6, 2015 or 6-Sep-2015 or similar.
this is how i did mine...
var d, m, day, yr;
d = new Date();
day = d.getDate();
m = d.getMonth();
yr = d.getFullYear();
document.getElementById("dateObj").value = m + "/" + day + "/" + yr;
thanks for your vote..
momentjs.org
this is also my favorite javascript library (underscore)

Date formatting in moment.js , weird date values

So I have 2 kinds of date coming from json.
m = '201811';
n = '/Date(1433030400000)/';
I am trying to use moment.js to format time, but I can not find appropriate methods for it I guess.
moment(m).format('YYYY DD') //"201811 01"
and the n value I can not understand it leads to this output :
moment(m).format('YYYY DD')//"2015 31"
When you pass a date to moment() constructor, you might have to specify in what format it is.
So for the first date you would need to do:
moment(m, 'YYYYMM').format('YYYY MM'); // if the date is indeed in the form YYYYMM
For the second date, just extract the numeric part from the string and feed it to moment:
var ts = n.match(/(\d+)/);
moment(+ts[1]).format('YYYY DD');
See the snippet:
var m = '201811';
var n = '/Date(1433030400000)/';
alert(moment(m, 'YYYYMM').format('YYYY MM'));
var ts = n.match(/(\d+)/);
moment(+ts[1]).format('YYYY DD');
alert(moment(+ts[1]).format('YYYY MM'));
<script src="http://momentjs.com/downloads/moment.js"></script>
EDIT:
thanks to #MattJohnson, if you have at least moment version 1.3.0, you can simply pass the string in the form /Date(1433030400000)/ to the moment() constructor, and it will automatically detect the proper format, see also here.
Just pass them to moment in the following format:
var m = '201811';
var n = '/Date(1433030400000)/';
var formattedM = window.moment(m, 'YYYYMM').format('YYYY MMM DD'); //2018 Nov 01
var formattedN = window.moment(n).format('YYYY MMM DD'); //2015 May 31
I've dropped an example into jsbin.
Thanks to Matt Johnson for pointing out that moment can take the /Date(1433030400000)/ format.

Convert UTC to standard date time format using javascript

How can I convert a UTC time into proper date - time format using Javascript?
This is what I want to do
var d = new Date("2014-01-01");
var new_d = d.toUTC(); // 1388534400000
var old_d = function(new_d){
// return "2014-01-01" // how can i get this?
}
Now How, can i get orignal date - 2014-01-01 from 1388534400000?
****Also, Please note that when i do this --- new Date(1388534400000); it gives date 1 day less.
That is, instead of giving Jan 01 2014, it gives Dec 31 2013. But, I want Jan 01 2014.****
Is there any method to do the opposite of toUTC() method?
// _________ For those whose toUTC() doesnt work
"toUTC" method works in console of my chrome
See screen shot below
When you pass a string containing hyphens to the Date constructor, it will treat that as UTC. And if you don't pass a time, it will consider it to be midnight. If you are in a time zone that is behind UTC (such as in most of the Americas), you will see the wrong local time conversion.
Here's a screenshot of my chrome dev console, so you can see what I mean
If I pass slashes instead:
Consider using moment.js - which will accept a format parameter that will help you avoid this issue.
Try using the following:
new Date(new_d);
The problem lies with the way you instantiate the Date.
Javascript interpretes the hyphens as an utc date, and slashes as local dates.
Giving the results that mark Explains.
var utcDate = new Date('2014-01-01') // returns a UTC date
var localDate = new Date('2014/01/01'); // Returns local date
But to translate a date back to your starting point string, you can do the following.
function toDateString(utcMillis){
var date = new Date(utcMillis);
d = date.getDate();
m = date.getMonth() +1;
y = date.getFullYear();
return y + '-' + addLeadingZero(m, 2) + '-' + addLeadingZero(d,2);
}
function addLeadingZero(n, length){
n = n+'';
if(n.length<length)
return addLeadingZero('0'+n, length--);
else
return n;
}
If you find yourself with a UTC date, you can still do this:
function toUTCDateString(utcMillis){
var date = new Date(utcMillis);
d = date.getUTCDate();
m = date.getUTCMonth() +1;
y = date.getUTCFullYear();
return y + '-' + addLeadingZero(m, 2) + '-' + addLeadingZero(d,2);
}
To play around with it, and see it for yourself, see this Fiddle:

How to create a date object from string in javascript [duplicate]

This question already has answers here:
Parsing a string to a date in JavaScript
(35 answers)
Closed 5 years ago.
Having this string 30/11/2011. I want to convert it to date object.
Do I need to use :
Date d = new Date(2011,11,30); /* months 1..12? */
or
Date d = new Date(2011,10,30); /* months 0..11? */
?
var d = new Date(2011,10,30);
as months are indexed from 0 in js.
You definitely want to use the second expression since months in JS are enumerated from 0.
Also you may use Date.parse method, but it uses different date format:
var timestamp = Date.parse("11/30/2011");
var dateObject = new Date(timestamp);
The syntax is as follows:
new Date(year, month [, day, hour, minute, second, millisecond ])
so
Date d = new Date(2011,10,30);
is correct; day, hour, minute, second, millisecond are optional.
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date
There are multiple methods of creating date as discussed above. I would not repeat same stuff. Here is small method to convert String to Date in Java Script if that is what you are looking for,
function compareDate(str1){
// str1 format should be dd/mm/yyyy. Separator can be anything e.g. / or -. It wont effect
var dt1 = parseInt(str1.substring(0,2));
var mon1 = parseInt(str1.substring(3,5));
var yr1 = parseInt(str1.substring(6,10));
var date1 = new Date(yr1, mon1-1, dt1);
return date1;
}
Very simple:
var dt=new Date("2011/11/30");
Date should be in ISO format yyyy/MM/dd.
First extract the string like this
var dateString = str.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
Then,
var d = new Date( dateString[3], dateString[2]-1, dateString[1] );
Always, for any issue regarding the JavaScript spec in practical, I will highly recommend the Mozilla Developer Network, and their JavaScript reference.
As it states in the topic of the Date object about the argument variant you use:
new Date(year, month, day [, hour, minute, second, millisecond ])
And about the months parameter:
month Integer value representing the month, beginning with 0 for January to 11 for December.
Clearly, then, you should use the month number 10 for November.
P.S.: The reason why I recommend the MDN is the correctness, good explanation of things, examples, and browser compatibility chart.
I can't believe javascript isn't more consistent with parsing dates. And I hear the default when there is no timezone is gonna change from UTC to local -- hope the web is prepared ;)
I prefer to let Javascript do the heavy lifting when it comes to parsing dates. However it would be nice to handle the local timezone issue fairly transparently. With both of these things in mind, here is a function to do it with the current status quo -- and when Javascript changes it will still work but then can be removed (with a little time for people to catch up with older browsers/nodejs of course).
function strToDate(dateStr)
{
var dateTry = new Date(dateStr);
if (!dateTry.getTime())
{
throw new Exception("Bad Date! dateStr: " + dateStr);
}
var tz = dateStr.trim().match(/(Z)|([+-](\d{2})\:?(\d{2}))$/);
if (!tz)
{
var newTzOffset = dateTry.getTimezoneOffset() / 60;
var newSignStr = (newTzOffset >= 0) ? '-' : '+';
var newTz = newSignStr + ('0' + Math.abs(newTzOffset)).slice(-2) + ':00';
dateStr = dateStr.trim() + newTz;
dateTry = new Date(dateStr);
if (!dateTry.getTime())
{
throw new Exception("Bad Date! dateStr: " + dateStr);
}
}
return dateTry;
}
We need a date object regardless; so createone. If there is a timezone, we are done. Otherwise, create a local timezone string using the +hh:mm format (more accepted than +hhmm).

Categories